Gert van der Knokke
/
C1541III
C1541-III mbed edition
D64_decoder.c@0:28557a4d2215, 2011-08-22 (annotated)
- Committer:
- gertk
- Date:
- Mon Aug 22 05:48:51 2011 +0000
- Revision:
- 0:28557a4d2215
very early test version, works only with FAT16 formatted sd cards
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gertk | 0:28557a4d2215 | 1 | /*----------------------------------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 2 | /* These routines are designed to decode a file according the D64 format */ |
gertk | 0:28557a4d2215 | 3 | /*----------------------------------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 4 | /* */ |
gertk | 0:28557a4d2215 | 5 | |
gertk | 0:28557a4d2215 | 6 | /* History: |
gertk | 0:28557a4d2215 | 7 | -------- |
gertk | 0:28557a4d2215 | 8 | 2007-03-30 added a buffer pointer to the D64blockread function, which is now called D64blockread_new, which gives some room to test the function before changing the entire software at 1000 places... to find out after 3 months i made a small mistake, therefore a temporarily routine with a different name |
gertk | 0:28557a4d2215 | 9 | and for d64blockwrite the same |
gertk | 0:28557a4d2215 | 10 | 2007-03-25 changed the independent BAM_buffer to the DOS_buffer at buffer location #4 (as on a real 1541 drive) |
gertk | 0:28557a4d2215 | 11 | 2006-11-21 added the truncation of everything behind the , or = sign in a save filename (or actually when adding a directory entry) |
gertk | 0:28557a4d2215 | 12 | 2006-10-25 fixed bug in the seekfreeblock, the routine pointed a free block inside track18, this is evil. This bug is fixed. Now a free block for saving purposes will never be allocated in track-18 |
gertk | 0:28557a4d2215 | 13 | 2006-09-09 scratch routine was not completed, it did not set the flags of the used blocks to FREE, FIXED |
gertk | 0:28557a4d2215 | 14 | 2006-09-07 write is maturing, now it is possible to write multiple files to one disk without problems, stil required is working on related actions like file checking error handling |
gertk | 0:28557a4d2215 | 15 | 2006-09-05 a tiny error in buffer copying caused mutilation of the BAM (disk label), fixed |
gertk | 0:28557a4d2215 | 16 | D64SeekFreeBlock did not return correct info causing the previous odd block to be overwritten |
gertk | 0:28557a4d2215 | 17 | added routines "read/write-freeblockspertrack" |
gertk | 0:28557a4d2215 | 18 | 2006-09-04 a small step further with write support, calculation of the track-sector flag was one byte off, fixed |
gertk | 0:28557a4d2215 | 19 | 2006-09-03 oopsie... accidentally swapped the names of the D64 read and write routines, creating all sorts of wierd problems |
gertk | 0:28557a4d2215 | 20 | 2006-09-02 worked on the D64BAMflagtest routine... |
gertk | 0:28557a4d2215 | 21 | 2006-09-01 renamed all routines within this source, now ALL routines start with D64 |
gertk | 0:28557a4d2215 | 22 | 2006-08-28 added 2 more routines to calculate track and sector from block address and vice versa |
gertk | 0:28557a4d2215 | 23 | 2006-07-09 it appears that some files use track=0 sector=0 to indicate that this was the last directory block |
gertk | 0:28557a4d2215 | 24 | this is not compatible with the docs I found which clearly states track=0 sector=255 |
gertk | 0:28557a4d2215 | 25 | 2006-02-03 embedded the calcbyteaddress routine inside a file read routine, makes D64 file access sourcecode much nicer to read |
gertk | 0:28557a4d2215 | 26 | 2006-02-02 improvements in code layout... i.o.w. making it more readable |
gertk | 0:28557a4d2215 | 27 | 2005-09-23 raw design of D64 decoder |
gertk | 0:28557a4d2215 | 28 | 2005-10-18 minor modifications in textual layout (code-cleanup) |
gertk | 0:28557a4d2215 | 29 | */ |
gertk | 0:28557a4d2215 | 30 | |
gertk | 0:28557a4d2215 | 31 | /* TO DO: |
gertk | 0:28557a4d2215 | 32 | ------ |
gertk | 0:28557a4d2215 | 33 | - routine "D64LoadFile_X_Bytes" needs to be updated using the 'newer' D64 routines |
gertk | 0:28557a4d2215 | 34 | |
gertk | 0:28557a4d2215 | 35 | - seek functie plaatsen in "fat16_on_PIC18.C", daar hoort 'ie thuis en niet in de D64 decoding routines |
gertk | 0:28557a4d2215 | 36 | - routines die gebruik maken van stringbuffers in minder code opschrijven |
gertk | 0:28557a4d2215 | 37 | */ |
gertk | 0:28557a4d2215 | 38 | |
gertk | 0:28557a4d2215 | 39 | /*----------------------------------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 40 | |
gertk | 0:28557a4d2215 | 41 | extern void OutputToRS232(); |
gertk | 0:28557a4d2215 | 42 | extern void OutputToLCD(); |
gertk | 0:28557a4d2215 | 43 | |
gertk | 0:28557a4d2215 | 44 | /*--------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 45 | /* includes */ |
gertk | 0:28557a4d2215 | 46 | /*--------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 47 | #include <mbed.h> |
gertk | 0:28557a4d2215 | 48 | #include <stdio.h> |
gertk | 0:28557a4d2215 | 49 | #include <main.h> |
gertk | 0:28557a4d2215 | 50 | #include <hardware.h> |
gertk | 0:28557a4d2215 | 51 | #include <fat.h> |
gertk | 0:28557a4d2215 | 52 | #include <delay.h> |
gertk | 0:28557a4d2215 | 53 | #include <D64_decoder.h> |
gertk | 0:28557a4d2215 | 54 | |
gertk | 0:28557a4d2215 | 55 | /*--------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 56 | /* (tunable) constants */ |
gertk | 0:28557a4d2215 | 57 | /*--------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 58 | |
gertk | 0:28557a4d2215 | 59 | |
gertk | 0:28557a4d2215 | 60 | /*--------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 61 | /* constants */ |
gertk | 0:28557a4d2215 | 62 | /*--------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 63 | #define FALSE 0 /*FALSE*/ |
gertk | 0:28557a4d2215 | 64 | #define TRUE 1 /*TRUE*/ |
gertk | 0:28557a4d2215 | 65 | |
gertk | 0:28557a4d2215 | 66 | /*--------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 67 | /* table */ |
gertk | 0:28557a4d2215 | 68 | /*--------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 69 | /*SPT (SectorsPerTrack) decoding table*/ |
gertk | 0:28557a4d2215 | 70 | /*Attention: TRACK counting starts at '1' (not at '0')*/ |
gertk | 0:28557a4d2215 | 71 | /* SECTOR counting starts at '0' (not at '1')*/ |
gertk | 0:28557a4d2215 | 72 | const unsigned char SPT[41]= {0, /*track 0 does not excist*/ |
gertk | 0:28557a4d2215 | 73 | 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,/*track 1-17*/ |
gertk | 0:28557a4d2215 | 74 | 19,19,19,19,19,19,19, /*track 18-24*/ |
gertk | 0:28557a4d2215 | 75 | 18,18,18,18,18,18, /*track 25-30*/ |
gertk | 0:28557a4d2215 | 76 | 17,17,17,17,17,17,17,17,17,17}; /*track 31-40*/ |
gertk | 0:28557a4d2215 | 77 | |
gertk | 0:28557a4d2215 | 78 | |
gertk | 0:28557a4d2215 | 79 | /*variables*/ |
gertk | 0:28557a4d2215 | 80 | extern struct file2TYPE file; /*file handle*/ |
gertk | 0:28557a4d2215 | 81 | extern struct directory_entry dir_entry; /*directory structure inside the D64*/ |
gertk | 0:28557a4d2215 | 82 | |
gertk | 0:28557a4d2215 | 83 | extern unsigned char error_code; /*this holds the error-message generated by one of the disk routines*/ |
gertk | 0:28557a4d2215 | 84 | extern unsigned char LastTrack; /*last accessed track variable*/ |
gertk | 0:28557a4d2215 | 85 | extern unsigned char LastSector; /*last accessed sector variable*/ |
gertk | 0:28557a4d2215 | 86 | |
gertk | 0:28557a4d2215 | 87 | /*--------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 88 | /* local functions */ |
gertk | 0:28557a4d2215 | 89 | /*--------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 90 | |
gertk | 0:28557a4d2215 | 91 | /*************************************************************************************/ |
gertk | 0:28557a4d2215 | 92 | /*External functions*/ |
gertk | 0:28557a4d2215 | 93 | /*************************************************************************************/ |
gertk | 0:28557a4d2215 | 94 | /*this routine clears the entire block_buffer*/ |
gertk | 0:28557a4d2215 | 95 | void Clear_RAM_buffer(void) |
gertk | 0:28557a4d2215 | 96 | { |
gertk | 0:28557a4d2215 | 97 | unsigned char lp; |
gertk | 0:28557a4d2215 | 98 | |
gertk | 0:28557a4d2215 | 99 | lp=0; |
gertk | 0:28557a4d2215 | 100 | do |
gertk | 0:28557a4d2215 | 101 | { |
gertk | 0:28557a4d2215 | 102 | RAM_buffer[lp] = 0x00; |
gertk | 0:28557a4d2215 | 103 | lp++; |
gertk | 0:28557a4d2215 | 104 | } |
gertk | 0:28557a4d2215 | 105 | while(lp!=0); |
gertk | 0:28557a4d2215 | 106 | } |
gertk | 0:28557a4d2215 | 107 | |
gertk | 0:28557a4d2215 | 108 | |
gertk | 0:28557a4d2215 | 109 | /*this routine will calculate the track and sector based on the given (256bytes, since D64 blocks are 256bytes) block*/ |
gertk | 0:28557a4d2215 | 110 | void D64ConvertBlockToTrackSector(unsigned int block, unsigned char *track, unsigned char *sector) |
gertk | 0:28557a4d2215 | 111 | { |
gertk | 0:28557a4d2215 | 112 | *track = 1; /*Attention: track starts at 1 */ |
gertk | 0:28557a4d2215 | 113 | *sector = 0; /*Attention: sector starts at 0 */ |
gertk | 0:28557a4d2215 | 114 | while(block) |
gertk | 0:28557a4d2215 | 115 | { |
gertk | 0:28557a4d2215 | 116 | *sector = *sector + 1; |
gertk | 0:28557a4d2215 | 117 | if (*sector > (SPT[*track] - 1)) |
gertk | 0:28557a4d2215 | 118 | { |
gertk | 0:28557a4d2215 | 119 | *sector = 0; |
gertk | 0:28557a4d2215 | 120 | *track = *track + 1; |
gertk | 0:28557a4d2215 | 121 | } |
gertk | 0:28557a4d2215 | 122 | block--; |
gertk | 0:28557a4d2215 | 123 | } |
gertk | 0:28557a4d2215 | 124 | } |
gertk | 0:28557a4d2215 | 125 | |
gertk | 0:28557a4d2215 | 126 | /*calculate the D64 block (D64 blocksize is 256 bytes) address determined by the D64-track-sector-byte numbers*/ |
gertk | 0:28557a4d2215 | 127 | unsigned int D64ConvertTrackSectorToBlock(unsigned char track, unsigned char sector) |
gertk | 0:28557a4d2215 | 128 | { |
gertk | 0:28557a4d2215 | 129 | unsigned int block; |
gertk | 0:28557a4d2215 | 130 | |
gertk | 0:28557a4d2215 | 131 | block = 0; |
gertk | 0:28557a4d2215 | 132 | while(track--) |
gertk | 0:28557a4d2215 | 133 | { |
gertk | 0:28557a4d2215 | 134 | block = block + SPT[track]; /*retrieve number of sector per track from table and multiply the number of sectors with 256 (256bytes per sector), add this to the total*/ |
gertk | 0:28557a4d2215 | 135 | } |
gertk | 0:28557a4d2215 | 136 | block = block + sector; |
gertk | 0:28557a4d2215 | 137 | return(block); |
gertk | 0:28557a4d2215 | 138 | } |
gertk | 0:28557a4d2215 | 139 | |
gertk | 0:28557a4d2215 | 140 | /*this routine will read the BAM (and stores it in the BAM_buffer (DOS_buffer[4].buffer[..]), this should be done everytime a new D64 image is selected*/ |
gertk | 0:28557a4d2215 | 141 | void D64ReadBAM(void) |
gertk | 0:28557a4d2215 | 142 | { |
gertk | 0:28557a4d2215 | 143 | /*this routine only supports 35 track disks, since I lack the knowledge of 40 track size disks*/ |
gertk | 0:28557a4d2215 | 144 | |
gertk | 0:28557a4d2215 | 145 | unsigned int lp, block, offset; |
gertk | 0:28557a4d2215 | 146 | |
gertk | 0:28557a4d2215 | 147 | block = D64ConvertTrackSectorToBlock(18,0); /*the block number is a 256byte blocksize, so for a card this would have to be devided by 2*/ |
gertk | 0:28557a4d2215 | 148 | if (block%2 == 0) /*determine is the value was odd ('1' = upper halve) or even ('0' = lower halve)*/ |
gertk | 0:28557a4d2215 | 149 | offset = 0; /*data in lower halve of 512byte block*/ |
gertk | 0:28557a4d2215 | 150 | else |
gertk | 0:28557a4d2215 | 151 | offset = 256; /*data in upper halve of 512byte block*/ |
gertk | 0:28557a4d2215 | 152 | block = block/2; /*convert to a 512byte blocksize (this devides by two and truncates)*/ |
gertk | 0:28557a4d2215 | 153 | FileReadSector_X(&file, block); /*read a 512byte block from the medium*/ |
gertk | 0:28557a4d2215 | 154 | lp = 4; /*copy the data from source to destination*/ |
gertk | 0:28557a4d2215 | 155 | while (lp < 144) |
gertk | 0:28557a4d2215 | 156 | { |
gertk | 0:28557a4d2215 | 157 | DOS_buffer[4].buffer[lp-4] = block_buffer[offset+lp]; |
gertk | 0:28557a4d2215 | 158 | lp++; |
gertk | 0:28557a4d2215 | 159 | } |
gertk | 0:28557a4d2215 | 160 | } |
gertk | 0:28557a4d2215 | 161 | |
gertk | 0:28557a4d2215 | 162 | /*this routine writes the BAM (as stored in the BAM_buffer (DOS_buffer[4].buffer[..]) back to the D64*/ |
gertk | 0:28557a4d2215 | 163 | void D64WriteBAM(void) |
gertk | 0:28557a4d2215 | 164 | { |
gertk | 0:28557a4d2215 | 165 | /*this routine only supports 35 track disks, since I lack the knowledge of 40 track size disks*/ |
gertk | 0:28557a4d2215 | 166 | unsigned char lp; |
gertk | 0:28557a4d2215 | 167 | |
gertk | 0:28557a4d2215 | 168 | D64BlockRead(18,0); /*read the block holding the BAM information*/ |
gertk | 0:28557a4d2215 | 169 | |
gertk | 0:28557a4d2215 | 170 | lp = 0; /*alter the bytes holding the BAM info*/ |
gertk | 0:28557a4d2215 | 171 | while (lp < 140) |
gertk | 0:28557a4d2215 | 172 | { |
gertk | 0:28557a4d2215 | 173 | RAM_buffer[lp+4] = DOS_buffer[4].buffer[lp]; /*copy source to destination*/ |
gertk | 0:28557a4d2215 | 174 | lp++; |
gertk | 0:28557a4d2215 | 175 | } |
gertk | 0:28557a4d2215 | 176 | |
gertk | 0:28557a4d2215 | 177 | D64BlockWrite(18,0); /*write the modified block*/ |
gertk | 0:28557a4d2215 | 178 | } |
gertk | 0:28557a4d2215 | 179 | |
gertk | 0:28557a4d2215 | 180 | /*this routine request the free blocks per sector*/ |
gertk | 0:28557a4d2215 | 181 | unsigned char D64ReadFreeBlocksPerTrack(unsigned char track) |
gertk | 0:28557a4d2215 | 182 | { |
gertk | 0:28557a4d2215 | 183 | unsigned char bytepointer; |
gertk | 0:28557a4d2215 | 184 | |
gertk | 0:28557a4d2215 | 185 | bytepointer = (track-1) << 2; /*multiply value by another 4*/ |
gertk | 0:28557a4d2215 | 186 | return(DOS_buffer[4].buffer[bytepointer]); /*return with requested value*/ |
gertk | 0:28557a4d2215 | 187 | } |
gertk | 0:28557a4d2215 | 188 | |
gertk | 0:28557a4d2215 | 189 | /*this routine request the free blocks per sector*/ |
gertk | 0:28557a4d2215 | 190 | unsigned char D64WriteFreeBlocksPerTrack(unsigned char track, unsigned char value) |
gertk | 0:28557a4d2215 | 191 | { |
gertk | 0:28557a4d2215 | 192 | unsigned char bytepointer; |
gertk | 0:28557a4d2215 | 193 | |
gertk | 0:28557a4d2215 | 194 | bytepointer = (track-1) << 2; /*multiply value by another 4*/ |
gertk | 0:28557a4d2215 | 195 | DOS_buffer[4].buffer[bytepointer] = value; |
gertk | 0:28557a4d2215 | 196 | D64WriteBAM(); /*write the modified BAM to the medium*/ |
gertk | 0:28557a4d2215 | 197 | return(TRUE); /*return with requested value*/ |
gertk | 0:28557a4d2215 | 198 | } |
gertk | 0:28557a4d2215 | 199 | |
gertk | 0:28557a4d2215 | 200 | |
gertk | 0:28557a4d2215 | 201 | /*test the status of the corresponding block-flag, return True if set and False if cleared*/ |
gertk | 0:28557a4d2215 | 202 | unsigned char D64BAMFlagTest(unsigned char track, unsigned char sector) |
gertk | 0:28557a4d2215 | 203 | { |
gertk | 0:28557a4d2215 | 204 | unsigned char bytepointer, bitpointer, lp, mask; |
gertk | 0:28557a4d2215 | 205 | |
gertk | 0:28557a4d2215 | 206 | /*determine in which byte the required track/sector-flag (bit) is located*/ |
gertk | 0:28557a4d2215 | 207 | bytepointer = 1 + (4 * (track-1)) + (sector/8); |
gertk | 0:28557a4d2215 | 208 | bitpointer = sector%8; |
gertk | 0:28557a4d2215 | 209 | |
gertk | 0:28557a4d2215 | 210 | mask = 0x01; /*use a mask to alter the correct flag (bit)*/ |
gertk | 0:28557a4d2215 | 211 | for (lp=bitpointer; lp>0; lp--) |
gertk | 0:28557a4d2215 | 212 | { |
gertk | 0:28557a4d2215 | 213 | mask<<=1; /*shift the byte one bit to the left*/ |
gertk | 0:28557a4d2215 | 214 | } |
gertk | 0:28557a4d2215 | 215 | |
gertk | 0:28557a4d2215 | 216 | if ((DOS_buffer[4].buffer[bytepointer] & mask) == 0) |
gertk | 0:28557a4d2215 | 217 | return(FALSE); |
gertk | 0:28557a4d2215 | 218 | else |
gertk | 0:28557a4d2215 | 219 | return(TRUE); |
gertk | 0:28557a4d2215 | 220 | } |
gertk | 0:28557a4d2215 | 221 | |
gertk | 0:28557a4d2215 | 222 | /*this routine can set/clear (TRUE/FALSE) the appropriate flag of the sepcified track or sector*/ |
gertk | 0:28557a4d2215 | 223 | void D64BAMFlagModify(unsigned char track, unsigned char sector, unsigned status) |
gertk | 0:28557a4d2215 | 224 | { |
gertk | 0:28557a4d2215 | 225 | unsigned char bytepointer, bitpointer, lp, mask; |
gertk | 0:28557a4d2215 | 226 | |
gertk | 0:28557a4d2215 | 227 | /*determine in which byte the required track/sector-flag (bit) is located*/ |
gertk | 0:28557a4d2215 | 228 | bytepointer = 1 + (4 * (track-1)) + (sector/8); |
gertk | 0:28557a4d2215 | 229 | bitpointer = sector%8; |
gertk | 0:28557a4d2215 | 230 | |
gertk | 0:28557a4d2215 | 231 | mask = 0xfe; /*use a mask to alter the correct flag (bit)*/ |
gertk | 0:28557a4d2215 | 232 | for (lp=bitpointer; lp>0; lp--) |
gertk | 0:28557a4d2215 | 233 | { |
gertk | 0:28557a4d2215 | 234 | mask<<=1; /*shift the byte one bit to the left*/ |
gertk | 0:28557a4d2215 | 235 | mask = mask + 1; /*make the LSB 1, since the shift left inserts 0's*/ |
gertk | 0:28557a4d2215 | 236 | } |
gertk | 0:28557a4d2215 | 237 | |
gertk | 0:28557a4d2215 | 238 | DOS_buffer[4].buffer[bytepointer] = DOS_buffer[4].buffer[bytepointer] & mask; |
gertk | 0:28557a4d2215 | 239 | mask = 0xFF - mask; /*invert the mask in order to use the mask to set the bit of the required flag*/ |
gertk | 0:28557a4d2215 | 240 | if (status == TRUE) /*test if the flag needs to be set or cleared*/ |
gertk | 0:28557a4d2215 | 241 | DOS_buffer[4].buffer[bytepointer] = DOS_buffer[4].buffer[bytepointer] | mask; |
gertk | 0:28557a4d2215 | 242 | } |
gertk | 0:28557a4d2215 | 243 | |
gertk | 0:28557a4d2215 | 244 | /*this routine will search for the first free block within the D64 according it's BAM, it returns the track and sector of that block*/ |
gertk | 0:28557a4d2215 | 245 | unsigned char D64SeekFreeBlock(unsigned char *track, unsigned char *sector) |
gertk | 0:28557a4d2215 | 246 | { |
gertk | 0:28557a4d2215 | 247 | /*this routine only supports 35 track disks, since I lack the knowledge of 40 track size disks*/ |
gertk | 0:28557a4d2215 | 248 | *track = 1; |
gertk | 0:28557a4d2215 | 249 | *sector = 0; |
gertk | 0:28557a4d2215 | 250 | |
gertk | 0:28557a4d2215 | 251 | while(!D64BAMFlagTest(*track, *sector)) /*scan the BAM for a free block*/ |
gertk | 0:28557a4d2215 | 252 | { |
gertk | 0:28557a4d2215 | 253 | *sector = *sector + 1; |
gertk | 0:28557a4d2215 | 254 | if (*sector == SPT[*track]) |
gertk | 0:28557a4d2215 | 255 | { |
gertk | 0:28557a4d2215 | 256 | *sector = 0; |
gertk | 0:28557a4d2215 | 257 | *track = * track + 1; |
gertk | 0:28557a4d2215 | 258 | if (*track == 18) /*prevent writing in the directory track*/ |
gertk | 0:28557a4d2215 | 259 | *track = 19; /*so if we reach it... just skip it!!!*/ |
gertk | 0:28557a4d2215 | 260 | } |
gertk | 0:28557a4d2215 | 261 | if (*track > 35) |
gertk | 0:28557a4d2215 | 262 | return(FALSE); /*exit when all tracks are scanned*/ |
gertk | 0:28557a4d2215 | 263 | } |
gertk | 0:28557a4d2215 | 264 | return(TRUE); /*exit with the track and sector of the first free block*/ |
gertk | 0:28557a4d2215 | 265 | } |
gertk | 0:28557a4d2215 | 266 | |
gertk | 0:28557a4d2215 | 267 | /*this routine clear a flag that indicates that the corresponding track is set*/ |
gertk | 0:28557a4d2215 | 268 | unsigned char D64BlockAllocate(unsigned char track, unsigned char sector) |
gertk | 0:28557a4d2215 | 269 | { |
gertk | 0:28557a4d2215 | 270 | if (D64BAMFlagTest(track, sector) == TRUE) |
gertk | 0:28557a4d2215 | 271 | { |
gertk | 0:28557a4d2215 | 272 | D64BAMFlagModify(track, sector, 0); /*clear the flag that indicates the specified track and sector*/ |
gertk | 0:28557a4d2215 | 273 | D64WriteBAM(); /*write the modified BAM to the medium*/ |
gertk | 0:28557a4d2215 | 274 | return(TRUE); /*operation succesfully performed*/ |
gertk | 0:28557a4d2215 | 275 | } |
gertk | 0:28557a4d2215 | 276 | else |
gertk | 0:28557a4d2215 | 277 | { |
gertk | 0:28557a4d2215 | 278 | return(FALSE); /*error:flag was allready cleared*/ |
gertk | 0:28557a4d2215 | 279 | } |
gertk | 0:28557a4d2215 | 280 | } |
gertk | 0:28557a4d2215 | 281 | |
gertk | 0:28557a4d2215 | 282 | /*this routine sets a flag that indicates that the corresponding track is free*/ |
gertk | 0:28557a4d2215 | 283 | unsigned char D64BlockFree(unsigned char track, unsigned char sector) |
gertk | 0:28557a4d2215 | 284 | { |
gertk | 0:28557a4d2215 | 285 | if (D64BAMFlagTest(track, sector) == FALSE) |
gertk | 0:28557a4d2215 | 286 | { |
gertk | 0:28557a4d2215 | 287 | D64BAMFlagModify(track, sector, 1); /*set the flag that indicates the specified track and sector*/ |
gertk | 0:28557a4d2215 | 288 | D64WriteBAM(); /*write the modified BAM to the medium*/ |
gertk | 0:28557a4d2215 | 289 | return(TRUE); /*operation succesfully performed*/ |
gertk | 0:28557a4d2215 | 290 | } |
gertk | 0:28557a4d2215 | 291 | else |
gertk | 0:28557a4d2215 | 292 | { |
gertk | 0:28557a4d2215 | 293 | return(FALSE); /*error:flag was allready set*/ |
gertk | 0:28557a4d2215 | 294 | } |
gertk | 0:28557a4d2215 | 295 | } |
gertk | 0:28557a4d2215 | 296 | |
gertk | 0:28557a4d2215 | 297 | /*this routine reads a block of a req. track-sector of a D64 into the RAM_buffer*/ |
gertk | 0:28557a4d2215 | 298 | void D64BlockRead(unsigned char track, unsigned char sector) |
gertk | 0:28557a4d2215 | 299 | { |
gertk | 0:28557a4d2215 | 300 | unsigned int lp, block, offset; |
gertk | 0:28557a4d2215 | 301 | |
gertk | 0:28557a4d2215 | 302 | block = D64ConvertTrackSectorToBlock(track, sector); /*the block number is a 256byte blocksize, so for a card this would have to be devided by 2*/ |
gertk | 0:28557a4d2215 | 303 | if (block%2 == 0) /*determine is the value was odd ('1' = upper halve) or even ('0' = lower halve)*/ |
gertk | 0:28557a4d2215 | 304 | offset = 0; /*data in lower halve of 512byte block*/ |
gertk | 0:28557a4d2215 | 305 | else |
gertk | 0:28557a4d2215 | 306 | offset = 256; /*data in upper halve of 512byte block*/ |
gertk | 0:28557a4d2215 | 307 | block = block/2; /*convert to a 512byte blocksize (this devides by two and truncates)*/ |
gertk | 0:28557a4d2215 | 308 | FileReadSector_X(&file, block); /*read a 512byte block from the medium*/ |
gertk | 0:28557a4d2215 | 309 | lp = 0; /*copy the data from source to destination*/ |
gertk | 0:28557a4d2215 | 310 | while (lp < 256) |
gertk | 0:28557a4d2215 | 311 | { |
gertk | 0:28557a4d2215 | 312 | RAM_buffer[lp] = block_buffer[offset+lp]; |
gertk | 0:28557a4d2215 | 313 | lp++; |
gertk | 0:28557a4d2215 | 314 | } |
gertk | 0:28557a4d2215 | 315 | } |
gertk | 0:28557a4d2215 | 316 | |
gertk | 0:28557a4d2215 | 317 | /*this routine reads a block of a req. track-sector of a D64 into the RAM_buffer*/ |
gertk | 0:28557a4d2215 | 318 | /*THIS IS THE FUTURE ROUTINE*/ |
gertk | 0:28557a4d2215 | 319 | void D64BlockRead_new(unsigned char buffer, unsigned char track, unsigned char sector) |
gertk | 0:28557a4d2215 | 320 | { |
gertk | 0:28557a4d2215 | 321 | unsigned int lp, block, offset; |
gertk | 0:28557a4d2215 | 322 | |
gertk | 0:28557a4d2215 | 323 | block = D64ConvertTrackSectorToBlock(track, sector); /*the block number is a 256byte blocksize, so for a card this would have to be devided by 2*/ |
gertk | 0:28557a4d2215 | 324 | if (block%2 == 0) /*determine is the value was odd ('1' = upper halve) or even ('0' = lower halve)*/ |
gertk | 0:28557a4d2215 | 325 | offset = 0; /*data in lower halve of 512byte block*/ |
gertk | 0:28557a4d2215 | 326 | else |
gertk | 0:28557a4d2215 | 327 | offset = 256; /*data in upper halve of 512byte block*/ |
gertk | 0:28557a4d2215 | 328 | block = block/2; /*convert to a 512byte blocksize (this devides by two and truncates)*/ |
gertk | 0:28557a4d2215 | 329 | FileReadSector_X(&file, block); /*read a 512byte block from the medium*/ |
gertk | 0:28557a4d2215 | 330 | lp = 0; /*copy the data from source to destination*/ |
gertk | 0:28557a4d2215 | 331 | while (lp < 256) |
gertk | 0:28557a4d2215 | 332 | { |
gertk | 0:28557a4d2215 | 333 | DOS_buffer[buffer].buffer[lp] = block_buffer[offset+lp]; /*read (or to be precise) copy, the data from the media buffer to the DOS_buffer as specified by the user*/ |
gertk | 0:28557a4d2215 | 334 | lp++; |
gertk | 0:28557a4d2215 | 335 | } |
gertk | 0:28557a4d2215 | 336 | } |
gertk | 0:28557a4d2215 | 337 | |
gertk | 0:28557a4d2215 | 338 | /*this routine write the contents of the RAM_buffer to the req. track-sector of the D64 file*/ |
gertk | 0:28557a4d2215 | 339 | void D64BlockWrite(unsigned char track, unsigned char sector) |
gertk | 0:28557a4d2215 | 340 | { |
gertk | 0:28557a4d2215 | 341 | unsigned int lp, block, offset; |
gertk | 0:28557a4d2215 | 342 | |
gertk | 0:28557a4d2215 | 343 | block = D64ConvertTrackSectorToBlock(track, sector); /*the block number is a 256byte blocksize, so for a card this would have to be devided by 2*/ |
gertk | 0:28557a4d2215 | 344 | if (block%2 == 0) /*determine is the value was odd ('1' = upper halve) or even ('0' = lower halve)*/ |
gertk | 0:28557a4d2215 | 345 | offset = 0; /*data in lower halve of 512byte block*/ |
gertk | 0:28557a4d2215 | 346 | else |
gertk | 0:28557a4d2215 | 347 | offset = 256; /*data in upper halve of 512byte block*/ |
gertk | 0:28557a4d2215 | 348 | block = block/2; /*convert to a 512byte blocksize (this devides by two and truncates)*/ |
gertk | 0:28557a4d2215 | 349 | FileReadSector_X(&file, block); /*read a 512byte block from the medium*/ |
gertk | 0:28557a4d2215 | 350 | lp = 0; /*copy the data from source to temp destination*/ |
gertk | 0:28557a4d2215 | 351 | while (lp < 256) |
gertk | 0:28557a4d2215 | 352 | { |
gertk | 0:28557a4d2215 | 353 | block_buffer[offset+lp] = RAM_buffer[lp]; |
gertk | 0:28557a4d2215 | 354 | lp++; |
gertk | 0:28557a4d2215 | 355 | } |
gertk | 0:28557a4d2215 | 356 | |
gertk | 0:28557a4d2215 | 357 | FileWriteSector_X(&file, block); /*write the altered block back to the medium*/ |
gertk | 0:28557a4d2215 | 358 | } |
gertk | 0:28557a4d2215 | 359 | |
gertk | 0:28557a4d2215 | 360 | /*this routine write the contents of the RAM_buffer to the req. track-sector of the D64 file*/ |
gertk | 0:28557a4d2215 | 361 | /*this is the future routine*/ |
gertk | 0:28557a4d2215 | 362 | void D64BlockWrite_new(unsigned char buffer, unsigned char track, unsigned char sector) |
gertk | 0:28557a4d2215 | 363 | { |
gertk | 0:28557a4d2215 | 364 | unsigned int lp, block, offset; |
gertk | 0:28557a4d2215 | 365 | |
gertk | 0:28557a4d2215 | 366 | block = D64ConvertTrackSectorToBlock(track, sector); /*the block number is a 256byte blocksize, so for a card this would have to be devided by 2*/ |
gertk | 0:28557a4d2215 | 367 | if (block%2 == 0) /*determine is the value was odd ('1' = upper halve) or even ('0' = lower halve)*/ |
gertk | 0:28557a4d2215 | 368 | offset = 0; /*data in lower halve of 512byte block*/ |
gertk | 0:28557a4d2215 | 369 | else |
gertk | 0:28557a4d2215 | 370 | offset = 256; /*data in upper halve of 512byte block*/ |
gertk | 0:28557a4d2215 | 371 | block = block/2; /*convert to a 512byte blocksize (this devides by two and truncates)*/ |
gertk | 0:28557a4d2215 | 372 | FileReadSector_X(&file, block); /*read a 512byte block from the medium*/ |
gertk | 0:28557a4d2215 | 373 | lp = 0; /*copy the data from source to temp destination*/ |
gertk | 0:28557a4d2215 | 374 | while (lp < 256) |
gertk | 0:28557a4d2215 | 375 | { |
gertk | 0:28557a4d2215 | 376 | block_buffer[offset+lp] = DOS_buffer[buffer].buffer[lp]; |
gertk | 0:28557a4d2215 | 377 | lp++; |
gertk | 0:28557a4d2215 | 378 | } |
gertk | 0:28557a4d2215 | 379 | |
gertk | 0:28557a4d2215 | 380 | FileWriteSector_X(&file, block); /*write the altered block back to the medium*/ |
gertk | 0:28557a4d2215 | 381 | } |
gertk | 0:28557a4d2215 | 382 | |
gertk | 0:28557a4d2215 | 383 | /*This routine will search for the first dir entry within track 18, it returns the track and sector of the corresponding file*/ |
gertk | 0:28557a4d2215 | 384 | /*mode: 0=first,1=next*/ |
gertk | 0:28557a4d2215 | 385 | unsigned char D64SeekDirEntry(unsigned char mode, unsigned char *track, unsigned char *sector, unsigned char *entry_cnt) |
gertk | 0:28557a4d2215 | 386 | { |
gertk | 0:28557a4d2215 | 387 | static unsigned char entry_counter, CurrentDirTrack, CurrentDirSector, NextDirTrack, NextDirSector; |
gertk | 0:28557a4d2215 | 388 | unsigned char offset; |
gertk | 0:28557a4d2215 | 389 | |
gertk | 0:28557a4d2215 | 390 | switch(mode) |
gertk | 0:28557a4d2215 | 391 | { |
gertk | 0:28557a4d2215 | 392 | case 0: /*read from first directory block (Track 18, Sector 1)*/ |
gertk | 0:28557a4d2215 | 393 | { |
gertk | 0:28557a4d2215 | 394 | NextDirTrack = 18; |
gertk | 0:28557a4d2215 | 395 | NextDirSector = 1; |
gertk | 0:28557a4d2215 | 396 | entry_counter = 0; |
gertk | 0:28557a4d2215 | 397 | break; |
gertk | 0:28557a4d2215 | 398 | } |
gertk | 0:28557a4d2215 | 399 | |
gertk | 0:28557a4d2215 | 400 | case 1: // read from next directory block (Track/Sector) |
gertk | 0:28557a4d2215 | 401 | { |
gertk | 0:28557a4d2215 | 402 | entry_counter++; |
gertk | 0:28557a4d2215 | 403 | if (entry_counter > 7) |
gertk | 0:28557a4d2215 | 404 | entry_counter = 0; |
gertk | 0:28557a4d2215 | 405 | break; |
gertk | 0:28557a4d2215 | 406 | } |
gertk | 0:28557a4d2215 | 407 | } |
gertk | 0:28557a4d2215 | 408 | |
gertk | 0:28557a4d2215 | 409 | *entry_cnt = entry_counter; |
gertk | 0:28557a4d2215 | 410 | |
gertk | 0:28557a4d2215 | 411 | if (entry_counter == 0) |
gertk | 0:28557a4d2215 | 412 | { |
gertk | 0:28557a4d2215 | 413 | if ((NextDirTrack == 0) && ((NextDirSector == 0) || (NextDirSector == 255))) /*officially the only exit would be track=0 sector=255, but also track=0 sector=0 is very common to indicate the last block of an directory*/ |
gertk | 0:28557a4d2215 | 414 | { |
gertk | 0:28557a4d2215 | 415 | return(FALSE); /*end of directory allready reached*/ |
gertk | 0:28557a4d2215 | 416 | } |
gertk | 0:28557a4d2215 | 417 | else |
gertk | 0:28557a4d2215 | 418 | { |
gertk | 0:28557a4d2215 | 419 | D64BlockRead(NextDirTrack, NextDirSector); |
gertk | 0:28557a4d2215 | 420 | CurrentDirTrack = NextDirTrack; |
gertk | 0:28557a4d2215 | 421 | CurrentDirSector = NextDirSector; |
gertk | 0:28557a4d2215 | 422 | NextDirTrack = RAM_buffer[0]; |
gertk | 0:28557a4d2215 | 423 | NextDirSector = RAM_buffer[1]; |
gertk | 0:28557a4d2215 | 424 | } |
gertk | 0:28557a4d2215 | 425 | } |
gertk | 0:28557a4d2215 | 426 | |
gertk | 0:28557a4d2215 | 427 | *track = CurrentDirTrack; |
gertk | 0:28557a4d2215 | 428 | *sector = CurrentDirSector; |
gertk | 0:28557a4d2215 | 429 | |
gertk | 0:28557a4d2215 | 430 | offset = entry_counter * 32; /*each dir entry consists of 32bytes*/ |
gertk | 0:28557a4d2215 | 431 | dir_entry.filetype = RAM_buffer[offset+2]; |
gertk | 0:28557a4d2215 | 432 | dir_entry.track_first_block = RAM_buffer[offset+3]; |
gertk | 0:28557a4d2215 | 433 | dir_entry.sector_first_block = RAM_buffer[offset+4]; |
gertk | 0:28557a4d2215 | 434 | dir_entry.filename[0] = RAM_buffer[offset+5]; |
gertk | 0:28557a4d2215 | 435 | dir_entry.filename[1] = RAM_buffer[offset+6]; |
gertk | 0:28557a4d2215 | 436 | dir_entry.filename[2] = RAM_buffer[offset+7]; |
gertk | 0:28557a4d2215 | 437 | dir_entry.filename[3] = RAM_buffer[offset+8]; |
gertk | 0:28557a4d2215 | 438 | dir_entry.filename[4] = RAM_buffer[offset+9]; |
gertk | 0:28557a4d2215 | 439 | dir_entry.filename[5] = RAM_buffer[offset+10]; |
gertk | 0:28557a4d2215 | 440 | dir_entry.filename[6] = RAM_buffer[offset+11]; |
gertk | 0:28557a4d2215 | 441 | dir_entry.filename[7] = RAM_buffer[offset+12]; |
gertk | 0:28557a4d2215 | 442 | dir_entry.filename[8] = RAM_buffer[offset+13]; |
gertk | 0:28557a4d2215 | 443 | dir_entry.filename[9] = RAM_buffer[offset+14]; |
gertk | 0:28557a4d2215 | 444 | dir_entry.filename[10] = RAM_buffer[offset+15]; |
gertk | 0:28557a4d2215 | 445 | dir_entry.filename[11] = RAM_buffer[offset+16]; |
gertk | 0:28557a4d2215 | 446 | dir_entry.filename[12] = RAM_buffer[offset+17]; |
gertk | 0:28557a4d2215 | 447 | dir_entry.filename[13] = RAM_buffer[offset+18]; |
gertk | 0:28557a4d2215 | 448 | dir_entry.filename[14] = RAM_buffer[offset+19]; |
gertk | 0:28557a4d2215 | 449 | dir_entry.filename[15] = RAM_buffer[offset+20]; |
gertk | 0:28557a4d2215 | 450 | dir_entry.track_first_block_relfile = RAM_buffer[offset+21]; |
gertk | 0:28557a4d2215 | 451 | dir_entry.sector_first_block_relfile = RAM_buffer[offset+22]; |
gertk | 0:28557a4d2215 | 452 | dir_entry.record_size_relfile = RAM_buffer[offset+23]; |
gertk | 0:28557a4d2215 | 453 | dir_entry.unused_1[0] = RAM_buffer[offset+24]; |
gertk | 0:28557a4d2215 | 454 | dir_entry.unused_1[1] = RAM_buffer[offset+25]; |
gertk | 0:28557a4d2215 | 455 | dir_entry.unused_1[2] = RAM_buffer[offset+26]; |
gertk | 0:28557a4d2215 | 456 | dir_entry.unused_1[3] = RAM_buffer[offset+27]; |
gertk | 0:28557a4d2215 | 457 | dir_entry.track_first_block_replacementfile = RAM_buffer[offset+28]; |
gertk | 0:28557a4d2215 | 458 | dir_entry.sector_first_block_replacementfile = RAM_buffer[offset+29]; |
gertk | 0:28557a4d2215 | 459 | dir_entry.blocksize_low_byte = RAM_buffer[offset+30]; |
gertk | 0:28557a4d2215 | 460 | dir_entry.blocksize_high_byte = RAM_buffer[offset+31]; |
gertk | 0:28557a4d2215 | 461 | dir_entry.unused_2[0] = RAM_buffer[offset+32]; |
gertk | 0:28557a4d2215 | 462 | dir_entry.unused_2[1] = RAM_buffer[offset+33]; |
gertk | 0:28557a4d2215 | 463 | |
gertk | 0:28557a4d2215 | 464 | return(TRUE); /*there is more info stored on other track(s)*/ |
gertk | 0:28557a4d2215 | 465 | } |
gertk | 0:28557a4d2215 | 466 | |
gertk | 0:28557a4d2215 | 467 | /*this routine will seek for the next block within the specified file, the first/current block is indicated by track and sector and the next block is returned over the same pointer*/ |
gertk | 0:28557a4d2215 | 468 | /*this routine is usefull for file DELETING/SCRATCHING and VALIDATING of files*/ |
gertk | 0:28557a4d2215 | 469 | unsigned char D64SeekNextBlock(unsigned char *track, unsigned char *sector) |
gertk | 0:28557a4d2215 | 470 | { |
gertk | 0:28557a4d2215 | 471 | D64BlockRead(*track, *sector); |
gertk | 0:28557a4d2215 | 472 | *track = RAM_buffer[0]; |
gertk | 0:28557a4d2215 | 473 | *sector = RAM_buffer[1]; |
gertk | 0:28557a4d2215 | 474 | |
gertk | 0:28557a4d2215 | 475 | if (*track == 0) /*track = 0 indicates the last sector of the file*/ |
gertk | 0:28557a4d2215 | 476 | return(FALSE); /*end of file reached, no further blocks*/ |
gertk | 0:28557a4d2215 | 477 | else |
gertk | 0:28557a4d2215 | 478 | return(TRUE); |
gertk | 0:28557a4d2215 | 479 | } |
gertk | 0:28557a4d2215 | 480 | |
gertk | 0:28557a4d2215 | 481 | /*this routine will add another entry inside the D64*/ |
gertk | 0:28557a4d2215 | 482 | unsigned char D64AddDirEntry(unsigned char ftype, unsigned char tfblock, unsigned char sfblock, unsigned char *fname, unsigned int blocksize, unsigned char tfblock_rel, unsigned char sfblock_rel, unsigned char size_rel, unsigned char tfblock_replace, unsigned char sfblock_replace) |
gertk | 0:28557a4d2215 | 483 | { |
gertk | 0:28557a4d2215 | 484 | unsigned char lp, lp2, offset, result, entry_cnt, fbpt; |
gertk | 0:28557a4d2215 | 485 | unsigned char CurrentDirTrack, CurrentDirSector; |
gertk | 0:28557a4d2215 | 486 | unsigned char NextDirSector; |
gertk | 0:28557a4d2215 | 487 | |
gertk | 0:28557a4d2215 | 488 | result = D64SeekDirEntry(0, &CurrentDirTrack, &CurrentDirSector, &entry_cnt); |
gertk | 0:28557a4d2215 | 489 | while(1) |
gertk | 0:28557a4d2215 | 490 | { |
gertk | 0:28557a4d2215 | 491 | if((result == TRUE) && (dir_entry.filetype == 0x00)) |
gertk | 0:28557a4d2215 | 492 | { |
gertk | 0:28557a4d2215 | 493 | break; |
gertk | 0:28557a4d2215 | 494 | } |
gertk | 0:28557a4d2215 | 495 | |
gertk | 0:28557a4d2215 | 496 | if(result == FALSE) |
gertk | 0:28557a4d2215 | 497 | { |
gertk | 0:28557a4d2215 | 498 | NextDirSector = CurrentDirSector + 1; |
gertk | 0:28557a4d2215 | 499 | if (NextDirSector > (SPT[CurrentDirTrack] -1)) |
gertk | 0:28557a4d2215 | 500 | { |
gertk | 0:28557a4d2215 | 501 | return(FALSE); /*directory is full*/ |
gertk | 0:28557a4d2215 | 502 | } |
gertk | 0:28557a4d2215 | 503 | else |
gertk | 0:28557a4d2215 | 504 | { |
gertk | 0:28557a4d2215 | 505 | D64BlockRead(CurrentDirTrack,CurrentDirSector); /*read the directory block where we need to create our new entry*/ |
gertk | 0:28557a4d2215 | 506 | RAM_buffer[0] = CurrentDirTrack; /*update the next track field, since this was 0 indicating that this was the last dir sector, but now it is the second last*/ |
gertk | 0:28557a4d2215 | 507 | RAM_buffer[1] = NextDirSector; /*update the next sector field*/ |
gertk | 0:28557a4d2215 | 508 | D64BlockWrite(CurrentDirTrack,CurrentDirSector); /*update the new info to the card*/ |
gertk | 0:28557a4d2215 | 509 | CurrentDirSector = NextDirSector; /*now we can state that the new t-s are the current one, since the pointer has been updated*/ |
gertk | 0:28557a4d2215 | 510 | D64BlockAllocate(CurrentDirTrack, CurrentDirSector); /*claim the next block, update the BAM*/ |
gertk | 0:28557a4d2215 | 511 | fbpt = D64ReadFreeBlocksPerTrack(CurrentDirTrack) - 1; /*decrement counter*/ |
gertk | 0:28557a4d2215 | 512 | D64WriteFreeBlocksPerTrack(CurrentDirTrack, fbpt); /*save new value to BAM*/ |
gertk | 0:28557a4d2215 | 513 | break; |
gertk | 0:28557a4d2215 | 514 | } |
gertk | 0:28557a4d2215 | 515 | } |
gertk | 0:28557a4d2215 | 516 | result = D64SeekDirEntry(1, &CurrentDirTrack, &CurrentDirSector, &entry_cnt); |
gertk | 0:28557a4d2215 | 517 | } |
gertk | 0:28557a4d2215 | 518 | D64BlockRead(CurrentDirTrack,CurrentDirSector); /*read the (new) dir-block before we can alter it*/ |
gertk | 0:28557a4d2215 | 519 | offset = entry_cnt * 32; /*each dir entry consists of 32bytes*/ |
gertk | 0:28557a4d2215 | 520 | |
gertk | 0:28557a4d2215 | 521 | RAM_buffer[offset+2] = ftype; |
gertk | 0:28557a4d2215 | 522 | RAM_buffer[offset+3] = tfblock; |
gertk | 0:28557a4d2215 | 523 | RAM_buffer[offset+4] = sfblock; |
gertk | 0:28557a4d2215 | 524 | |
gertk | 0:28557a4d2215 | 525 | /*derive the filename from the command string*/ |
gertk | 0:28557a4d2215 | 526 | lp = 0; |
gertk | 0:28557a4d2215 | 527 | lp2 = 0; |
gertk | 0:28557a4d2215 | 528 | while(lp<16) |
gertk | 0:28557a4d2215 | 529 | { |
gertk | 0:28557a4d2215 | 530 | if ((fname[lp2] !=0) && (fname[lp2] !=',') && (fname[lp2] !='=')) /*check for end of filename, if the string ends with 0 (null-byte, or if the string is separated by a ','-sign or if the string is separated by an '='-sign*/ |
gertk | 0:28557a4d2215 | 531 | { |
gertk | 0:28557a4d2215 | 532 | RAM_buffer[offset+5+lp] = fname[lp2]; |
gertk | 0:28557a4d2215 | 533 | lp2++; |
gertk | 0:28557a4d2215 | 534 | } |
gertk | 0:28557a4d2215 | 535 | else |
gertk | 0:28557a4d2215 | 536 | { |
gertk | 0:28557a4d2215 | 537 | RAM_buffer[offset+5+lp] = 160; /*'padd' the filename with shifted spaces*/ |
gertk | 0:28557a4d2215 | 538 | } |
gertk | 0:28557a4d2215 | 539 | lp++; |
gertk | 0:28557a4d2215 | 540 | } |
gertk | 0:28557a4d2215 | 541 | |
gertk | 0:28557a4d2215 | 542 | RAM_buffer[offset+21] = tfblock_rel; |
gertk | 0:28557a4d2215 | 543 | RAM_buffer[offset+22] = sfblock_rel; |
gertk | 0:28557a4d2215 | 544 | RAM_buffer[offset+23] = size_rel; |
gertk | 0:28557a4d2215 | 545 | |
gertk | 0:28557a4d2215 | 546 | RAM_buffer[offset+24] = 0x00; |
gertk | 0:28557a4d2215 | 547 | RAM_buffer[offset+25] = 0x00; |
gertk | 0:28557a4d2215 | 548 | RAM_buffer[offset+26] = 0x00; |
gertk | 0:28557a4d2215 | 549 | RAM_buffer[offset+27] = 0x00; |
gertk | 0:28557a4d2215 | 550 | |
gertk | 0:28557a4d2215 | 551 | RAM_buffer[offset+28] = tfblock_replace; |
gertk | 0:28557a4d2215 | 552 | RAM_buffer[offset+29] = sfblock_replace; |
gertk | 0:28557a4d2215 | 553 | RAM_buffer[offset+30] = blocksize%256; |
gertk | 0:28557a4d2215 | 554 | RAM_buffer[offset+31] = blocksize/256; |
gertk | 0:28557a4d2215 | 555 | |
gertk | 0:28557a4d2215 | 556 | RAM_buffer[offset+32] = 0x00; |
gertk | 0:28557a4d2215 | 557 | RAM_buffer[offset+33] = 0x00; |
gertk | 0:28557a4d2215 | 558 | |
gertk | 0:28557a4d2215 | 559 | D64BlockWrite(CurrentDirTrack,CurrentDirSector); |
gertk | 0:28557a4d2215 | 560 | return(TRUE); |
gertk | 0:28557a4d2215 | 561 | } |
gertk | 0:28557a4d2215 | 562 | |
gertk | 0:28557a4d2215 | 563 | /*this routine will scratch (alias DELETE) a file entry. Actually, it sets the direntry to scratched and sets all blocks to free, the data is still present and can be retreived if not overwritten by another file*/ |
gertk | 0:28557a4d2215 | 564 | unsigned char D64ScratchDirEntry(unsigned char dirtrack, unsigned char dirsector, unsigned char direntry) |
gertk | 0:28557a4d2215 | 565 | { |
gertk | 0:28557a4d2215 | 566 | unsigned char offset, track, sector, fbpt; |
gertk | 0:28557a4d2215 | 567 | |
gertk | 0:28557a4d2215 | 568 | offset = direntry * 32; /*each dir entry consists of 32bytes*/ |
gertk | 0:28557a4d2215 | 569 | D64BlockRead(dirtrack, dirsector); /*load the directory block of interest*/ |
gertk | 0:28557a4d2215 | 570 | RAM_buffer[offset+2] = 0x00; /*make file of type "SCRatched"*/ |
gertk | 0:28557a4d2215 | 571 | D64BlockWrite(dirtrack, dirsector); /*save the (altered) block back*/ |
gertk | 0:28557a4d2215 | 572 | track = RAM_buffer[offset+3]; /*track of the first block of the file that is to be deleted*/ |
gertk | 0:28557a4d2215 | 573 | sector = RAM_buffer[offset+4]; /*sector of the first block of the file that is to be deleted*/ |
gertk | 0:28557a4d2215 | 574 | D64BlockFree(track, sector); /*free the first block of the file in the BAM*/ |
gertk | 0:28557a4d2215 | 575 | fbpt = D64ReadFreeBlocksPerTrack(track) + 1; /*increment the FreeBlockPerTrack counter*/ |
gertk | 0:28557a4d2215 | 576 | D64WriteFreeBlocksPerTrack(track, fbpt); /*save new value to BAM*/ |
gertk | 0:28557a4d2215 | 577 | |
gertk | 0:28557a4d2215 | 578 | while(D64SeekNextBlock(&track, §or)) |
gertk | 0:28557a4d2215 | 579 | { |
gertk | 0:28557a4d2215 | 580 | D64BlockFree(track, sector); /*free the ... block of the file in the BAM*/ |
gertk | 0:28557a4d2215 | 581 | fbpt = D64ReadFreeBlocksPerTrack(track) + 1; /*increment the FreeBlockPerTrack counter*/ |
gertk | 0:28557a4d2215 | 582 | D64WriteFreeBlocksPerTrack(track, fbpt); /*save new value to BAM*/ |
gertk | 0:28557a4d2215 | 583 | } |
gertk | 0:28557a4d2215 | 584 | return(TRUE); |
gertk | 0:28557a4d2215 | 585 | } |
gertk | 0:28557a4d2215 | 586 | |
gertk | 0:28557a4d2215 | 587 | /*this routine will rename a directory entry*/ |
gertk | 0:28557a4d2215 | 588 | /*the filename to be changed is specified by it's dirtrack, dirsector and entry number within the directory track*/ |
gertk | 0:28557a4d2215 | 589 | /*the new filename is specified in filename*/ |
gertk | 0:28557a4d2215 | 590 | unsigned char D64RenameDirEntry(unsigned char *fname, unsigned char dirtrack, unsigned char dirsector, unsigned char direntry) |
gertk | 0:28557a4d2215 | 591 | { |
gertk | 0:28557a4d2215 | 592 | unsigned char offset, lp, lp2; |
gertk | 0:28557a4d2215 | 593 | |
gertk | 0:28557a4d2215 | 594 | D64BlockRead(dirtrack, dirsector); /*read the block of interest*/ |
gertk | 0:28557a4d2215 | 595 | |
gertk | 0:28557a4d2215 | 596 | offset = direntry * 32; /*each dir entry consists of 32bytes*/ |
gertk | 0:28557a4d2215 | 597 | |
gertk | 0:28557a4d2215 | 598 | /*derive the filename from the command string*/ |
gertk | 0:28557a4d2215 | 599 | lp = 0; |
gertk | 0:28557a4d2215 | 600 | lp2 = 0; |
gertk | 0:28557a4d2215 | 601 | while(lp<16) |
gertk | 0:28557a4d2215 | 602 | { |
gertk | 0:28557a4d2215 | 603 | if (fname[lp2] !=0) |
gertk | 0:28557a4d2215 | 604 | { |
gertk | 0:28557a4d2215 | 605 | RAM_buffer[offset+5+lp] = fname[lp2]; |
gertk | 0:28557a4d2215 | 606 | lp2++; |
gertk | 0:28557a4d2215 | 607 | } |
gertk | 0:28557a4d2215 | 608 | else |
gertk | 0:28557a4d2215 | 609 | { |
gertk | 0:28557a4d2215 | 610 | RAM_buffer[offset+5+lp] = 160; /*'padd' the filename with shifted spaces*/ |
gertk | 0:28557a4d2215 | 611 | } |
gertk | 0:28557a4d2215 | 612 | lp++; |
gertk | 0:28557a4d2215 | 613 | } |
gertk | 0:28557a4d2215 | 614 | |
gertk | 0:28557a4d2215 | 615 | D64BlockWrite(dirtrack, dirsector); /*write back the altered block*/ |
gertk | 0:28557a4d2215 | 616 | return(TRUE); |
gertk | 0:28557a4d2215 | 617 | } |
gertk | 0:28557a4d2215 | 618 | |
gertk | 0:28557a4d2215 | 619 | |
gertk | 0:28557a4d2215 | 620 | /*this routine will read one sector containing up to 8 filename entries from the D64 image directory*/ |
gertk | 0:28557a4d2215 | 621 | /*mode: 0=first,1=next*/ |
gertk | 0:28557a4d2215 | 622 | unsigned char D64LoadFileNameSector(unsigned char mode, unsigned char *dirtrack, unsigned char *dirsector) |
gertk | 0:28557a4d2215 | 623 | { |
gertk | 0:28557a4d2215 | 624 | static unsigned char NextDirTrack, NextDirSector; |
gertk | 0:28557a4d2215 | 625 | |
gertk | 0:28557a4d2215 | 626 | switch(mode) |
gertk | 0:28557a4d2215 | 627 | { |
gertk | 0:28557a4d2215 | 628 | case 0: /*read from first directory block (Track 18, Sector 1)*/ |
gertk | 0:28557a4d2215 | 629 | { |
gertk | 0:28557a4d2215 | 630 | NextDirTrack = 18; |
gertk | 0:28557a4d2215 | 631 | NextDirSector = 1; |
gertk | 0:28557a4d2215 | 632 | break; |
gertk | 0:28557a4d2215 | 633 | } |
gertk | 0:28557a4d2215 | 634 | |
gertk | 0:28557a4d2215 | 635 | case 1: /*read from next directory block (Track , Sector )*/ |
gertk | 0:28557a4d2215 | 636 | { |
gertk | 0:28557a4d2215 | 637 | if ((NextDirTrack == 0) && ((NextDirSector == 0) || (NextDirSector == 255))) /*officially the only exit would be track=0 sector=255, but also track=0 sector=0 is very common to indicate the last block of an directory*/ |
gertk | 0:28557a4d2215 | 638 | return(FALSE); /*end of directory allready reached*/ |
gertk | 0:28557a4d2215 | 639 | break; |
gertk | 0:28557a4d2215 | 640 | } |
gertk | 0:28557a4d2215 | 641 | } |
gertk | 0:28557a4d2215 | 642 | |
gertk | 0:28557a4d2215 | 643 | *dirtrack = NextDirTrack; |
gertk | 0:28557a4d2215 | 644 | *dirsector = NextDirSector; |
gertk | 0:28557a4d2215 | 645 | |
gertk | 0:28557a4d2215 | 646 | D64LoadFile_X_Bytes(&file,NextDirTrack,NextDirSector,0,256); /*location of next directory block*/ |
gertk | 0:28557a4d2215 | 647 | NextDirTrack = block_buffer[0]; |
gertk | 0:28557a4d2215 | 648 | NextDirSector = block_buffer[1]; |
gertk | 0:28557a4d2215 | 649 | return(TRUE); /*there is more info stored on other track(s)*/ |
gertk | 0:28557a4d2215 | 650 | } |
gertk | 0:28557a4d2215 | 651 | |
gertk | 0:28557a4d2215 | 652 | |
gertk | 0:28557a4d2215 | 653 | /*this routine will read the D64 file and adds calculates the total number of free blocks within the D64-file*/ |
gertk | 0:28557a4d2215 | 654 | unsigned int D64LoadFreeBlocks(void) |
gertk | 0:28557a4d2215 | 655 | { |
gertk | 0:28557a4d2215 | 656 | unsigned int FreeBlocks; |
gertk | 0:28557a4d2215 | 657 | unsigned char lp; |
gertk | 0:28557a4d2215 | 658 | |
gertk | 0:28557a4d2215 | 659 | D64LoadFile_X_Bytes(&file,18,0,0,256); /*directory block*/ |
gertk | 0:28557a4d2215 | 660 | FreeBlocks = 0; |
gertk | 0:28557a4d2215 | 661 | lp = 1; |
gertk | 0:28557a4d2215 | 662 | while(lp<=35) /*calculate the number of free blocks that can be used for actual user DATA using all 35 tracks stored in the BAM*/ |
gertk | 0:28557a4d2215 | 663 | { |
gertk | 0:28557a4d2215 | 664 | if (lp != 18) /*exclude the DIRECTORY track, since this track can not store user DATA (it is used by the system)*/ |
gertk | 0:28557a4d2215 | 665 | { |
gertk | 0:28557a4d2215 | 666 | FreeBlocks = FreeBlocks + block_buffer[4*lp]; /*the number of usable blocks is stored every 4 bytes*/ |
gertk | 0:28557a4d2215 | 667 | } |
gertk | 0:28557a4d2215 | 668 | lp++; |
gertk | 0:28557a4d2215 | 669 | } |
gertk | 0:28557a4d2215 | 670 | return(FreeBlocks); |
gertk | 0:28557a4d2215 | 671 | } |
gertk | 0:28557a4d2215 | 672 | |
gertk | 0:28557a4d2215 | 673 | |
gertk | 0:28557a4d2215 | 674 | |
gertk | 0:28557a4d2215 | 675 | /*----------------------------------------------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 676 | /*----------------------------------------------------------------------------------------------*/ |
gertk | 0:28557a4d2215 | 677 | |
gertk | 0:28557a4d2215 | 678 | /*this routine will search (inside the D64) for a file that matches the given filename search pattern*/ |
gertk | 0:28557a4d2215 | 679 | /*If found (TRUE), it return the Track and sector of the first block, as well as the blocksize of the file*/ |
gertk | 0:28557a4d2215 | 680 | unsigned char D64SeekFile(unsigned char *filename, unsigned char *track, unsigned char *sector, unsigned int *blocksize, unsigned char *dirtrack, unsigned char *dirsector, unsigned char *direntry) |
gertk | 0:28557a4d2215 | 681 | { |
gertk | 0:28557a4d2215 | 682 | unsigned char cnt, lp, offset, mode, dtrack, dsector; |
gertk | 0:28557a4d2215 | 683 | |
gertk | 0:28557a4d2215 | 684 | error_code = 0; /*unless we fail we will exit with no error*/ |
gertk | 0:28557a4d2215 | 685 | mode=0; /*set sector read to first sector*/ |
gertk | 0:28557a4d2215 | 686 | while(D64LoadFileNameSector(mode, &dtrack, &dsector)) /*get directory filename sector*/ |
gertk | 0:28557a4d2215 | 687 | { |
gertk | 0:28557a4d2215 | 688 | mode= 1; /*set sector read to next sector*/ |
gertk | 0:28557a4d2215 | 689 | cnt = 0; /*clear file index counter within this sector*/ |
gertk | 0:28557a4d2215 | 690 | while(cnt <8) |
gertk | 0:28557a4d2215 | 691 | { |
gertk | 0:28557a4d2215 | 692 | *dirtrack = dtrack; |
gertk | 0:28557a4d2215 | 693 | *dirsector = dsector; |
gertk | 0:28557a4d2215 | 694 | *direntry = cnt; |
gertk | 0:28557a4d2215 | 695 | offset = 2 + cnt*32; /*calculate the offset for each entry within this sector*/ |
gertk | 0:28557a4d2215 | 696 | if ((block_buffer[offset+0] != 0x00) && (block_buffer[offset+0] != 0x80)) /*scratched files (0x00) are NOT displayed in the directory, and deleted files (0x80) cannot be opened*/ |
gertk | 0:28557a4d2215 | 697 | { |
gertk | 0:28557a4d2215 | 698 | *track = block_buffer[offset+1]; /*the first block with the data of this is stored in track/sector*/ |
gertk | 0:28557a4d2215 | 699 | *sector = block_buffer[offset+2]; |
gertk | 0:28557a4d2215 | 700 | *blocksize = block_buffer[offset+28] + (256*(block_buffer[offset+29])); /*calculate the size of this file (in blocks)*/ |
gertk | 0:28557a4d2215 | 701 | lp = 2; |
gertk | 0:28557a4d2215 | 702 | do |
gertk | 0:28557a4d2215 | 703 | { |
gertk | 0:28557a4d2215 | 704 | // OutputToRS232(); /*set standard output to RS232*/ |
gertk | 0:28557a4d2215 | 705 | // printf("\r\nblock_buffer[%d]=%c filename[%d]=%c",(offset+lp),block_buffer[offset+lp],(lp-3),filename[lp-3]); |
gertk | 0:28557a4d2215 | 706 | // OutputToLCD(); /*set standard output to LCD*/ |
gertk | 0:28557a4d2215 | 707 | lp++; |
gertk | 0:28557a4d2215 | 708 | if (lp == 19) /*when we have reached all to the max number of chars there is no chr$(160)... but we do have a 100% match*/ |
gertk | 0:28557a4d2215 | 709 | return(TRUE); /*we have a 100% match*/ |
gertk | 0:28557a4d2215 | 710 | |
gertk | 0:28557a4d2215 | 711 | if((filename[lp-3] == 0x0D) && (block_buffer[offset+lp] == 160)) /*test if this searchstring ends with a CarriageReturn if so then we DO have a 100% match*/ |
gertk | 0:28557a4d2215 | 712 | return(TRUE); /*we have a 100% match*/ |
gertk | 0:28557a4d2215 | 713 | |
gertk | 0:28557a4d2215 | 714 | if((filename[lp-3] != 0) && (block_buffer[offset+lp] == 160)) /*when the search string has not been ended but the filename has... no match*/ |
gertk | 0:28557a4d2215 | 715 | break; /*we have no match*/ |
gertk | 0:28557a4d2215 | 716 | |
gertk | 0:28557a4d2215 | 717 | if((filename[lp-3] == 0) && (block_buffer[offset+lp] != 160)) /*when the search string has been ended but the filename not... no match*/ |
gertk | 0:28557a4d2215 | 718 | break; /*we have no match*/ |
gertk | 0:28557a4d2215 | 719 | |
gertk | 0:28557a4d2215 | 720 | if((filename[lp-3] == 0) && (block_buffer[offset+lp] == 160)) /*when we have reached all to the end of both strings... we have a 100% match*/ |
gertk | 0:28557a4d2215 | 721 | return(TRUE); /*we have a 100% match*/ |
gertk | 0:28557a4d2215 | 722 | |
gertk | 0:28557a4d2215 | 723 | /*wildcard filter*/ |
gertk | 0:28557a4d2215 | 724 | if (filename[lp-3] == '?') /*when we encounter an '?', it does not matter what the real char of the filename is*/ |
gertk | 0:28557a4d2215 | 725 | block_buffer[offset+lp] = '?'; /*therefore we can replace the real char by a '?' so that the comparison (at the end of this loop) can still be valid*/ |
gertk | 0:28557a4d2215 | 726 | |
gertk | 0:28557a4d2215 | 727 | if (filename[lp-3] == '*') /*when we have come so far and detected a * in our search string... we may consider this a match*/ |
gertk | 0:28557a4d2215 | 728 | return(TRUE); /*we have a partial or possible 100% match... but good enough to return with TRUE*/ |
gertk | 0:28557a4d2215 | 729 | } |
gertk | 0:28557a4d2215 | 730 | while(block_buffer[offset+lp] == filename[lp-3]); /*do the compare of current char of both strings*/ |
gertk | 0:28557a4d2215 | 731 | } |
gertk | 0:28557a4d2215 | 732 | cnt++; |
gertk | 0:28557a4d2215 | 733 | } |
gertk | 0:28557a4d2215 | 734 | } |
gertk | 0:28557a4d2215 | 735 | |
gertk | 0:28557a4d2215 | 736 | OutputToRS232(); /*set standard output to RS232*/ |
gertk | 0:28557a4d2215 | 737 | printf("\r\nfile not found, exitting"); |
gertk | 0:28557a4d2215 | 738 | OutputToLCD(); |
gertk | 0:28557a4d2215 | 739 | |
gertk | 0:28557a4d2215 | 740 | error_code = 62; /*FILE NOT FOUND*/ |
gertk | 0:28557a4d2215 | 741 | return(FALSE); /*no match could be found*/ |
gertk | 0:28557a4d2215 | 742 | } |
gertk | 0:28557a4d2215 | 743 | |
gertk | 0:28557a4d2215 | 744 | unsigned char D64LoadFile_X_Bytes(struct file2TYPE *file, unsigned char track, unsigned char sector, unsigned char byte, unsigned int NmbrOfBytes) |
gertk | 0:28557a4d2215 | 745 | { |
gertk | 0:28557a4d2215 | 746 | unsigned long ByteAddress; |
gertk | 0:28557a4d2215 | 747 | |
gertk | 0:28557a4d2215 | 748 | /*update the variable regarding the last accesses track and sector*/ |
gertk | 0:28557a4d2215 | 749 | LastTrack = track; /*this values is required by the error-read routine*/ |
gertk | 0:28557a4d2215 | 750 | LastSector = sector; /*this values is required by the error-read routine*/ |
gertk | 0:28557a4d2215 | 751 | |
gertk | 0:28557a4d2215 | 752 | /*calculate the byte address determined by the D64-track-sector-byte numbers*/ |
gertk | 0:28557a4d2215 | 753 | ByteAddress = 0; |
gertk | 0:28557a4d2215 | 754 | while(track--) |
gertk | 0:28557a4d2215 | 755 | { |
gertk | 0:28557a4d2215 | 756 | ByteAddress = ByteAddress + 256 * SPT[track]; /*retrieve number of sector per track from table and multiply the number of sectors with 256 (256bytes per sector), add this to the total*/ |
gertk | 0:28557a4d2215 | 757 | } |
gertk | 0:28557a4d2215 | 758 | ByteAddress = ByteAddress + 256 * sector; |
gertk | 0:28557a4d2215 | 759 | ByteAddress = ByteAddress + byte; |
gertk | 0:28557a4d2215 | 760 | |
gertk | 0:28557a4d2215 | 761 | /*read the required data from the card located at the calculated address*/ |
gertk | 0:28557a4d2215 | 762 | FileRead_X_Bytes(file,ByteAddress,NmbrOfBytes); |
gertk | 0:28557a4d2215 | 763 | |
gertk | 0:28557a4d2215 | 764 | return(TRUE); |
gertk | 0:28557a4d2215 | 765 | } |