hcj@lzaz.ATT.COM (HC Johnson) (11/14/88)
# ===================================================================== # I just realized that the problems in reading the fat area into memory # arrise on the Atari from the cluster size of 2. MS/DOS would have # used clusters of 8 for large file systems. # # Summary of problems found with tos.c: # 1. data_start. Apparently MS/DOS may skip a disk block in positioning # cluster number 2. ATARI always positions data_start after the # directory. # 2. FAT size can be > 2^15. ATARI always uses a cluster size of 2 which # lets the fat get large. This showed up to problems using 16 bit ints. # A. sbrk(integer) cannot allocate the fat size. This is correct behavior # as sbrk(a negative number) is valid. The internal routine lsbrk # was added to solve this problem. # B. read(....,unsigned int) fails. This is mostly due to the message # passing defines, which call all 16 bit quantities integers, rather # than unsigned integers. THIS is a BUG!. # 3. When new clusters are added to a fat on the hard disk, there is a gross # sign extension problem, causing fat 80 to be written as ff80. This # was caused by erroneously adding a (char) cast where one was not needed. # # This is a diff of my tos.c with the original. # ===================================================================== 20d19 < #define ATARI 1 25a25,26 > #undef DEBUG > 109,110c110,111 < #define disk_read(s, a, b) disk_io(READ, (s), (a), (short)(b)) < #define disk_write(s, a, b) disk_io(WRITE, (s), (a), (short)(b)) --- > #define disk_read(s, a, b) disk_io(READ, (s), (a), (b)) > #define disk_write(s, a, b) disk_io(WRITE, (s), (a), (b)) 137,139c138,140 < root_entries, < sub_entries; < long fat_size; --- > fat_size, > root_entries, > sub_entries; 258d258 < char *lsbrk(); 339,344d338 < < /* MSDOS positions the data start differently from ATARI; < ATARI is always adjacent to the directory < */ < < #if !ATARI 351,353c345 < #else < + FAT_START)); < #endif --- > 366,369c358 < /* We cannot use sbrk as it is (properly) defined as accepting a signed int < * and fat_size may be > 2^15. < */ < if( (fat= (unsigned char*)lsbrk( fat_size )) <= (unsigned char*)0 ){ --- > if( (fat= (unsigned char*)sbrk( fat_size )) <= (unsigned char*)0 ){ 373,377c362 < /* We cannot use disk_io, as it (incorrectly) only accepts a signed int < * and fat_size may be > 2^15. < * likely the correct fix is to change the library. < */ < disk_iol(READ,FAT_START, fat, fat_size); --- > disk_read(FAT_START, fat, fat_size); 383,384c368 < print_string( TRUE, "data_start: %L bytes (%L blocks)\n", < data_start, data_start/512 ); --- > print_string( TRUE, "data_start: %L\n", data_start ); 395,396d378 < print_string(TRUE, "copy=%x is=%x fat_size=%L FAT_START=%L\n", < fat_check,fat[0],fat_size,FAT_START); 660,664c642,643 < if (write(fd, output, index) != index) { < print_string(TRUE,"Failed: write(%L,%L,%L)\n", < fd,output,(long)index); < bad(); < } --- > if (write(fd, output, index) != index) > bad(); 914,933d892 < /* sbrk is defined as accepting a signed int. passing it a number > 2^15 < * causes it to release memory. < * Thus, lsbrk calls sbrk multiple times. < */ < char * < lsbrk(l) < long l; < { < char *cp,*r; < short sl; < < cp = sbrk(0); < while(l) { < sl = l>0x7ff0L?0x7ff0:l; < if((r=sbrk(sl)) <= (char*)0) < return(r); < l -= sl; < } < return(cp); < } 1019,1022d977 < if(number < 0L) { < temp[i++] = '-'; < number = 0 - number; < } 1147,1148c1102,1103 < *(fat_index+1) = cl_2>>8; /* NO char CAST */ < *fat_index = cl_2; /* NO char CAST */ --- > *(fat_index+1) = (char)cl_2>>8; > *fat_index = (char)cl_2; 1217,1233d1171 < /* Break up the reads in to something less than 2^15 */ < < disk_iol(op, seek, address, bytes) < register BOOL op; < unsigned long seek; < unsigned long address; < register unsigned long bytes; < { < unsigned short shbytes; < while(bytes) { < shbytes = bytes > 0x7ff0L? 0x7ff0: bytes; < disk_io(op,seek,address,shbytes); < seek += shbytes; < address += shbytes; < bytes -= shbytes; < } < } 1242,1247d1179 < #ifdef DEBUG < print_string(TRUE,"%s: seek=%L block=%d size=%d\n", < (op==READ?"READ":"WRITE"), < seek,(int)(seek>>9),(int)(bytes>>9)); < #endif < 1260,1261d1191 < print_string(TRUE,"Failed r/w (%L,%L, %L)\n", < disk,address,(long)bytes); #===================================================================== Howard C. Johnson ATT Bell Labs ...lzaz!hcj