hcj@lzaz.ATT.COM (HC Johnson) (09/11/89)
Here is a recapitulation of problems with the ST-minix tos.c. When ST-Minix was first released this program showd up some of the dreary limitations of the C-library. Basicly, its got a 16 bit signed interface. only a pointer got stretched to a long for the 68000. Some of the more obvious bugs fixed. 1. fat size larger that 32K doesnt work. - fix requires adding lsbrk(long) and disk_iol(,,long) 2. the PC algorithm for computing data start allow it to vary by 1 from what TOS wants. - This causes missed reads, and corruption of other files when writing. 3. Sign extension problems writes totally wrong fats if fat number is > 0x7f. (only if hard disk, not a floppy problem). - This RUINS the file system. This works for me. I trust it will work for you. p.s. The last time I posted this, it would print some garbage numbers when it ran into problems. Now it should be more well behaved. Howard C. Johnson ATT Bell Labs att!lzaz!hcj hcj@lzaz.att.com ======cut here===== *** /usr/src/commands/tos.c Thu Oct 29 18:34:28 1988 --- tos.c Thu Nov 18 21:01:07 1988 *************** *** 22,29 **** #include <sys/stat.h> - #undef DEBUG - #define MAX_CLUSTER_SIZE 1024 #define MAX_ROOT_ENTRIES 512 --- 22,27 ---- *************** *** 107,114 **** #define READ 0 #define WRITE 1 ! #define disk_read(s, a, b) disk_io(READ, (s), (a), (b)) ! #define disk_write(s, a, b) disk_io(WRITE, (s), (a), (b)) #define FIND 3 #define LABEL 4 #define ENTRY 5 --- 105,112 ---- #define READ 0 #define WRITE 1 ! #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 FIND 3 #define LABEL 4 #define ENTRY 5 *************** *** 118,124 **** #define new_entry(d, e) directory(d, e, ENTRY, NIL_PTR) #define is_dir(d) ((d)->d_attribute & SUB_DIR) ! #define isHardDisk (device[5] == 'h') #define EOF 0400 #define EOF_MARK '\032' #define STD_OUT 1 --- 116,122 ---- #define new_entry(d, e) directory(d, e, ENTRY, NIL_PTR) #define is_dir(d) ((d)->d_attribute & SUB_DIR) ! #define isHardDisk ((device[5] == 'h')||(device[6] == ':')) #define EOF 0400 #define EOF_MARK '\032' #define STD_OUT 1 *************** *** 135,143 **** long mark; short total_clusters, cluster_size, ! fat_size, ! root_entries, ! sub_entries; long max_cluster; long data_start; --- 133,141 ---- long mark; short total_clusters, cluster_size, ! root_entries, ! sub_entries; ! long fat_size; long max_cluster; long data_start; *************** *** 256,261 **** --- 254,260 ---- print_string( TRUE, "hidden sectors: %L\n", (long)m_nhid ); #endif DEBUG } + char *lsbrk(); main(argc, argv) int argc; *************** *** 336,348 **** fat_size = m_bps * m_spf; data_start = (( (long)m_ndirs * (long)sizeof(DIRECTORY) + (long)fat_size * 2L + ((long)cluster_size - 1L) ) /(long)cluster_size ) *(long)cluster_size; if( isHardDisk ){ data_start += m_bps; /* some heuristic */ } ! max_cluster = total_clusters - (data_start/cluster_size) - 2; root_entries = m_ndirs; --- 335,351 ---- fat_size = m_bps * m_spf; data_start = (( (long)m_ndirs * (long)sizeof(DIRECTORY) + (long)fat_size * 2L + + #ifdef PCMINIX + ((long)cluster_size - 1L) ) /(long)cluster_size ) *(long)cluster_size; if( isHardDisk ){ data_start += m_bps; /* some heuristic */ } ! #else ! + FAT_START)); ! #endif max_cluster = total_clusters - (data_start/cluster_size) - 2; root_entries = m_ndirs; *************** *** 355,371 **** ); exit(1); } ! if( (fat= (unsigned char*)sbrk( fat_size )) <= (unsigned char*)0 ){ print_string(TRUE, "Can't set break!\n" ); exit(1); } ! disk_read(FAT_START, fat, fat_size); #ifdef DEBUG print_string( TRUE, "total_clusters: %L\n", (long)total_clusters ); print_string( TRUE, "cluster_size: %L\n", (long)cluster_size ); print_string( TRUE, "fat_size: %L\n", (long)fat_size ); ! print_string( TRUE, "data_start: %L\n", data_start ); print_string( TRUE, "root_entries: %L\n", (long)root_entries ); print_string( TRUE, "sub_entries: %L\n", (long)sub_entries ); print_string( TRUE, "fat type is %d\n", sh88tosh68( &fat[1] ) ); --- 358,375 ---- ); exit(1); } ! if( (fat= (unsigned char*)lsbrk( fat_size )) <= (unsigned char*)0 ){ print_string(TRUE, "Can't set break!\n" ); exit(1); } ! disk_iol(READ,FAT_START, fat, fat_size); #ifdef DEBUG print_string( TRUE, "total_clusters: %L\n", (long)total_clusters ); print_string( TRUE, "cluster_size: %L\n", (long)cluster_size ); print_string( TRUE, "fat_size: %L\n", (long)fat_size ); ! print_string( TRUE, "data_start: %L bytes (%L blocks)\n", ! data_start, data_start/512 ); print_string( TRUE, "root_entries: %L\n", (long)root_entries ); print_string( TRUE, "sub_entries: %L\n", (long)sub_entries ); print_string( TRUE, "fat type is %d\n", sh88tosh68( &fat[1] ) ); *************** *** 376,381 **** --- 380,387 ---- if (fat_check != fat[0]) { print_string(TRUE, "Disk type in FAT copy differs from disk type in FAT original.\n"); + print_string(TRUE, "copy=%x is=%x fat_size=%L FAT_START=%L\n", + fat_check,fat[0],fat_size,FAT_START); exit(1); } *************** *** 639,646 **** output[index++] = '\r'; lf_pending = FALSE; } ! if (write(fd, output, index) != index) ! bad(); index = 0; return; } --- 645,655 ---- output[index++] = '\r'; lf_pending = FALSE; } ! if (write(fd, output, index) != index) { ! print_string(TRUE,"Failed: write(%L,%L,%L)\n", ! fd,output,(long)index); ! bad(); ! } index = 0; return; } *************** *** 889,895 **** "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; ! modes(mode) register unsigned char mode; { --- 898,919 ---- "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; ! 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); ! } modes(mode) register unsigned char mode; { *************** *** 975,980 **** --- 999,1008 ---- if (number == 0) temp[i++] = '0'; + if(number < 0L) { + temp[i++] = '-'; + number = 0 - number; + } while (number) { temp[i++] = (char) (number % 10L + '0'); number /= 10L; *************** *** 1099,1106 **** } }else{ fat_index= &fat[cl_1 * 2]; ! *(fat_index+1) = (char)cl_2>>8; ! *fat_index = (char)cl_2; } } --- 1127,1134 ---- } }else{ fat_index= &fat[cl_1 * 2]; ! *(fat_index+1) = cl_2>>8; ! *fat_index = cl_2; } } *************** *** 1169,1174 **** --- 1197,1217 ---- *dest++ = *src++; } + 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; + } + } disk_io(op, seek, address, bytes) register BOOL op; unsigned long seek; *************** *** 1177,1182 **** --- 1220,1231 ---- { unsigned int r; + #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 + if (lseek(disk,(long) seek, 0) < 0L) { flush(); print_string(TRUE, "Bad lseek\n"); *************** *** 1189,1194 **** --- 1238,1245 ---- r = write(disk, address, bytes); } if (r != bytes){ + print_string(TRUE,"Failed r/w (%L,%L, %L)\n", + disk,address,(long)bytes); bad(); } }