-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathtape.c
163 lines (147 loc) · 4.12 KB
/
tape.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include <stdio.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "avrlibdefs.h" // global AVRLIB defines
#include "avrlibtypes.h" // global AVRLIB types definitions
#include "tape.h"
#include "display.h"
#include "fat.h"
#include "usart.h"
extern unsigned char atari_sector_buffer[];
extern struct FileInfoStruct FileInfo;
extern void Clear_atari_sector_buffer();
unsigned short block;
unsigned short baud;
void set_tape_baud () {
//UBRR = (F_CPU/16/BAUD)-1 +U2X
USART_Init(F_CPU/16/(baud/2)-1);
}
unsigned int send_tape_block (unsigned int offset) {
unsigned char *p = atari_sector_buffer+BLOCK_LEN-1;
unsigned char i,r;
if (offset < FileInfo.vDisk->size) { //data record
sprintf_P((char*)atari_sector_buffer,PSTR("Block %u / %u "),offset/BLOCK_LEN+1,(FileInfo.vDisk->size-1)/BLOCK_LEN+1);
print_str(35,132,2,Yellow,window_bg, (char*) atari_sector_buffer);
//read block
r = faccess_offset(FILE_ACCESS_READ,offset,BLOCK_LEN);
//shift buffer 3 bytes right
for(i = 0; i < BLOCK_LEN; i++) {
*(p+3) = *p;
p--;
}
if(r < BLOCK_LEN) { //no full record?
atari_sector_buffer[2] = 0xfa; //mark partial record
atari_sector_buffer[130] = r; //set size in last byte
}
else
atari_sector_buffer[2] = 0xfc; //mark full record
offset += r;
}
else { //this is the last/end record
print_str_P(35,132,2,Yellow,window_bg, PSTR("End "));
Clear_atari_sector_buffer(BLOCK_LEN+3);
atari_sector_buffer[2] = 0xfe; //mark end record
offset = 0;
}
atari_sector_buffer[0] = 0x55; //sync marker
atari_sector_buffer[1] = 0x55;
USART_Send_Buffer(atari_sector_buffer,BLOCK_LEN+3);
USART_Transmit_Byte(get_checksum(atari_sector_buffer,BLOCK_LEN+3));
_delay_ms(300); //PRG(0-N) + PRWT(0.25s) delay
return(offset);
}
void check_for_FUJI_file () {
struct tape_FUJI_hdr *hdr = (struct tape_FUJI_hdr *)atari_sector_buffer;
char *p = hdr->chunk_type;
faccess_offset(FILE_ACCESS_READ,0,sizeof(struct tape_FUJI_hdr));
if ( p[0] == 'F' && //search for FUJI header
p[1] == 'U' &&
p[2] == 'J' &&
p[3] == 'I' )
{
tape_flags.FUJI = 1;
}
else {
tape_flags.FUJI = 0;
}
if(tape_flags.turbo) //set fix to
baud = 1000; //1000 baud
else
baud = 600;
set_tape_baud();
block = 0;
return;
}
unsigned int send_FUJI_tape_block (unsigned int offset) {
unsigned short r;
unsigned short gap, len;
unsigned short buflen = 256;
unsigned char first = 1;
struct tape_FUJI_hdr *hdr = (struct tape_FUJI_hdr *)atari_sector_buffer;
char *p = hdr->chunk_type;
while (offset < FileInfo.vDisk->size) {
//read header
faccess_offset(FILE_ACCESS_READ,offset,
sizeof(struct tape_FUJI_hdr));
len = hdr->chunk_length;
if ( p[0] == 'd' && //is a data header?
p[1] == 'a' &&
p[2] == 't' &&
p[3] == 'a' )
{
block++;
break;
}
else if(p[0] == 'b' && //is a baud header?
p[1] == 'a' &&
p[2] == 'u' &&
p[3] == 'd' )
{
if(tape_flags.turbo) //ignore baud hdr
continue;
baud = hdr->irg_length;
set_tape_baud();
}
offset += sizeof(struct tape_FUJI_hdr) + len;
}
gap = hdr->irg_length; //save GAP
len = hdr->chunk_length;
sprintf_P((char*)atari_sector_buffer,
PSTR("Baud: %u Length: %u Gap: %u "),baud, len, gap);
print_str(15,153,1,Green,window_bg, (char*) atari_sector_buffer);
while(gap--)
_delay_ms(1); //wait GAP
if (offset < FileInfo.vDisk->size) { //data record
sprintf_P((char*)atari_sector_buffer,
PSTR("Block %u "),block);
print_str(35,132,2,Yellow,window_bg,
(char*) atari_sector_buffer);
//read block
offset += sizeof(struct tape_FUJI_hdr); //skip chunk hdr
while(len) {
if(len > 256)
len -= 256;
else {
buflen = len;
len = 0;
}
r = faccess_offset(FILE_ACCESS_READ,offset,buflen);
offset += r;
USART_Send_Buffer(atari_sector_buffer,buflen);
if(first && atari_sector_buffer[2] == 0xfe) {
//most multi stage loaders starting over by self
// so do not stop here!
//tape_flags.run = 0;
block = 0;
}
first = 0;
}
if(block == 0)
_delay_ms(200); //add an end gap to be sure
}
else {
//block = 0;
offset = 0;
}
return(offset);
}