C1541-III mbed edition

Dependencies:   mbed

Committer:
gertk
Date:
Mon Aug 22 21:11:59 2011 +0000
Revision:
1:0cbbb66a6100
Parent:
0:28557a4d2215
updated the nRESET pin to an interrupt capable pin (p29)

Who changed what in which revision?

UserRevisionLine numberNew 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, &sector))
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 }