diff --git a/sys/sys.c b/sys/sys.c index 7114bc6..4cd08d0 100644 --- a/sys/sys.c +++ b/sys/sys.c @@ -25,11 +25,55 @@ 675 Mass Ave, Cambridge, MA 02139, USA. ***************************************************************/ +/* Revision 2.0 tomehlert 2001/4/26 + + no direct access to the disk any more, this is FORMAT's job + no floppy.asm anymore, no segmentation problems. + no access to partition tables + + instead copy boot sector using int25/int26 = absdiskread()/write + + if xxDOS is able to handle the disk, SYS should work + + additionally some space savers: + + replaced fopen() by open() + + included (slighly modified) PRF.c from kernel + + size is no ~7500 byte vs. ~13690 before + +*/ /* $Log$ - * Revision 1.5 2001/03/25 17:11:54 bartoldeman - * Fixed sys.com compilation. Updated to 2023. Also: see history.txt. + * Revision 1.6 2001/04/29 17:34:41 bartoldeman + * /* Revision 2.1 tomehlert 2001/4/26 * + * changed the file system detection code. + * */ + * + * /* Revision 2.0 tomehlert 2001/4/26 + * + * no direct access to the disk any more, this is FORMAT's job + * no floppy.asm anymore, no segmentation problems. + * no access to partition tables + * + * instead copy boot sector using int25/int26 = absdiskread()/write + * + * if xxDOS is able to handle the disk, SYS should work + * + * additionally some space savers: + * + * replaced fopen() by open() + * + * included (slighly modified) PRF.c from kernel + * + * size is no ~7500 byte vs. ~13690 before + * */ + * +/* Revision 1.5 2001/03/25 17:11:54 bartoldeman +/* Fixed sys.com compilation. Updated to 2023. Also: see history.txt. +/* /* Revision 1.4 2000/08/06 05:50:17 jimtabor /* Add new files and update cvs with patches and changes /* @@ -80,108 +124,42 @@ * */ +/* + TE thinks, that the boot info storage should be done by FORMAT, noone else + + unfortunately, that doesn't work ??? +*/ #define STORE_BOOT_INFO +#define DEBUG + #include #include #include -/*#include */ +#include #include #include #include #include #include "portab.h" -#include "device.h" #include "b_fat12.h" #include "b_fat16.h" -BYTE *pgm = "sys"; +BYTE pgm[] = "sys"; -BOOL fl_reset(WORD); -COUNT fl_rd_status(WORD); -COUNT fl_read(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); -COUNT fl_write(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); -BOOL fl_verify(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); -BOOL fl_format(WORD, BYTE FAR *); -VOID get_boot(COUNT); -VOID put_boot(COUNT); +void put_boot(COUNT); BOOL check_space(COUNT, BYTE *); -COUNT ltop(WORD *, WORD *, WORD *, COUNT, COUNT, LONG, byteptr); BOOL copy(COUNT, BYTE *); -BOOL DiskReset(COUNT); COUNT DiskRead(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); COUNT DiskWrite(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); -/* special word packing prototypes */ - -#ifdef NATIVE -#define getlong(vp, lp) (*(LONG *)(lp)=*(LONG *)(vp)) -#define getword(vp, wp) (*(WORD *)(wp)=*(WORD *)(vp)) -#define getbyte(vp, bp) (*(BYTE *)(bp)=*(BYTE *)(vp)) -#define fgetlong(vp, lp) (*(LONG FAR *)(lp)=*(LONG FAR *)(vp)) -#define fgetword(vp, wp) (*(WORD FAR *)(wp)=*(WORD FAR *)(vp)) -#define fgetbyte(vp, bp) (*(BYTE FAR *)(bp)=*(BYTE FAR *)(vp)) -#define fputlong(lp, vp) (*(LONG FAR *)(vp)=*(LONG FAR *)(lp)) -#define fputword(wp, vp) (*(WORD FAR *)(vp)=*(WORD FAR *)(wp)) -#define fputbyte(bp, vp) (*(BYTE FAR *)(vp)=*(BYTE FAR *)(bp)) -#else -VOID getword(VOID *, WORD *); -VOID getbyte(VOID *, BYTE *); -VOID fgetlong(VOID FAR *, LONG FAR *); -VOID fgetword(VOID FAR *, WORD FAR *); -VOID fgetbyte(VOID FAR *, BYTE FAR *); -VOID fputlong(LONG FAR *, VOID FAR *); -VOID fputword(WORD FAR *, VOID FAR *); -VOID fputbyte(BYTE FAR *, VOID FAR *); -#endif #define SEC_SIZE 512 -#define NDEV 4 #define COPY_SIZE 32768 -#define NRETRY 5 -static struct media_info -{ - ULONG mi_size; /* physical sector size */ - UWORD mi_heads; /* number of heads (sides) */ - UWORD mi_cyls; /* number of cyl/drive */ - UWORD mi_sectors; /* number of sectors/cyl */ - ULONG mi_offset; /* relative partition offset */ -}; -union -{ - BYTE bytes[2 * SEC_SIZE]; - boot boot_sector; -} - buffer; - -static struct media_info miarray[NDEV] = -{ - {720l, 2, 40, 9, 0l}, - {720l, 2, 40, 9, 0l}, - {720l, 2, 40, 9, 0l}, - {720l, 2, 40, 9, 0l} -}; - -#define PARTOFF 0x1be -#define N_PART 4 - -static struct -{ - BYTE peBootable; - BYTE peBeginHead; - BYTE peBeginSector; - UWORD peBeginCylinder; - BYTE peFileSystem; - BYTE peEndHead; - BYTE peEndSector; - UWORD peEndCylinder; - LONG peStartSector; - LONG peSectors; -} partition[N_PART]; struct bootsectortype { @@ -213,164 +191,87 @@ struct bootsectortype }; -static int DrvMap[4] = -{0, 1, 0x80, 0x81}; -COUNT drive, active; +COUNT drive; UBYTE newboot[SEC_SIZE], oldboot[SEC_SIZE]; -#ifdef DEBUG -FILE *log; -#endif -#define SBSIZE 51 #define SBOFFSET 11 +#define SBSIZE (sizeof(struct bootsectortype) - SBOFFSET) -#define SIZEOF_PARTENT 16 -#define FAT12 0x01 -#define FAT16SMALL 0x04 -#define EXTENDED 0x05 -#define FAT16LARGE 0x06 - -#define N_RETRY 5 - -COUNT get_part(COUNT drive, COUNT idx) -{ - REG retry = N_RETRY; - REG BYTE *p = (BYTE *) & buffer.bytes[PARTOFF + (idx * SIZEOF_PARTENT)]; - REG ret; - BYTE packed_byte, pb1; - - do - { - ret = fl_read((WORD) DrvMap[drive], (WORD) 0, (WORD) 0, (WORD) 1, (WORD) 1, (byteptr) & buffer); - } - while (ret != 0 && --retry > 0); - if (ret != 0) - return FALSE; - getbyte((VOID *) p, &partition[idx].peBootable); - ++p; - getbyte((VOID *) p, &partition[idx].peBeginHead); - ++p; - getbyte((VOID *) p, &packed_byte); - partition[idx].peBeginSector = packed_byte & 0x3f; - ++p; - getbyte((VOID *) p, &pb1); - ++p; - partition[idx].peBeginCylinder = pb1 + ((0xc0 & packed_byte) << 2); - getbyte((VOID *) p, &partition[idx].peFileSystem); - ++p; - getbyte((VOID *) p, &partition[idx].peEndHead); - ++p; - getbyte((VOID *) p, &packed_byte); - partition[idx].peEndSector = packed_byte & 0x3f; - ++p; - getbyte((VOID *) p, &pb1); - ++p; - partition[idx].peEndCylinder = pb1 + ((0xc0 & packed_byte) << 2); - getlong((VOID *) p, &partition[idx].peStartSector); - p += sizeof(LONG); - getlong((VOID *) p, &partition[idx].peSectors); - return TRUE; -} VOID main(COUNT argc, char **argv) { printf("FreeDOS System Installer v1.0\n\n"); - if (argc != 2) + if (argc != 2) { - fprintf(stderr, "Usage: %s drive\n drive = A,B,etc.\n", pgm); + printf("Usage: %s drive\n drive = A,B,etc.\n", pgm); exit(1); } - drive = *argv[1] - (islower(*argv[1]) ? 'a' : 'A'); - if (drive < 0 || drive >= NDEV) + drive = toupper(*argv[1]) - 'A'; + if (drive < 0 || drive >= 26) { - fprintf(stderr, "%s: drive out of range\n", pgm); + printf( "%s: drive %c must be A:..Z:\n", pgm,*argv[1]); exit(1); } - if (!DiskReset(drive)) - { - fprintf(stderr, "%s: cannot reset drive %c:", - drive, 'A' + drive); - exit(1); - } - - get_boot(drive); if (!check_space(drive, oldboot)) { - fprintf(stderr, "%s: Not enough space to transfer system files\n", pgm); + printf("%s: Not enough space to transfer system files\n", pgm); exit(1); } -#ifdef DEBUG - if ((log = fopen("sys.log", "w")) == NULL) - { - printf("Can't write log file.\n"); - log = NULL; - } -#endif - - printf("Writing boot sector...\n"); - put_boot(drive); printf("\nCopying KERNEL.SYS..."); if (!copy(drive, "kernel.sys")) { - fprintf(stderr, "\n%s: cannot copy \"KERNEL.SYS\"\n", pgm); -#ifdef DEBUG - fclose(log); -#endif + printf("\n%s: cannot copy \"KERNEL.SYS\"\n", pgm); exit(1); } printf("\nCopying COMMAND.COM..."); if (!copy(drive, "command.com")) { - fprintf(stderr, "\n%s: cannot copy \"COMMAND.COM\"\n", pgm); -#ifdef DEBUG - fclose(log); -#endif + printf("\n%s: cannot copy \"COMMAND.COM\"\n", pgm); exit(1); } - printf("\nSystem transfered.\n"); -#ifdef DEBUG - fclose(log); -#endif + + printf("\nWriting boot sector...\n"); + put_boot(drive); + + printf("\nSystem transferred.\n"); exit(0); } #ifdef DEBUG VOID dump_sector(unsigned char far * sec) { - if (log) - { COUNT x, y; char c; for (x = 0; x < 32; x++) { - fprintf(log, "%03X ", x * 16); + printf("%03X ", x * 16); for (y = 0; y < 16; y++) { - fprintf(log, "%02X ", sec[x * 16 + y]); + printf("%02X ", sec[x * 16 + y]); } for (y = 0; y < 16; y++) { c = oldboot[x * 16 + y]; if (isprint(c)) - fprintf(log, "%c", c); + printf( "%c", c); else - fprintf(log, "."); + printf( "."); } - fprintf(log, "\n"); - } - fprintf(log, "\n"); - } + printf( "\n"); + } + + printf( "\n"); } #endif @@ -383,306 +284,154 @@ VOID put_boot(COUNT drive) WORD count; ULONG temp; struct bootsectortype *bs; - - if (drive >= 2) - { - head = partition[active].peBeginHead; - sector = partition[active].peBeginSector; - track = partition[active].peBeginCylinder; - } - else - { - head = 0; - sector = 1; - track = 0; - } - - /* Read current boot sector */ - if ((i = DiskRead(DrvMap[drive], head, track, sector, 1, (BYTE far *) oldboot)) != 0) - { - fprintf(stderr, "%s: disk read error (code = 0x%02x)\n", pgm, i & 0xff); - exit(1); - } + #ifdef DEBUG - fprintf(log, "Old Boot Sector:\n"); + printf("Reading old bootsector from drive %c:\n",drive+'A'); +#endif + + if (absread(drive, 1, 0, oldboot) != 0) + { + printf("can't read old boot sector for drive %c:\n", drive +'A'); + exit(1); + } + + +#ifdef DDEBUG + printf("Old Boot Sector:\n"); dump_sector(oldboot); #endif + bs = (struct bootsectortype *) & oldboot; if ((bs->bsFileSysType[4] == '6') && (bs->bsBootSignature == 0x29)) { memcpy(newboot, b_fat16, SEC_SIZE); /* copy FAT16 boot sector */ printf("FAT type: FAT16\n"); -#ifdef DEBUG - fprintf(log, "FAT type: FAT16\n"); -#endif } else { memcpy(newboot, b_fat12, SEC_SIZE); /* copy FAT12 boot sector */ printf("FAT type: FAT12\n"); -#ifdef DEBUG - fprintf(log, "FAT type: FAT12\n"); -#endif } /* Copy disk parameter from old sector to new sector */ memcpy(&newboot[SBOFFSET], &oldboot[SBOFFSET], SBSIZE); bs = (struct bootsectortype *) & newboot; - /* root directory sectors */ + #ifdef STORE_BOOT_INFO + /* TE thinks : never, see above */ + /* temporary HACK for the load segment (0x0060): it is in unused */ + /* only needed for older kernels */ + *((UWORD *)(bs->unused)) = *((UWORD *)(((struct bootsectortype *)&b_fat16)->unused)); + /* end of HACK */ + /* root directory sectors */ + bs->sysRootDirSecs = bs->bsRootDirEnts / 16; -#endif -#ifdef DEBUG - fprintf(log, "root dir entries = %u\n", bs->bsRootDirEnts); - fprintf(log, "root dir sectors = %u\n", bs->sysRootDirSecs); -#endif - /* sector FAT starts on */ + /* sector FAT starts on */ temp = bs->bsHiddenSecs + bs->bsResSectors; -#ifdef STORE_BOOT_INFO bs->sysFatStart = temp; -#endif -#ifdef DEBUG - fprintf(log, "FAT starts at sector %lu = (%lu + %u)\n", temp, - bs->bsHiddenSecs, bs->bsResSectors); -#endif - - /* sector root directory starts on */ + + /* sector root directory starts on */ temp = temp + bs->bsFATsecs * bs->bsFATs; -#ifdef STORE_BOOT_INFO bs->sysRootDirStart = temp; -#endif -#ifdef DEBUG - fprintf(log, "Root directory starts at sector %lu = (PREVIOUS + %u * %u)\n", - temp, bs->bsFATsecs, bs->bsFATs); -#endif - - /* sector data starts on */ + + /* sector data starts on */ temp = temp + bs->sysRootDirSecs; -#ifdef STORE_BOOT_INFO bs->sysDataStart = temp; -#endif + + #ifdef DEBUG - fprintf(log, "DATA starts at sector %lu = (PREVIOUS + %u)\n", temp, + printf("Root dir entries = %u\n", bs->bsRootDirEnts); + printf("Root dir sectors = %u\n", bs->sysRootDirSecs); + + printf( "FAT starts at sector %lu = (%lu + %u)\n", bs->sysFatStart, + bs->bsHiddenSecs, bs->bsResSectors); + printf("Root directory starts at sector %lu = (PREVIOUS + %u * %u)\n", + bs->sysRootDirStart, bs->bsFATsecs, bs->bsFATs); + printf("DATA starts at sector %lu = (PREVIOUS + %u)\n", bs->sysDataStart, bs->sysRootDirSecs); #endif +#endif -#ifdef DEBUG - fprintf(log, "\nNew Boot Sector:\n"); +#ifdef DDEBUG + printf("\nNew Boot Sector:\n"); dump_sector(newboot); #endif - if ((i = DiskWrite(DrvMap[drive], head, track, sector, 1, (BYTE far *) newboot)) != 0) - { - fprintf(stderr, "%s: disk write error (code = 0x%02x)\n", pgm, i & 0xff); +#ifdef DEBUG + printf("writing new bootsector to drive %c:\n",drive+'A'); +#endif + + if (abswrite(drive, 1, 0, newboot) != 0) + { + printf("Can't write new boot sector to drive %c:\n", drive +'A'); exit(1); - } + } + } -VOID get_boot(COUNT drive) -{ - COUNT i; - COUNT ifd; - WORD head, track, sector, ret; - WORD count; - - if (drive >= 2) - { - head = partition[active].peBeginHead; - sector = partition[active].peBeginSector; - track = partition[active].peBeginCylinder; - } - else - { - head = 0; - sector = 1; - track = 0; - } - - if ((i = DiskRead(DrvMap[drive], head, track, sector, 1, (BYTE far *) oldboot)) != 0) - { - fprintf(stderr, "%s: disk read error (code = 0x%02x)\n", pgm, i & 0xff); - exit(1); - } -} BOOL check_space(COUNT drive, BYTE * BlkBuffer) { - BYTE *bpbp; -#if 0 /* these local variables are never used */ - BYTE nfat; - UWORD nfsect; - ULONG hidden; - UBYTE nreserved; -#endif - ULONG count; - ULONG block; - UCOUNT i; - WORD track, head, sector; - UBYTE buffer[SEC_SIZE]; - ULONG bpb_huge; - UWORD bpb_nsize; - - /* get local information */ -#if 0 /* these local variables are never used */ - getbyte((VOID *) & BlkBuffer[BT_BPB + BPB_NFAT], &nfat); - getword((VOID *) & BlkBuffer[BT_BPB + BPB_NFSECT], &nfsect); - getlong((VOID *) & BlkBuffer[BT_BPB + BPB_HIDDEN], &hidden); - getbyte((VOID *) & BlkBuffer[BT_BPB + BPB_NRESERVED], &nreserved); -#endif - - getlong((VOID *) & BlkBuffer[BT_BPB + BPB_HUGE], &bpb_huge); - getword((VOID *) & BlkBuffer[BT_BPB + BPB_NSIZE], &bpb_nsize); - - count = miarray[drive].mi_size = bpb_nsize == 0 ? - bpb_huge : bpb_nsize; - - /* Fix media information for disk */ - getword((&(((BYTE *) & BlkBuffer[BT_BPB])[BPB_NHEADS])), &miarray[drive].mi_heads); - head = miarray[drive].mi_heads; - getword((&(((BYTE *) & BlkBuffer[BT_BPB])[BPB_NSECS])), &miarray[drive].mi_sectors); - if (miarray[drive].mi_size == 0) - getlong(&((((BYTE *) & BlkBuffer[BT_BPB])[BPB_HUGE])), &miarray[drive].mi_size); - sector = miarray[drive].mi_sectors; - if (head == 0 || sector == 0) - { - fprintf(stderr, "Drive initialization failure.\n"); - exit(1); - } - miarray[drive].mi_cyls = count / (head * sector); + /* this should check, if on destination is enough space + to hold command.com+ kernel.sys */ + + if (drive); + if (BlkBuffer); + return 1; } -/* */ -/* Do logical block number to physical head/track/sector mapping */ -/* */ -static COUNT ltop(trackp, sectorp, headp, unit, count, strt_sect, strt_addr) -WORD *trackp, *sectorp, *headp; -REG COUNT unit; -LONG strt_sect; -COUNT count; -byteptr strt_addr; -{ -#ifdef I86 - ULONG ltemp; -#endif - REG ls, ps; - -#ifdef I86 - /* Adjust for segmented architecture */ - ltemp = (((ULONG) mk_segment(strt_addr) << 4) + mk_offset(strt_addr)) & 0xffff; - /* Test for 64K boundary crossing and return count large */ - /* enough not to exceed the threshold. */ - count = (((ltemp + SEC_SIZE * count) & 0xffff0000l) != 0l) - ? (0xffffl - ltemp) / SEC_SIZE - : count; -#endif - - *trackp = strt_sect / (miarray[unit].mi_heads * miarray[unit].mi_sectors); - *sectorp = strt_sect % miarray[unit].mi_sectors + 1; - *headp = (strt_sect % (miarray[unit].mi_sectors * miarray[unit].mi_heads)) - / miarray[unit].mi_sectors; - if (((ls = *headp * miarray[unit].mi_sectors + *sectorp - 1) + count) > - (ps = miarray[unit].mi_heads * miarray[unit].mi_sectors)) - count = ps - ls; - return count; -} BOOL copy(COUNT drive, BYTE * file) { BYTE dest[64]; - COUNT ifd, ofd, ret; - FILE *s, *d; + COUNT ifd, ofd; + unsigned ret; + int fdin, fdout; BYTE buffer[COPY_SIZE]; struct ftime ftime; + ULONG copied = 0; sprintf(dest, "%c:\\%s", 'A' + drive, file); - if ((s = fopen(file, "rb")) == NULL) + if ((fdin = open(file, O_RDONLY|O_BINARY)) < 0) { - fprintf(stderr, "%s: \"%s\" not found\n", pgm, file); + printf( "%s: \"%s\" not found\n", pgm, file); return FALSE; } - _fmode = O_BINARY; - if ((d = fopen(dest, "wb")) == NULL) + if ((fdout = open(dest, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,S_IREAD|S_IWRITE)) < 0) { - fclose(s); - fprintf(stderr, "%s: can't create\"%s\"\n", pgm, dest); + printf( " %s: can't create\"%s\"\nDOS errnum %d", pgm, dest, errno); + close(fdin); return FALSE; } - while ((ret = fread(buffer, 1, COPY_SIZE, s)) != 0) - fwrite(buffer, 1, ret, d); - - getftime(fileno(s), &ftime); - setftime(fileno(d), &ftime); - - fclose(s); - fclose(d); - - return TRUE; -} - -BOOL DiskReset(COUNT Drive) -{ - REG COUNT idx; - - /* Reset the drives */ - fl_reset(DrvMap[drive]); - - if (Drive >= 2 && Drive < NDEV) - { - COUNT RetCode; - - /* Retrieve all the partition information */ - for (RetCode = TRUE, idx = 0; RetCode && (idx < N_PART); idx++) - RetCode = get_part(Drive, idx); - if (!RetCode) - return FALSE; - - /* Search for the first DOS partition and start */ - /* building the map for the hard drive */ - for (idx = 0; idx < N_PART; idx++) + while ((ret = read(fdin, buffer,COPY_SIZE)) > 0) { - if (partition[idx].peFileSystem == FAT12 - || partition[idx].peFileSystem == FAT16SMALL - || partition[idx].peFileSystem == FAT16LARGE) - { - miarray[Drive].mi_offset - = partition[idx].peStartSector; - active = idx; - break; - } - } - } + if (write(fdout, buffer, ret) != ret) + { + printf("Can't write %u bytes to %s\n",dest); + close(fdout); + unlink(dest); + break; + } + copied += ret; + } + + getftime(fdin, &ftime); + setftime(fdout, &ftime); + + close(fdin); + close(fdout); + + printf("%lu Bytes transferred", copied); return TRUE; } -COUNT DiskRead(WORD drive, WORD head, WORD track, WORD sector, WORD count, BYTE FAR * buffer) -{ - int nRetriesLeft; - for (nRetriesLeft = NRETRY; nRetriesLeft > 0; --nRetriesLeft) - { - if (fl_read(drive, head, track, sector, count, buffer) == count) - return count; - } - return 0; -} - -COUNT DiskWrite(WORD drive, WORD head, WORD track, WORD sector, WORD count, BYTE FAR * buffer) -{ - int nRetriesLeft; - - for (nRetriesLeft = NRETRY; nRetriesLeft > 0; --nRetriesLeft) - { - if (fl_write(drive, head, track, sector, count, buffer) == count) - return count; - } - return 0; -}