mirror of
https://github.com/FDOS/kernel.git
synced 2025-07-23 13:54:30 +02:00
/* 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.
|
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$
|
/* $Log$
|
||||||
* Revision 1.5 2001/03/25 17:11:54 bartoldeman
|
* Revision 1.6 2001/04/29 17:34:41 bartoldeman
|
||||||
* Fixed sys.com compilation. Updated to 2023. Also: see history.txt.
|
* /* 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
|
/* Revision 1.4 2000/08/06 05:50:17 jimtabor
|
||||||
/* Add new files and update cvs with patches and changes
|
/* 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 STORE_BOOT_INFO
|
||||||
|
|
||||||
|
#define DEBUG
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
/*#include <sys/stat.h>*/
|
#include <sys/stat.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <mem.h>
|
#include <mem.h>
|
||||||
#include "portab.h"
|
#include "portab.h"
|
||||||
#include "device.h"
|
|
||||||
|
|
||||||
#include "b_fat12.h"
|
#include "b_fat12.h"
|
||||||
#include "b_fat16.h"
|
#include "b_fat16.h"
|
||||||
|
|
||||||
BYTE *pgm = "sys";
|
BYTE pgm[] = "sys";
|
||||||
|
|
||||||
BOOL fl_reset(WORD);
|
void put_boot(COUNT);
|
||||||
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);
|
|
||||||
BOOL check_space(COUNT, BYTE *);
|
BOOL check_space(COUNT, BYTE *);
|
||||||
COUNT ltop(WORD *, WORD *, WORD *, COUNT, COUNT, LONG, byteptr);
|
|
||||||
BOOL copy(COUNT, BYTE *);
|
BOOL copy(COUNT, BYTE *);
|
||||||
BOOL DiskReset(COUNT);
|
|
||||||
COUNT DiskRead(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
|
COUNT DiskRead(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
|
||||||
COUNT DiskWrite(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 SEC_SIZE 512
|
||||||
#define NDEV 4
|
|
||||||
#define COPY_SIZE 32768
|
#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
|
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];
|
UBYTE newboot[SEC_SIZE], oldboot[SEC_SIZE];
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
FILE *log;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SBSIZE 51
|
|
||||||
#define SBOFFSET 11
|
#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)
|
VOID main(COUNT argc, char **argv)
|
||||||
{
|
{
|
||||||
printf("FreeDOS System Installer v1.0\n\n");
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
drive = *argv[1] - (islower(*argv[1]) ? 'a' : 'A');
|
drive = toupper(*argv[1]) - 'A';
|
||||||
if (drive < 0 || drive >= NDEV)
|
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);
|
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))
|
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);
|
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...");
|
printf("\nCopying KERNEL.SYS...");
|
||||||
if (!copy(drive, "kernel.sys"))
|
if (!copy(drive, "kernel.sys"))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "\n%s: cannot copy \"KERNEL.SYS\"\n", pgm);
|
printf("\n%s: cannot copy \"KERNEL.SYS\"\n", pgm);
|
||||||
#ifdef DEBUG
|
|
||||||
fclose(log);
|
|
||||||
#endif
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nCopying COMMAND.COM...");
|
printf("\nCopying COMMAND.COM...");
|
||||||
if (!copy(drive, "command.com"))
|
if (!copy(drive, "command.com"))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "\n%s: cannot copy \"COMMAND.COM\"\n", pgm);
|
printf("\n%s: cannot copy \"COMMAND.COM\"\n", pgm);
|
||||||
#ifdef DEBUG
|
|
||||||
fclose(log);
|
|
||||||
#endif
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf("\nSystem transfered.\n");
|
|
||||||
#ifdef DEBUG
|
printf("\nWriting boot sector...\n");
|
||||||
fclose(log);
|
put_boot(drive);
|
||||||
#endif
|
|
||||||
|
printf("\nSystem transferred.\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
VOID dump_sector(unsigned char far * sec)
|
VOID dump_sector(unsigned char far * sec)
|
||||||
{
|
{
|
||||||
if (log)
|
|
||||||
{
|
|
||||||
COUNT x, y;
|
COUNT x, y;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
for (x = 0; x < 32; x++)
|
for (x = 0; x < 32; x++)
|
||||||
{
|
{
|
||||||
fprintf(log, "%03X ", x * 16);
|
printf("%03X ", x * 16);
|
||||||
for (y = 0; y < 16; y++)
|
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++)
|
for (y = 0; y < 16; y++)
|
||||||
{
|
{
|
||||||
c = oldboot[x * 16 + y];
|
c = oldboot[x * 16 + y];
|
||||||
if (isprint(c))
|
if (isprint(c))
|
||||||
fprintf(log, "%c", c);
|
printf( "%c", c);
|
||||||
else
|
else
|
||||||
fprintf(log, ".");
|
printf( ".");
|
||||||
}
|
}
|
||||||
fprintf(log, "\n");
|
printf( "\n");
|
||||||
}
|
}
|
||||||
fprintf(log, "\n");
|
|
||||||
}
|
printf( "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -383,306 +284,154 @@ VOID put_boot(COUNT drive)
|
|||||||
WORD count;
|
WORD count;
|
||||||
ULONG temp;
|
ULONG temp;
|
||||||
struct bootsectortype *bs;
|
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
|
#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);
|
dump_sector(oldboot);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bs = (struct bootsectortype *) & oldboot;
|
bs = (struct bootsectortype *) & oldboot;
|
||||||
if ((bs->bsFileSysType[4] == '6') && (bs->bsBootSignature == 0x29))
|
if ((bs->bsFileSysType[4] == '6') && (bs->bsBootSignature == 0x29))
|
||||||
{
|
{
|
||||||
memcpy(newboot, b_fat16, SEC_SIZE); /* copy FAT16 boot sector */
|
memcpy(newboot, b_fat16, SEC_SIZE); /* copy FAT16 boot sector */
|
||||||
printf("FAT type: FAT16\n");
|
printf("FAT type: FAT16\n");
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(log, "FAT type: FAT16\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(newboot, b_fat12, SEC_SIZE); /* copy FAT12 boot sector */
|
memcpy(newboot, b_fat12, SEC_SIZE); /* copy FAT12 boot sector */
|
||||||
printf("FAT type: FAT12\n");
|
printf("FAT type: FAT12\n");
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(log, "FAT type: FAT12\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy disk parameter from old sector to new sector */
|
/* Copy disk parameter from old sector to new sector */
|
||||||
memcpy(&newboot[SBOFFSET], &oldboot[SBOFFSET], SBSIZE);
|
memcpy(&newboot[SBOFFSET], &oldboot[SBOFFSET], SBSIZE);
|
||||||
|
|
||||||
bs = (struct bootsectortype *) & newboot;
|
bs = (struct bootsectortype *) & newboot;
|
||||||
/* root directory sectors */
|
|
||||||
#ifdef STORE_BOOT_INFO
|
#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;
|
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;
|
temp = bs->bsHiddenSecs + bs->bsResSectors;
|
||||||
#ifdef STORE_BOOT_INFO
|
|
||||||
bs->sysFatStart = temp;
|
bs->sysFatStart = temp;
|
||||||
#endif
|
|
||||||
#ifdef DEBUG
|
/* sector root directory starts on */
|
||||||
fprintf(log, "FAT starts at sector %lu = (%lu + %u)\n", temp,
|
|
||||||
bs->bsHiddenSecs, bs->bsResSectors);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* sector root directory starts on */
|
|
||||||
temp = temp + bs->bsFATsecs * bs->bsFATs;
|
temp = temp + bs->bsFATsecs * bs->bsFATs;
|
||||||
#ifdef STORE_BOOT_INFO
|
|
||||||
bs->sysRootDirStart = temp;
|
bs->sysRootDirStart = temp;
|
||||||
#endif
|
|
||||||
#ifdef DEBUG
|
/* sector data starts on */
|
||||||
fprintf(log, "Root directory starts at sector %lu = (PREVIOUS + %u * %u)\n",
|
|
||||||
temp, bs->bsFATsecs, bs->bsFATs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* sector data starts on */
|
|
||||||
temp = temp + bs->sysRootDirSecs;
|
temp = temp + bs->sysRootDirSecs;
|
||||||
#ifdef STORE_BOOT_INFO
|
|
||||||
bs->sysDataStart = temp;
|
bs->sysDataStart = temp;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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);
|
bs->sysRootDirSecs);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DDEBUG
|
||||||
fprintf(log, "\nNew Boot Sector:\n");
|
printf("\nNew Boot Sector:\n");
|
||||||
dump_sector(newboot);
|
dump_sector(newboot);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((i = DiskWrite(DrvMap[drive], head, track, sector, 1, (BYTE far *) newboot)) != 0)
|
#ifdef DEBUG
|
||||||
{
|
printf("writing new bootsector to drive %c:\n",drive+'A');
|
||||||
fprintf(stderr, "%s: disk write error (code = 0x%02x)\n", pgm, i & 0xff);
|
#endif
|
||||||
|
|
||||||
|
if (abswrite(drive, 1, 0, newboot) != 0)
|
||||||
|
{
|
||||||
|
printf("Can't write new boot sector to drive %c:\n", drive +'A');
|
||||||
exit(1);
|
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)
|
BOOL check_space(COUNT drive, BYTE * BlkBuffer)
|
||||||
{
|
{
|
||||||
BYTE *bpbp;
|
/* this should check, if on destination is enough space
|
||||||
#if 0 /* these local variables are never used */
|
to hold command.com+ kernel.sys */
|
||||||
BYTE nfat;
|
|
||||||
UWORD nfsect;
|
if (drive);
|
||||||
ULONG hidden;
|
if (BlkBuffer);
|
||||||
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);
|
|
||||||
|
|
||||||
return 1;
|
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)
|
BOOL copy(COUNT drive, BYTE * file)
|
||||||
{
|
{
|
||||||
BYTE dest[64];
|
BYTE dest[64];
|
||||||
COUNT ifd, ofd, ret;
|
COUNT ifd, ofd;
|
||||||
FILE *s, *d;
|
unsigned ret;
|
||||||
|
int fdin, fdout;
|
||||||
BYTE buffer[COPY_SIZE];
|
BYTE buffer[COPY_SIZE];
|
||||||
struct ftime ftime;
|
struct ftime ftime;
|
||||||
|
ULONG copied = 0;
|
||||||
|
|
||||||
sprintf(dest, "%c:\\%s", 'A' + drive, file);
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
_fmode = O_BINARY;
|
if ((fdout = open(dest, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,S_IREAD|S_IWRITE)) < 0)
|
||||||
if ((d = fopen(dest, "wb")) == NULL)
|
|
||||||
{
|
{
|
||||||
fclose(s);
|
printf( " %s: can't create\"%s\"\nDOS errnum %d", pgm, dest, errno);
|
||||||
fprintf(stderr, "%s: can't create\"%s\"\n", pgm, dest);
|
close(fdin);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((ret = fread(buffer, 1, COPY_SIZE, s)) != 0)
|
while ((ret = read(fdin, buffer,COPY_SIZE)) > 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++)
|
|
||||||
{
|
{
|
||||||
if (partition[idx].peFileSystem == FAT12
|
if (write(fdout, buffer, ret) != ret)
|
||||||
|| partition[idx].peFileSystem == FAT16SMALL
|
{
|
||||||
|| partition[idx].peFileSystem == FAT16LARGE)
|
printf("Can't write %u bytes to %s\n",dest);
|
||||||
{
|
close(fdout);
|
||||||
miarray[Drive].mi_offset
|
unlink(dest);
|
||||||
= partition[idx].peStartSector;
|
break;
|
||||||
active = idx;
|
}
|
||||||
break;
|
copied += ret;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
getftime(fdin, &ftime);
|
||||||
|
setftime(fdout, &ftime);
|
||||||
|
|
||||||
|
close(fdin);
|
||||||
|
close(fdout);
|
||||||
|
|
||||||
|
printf("%lu Bytes transferred", copied);
|
||||||
|
|
||||||
return TRUE;
|
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…
x
Reference in New Issue
Block a user