mirror of https://github.com/FDOS/kernel.git
/* 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 */ git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@217 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
64474e1dd4
commit
f52e31f5c5
573
sys/sys.c
573
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
/*#include <sys/stat.h>*/
|
||||
#include <sys/stat.h>
|
||||
#include <io.h>
|
||||
#include <dos.h>
|
||||
#include <ctype.h>
|
||||
#include <mem.h>
|
||||
#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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue