mirror of
https://github.com/FDOS/kernel.git
synced 2025-04-08 17:15:17 +02:00
Ran all .c and .h files through "indent"
git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@329 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
684a2cb93d
commit
b6d423a1b3
@ -1,14 +1,14 @@
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define asm __asm
|
||||
#if _MSC_VER >= 700
|
||||
#pragma warning(disable:4103)
|
||||
#endif
|
||||
#pragma pack(1)
|
||||
#elif defined(_QC) || defined(__WATCOM__)
|
||||
#pragma pack(1)
|
||||
#elif defined(__ZTC__)
|
||||
#pragma ZTC align 1
|
||||
#elif defined(__TURBOC__) && (__TURBOC__ > 0x202)
|
||||
#pragma option -a-
|
||||
#define asm __asm
|
||||
#if _MSC_VER >= 700
|
||||
#pragma warning(disable:4103)
|
||||
#endif
|
||||
#pragma pack(1)
|
||||
#elif defined(_QC) || defined(__WATCOM__)
|
||||
#pragma pack(1)
|
||||
#elif defined(__ZTC__)
|
||||
#pragma ZTC align 1
|
||||
#elif defined(__TURBOC__) && (__TURBOC__ > 0x202)
|
||||
#pragma option -a-
|
||||
#endif
|
||||
|
19
hdr/buffer.h
19
hdr/buffer.h
@ -32,14 +32,14 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *buffer_hRcsId = "$Id$";
|
||||
static BYTE *buffer_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define BUFFERSIZE 512
|
||||
struct buffer
|
||||
{
|
||||
WORD b_dummy; /* dummy self pointing word to keep MFT from crashing */
|
||||
struct buffer {
|
||||
WORD b_dummy; /* dummy self pointing word to keep MFT from crashing */
|
||||
struct buffer
|
||||
FAR *b_next; /* form linked list for LRU */
|
||||
BYTE b_unit; /* disk for this buffer */
|
||||
@ -52,14 +52,12 @@ struct buffer
|
||||
#else
|
||||
UWORD b_offset; /* span between copies */
|
||||
#endif
|
||||
#if 0 /*TE*/
|
||||
union
|
||||
{
|
||||
#if 0 /*TE*/
|
||||
union {
|
||||
struct dpb FAR *_b_dpbp; /* pointer to DPB */
|
||||
LONG _b_huge_blkno; /* DOS-C: actual block number if >= 0xffff */
|
||||
}
|
||||
_b;
|
||||
#endif
|
||||
} _b;
|
||||
#endif
|
||||
BYTE b_buffer[BUFFERSIZE]; /* 512 byte sectors for now */
|
||||
};
|
||||
|
||||
@ -79,4 +77,3 @@ struct buffer
|
||||
* Rev 1.0 20 Apr 2001 17:30:00 Bart Oldeman
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
27
hdr/cds.h
27
hdr/cds.h
@ -28,30 +28,25 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *Cds_hRcsId = "$Id$";
|
||||
static BYTE *Cds_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MAX_CDSPATH 67
|
||||
|
||||
struct cds
|
||||
{
|
||||
struct cds {
|
||||
BYTE cdsCurrentPath[MAX_CDSPATH];
|
||||
UWORD cdsFlags;
|
||||
struct dpb FAR *cdsDpb;
|
||||
|
||||
union
|
||||
{
|
||||
BYTE FAR *
|
||||
_cdsRedirRec;
|
||||
struct
|
||||
{
|
||||
union {
|
||||
BYTE FAR *_cdsRedirRec;
|
||||
struct {
|
||||
UWORD _cdsStrtClst;
|
||||
UWORD _cdsParam;
|
||||
}
|
||||
_cdsRedir;
|
||||
}
|
||||
_cdsUnion;
|
||||
} _cdsRedir;
|
||||
} _cdsUnion;
|
||||
|
||||
UWORD cdsStoreUData;
|
||||
|
||||
@ -67,11 +62,9 @@ struct cds
|
||||
#define cdsRedirRec _cdsUnion._cdsRedirRec
|
||||
#define cdsParam _cdsUnion._cdsRedir._cdsParam
|
||||
|
||||
typedef struct _cdstbl
|
||||
{
|
||||
typedef struct _cdstbl {
|
||||
struct cds cds_table[26];
|
||||
}
|
||||
cdstbl;
|
||||
} cdstbl;
|
||||
|
||||
/* Bits for cdsFlags */
|
||||
#define CDSNETWDRV 0x8000
|
||||
|
@ -32,13 +32,12 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *clock_hRcsId = "$Id$";
|
||||
static BYTE *clock_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
struct ClockRecord
|
||||
{
|
||||
struct ClockRecord {
|
||||
UWORD clkDays; /* days since Jan 1, 1980. */
|
||||
UBYTE clkMinutes; /* residual minutes. */
|
||||
UBYTE clkHours; /* residual hours. */
|
||||
|
@ -32,7 +32,8 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *date_hRcsId = "$Id$";
|
||||
static BYTE *date_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
44
hdr/dcb.h
44
hdr/dcb.h
@ -30,13 +30,13 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *clock_hRcsId = "$Id$";
|
||||
static BYTE *clock_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Internal drive parameter block */
|
||||
struct dpb
|
||||
{
|
||||
struct dpb {
|
||||
BYTE dpb_unit; /* unit for error reporting */
|
||||
BYTE dpb_subunit; /* the sub-unit for driver */
|
||||
UWORD dpb_secsize; /* sector size */
|
||||
@ -56,41 +56,39 @@ struct dpb
|
||||
struct dpb FAR * /* next dpb in chain */
|
||||
dpb_next; /* -1 = end */
|
||||
UWORD dpb_cluster; /* cluster # of first free */
|
||||
/* -1 if not known */
|
||||
/* -1 if not known */
|
||||
#ifndef WITHFAT32
|
||||
UWORD dpb_nfreeclst; /* number of free clusters */
|
||||
/* -1 if not known */
|
||||
#else
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
UWORD dpb_nfreeclst; /* number of free clusters */
|
||||
/* -1 if not known */
|
||||
#else
|
||||
union {
|
||||
struct {
|
||||
UWORD dpb_nfreeclst_lo;
|
||||
UWORD dpb_nfreeclst_hi;
|
||||
} dpb_nfreeclst_st;
|
||||
ULONG _dpb_xnfreeclst; /* number of free clusters */
|
||||
/* -1 if not known */
|
||||
ULONG _dpb_xnfreeclst; /* number of free clusters */
|
||||
/* -1 if not known */
|
||||
} dpb_nfreeclst_un;
|
||||
#define dpb_nfreeclst dpb_nfreeclst_un.dpb_nfreeclst_st.dpb_nfreeclst_lo
|
||||
#define dpb_xnfreeclst dpb_nfreeclst_un._dpb_xnfreeclst
|
||||
|
||||
#define dpb_nfreeclst dpb_nfreeclst_un.dpb_nfreeclst_st.dpb_nfreeclst_lo
|
||||
#define dpb_xnfreeclst dpb_nfreeclst_un._dpb_xnfreeclst
|
||||
|
||||
UWORD dpb_xflags; /* extended flags, see bpb */
|
||||
UWORD dpb_xfsinfosec; /* FS info sector number, */
|
||||
/* 0xFFFF if unknown */
|
||||
/* 0xFFFF if unknown */
|
||||
UWORD dpb_xbackupsec; /* backup boot sector number */
|
||||
/* 0xFFFF if unknown */
|
||||
/* 0xFFFF if unknown */
|
||||
ULONG dpb_xdata;
|
||||
ULONG dpb_xsize; /* # of clusters+1 on media */
|
||||
ULONG dpb_xfatsize; /* # of sectors / FAT */
|
||||
ULONG dpb_xrootclst; /* starting cluster of root dir */
|
||||
ULONG dpb_xcluster; /* cluster # of first free */
|
||||
/* -1 if not known */
|
||||
#endif
|
||||
/* -1 if not known */
|
||||
#endif
|
||||
};
|
||||
|
||||
#define UNKNCLUSTER 0x0000 /* see RBIL INT 21/AH=52 entry */
|
||||
#define XUNKNCLSTFREE 0xffffffffl /* unknown for DOS */
|
||||
#define UNKNCLSTFREE 0xffff /* unknown for DOS */
|
||||
#define UNKNCLUSTER 0x0000 /* see RBIL INT 21/AH=52 entry */
|
||||
#define XUNKNCLSTFREE 0xffffffffl /* unknown for DOS */
|
||||
#define UNKNCLSTFREE 0xffff /* unknown for DOS */
|
||||
|
||||
/*
|
||||
* Log: dcb.h,v
|
||||
|
266
hdr/device.h
266
hdr/device.h
@ -29,11 +29,11 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *device_hRcsId = "$Id$";
|
||||
static BYTE *device_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Status Word Bits
|
||||
*/
|
||||
@ -122,8 +122,7 @@ static BYTE *device_hRcsId = "$Id$";
|
||||
|
||||
/* Device header */
|
||||
|
||||
struct dhdr
|
||||
{
|
||||
struct dhdr {
|
||||
struct dhdr
|
||||
FAR *dh_next;
|
||||
UWORD dh_attr;
|
||||
@ -153,10 +152,9 @@ struct dhdr
|
||||
|
||||
#define FAT_NO_MIRRORING 0x80
|
||||
|
||||
#define BPB_SIZEOF 31 /* size of the standard BPB */
|
||||
#define BPB_SIZEOF 31 /* size of the standard BPB */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
UWORD bpb_nbyte; /* Bytes per Sector */
|
||||
UBYTE bpb_nsector; /* Sectors per Allocation Unit */
|
||||
UWORD bpb_nreserved; /* # Reserved Sectors */
|
||||
@ -169,23 +167,22 @@ typedef struct
|
||||
UWORD bpb_nheads; /* Number of heads */
|
||||
ULONG bpb_hidden; /* Hidden sectors */
|
||||
ULONG bpb_huge; /* Size in sectors if */
|
||||
/* bpb_nsize == 0 */
|
||||
/* bpb_nsize == 0 */
|
||||
#ifdef WITHFAT32
|
||||
ULONG bpb_xnfsect; /* FAT size in sectors if */
|
||||
/* bpb_nfsect == 0 */
|
||||
/* bpb_nfsect == 0 */
|
||||
UWORD bpb_xflags; /* extended flags */
|
||||
/* bit 7: disable mirroring */
|
||||
/* bits 6-4: reserved (0) */
|
||||
/* bits 3-0: active FAT number */
|
||||
/* bit 7: disable mirroring */
|
||||
/* bits 6-4: reserved (0) */
|
||||
/* bits 3-0: active FAT number */
|
||||
UWORD bpb_xfsversion; /* filesystem version */
|
||||
ULONG bpb_xrootclst; /* starting cluster of root dir */
|
||||
UWORD bpb_xfsinfosec; /* FS info sector number, */
|
||||
/* 0xFFFF if unknown */
|
||||
/* 0xFFFF if unknown */
|
||||
UWORD bpb_xbackupsec; /* backup boot sector number */
|
||||
/* 0xFFFF if unknown */
|
||||
/* 0xFFFF if unknown */
|
||||
#endif
|
||||
}
|
||||
bpb;
|
||||
} bpb;
|
||||
|
||||
#define N_RETRY 5 /* number of retries permitted */
|
||||
#define SEC_SIZE 512 /* size of sector in bytes */
|
||||
@ -193,64 +190,61 @@ bpb;
|
||||
#define LBA_READ 0x4200
|
||||
#define LBA_WRITE 0x4300
|
||||
|
||||
|
||||
struct _bios_LBA_address_packet /* Used to access a hard disk via LBA */
|
||||
/* Added by Brian E. Reifsnyder */
|
||||
struct _bios_LBA_address_packet
|
||||
/* Used to access a hard disk via LBA */
|
||||
/* Added by Brian E. Reifsnyder */
|
||||
{
|
||||
unsigned char packet_size; /* size of this packet...set to 16 */
|
||||
unsigned char reserved_1; /* set to 0...unused */
|
||||
unsigned char number_of_blocks; /* 0 < number_of_blocks < 128 */
|
||||
unsigned char reserved_2; /* set to 0...unused */
|
||||
UBYTE far * buffer_address; /* addr of transfer buffer */
|
||||
unsigned long block_address; /* LBA address */
|
||||
unsigned long block_address_high; /* high bytes of LBA addr...unused */
|
||||
unsigned char packet_size; /* size of this packet...set to 16 */
|
||||
unsigned char reserved_1; /* set to 0...unused */
|
||||
unsigned char number_of_blocks; /* 0 < number_of_blocks < 128 */
|
||||
unsigned char reserved_2; /* set to 0...unused */
|
||||
UBYTE far *buffer_address; /* addr of transfer buffer */
|
||||
unsigned long block_address; /* LBA address */
|
||||
unsigned long block_address_high; /* high bytes of LBA addr...unused */
|
||||
};
|
||||
|
||||
struct CHS {
|
||||
ULONG Cylinder;
|
||||
UWORD Head;
|
||||
UWORD Sector;
|
||||
ULONG Cylinder;
|
||||
UWORD Head;
|
||||
UWORD Sector;
|
||||
};
|
||||
|
||||
/* DOS 4.0-7.0 drive data table (see RBIL at INT2F,AX=0803) */
|
||||
typedef struct ddtstruct
|
||||
{
|
||||
typedef struct ddtstruct {
|
||||
struct ddtstruct FAR *ddt_next;
|
||||
/* pointer to next table (offset FFFFh if last table) */
|
||||
UBYTE ddt_driveno; /* physical unit number (for INT 13) */
|
||||
UBYTE ddt_logdriveno; /* logical drive number (0=A:) */
|
||||
bpb ddt_bpb; /* BIOS Parameter Block */
|
||||
/* pointer to next table (offset FFFFh if last table) */
|
||||
UBYTE ddt_driveno; /* physical unit number (for INT 13) */
|
||||
UBYTE ddt_logdriveno; /* logical drive number (0=A:) */
|
||||
bpb ddt_bpb; /* BIOS Parameter Block */
|
||||
UBYTE ddt_flags;
|
||||
/* bit 6: 16-bit FAT instead of 12-bit
|
||||
bit 7: unsupportable disk (all accesses will return Not Ready) */
|
||||
UWORD ddt_FileOC; /* Count of Open files on Drv */
|
||||
UBYTE ddt_type; /* device type */
|
||||
UWORD ddt_descflags;/* bit flags describing drive */
|
||||
UWORD ddt_ncyl; /* number of cylinders
|
||||
(for partition only, if hard disk) */
|
||||
bpb ddt_defbpb; /* BPB for default (highest) capacity supported */
|
||||
UBYTE ddt_reserved[6]; /* (part of BPB above) */
|
||||
UBYTE ddt_ltrack; /* last track accessed */
|
||||
union
|
||||
{
|
||||
ULONG ddt_lasttime; /* removable media: time of last access
|
||||
in clock ticks (FFFFFFFFh if never) */
|
||||
struct
|
||||
{
|
||||
UWORD ddt_part; /* partition (FFFFh = primary, 0001h = extended)
|
||||
always 0001h for DOS 5+ */
|
||||
UWORD ddt_abscyl; /* absolute cylinder number of partition's
|
||||
start on physical drive
|
||||
(FFFFh if primary partition in DOS 4.x)*/
|
||||
/* bit 6: 16-bit FAT instead of 12-bit
|
||||
bit 7: unsupportable disk (all accesses will return Not Ready) */
|
||||
UWORD ddt_FileOC; /* Count of Open files on Drv */
|
||||
UBYTE ddt_type; /* device type */
|
||||
UWORD ddt_descflags; /* bit flags describing drive */
|
||||
UWORD ddt_ncyl; /* number of cylinders
|
||||
(for partition only, if hard disk) */
|
||||
bpb ddt_defbpb; /* BPB for default (highest) capacity supported */
|
||||
UBYTE ddt_reserved[6]; /* (part of BPB above) */
|
||||
UBYTE ddt_ltrack; /* last track accessed */
|
||||
union {
|
||||
ULONG ddt_lasttime; /* removable media: time of last access
|
||||
in clock ticks (FFFFFFFFh if never) */
|
||||
struct {
|
||||
UWORD ddt_part; /* partition (FFFFh = primary, 0001h = extended)
|
||||
always 0001h for DOS 5+ */
|
||||
UWORD ddt_abscyl; /* absolute cylinder number of partition's
|
||||
start on physical drive
|
||||
(FFFFh if primary partition in DOS 4.x) */
|
||||
} ddt_hd;
|
||||
} ddt_fh;
|
||||
UBYTE ddt_volume[12]; /* ASCIIZ volume label or "NO NAME " if none
|
||||
(apparently taken from extended boot record
|
||||
rather than root directory) */
|
||||
ULONG ddt_serialno; /* serial number */
|
||||
UBYTE ddt_fstype[9]; /* ASCIIZ filesystem type ("FAT12 " or "FAT16 ")*/
|
||||
ULONG ddt_offset; /* relative partition offset */
|
||||
BITS ddt_LBASupported:1; /* set, if INT13 extensions enabled */
|
||||
UBYTE ddt_volume[12]; /* ASCIIZ volume label or "NO NAME " if none
|
||||
(apparently taken from extended boot record
|
||||
rather than root directory) */
|
||||
ULONG ddt_serialno; /* serial number */
|
||||
UBYTE ddt_fstype[9]; /* ASCIIZ filesystem type ("FAT12 " or "FAT16 ") */
|
||||
ULONG ddt_offset; /* relative partition offset */
|
||||
BITS ddt_LBASupported:1; /* set, if INT13 extensions enabled */
|
||||
BITS ddt_WriteVerifySupported:1;
|
||||
} ddt;
|
||||
|
||||
@ -268,41 +262,39 @@ typedef struct ddtstruct
|
||||
|
||||
/* typedef struct ddtstruct ddt;*/
|
||||
|
||||
struct gblkio
|
||||
{
|
||||
UBYTE gbio_spcfunbit;
|
||||
UBYTE gbio_devtype;
|
||||
UWORD gbio_devattrib;
|
||||
UWORD gbio_ncyl;
|
||||
UBYTE gbio_media;
|
||||
bpb gbio_bpb;
|
||||
UWORD gbio_nsecs;
|
||||
struct gblkio {
|
||||
UBYTE gbio_spcfunbit;
|
||||
UBYTE gbio_devtype;
|
||||
UWORD gbio_devattrib;
|
||||
UWORD gbio_ncyl;
|
||||
UBYTE gbio_media;
|
||||
bpb gbio_bpb;
|
||||
UWORD gbio_nsecs;
|
||||
};
|
||||
|
||||
struct gblkfv /* for format / verify track */
|
||||
struct gblkfv /* for format / verify track */
|
||||
{
|
||||
UBYTE gbfv_spcfunbit;
|
||||
UWORD gbfv_head;
|
||||
UWORD gbfv_cyl;
|
||||
UWORD gbfv_ntracks;
|
||||
UBYTE gbfv_spcfunbit;
|
||||
UWORD gbfv_head;
|
||||
UWORD gbfv_cyl;
|
||||
UWORD gbfv_ntracks;
|
||||
};
|
||||
|
||||
struct gblkrw /* for read / write track */
|
||||
struct gblkrw /* for read / write track */
|
||||
{
|
||||
UBYTE gbrw_spcfunbit;
|
||||
UWORD gbrw_head;
|
||||
UWORD gbrw_cyl;
|
||||
UWORD gbrw_sector;
|
||||
UWORD gbrw_nsecs;
|
||||
UBYTE FAR * gbrw_buffer;
|
||||
UBYTE gbrw_spcfunbit;
|
||||
UWORD gbrw_head;
|
||||
UWORD gbrw_cyl;
|
||||
UWORD gbrw_sector;
|
||||
UWORD gbrw_nsecs;
|
||||
UBYTE FAR *gbrw_buffer;
|
||||
};
|
||||
|
||||
struct Gioc_media
|
||||
{
|
||||
WORD ioc_level;
|
||||
struct Gioc_media {
|
||||
WORD ioc_level;
|
||||
ULONG ioc_serialno;
|
||||
BYTE ioc_volume[11];
|
||||
BYTE ioc_fstype[8];
|
||||
BYTE ioc_volume[11];
|
||||
BYTE ioc_fstype[8];
|
||||
};
|
||||
|
||||
/* */
|
||||
@ -315,90 +307,68 @@ struct Gioc_media
|
||||
#define BT_BPB 11
|
||||
#define BT_SIZEOF 36
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE bt_jump[3]; /* Boot Jump opcodes */
|
||||
BYTE bt_oem[8]; /* OEM Name */
|
||||
bpb bt_bpb; /* BPB for this media/device */
|
||||
WORD bt_nsecs; /* # Sectors per Track */
|
||||
WORD bt_nheads; /* # Heads */
|
||||
WORD bt_hidden; /* # Hidden sectors */
|
||||
LONG bt_huge; /* use if nsecs == 0 */
|
||||
BYTE bt_drvno;
|
||||
BYTE bt_reserv;
|
||||
BYTE bt_btid;
|
||||
typedef struct {
|
||||
BYTE bt_jump[3]; /* Boot Jump opcodes */
|
||||
BYTE bt_oem[8]; /* OEM Name */
|
||||
bpb bt_bpb; /* BPB for this media/device */
|
||||
WORD bt_nsecs; /* # Sectors per Track */
|
||||
WORD bt_nheads; /* # Heads */
|
||||
WORD bt_hidden; /* # Hidden sectors */
|
||||
LONG bt_huge; /* use if nsecs == 0 */
|
||||
BYTE bt_drvno;
|
||||
BYTE bt_reserv;
|
||||
BYTE bt_btid;
|
||||
ULONG bt_serialno;
|
||||
BYTE bt_volume[11];
|
||||
BYTE bt_fstype[8];
|
||||
}
|
||||
boot;
|
||||
BYTE bt_volume[11];
|
||||
BYTE bt_fstype[8];
|
||||
} boot;
|
||||
|
||||
/* File system information structure */
|
||||
struct fsinfo
|
||||
{
|
||||
UDWORD fi_signature; /* must be 0x61417272 */
|
||||
DWORD fi_nfreeclst; /* number of free clusters, -1 if unknown */
|
||||
DWORD fi_cluster; /* most recently allocated cluster, -1 if unknown */
|
||||
struct fsinfo {
|
||||
UDWORD fi_signature; /* must be 0x61417272 */
|
||||
DWORD fi_nfreeclst; /* number of free clusters, -1 if unknown */
|
||||
DWORD fi_cluster; /* most recently allocated cluster, -1 if unknown */
|
||||
UBYTE fi_reserved[12];
|
||||
};
|
||||
|
||||
typedef boot super; /* Alias for boot structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
UBYTE r_length; /* Request Header length */
|
||||
UBYTE r_unit; /* Unit Code */
|
||||
UBYTE r_command; /* Command Code */
|
||||
WORD r_status; /* Status */
|
||||
BYTE r_reserved[8]; /* DOS Reserved Area */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
UBYTE _r_nunits; /* number of units */
|
||||
BYTE FAR *_r_endaddr; /* Ending Address */
|
||||
bpb *FAR * _r_bpbptr; /* ptr to BPB array */
|
||||
UBYTE _r_firstunit;
|
||||
}
|
||||
_r_init;
|
||||
struct
|
||||
{
|
||||
} _r_init;
|
||||
struct {
|
||||
BYTE _r_meddesc; /* MEDIA Descriptor */
|
||||
BYTE _r_retcode; /* Return Code */
|
||||
BYTE FAR
|
||||
* _r_vid; /* volume id */
|
||||
}
|
||||
_r_media;
|
||||
struct
|
||||
{
|
||||
BYTE FAR * _r_vid; /* volume id */
|
||||
} _r_media;
|
||||
struct {
|
||||
BYTE _r_meddesc; /* MEDIA Descriptor */
|
||||
boot FAR
|
||||
* _r_fat; /* boot sector pointer */
|
||||
bpb FAR
|
||||
* _r_bpbpt; /* ptr to BPB table */
|
||||
}
|
||||
_r_bpb;
|
||||
struct
|
||||
{
|
||||
boot FAR * _r_fat; /* boot sector pointer */
|
||||
bpb FAR * _r_bpbpt; /* ptr to BPB table */
|
||||
} _r_bpb;
|
||||
struct {
|
||||
BYTE _r_meddesc; /* MEDIA Descriptor */
|
||||
BYTE FAR
|
||||
* _r_trans; /* Transfer Address */
|
||||
BYTE FAR * _r_trans; /* Transfer Address */
|
||||
UWORD _r_count; /* Byte/Sector Count */
|
||||
UWORD _r_start; /* Starting Sector No. */
|
||||
BYTE FAR
|
||||
* _r_vid; /* Pointer to volume id */
|
||||
BYTE FAR * _r_vid; /* Pointer to volume id */
|
||||
LONG _r_huge; /* for > 32Mb drives */
|
||||
}
|
||||
_r_rw;
|
||||
struct
|
||||
{
|
||||
} _r_rw;
|
||||
struct {
|
||||
BYTE _r_ndbyte; /* Byte Read From Device */
|
||||
}
|
||||
_r_nd;
|
||||
}
|
||||
_r_x;
|
||||
}
|
||||
request;
|
||||
} _r_nd;
|
||||
} _r_x;
|
||||
} request;
|
||||
|
||||
#define HUGECOUNT 0xffff
|
||||
#define MAXSHORT 0xffffl
|
||||
|
@ -30,26 +30,24 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *dirmatch_hRcsId = "$Id$";
|
||||
static BYTE *dirmatch_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
BYTE dm_drive;
|
||||
BYTE dm_name_pat[FNAME_SIZE + FEXT_SIZE];
|
||||
BYTE dm_attr_srch;
|
||||
UWORD dm_entry;
|
||||
#ifdef WITHFAT32
|
||||
#ifdef WITHFAT32
|
||||
ULONG dm_dircluster;
|
||||
#else
|
||||
#else
|
||||
UWORD dm_dircluster;
|
||||
UWORD reserved;
|
||||
#endif
|
||||
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
BITS /* directory has been modified */
|
||||
f_dmod:1;
|
||||
BITS /* directory is the root */
|
||||
@ -60,16 +58,14 @@ typedef struct
|
||||
f_ddir:1;
|
||||
BITS /* filler to avoid a bad bug (feature?) in */
|
||||
f_filler:12; /* TC 2.01 */
|
||||
}
|
||||
dm_flags; /* file flags */
|
||||
} dm_flags; /* file flags */
|
||||
|
||||
BYTE dm_attr_fnd; /* found file attribute */
|
||||
time dm_time; /* file time */
|
||||
date dm_date; /* file date */
|
||||
LONG dm_size; /* file size */
|
||||
BYTE dm_name[FNAME_SIZE + FEXT_SIZE + 2]; /* file name */
|
||||
}
|
||||
dmatch;
|
||||
BYTE dm_name[FNAME_SIZE + FEXT_SIZE + 2]; /* file name */
|
||||
} dmatch;
|
||||
|
||||
/*
|
||||
* Log: dirmatch.h,v
|
||||
|
@ -30,19 +30,18 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *dosnames_hRcsId = "$Id$";
|
||||
static BYTE *dosnames_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#define PARSE_MAX 64
|
||||
|
||||
struct dosnames
|
||||
{
|
||||
struct dosnames {
|
||||
UBYTE dn_drive; /* the drive that was parsed */
|
||||
UBYTE dn_network[PARSE_MAX]; /* specified network */
|
||||
UBYTE dn_path[PARSE_MAX]; /* the path */
|
||||
UBYTE dn_name[FNAME_SIZE + FEXT_SIZE + 1]; /* the file name */
|
||||
UBYTE dn_name[FNAME_SIZE + FEXT_SIZE + 1]; /* the file name */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -30,11 +30,11 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *error_hRcsId = "$Id$";
|
||||
static BYTE *error_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Internal system error returns */
|
||||
#define SUCCESS 0 /* Function was successful */
|
||||
#define DE_INVLDFUNC -1 /* Invalid function number */
|
||||
@ -60,7 +60,7 @@ static BYTE *error_hRcsId = "$Id$";
|
||||
#define DE_SEEK -25 /* error on file seek */
|
||||
#define DE_HNDLDSKFULL -28 /* handle disk full (?) */
|
||||
|
||||
#define DE_INVLDPARM -0x57 /* invalid parameter */
|
||||
#define DE_INVLDPARM -0x57 /* invalid parameter */
|
||||
|
||||
#define DE_DEADLOCK -36
|
||||
#define DE_LOCK -39
|
||||
|
10
hdr/exe.h
10
hdr/exe.h
@ -30,13 +30,12 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *exe_hRcsId = "$Id$";
|
||||
static BYTE *exe_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
UWORD exSignature;
|
||||
UWORD exExtraBytes;
|
||||
UWORD exPages;
|
||||
@ -51,8 +50,7 @@ typedef struct
|
||||
UWORD exInitCS;
|
||||
UWORD exRelocTable;
|
||||
UWORD exOverlay;
|
||||
}
|
||||
exe_header;
|
||||
} exe_header;
|
||||
|
||||
#define MAGIC 0x5a4d
|
||||
|
||||
|
23
hdr/fat.h
23
hdr/fat.h
@ -30,11 +30,11 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *fat_hRcsId = "$Id$";
|
||||
static BYTE *fat_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* FAT file system attribute bits */
|
||||
#define D_NORMAL 0 /* normal */
|
||||
#define D_RDONLY 0x01 /* read-only file */
|
||||
@ -79,8 +79,7 @@ static BYTE *fat_hRcsId = "$Id$";
|
||||
/* dpb_size == 0 for FAT32, hence doing -1 here */
|
||||
|
||||
/* FAT file system directory entry */
|
||||
struct dirent
|
||||
{
|
||||
struct dirent {
|
||||
UBYTE dir_name[FNAME_SIZE]; /* Filename */
|
||||
UBYTE dir_ext[FEXT_SIZE]; /* Filename extension */
|
||||
UBYTE dir_attrib; /* File Attribute */
|
||||
@ -93,12 +92,11 @@ struct dirent
|
||||
time dir_time; /* Time file created/updated */
|
||||
date dir_date; /* Date file created/updated */
|
||||
UWORD dir_start; /* Starting cluster */
|
||||
/* 1st available = 2 */
|
||||
/* 1st available = 2 */
|
||||
ULONG dir_size; /* File size in bytes */
|
||||
};
|
||||
|
||||
struct lfn_entry
|
||||
{
|
||||
struct lfn_entry {
|
||||
UBYTE lfn_id;
|
||||
UNICODE lfn_name0_4[5];
|
||||
UBYTE lfn_attrib;
|
||||
@ -142,16 +140,15 @@ struct lfn_entry
|
||||
|
||||
#define DIRENT_SIZE 32
|
||||
|
||||
struct lfn_inode
|
||||
{
|
||||
struct lfn_inode {
|
||||
UNICODE name[256];
|
||||
|
||||
|
||||
struct dirent l_dir;
|
||||
|
||||
|
||||
ULONG l_diroff; /* offset of the dir entry */
|
||||
};
|
||||
|
||||
typedef struct lfn_inode FAR * lfn_inode_ptr;
|
||||
|
||||
typedef struct lfn_inode FAR *lfn_inode_ptr;
|
||||
|
||||
/*
|
||||
* Log: fat.h,v
|
||||
|
22
hdr/fcb.h
22
hdr/fcb.h
@ -30,11 +30,11 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *fcb_hRcsId = "$Id$";
|
||||
static BYTE *fcb_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* fcb convience defines */
|
||||
/* block device info */
|
||||
#define FID_CHARDEV 0x80 /* 1 defines character device */
|
||||
@ -77,8 +77,7 @@ static BYTE *fcb_hRcsId = "$Id$";
|
||||
#define FCB_WRITE 1
|
||||
|
||||
/* File Control Block (FCB) */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
BYTE fcb_drive; /* Drive number 0=default, 1=A, etc */
|
||||
BYTE fcb_fname[FNAME_SIZE]; /* File name */
|
||||
BYTE fcb_fext[FEXT_SIZE]; /* File name Extension */
|
||||
@ -99,21 +98,17 @@ typedef struct
|
||||
/* end reserved */
|
||||
UBYTE fcb_curec; /* Current block number of */
|
||||
ULONG fcb_rndm; /* Current relative record number */
|
||||
}
|
||||
fcb;
|
||||
} fcb;
|
||||
|
||||
/* FAT extended fcb */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
UBYTE xfcb_flag; /* 0xff indicates Extended FCB */
|
||||
BYTE xfcb_resvrd[5]; /* Reserved */
|
||||
UBYTE xfcb_attrib; /* Attribute */
|
||||
fcb xfcb_fcb;
|
||||
}
|
||||
xfcb;
|
||||
} xfcb;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
UBYTE renDriveID; /* drive no. */
|
||||
BYTE renOldName[8]; /* Old Filename */
|
||||
BYTE renOldExtent[3]; /* Old File Extension */
|
||||
@ -121,8 +116,7 @@ typedef struct
|
||||
BYTE renNewName[8]; /* New Filename */
|
||||
BYTE renNewExtent[3]; /* New FileExtension */
|
||||
BYTE renReserved2[9];
|
||||
}
|
||||
rfcb;
|
||||
} rfcb;
|
||||
|
||||
/*
|
||||
* Log: fcb.h,v
|
||||
|
@ -30,11 +30,11 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *file_hRcsId = "$Id$";
|
||||
static BYTE *file_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* 0 = CON, standard input, can be redirected */
|
||||
/* 1 = CON, standard output, can be redirected */
|
||||
/* 2 = CON, standard error */
|
||||
|
24
hdr/fnode.h
24
hdr/fnode.h
@ -30,25 +30,22 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *fnode_hRcsId = "$Id$";
|
||||
static BYTE *fnode_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
struct f_node
|
||||
{
|
||||
struct f_node {
|
||||
UWORD f_count; /* number of uses of this file */
|
||||
COUNT f_mode; /* read, write, read-write, etc */
|
||||
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
BITS f_dmod:1; /* directory has been modified */
|
||||
BITS f_droot:1; /* directory is the root */
|
||||
BITS f_dnew:1; /* fnode is new and needs fill */
|
||||
BITS f_ddir:1; /* fnode is assigned to dir */
|
||||
BITS f_ddate:1; /* date set using setdate */
|
||||
}
|
||||
f_flags; /* file flags */
|
||||
} f_flags; /* file flags */
|
||||
|
||||
struct dirent f_dir; /* this file's dir entry image */
|
||||
|
||||
@ -67,21 +64,20 @@ struct f_node
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct lfn_inode
|
||||
{
|
||||
struct lfn_inode {
|
||||
UNICODE name[255];
|
||||
|
||||
struct dirent l_dir; /* this file's dir entry image */
|
||||
|
||||
ULONG l_diroff; /* offset of the dir entry */
|
||||
CLUSTER l_dirstart; /* the starting cluster of dir */
|
||||
/* when dir is not root */
|
||||
};
|
||||
/* when dir is not root */
|
||||
};
|
||||
|
||||
typedef struct lfn_inode FAR * lfn_inode_ptr;
|
||||
typedef struct lfn_inode FAR *lfn_inode_ptr;
|
||||
#endif
|
||||
|
||||
typedef struct f_node * f_node_ptr;
|
||||
typedef struct f_node *f_node_ptr;
|
||||
|
||||
/*
|
||||
* Log: fnode.h,v
|
||||
|
10
hdr/kbd.h
10
hdr/kbd.h
@ -30,21 +30,19 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *kbd_hRcsId = "$Id$";
|
||||
static BYTE *kbd_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#define KBD_MAXLENGTH 256
|
||||
|
||||
/* Keyboard buffer */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
UBYTE kb_size; /* size of buffer in bytes */
|
||||
UBYTE kb_count; /* number of bytes returned */
|
||||
BYTE kb_buf[KBD_MAXLENGTH]; /* the buffer itself */
|
||||
}
|
||||
keyboard;
|
||||
} keyboard;
|
||||
|
||||
/*
|
||||
* Log: kbd.h,v
|
||||
|
@ -13,15 +13,15 @@
|
||||
< 0 : not possible to skip config.sys
|
||||
= 0 : only possible if already pressed before, no message
|
||||
> 0 : wait so long for F5/F8
|
||||
*/
|
||||
*/
|
||||
typedef struct _KernelConfig {
|
||||
char CONFIG[6]; /* "CONFIG" */
|
||||
unsigned short ConfigSize;
|
||||
|
||||
unsigned char DLASortByDriveNo;
|
||||
unsigned char InitDiskShowDriveAssignment;
|
||||
signed char SkipConfigSeconds;
|
||||
unsigned char ForceLBA;
|
||||
unsigned char GlobalEnableLBAsupport; /* = 0 --> disable LBA support */
|
||||
} KernelConfig;
|
||||
extern struct _KernelConfig FAR LowKernelConfig;
|
||||
char CONFIG[6]; /* "CONFIG" */
|
||||
unsigned short ConfigSize;
|
||||
|
||||
unsigned char DLASortByDriveNo;
|
||||
unsigned char InitDiskShowDriveAssignment;
|
||||
signed char SkipConfigSeconds;
|
||||
unsigned char ForceLBA;
|
||||
unsigned char GlobalEnableLBAsupport; /* = 0 --> disable LBA support */
|
||||
} KernelConfig;
|
||||
extern struct _KernelConfig FAR LowKernelConfig;
|
||||
|
@ -30,7 +30,8 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *mcb_hRcsId = "$Id$";
|
||||
static BYTE *mcb_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -56,15 +57,13 @@ static BYTE *mcb_hRcsId = "$Id$";
|
||||
typedef UWORD seg;
|
||||
typedef UWORD offset;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
BYTE m_type; /* mcb type - chain or end */
|
||||
UWORD m_psp; /* owner id via psp segment */
|
||||
UWORD m_size; /* size of segment in paragraphs */
|
||||
BYTE m_fill[3];
|
||||
BYTE m_name[8]; /* owner name limited to 8 bytes */
|
||||
}
|
||||
mcb;
|
||||
} mcb;
|
||||
|
||||
/*
|
||||
* Log: mcb.h,v
|
||||
|
@ -59,30 +59,22 @@
|
||||
#define REM_PRINTREDIR 0x1125
|
||||
#define REM_EXTOC 0x112e
|
||||
|
||||
struct rgds
|
||||
{
|
||||
struct rgds {
|
||||
UWORD r_spc;
|
||||
UWORD r_navc;
|
||||
UWORD r_bps;
|
||||
UWORD r_nc;
|
||||
};
|
||||
|
||||
struct remote_fileattrib
|
||||
{
|
||||
struct remote_fileattrib {
|
||||
UWORD rfa_file; /* File Attributes */
|
||||
union
|
||||
{
|
||||
union {
|
||||
ULONG rfa_filesize; /* file size */
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
UWORD rfa_filesize_lo; /* DI Low */
|
||||
UWORD rfa_filesize_hi; /* BX High */
|
||||
}
|
||||
_split_rfa_fz;
|
||||
}
|
||||
rfa_fz_union;
|
||||
} _split_rfa_fz;
|
||||
} rfa_fz_union;
|
||||
UWORD rfa_time;
|
||||
UWORD rfa_date;
|
||||
};
|
||||
|
||||
|
||||
|
236
hdr/nls.h
236
hdr/nls.h
@ -281,20 +281,19 @@
|
||||
access to often used and mandatoryly present tables. */
|
||||
#define NLS_REORDER_POINTERS
|
||||
|
||||
|
||||
/*
|
||||
* How the kernel and NLSFUNC communicate with each other
|
||||
*/
|
||||
/* Must be returned by NLSFUNC upon MUX-14-00 */
|
||||
/* Must be returned by NLSFUNC upon MUX-14-00 */
|
||||
#define NLS_FREEDOS_NLSFUNC_ID 0x534b
|
||||
/* Represents a call to DOS-38 within DOS-65 handlers.
|
||||
Current implementation relys on 0x101! */
|
||||
/* Represents a call to DOS-38 within DOS-65 handlers.
|
||||
Current implementation relys on 0x101! */
|
||||
#define NLS_DOS_38 0x101
|
||||
/* NLSFUNC may return NLS_REDO to instruct the kernel to
|
||||
try to perform the same action another time. This is most
|
||||
useful if the kernel only loads the NLS pkg into memory so
|
||||
the kernel will find it and will process the request internally
|
||||
now. */
|
||||
/* NLSFUNC may return NLS_REDO to instruct the kernel to
|
||||
try to perform the same action another time. This is most
|
||||
useful if the kernel only loads the NLS pkg into memory so
|
||||
the kernel will find it and will process the request internally
|
||||
now. */
|
||||
#define NLS_REDO 353
|
||||
|
||||
/* Codes of the subfunctions of external NLSFUNC */
|
||||
@ -320,42 +319,41 @@
|
||||
a "1" in the bitfield means that the feature is active/enabled.
|
||||
All currently non-defined bits are to be zero to allow future
|
||||
useage. */
|
||||
#define NLS_FLAG_DIRECT_UPCASE 0x0001 /* DOS-65-2[012], */
|
||||
#define NLS_FLAG_DIRECT_FUPCASE 0x0002 /* DOS-65-A[012], internal */
|
||||
#define NLS_FLAG_DIRECT_YESNO 0x0004 /* DOS-65-23 */
|
||||
#define NLS_FLAG_DIRECT_GETDATA 0x0008 /* DOS-65-XX, DOS-38 */
|
||||
#define NLS_FLAG_DIRECT_UPCASE 0x0001 /* DOS-65-2[012], */
|
||||
#define NLS_FLAG_DIRECT_FUPCASE 0x0002 /* DOS-65-A[012], internal */
|
||||
#define NLS_FLAG_DIRECT_YESNO 0x0004 /* DOS-65-23 */
|
||||
#define NLS_FLAG_DIRECT_GETDATA 0x0008 /* DOS-65-XX, DOS-38 */
|
||||
|
||||
#define NLS_FLAG_HARDCODED NLS_FLAG_DIRECT_UPCASE \
|
||||
| NLS_FLAG_DIRECT_FUPCASE \
|
||||
| NLS_FLAG_DIRECT_YESNO \
|
||||
| NLS_FLAG_DIRECT_GETDATA
|
||||
|
||||
/* No codepage / country code given */
|
||||
/* No codepage / country code given */
|
||||
#define NLS_DEFAULT ((UWORD)-1)
|
||||
|
||||
/*
|
||||
* This is the data in the exact order returned by DOS-65-01
|
||||
*/
|
||||
struct nlsExtCntryInfo
|
||||
{
|
||||
UBYTE subfct; /* always 1 */
|
||||
WORD size; /* size of this structure
|
||||
without this WORD itself */
|
||||
WORD countryCode; /* current country code */
|
||||
WORD codePage; /* current code page (CP) */
|
||||
struct nlsExtCntryInfo {
|
||||
UBYTE subfct; /* always 1 */
|
||||
WORD size; /* size of this structure
|
||||
without this WORD itself */
|
||||
WORD countryCode; /* current country code */
|
||||
WORD codePage; /* current code page (CP) */
|
||||
|
||||
/*
|
||||
* This is the data in the exact order as to return on
|
||||
* DOS-38; it is also the most (important) part of DOS-65-01
|
||||
*/
|
||||
/* Note: The ASCIZ strings might become
|
||||
a totally different understanding with
|
||||
DBCS (Double Byte Character Support) */
|
||||
/*
|
||||
* This is the data in the exact order as to return on
|
||||
* DOS-38; it is also the most (important) part of DOS-65-01
|
||||
*/
|
||||
/* Note: The ASCIZ strings might become
|
||||
a totally different understanding with
|
||||
DBCS (Double Byte Character Support) */
|
||||
WORD dateFmt; /* order of portions of date
|
||||
0: mm/dd/yyyy (USA)
|
||||
1: dd/mm/yyyy (Europe)
|
||||
2: yyyy/mm/dd (Japan)
|
||||
*/
|
||||
0: mm/dd/yyyy (USA)
|
||||
1: dd/mm/yyyy (Europe)
|
||||
2: yyyy/mm/dd (Japan)
|
||||
*/
|
||||
char curr[5]; /* ASCIZ of currency string */
|
||||
char thSep[2]; /* ASCIZ of thousand's separator */
|
||||
char point[2]; /* ASCIZ of decimal point */
|
||||
@ -363,64 +361,63 @@ struct nlsExtCntryInfo
|
||||
char timeSep[2]; /* ASCIZ of time separator */
|
||||
BYTE currFmt; /* format of currency:
|
||||
bit 0: currency string is placed
|
||||
0: before number
|
||||
1: behind number
|
||||
0: before number
|
||||
1: behind number
|
||||
bit 1: currency string and number are
|
||||
separated by a space
|
||||
0: No
|
||||
1: Yes
|
||||
separated by a space
|
||||
0: No
|
||||
1: Yes
|
||||
bit 2: currency string replaces decimal
|
||||
sign
|
||||
0: No
|
||||
1: Yes
|
||||
sign
|
||||
0: No
|
||||
1: Yes
|
||||
*/
|
||||
BYTE prescision; /* of monetary numbers */
|
||||
BYTE timeFmt; /* time format:
|
||||
0: 12 hours (append AM/PM)
|
||||
1: 24 houres
|
||||
*/
|
||||
VOID(FAR * upCaseFct) (VOID); /* far call to a function upcasing the
|
||||
character in register AL */
|
||||
0: 12 hours (append AM/PM)
|
||||
1: 24 houres
|
||||
*/
|
||||
VOID(FAR * upCaseFct) (VOID); /* far call to a function upcasing the
|
||||
character in register AL */
|
||||
char dataSep[2]; /* ASCIZ of separator in data records */
|
||||
};
|
||||
|
||||
struct nlsPointer { /* Information of DOS-65-0X is addressed
|
||||
by a pointer */
|
||||
UBYTE subfct; /* number of the subfunction */
|
||||
VOID FAR *pointer; /* the pointer to be returned when the subfunction
|
||||
of DOS-65 is called (Note: won't work for
|
||||
subfunctions 0, 1, 0x20, 0x21, 0x22, 0x23,
|
||||
0xA0, 0xA1,& 0xA2 */
|
||||
struct nlsPointer { /* Information of DOS-65-0X is addressed
|
||||
by a pointer */
|
||||
UBYTE subfct; /* number of the subfunction */
|
||||
VOID FAR *pointer; /* the pointer to be returned when the subfunction
|
||||
of DOS-65 is called (Note: won't work for
|
||||
subfunctions 0, 1, 0x20, 0x21, 0x22, 0x23,
|
||||
0xA0, 0xA1,& 0xA2 */
|
||||
};
|
||||
|
||||
|
||||
struct nlsPackage { /* the contents of one chain item of the
|
||||
list of NLS packages */
|
||||
struct nlsPackage FAR *nxt; /* next item in chain */
|
||||
UWORD cntry, cp; /* country ID / codepage of this NLS pkg */
|
||||
int flags; /* direct access and other flags */
|
||||
/* Note: Depending on the flags above all remaining
|
||||
portions may be omitted, if the external NLSFUNC-like
|
||||
MUX-14 processor does not require them and performs
|
||||
all actions itself, so that the kernel never tries to
|
||||
fetch this information itself. */
|
||||
UBYTE yeschar; /* yes / no character DOS-65-23 */
|
||||
UBYTE nochar;
|
||||
unsigned numSubfct; /* number of supported sub-functions */
|
||||
struct nlsPointer nlsPointers[1]; /* grows dynamically */
|
||||
struct nlsPackage { /* the contents of one chain item of the
|
||||
list of NLS packages */
|
||||
struct nlsPackage FAR *nxt; /* next item in chain */
|
||||
UWORD cntry, cp; /* country ID / codepage of this NLS pkg */
|
||||
int flags; /* direct access and other flags */
|
||||
/* Note: Depending on the flags above all remaining
|
||||
portions may be omitted, if the external NLSFUNC-like
|
||||
MUX-14 processor does not require them and performs
|
||||
all actions itself, so that the kernel never tries to
|
||||
fetch this information itself. */
|
||||
UBYTE yeschar; /* yes / no character DOS-65-23 */
|
||||
UBYTE nochar;
|
||||
unsigned numSubfct; /* number of supported sub-functions */
|
||||
struct nlsPointer nlsPointers[1]; /* grows dynamically */
|
||||
};
|
||||
|
||||
struct nlsDBCS { /* The internal structure is unknown to me */
|
||||
UWORD numEntries;
|
||||
UWORD dbcsTbl[1];
|
||||
struct nlsDBCS { /* The internal structure is unknown to me */
|
||||
UWORD numEntries;
|
||||
UWORD dbcsTbl[1];
|
||||
};
|
||||
|
||||
struct nlsCharTbl {
|
||||
/* table containing a list of characters */
|
||||
UWORD numEntries; /* number of entries of this table.
|
||||
If <= 0x80, the first element of
|
||||
the table corresponse to character 0x80 */
|
||||
unsigned char tbl[1]; /* grows dynamically */
|
||||
/* table containing a list of characters */
|
||||
UWORD numEntries; /* number of entries of this table.
|
||||
If <= 0x80, the first element of
|
||||
the table corresponse to character 0x80 */
|
||||
unsigned char tbl[1]; /* grows dynamically */
|
||||
};
|
||||
#define nlsChBuf(len) struct nlsCharTbl##len { \
|
||||
UWORD numEntries; \
|
||||
@ -431,37 +428,35 @@ nlsChBuf(256);
|
||||
|
||||
/* in file names permittable characters for DOS-65-05 */
|
||||
struct nlsFnamTerm {
|
||||
WORD size; /* size of this structure */
|
||||
BYTE dummy1;
|
||||
char firstCh,
|
||||
lastCh; /* first, last permittable character */
|
||||
BYTE dummy2;
|
||||
char firstExcl,
|
||||
lastExcl; /* first, last excluded character */
|
||||
BYTE dummy3;
|
||||
BYTE numSep; /* number of file name separators */
|
||||
char separators[1]; /* grows dynamically */
|
||||
WORD size; /* size of this structure */
|
||||
BYTE dummy1;
|
||||
char firstCh, lastCh; /* first, last permittable character */
|
||||
BYTE dummy2;
|
||||
char firstExcl, lastExcl; /* first, last excluded character */
|
||||
BYTE dummy3;
|
||||
BYTE numSep; /* number of file name separators */
|
||||
char separators[1]; /* grows dynamically */
|
||||
};
|
||||
|
||||
struct nlsInfoBlock { /* This block contains all information
|
||||
shared by the kernel and the external NLSFUNC program */
|
||||
char FAR *fname; /* filename from COUNTRY=;
|
||||
maybe tweaked by NLSFUNC */
|
||||
UWORD sysCodePage; /* system code page */
|
||||
unsigned flags; /* implementation flags */
|
||||
struct nlsPackage FAR *actPkg; /* current NLS package */
|
||||
struct nlsPackage FAR *chain; /* first item of info chain --
|
||||
hardcoded U.S.A./CP437 */
|
||||
struct nlsInfoBlock { /* This block contains all information
|
||||
shared by the kernel and the external NLSFUNC program */
|
||||
char FAR *fname; /* filename from COUNTRY=;
|
||||
maybe tweaked by NLSFUNC */
|
||||
UWORD sysCodePage; /* system code page */
|
||||
unsigned flags; /* implementation flags */
|
||||
struct nlsPackage FAR *actPkg; /* current NLS package */
|
||||
struct nlsPackage FAR *chain; /* first item of info chain --
|
||||
hardcoded U.S.A./CP437 */
|
||||
};
|
||||
|
||||
extern struct nlsInfoBlock nlsInfo;
|
||||
extern struct nlsPackage nlsPackageHardcoded;
|
||||
/* These are the "must have" tables within the hard coded NLS pkg */
|
||||
extern struct nlsFnamTerm nlsFnameTermHardcoded;
|
||||
extern struct nlsDBCS nlsDBCSHardcoded;
|
||||
extern struct nlsCharTbl nlsUpcaseHardcoded;
|
||||
extern struct nlsCharTbl nlsFUpcaseHardcoded;
|
||||
extern struct nlsCharTbl nlsCollHardcoded;
|
||||
extern struct nlsInfoBlock nlsInfo;
|
||||
extern struct nlsPackage nlsPackageHardcoded;
|
||||
/* These are the "must have" tables within the hard coded NLS pkg */
|
||||
extern struct nlsFnamTerm nlsFnameTermHardcoded;
|
||||
extern struct nlsDBCS nlsDBCSHardcoded;
|
||||
extern struct nlsCharTbl nlsUpcaseHardcoded;
|
||||
extern struct nlsCharTbl nlsFUpcaseHardcoded;
|
||||
extern struct nlsCharTbl nlsCollHardcoded;
|
||||
extern struct nlsExtCntryInfo nlsCntryInfoHardcoded;
|
||||
extern BYTE FAR hcTablesStart[], hcTablesEnd[];
|
||||
|
||||
@ -522,35 +517,34 @@ extern BYTE FAR hcTablesStart[], hcTablesEnd[];
|
||||
|
||||
#define CSYS_FD_IDSTRING "FreeDOS COUNTRY.SYS v1.0\r\n"
|
||||
|
||||
struct nlsCSys_function { /* S3: function definition */
|
||||
UDWORD csys_rpos; /* relative position to actual data */
|
||||
UWORD csys_length;
|
||||
UBYTE csys_fctID; /* As passed to DOS-65-XX */
|
||||
UBYTE csys_reserved1; /* always 0, reserved for future use */
|
||||
struct nlsCSys_function { /* S3: function definition */
|
||||
UDWORD csys_rpos; /* relative position to actual data */
|
||||
UWORD csys_length;
|
||||
UBYTE csys_fctID; /* As passed to DOS-65-XX */
|
||||
UBYTE csys_reserved1; /* always 0, reserved for future use */
|
||||
};
|
||||
|
||||
struct nlsCSys_ccDefinition { /* S1: country/codepage reference */
|
||||
UDWORD csys_rpos; /* moving the 4byte value to the front
|
||||
can increase performance */
|
||||
UWORD csys_cp;
|
||||
UWORD csys_cntry;
|
||||
struct nlsCSys_ccDefinition { /* S1: country/codepage reference */
|
||||
UDWORD csys_rpos; /* moving the 4byte value to the front
|
||||
can increase performance */
|
||||
UWORD csys_cp;
|
||||
UWORD csys_cntry;
|
||||
};
|
||||
|
||||
struct nlsCSys_numEntries { /* helper structure for "number of entries" */
|
||||
UWORD csys_numEntries;
|
||||
struct nlsCSys_numEntries { /* helper structure for "number of entries" */
|
||||
UWORD csys_numEntries;
|
||||
};
|
||||
|
||||
/* Actually, this structure is never really used */
|
||||
struct nlsCSys_fileHeader { /* S0: primary structure */
|
||||
unsigned char csys_idstring[sizeof(CSYS_FD_IDSTRING) - 1];
|
||||
/* decrement by 1 to cut off \0 from IDString -- ska*/
|
||||
struct nlsCSys_fileHeader { /* S0: primary structure */
|
||||
unsigned char csys_idstring[sizeof(CSYS_FD_IDSTRING) - 1];
|
||||
/* decrement by 1 to cut off \0 from IDString -- ska */
|
||||
};
|
||||
|
||||
struct nlsCSys_completeFileHeader { /* as S0, but full 128 bytes */
|
||||
unsigned char csys_idstring[sizeof(CSYS_FD_IDSTRING) - 1];
|
||||
unsigned char csys_padbytes[128 - (sizeof(CSYS_FD_IDSTRING) - 1)];
|
||||
struct nlsCSys_completeFileHeader { /* as S0, but full 128 bytes */
|
||||
unsigned char csys_idstring[sizeof(CSYS_FD_IDSTRING) - 1];
|
||||
unsigned char csys_padbytes[128 - (sizeof(CSYS_FD_IDSTRING) - 1)];
|
||||
};
|
||||
|
||||
|
||||
/* standard alignment */
|
||||
#include <algndflt.h>
|
||||
|
49
hdr/pcb.h
49
hdr/pcb.h
@ -51,27 +51,23 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *pcb_hRcsId = "$Id$";
|
||||
static BYTE *pcb_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Force one-byte alignment for all the internal structures, see above */
|
||||
#include <algnbyte.h>
|
||||
/* */
|
||||
/* interrupt handler structure definition */
|
||||
/* */
|
||||
typedef union
|
||||
{
|
||||
typedef union {
|
||||
UWORD x; /* access mode for ax, bx, etc. */
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
UBYTE l; /* access mode for al, bl, etc. */
|
||||
UBYTE h; /* access mode for ah, bh, etc. */
|
||||
}
|
||||
b;
|
||||
}
|
||||
xreg;
|
||||
} b;
|
||||
} xreg;
|
||||
|
||||
/* The structure assumes that:
|
||||
1) An interrupt was invoked, &
|
||||
@ -79,41 +75,26 @@ xreg;
|
||||
Furthermore, the PUSH$ALL macro must push ES first and AX last.
|
||||
-- 2000/03/22 ska*/
|
||||
/* maps MS-DOS unique stacking order */
|
||||
typedef struct _iregss
|
||||
{
|
||||
xreg a,
|
||||
b,
|
||||
c,
|
||||
d;
|
||||
UWORD si,
|
||||
di,
|
||||
bp,
|
||||
ds,
|
||||
es;
|
||||
UWORD ip,
|
||||
cs,
|
||||
flags;
|
||||
}
|
||||
iregs;
|
||||
typedef struct _iregss {
|
||||
xreg a, b, c, d;
|
||||
UWORD si, di, bp, ds, es;
|
||||
UWORD ip, cs, flags;
|
||||
} iregs;
|
||||
|
||||
/* Registers directly passed to syscall;
|
||||
must be the same order as iregs!
|
||||
Is used to define parameters. */
|
||||
must be the same order as iregs!
|
||||
Is used to define parameters. */
|
||||
#define DIRECT_IREGS \
|
||||
xreg a, xreg b, xreg c, xreg d, \
|
||||
UWORD si, UWORD di, UWORD bp, UWORD ds, UWORD es, \
|
||||
UWORD ip, UWORD cs, UWORD flags
|
||||
|
||||
|
||||
|
||||
/* Process control block for task switching */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
UWORD pc_ss;
|
||||
UWORD pc_sp;
|
||||
iregs pc_regs;
|
||||
}
|
||||
pcb;
|
||||
} pcb;
|
||||
|
||||
/* Note: The following figure is not made by myself and I assume that
|
||||
the order of "ES" through "AX" are misinterpreted?! -- 2000/03/22 ska*/
|
||||
|
91
hdr/portab.h
91
hdr/portab.h
@ -30,7 +30,8 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static char *portab_hRcsId = "$Id$";
|
||||
static char *portab_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -57,84 +58,71 @@ static char *portab_hRcsId = "$Id$";
|
||||
/* */
|
||||
/****************************************************************/
|
||||
|
||||
|
||||
/* commandline overflow - removing -DI86 TE*/
|
||||
/* commandline overflow - removing -DI86 TE */
|
||||
#if defined(__TURBOC__)
|
||||
|
||||
#define I86
|
||||
#define CDECL cdecl
|
||||
void __int__(int);
|
||||
|
||||
#elif defined (_MSC_VER)
|
||||
#define I86
|
||||
#define CDECL cdecl
|
||||
void __int__(int);
|
||||
|
||||
#define I86
|
||||
#define CDECL _cdecl
|
||||
#define __int__(intno) asm int intno;
|
||||
#elif defined (_MSC_VER)
|
||||
|
||||
#if defined(M_I286) /* /G3 doesn't set M_I386, but sets M_I286 TE*/
|
||||
#define I386
|
||||
#endif
|
||||
#define I86
|
||||
#define CDECL _cdecl
|
||||
#define __int__(intno) asm int intno;
|
||||
|
||||
#elif defined(__WATCOMC__) /* don't know a better way */
|
||||
#if defined(M_I286) /* /G3 doesn't set M_I386, but sets M_I286 TE */
|
||||
#define I386
|
||||
#endif
|
||||
|
||||
#define I86
|
||||
#define __int__(intno) asm int intno;
|
||||
#define asm __asm
|
||||
#define far __far
|
||||
#define CDECL __cdecl
|
||||
|
||||
#if _M_IX86 >= 300
|
||||
#define I386
|
||||
#endif
|
||||
#elif defined(__WATCOMC__) /* don't know a better way */
|
||||
|
||||
#define I86
|
||||
#define __int__(intno) asm int intno;
|
||||
#define asm __asm
|
||||
#define far __far
|
||||
#define CDECL __cdecl
|
||||
|
||||
#if _M_IX86 >= 300
|
||||
#define I386
|
||||
#endif
|
||||
|
||||
#elif defined (_MYMC68K_COMILER_)
|
||||
|
||||
#define MC68K
|
||||
#define MC68K
|
||||
|
||||
#else
|
||||
anyone knows a _portable_ way to create nice errors??
|
||||
at least this causes the compiler not to compile :-)
|
||||
#else
|
||||
anyone knows a _portable_ way to create nice errors ? ?
|
||||
at least this causes the compiler not to compile : -)
|
||||
#endif
|
||||
/* functions, that are shared between C and ASM _must_
|
||||
have a certain calling standard. These are declared
|
||||
as 'ASMCFUNC', and is (and will be ?-) cdecl */
|
||||
have a certain calling standard. These are declared
|
||||
as 'ASMCFUNC', and is (and will be ?-) cdecl */
|
||||
#define ASMCFUNC cdecl
|
||||
|
||||
#ifdef MC68K
|
||||
|
||||
#define far /* No far type */
|
||||
#define interrupt /* No interrupt type */
|
||||
|
||||
#define VOID void
|
||||
#define FAR /* linear architecture */
|
||||
#define NEAR /* " " */
|
||||
#define INRPT interrupt
|
||||
|
||||
#define CONST
|
||||
#define REG register
|
||||
|
||||
#define API int /* linear architecture */
|
||||
#define NONNATIVE
|
||||
|
||||
#define PARASIZE 4096 /* "paragraph" size */
|
||||
#endif
|
||||
|
||||
#ifdef I86
|
||||
|
||||
#define VOID void
|
||||
#define FAR far /* segment architecture */
|
||||
#define NEAR near /* " " */
|
||||
#define INRPT interrupt
|
||||
|
||||
#define CONST const
|
||||
#define REG register
|
||||
|
||||
#define API int far pascal /* segment architecture */
|
||||
#define API int far pascal /* segment architecture */
|
||||
#define NATIVE
|
||||
|
||||
#define PARASIZE 16 /* "paragraph" size */
|
||||
#endif
|
||||
|
||||
/* */
|
||||
/* Boolean type & definitions of TRUE and FALSE boolean values */
|
||||
/* */
|
||||
@ -186,8 +174,7 @@ typedef unsigned short CLUSTER;
|
||||
#endif
|
||||
typedef unsigned short UNICODE;
|
||||
|
||||
#define STATIC /* local calls inside module */
|
||||
|
||||
#define STATIC /* local calls inside module */
|
||||
|
||||
#ifdef UNIX
|
||||
typedef char FAR *ADDRESS;
|
||||
@ -220,16 +207,16 @@ typedef signed long LONG;
|
||||
this suppresses the warning
|
||||
unreferenced parameter 'x'
|
||||
and (hopefully) generates no code
|
||||
*/
|
||||
*/
|
||||
|
||||
#if defined(__TURBOC__)
|
||||
#define UNREFERENCED_PARAMETER(x) if (x);
|
||||
#else
|
||||
#define UNREFERENCED_PARAMETER(x) x;
|
||||
#endif
|
||||
#define UNREFERENCED_PARAMETER(x) if (x);
|
||||
#else
|
||||
#define UNREFERENCED_PARAMETER(x) x;
|
||||
#endif
|
||||
|
||||
#ifdef I86 /* commandline overflow - removing /DPROTO TE*/
|
||||
#define PROTO
|
||||
#ifdef I86 /* commandline overflow - removing /DPROTO TE */
|
||||
#define PROTO
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -30,7 +30,8 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *process_hRcsId = "$Id$";
|
||||
static BYTE *process_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -40,36 +41,27 @@ static BYTE *process_hRcsId = "$Id$";
|
||||
#define P_NOWAIT 1 /* both concurrent -- not implemented */
|
||||
#define P_OVERLAY 2 /* child replaces parent, parent no longer exists */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
UWORD load_seg;
|
||||
UWORD reloc;
|
||||
}
|
||||
_load;
|
||||
struct
|
||||
{
|
||||
} _load;
|
||||
struct {
|
||||
UWORD env_seg;
|
||||
CommandTail FAR *cmd_line;
|
||||
fcb FAR *fcb_1;
|
||||
fcb FAR *fcb_2;
|
||||
BYTE FAR *stack;
|
||||
BYTE FAR *start_addr;
|
||||
}
|
||||
_exec;
|
||||
}
|
||||
ldata;
|
||||
}
|
||||
exec_blk;
|
||||
} _exec;
|
||||
} ldata;
|
||||
} exec_blk;
|
||||
|
||||
#define exec ldata._exec
|
||||
#define load ldata._load
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
UWORD ps_exit; /* 00 CP/M-like exit poimt */
|
||||
UWORD ps_size; /* 02 memory size in paragraphs */
|
||||
BYTE ps_fill1; /* 04 single char fill */
|
||||
@ -77,9 +69,9 @@ typedef struct
|
||||
/* CP/M-like entry point */
|
||||
UBYTE ps_farcall; /* 05 far call opcode */
|
||||
VOID(FAR * ps_reentry) (); /* 06 re-entry point */
|
||||
VOID(interrupt FAR * ps_isv22) (),/* 0a terminate address */
|
||||
(interrupt FAR * ps_isv23) (), /* 0e break address */
|
||||
(interrupt FAR * ps_isv24) (); /* 12 critical error address */
|
||||
VOID(interrupt FAR * ps_isv22) (), /* 0a terminate address */
|
||||
(interrupt FAR * ps_isv23) (), /* 0e break address */
|
||||
(interrupt FAR * ps_isv24) (); /* 12 critical error address */
|
||||
UWORD ps_parent; /* 16 parent psp segment */
|
||||
UBYTE ps_files[20]; /* 18 file table - 0xff is unused */
|
||||
UWORD ps_environ; /* 2c environment paragraph */
|
||||
@ -89,39 +81,25 @@ typedef struct
|
||||
VOID FAR *ps_prevpsp; /* 38 previous psp pointer */
|
||||
BYTE FAR *ps_dta; /* 3c process dta address */
|
||||
BYTE ps_fill2[16];
|
||||
UBYTE ps_unix[3]; /* unix style call - 0xcd 0x21 0xcb */
|
||||
UBYTE ps_unix[3]; /* unix style call - 0xcd 0x21 0xcb */
|
||||
BYTE ps_fill3[9];
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
fcb
|
||||
_ps_fcb1; /* first command line argument */
|
||||
}
|
||||
_u1;
|
||||
struct
|
||||
{
|
||||
BYTE
|
||||
fill4[16];
|
||||
fcb
|
||||
_ps_fcb2; /* second command line argument */
|
||||
}
|
||||
_u2;
|
||||
struct
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
fcb _ps_fcb1; /* first command line argument */
|
||||
} _u1;
|
||||
struct {
|
||||
BYTE fill4[16];
|
||||
fcb _ps_fcb2; /* second command line argument */
|
||||
} _u2;
|
||||
struct {
|
||||
BYTE fill5[36];
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
BYTE _ps_cmd_count;
|
||||
BYTE _ps_cmd[127]; /* command tail */
|
||||
}
|
||||
_u4;
|
||||
}
|
||||
_u3;
|
||||
}
|
||||
_u;
|
||||
}
|
||||
psp;
|
||||
} _u4;
|
||||
} _u3;
|
||||
} _u;
|
||||
} psp;
|
||||
|
||||
#define ps_fcb1 _u._u1._ps_fcb1
|
||||
#define ps_fcb2 _u._u2._ps_fcb2
|
||||
|
47
hdr/sft.h
47
hdr/sft.h
@ -29,16 +29,15 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *sft_hRcsId = "$Id$";
|
||||
static BYTE *sft_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#define SFTMAX 128
|
||||
|
||||
/* Handle Definition entry */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
WORD sft_count; /* 00 - reference count */
|
||||
WORD sft_mode; /* 02 - open mode - see below */
|
||||
BYTE sft_attrib; /* 04 - file attribute - dir style */
|
||||
@ -46,24 +45,17 @@ typedef struct
|
||||
union /* 05 */
|
||||
{
|
||||
WORD _sft_flags;
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
BYTE _sft_flags_lo;
|
||||
BYTE _sft_flags_hi;
|
||||
}
|
||||
_split_sft_flags;
|
||||
}
|
||||
sft_flags_union;
|
||||
} _split_sft_flags;
|
||||
} sft_flags_union;
|
||||
|
||||
union /* 07 */
|
||||
{
|
||||
struct dpb FAR *
|
||||
_sft_dcb; /* The device control block */
|
||||
struct dhdr FAR *
|
||||
_sft_dev; /* device driver for char dev */
|
||||
}
|
||||
|
||||
sft_dcb_or_dev;
|
||||
struct dpb FAR *_sft_dcb; /* The device control block */
|
||||
struct dhdr FAR *_sft_dev; /* device driver for char dev */
|
||||
} sft_dcb_or_dev;
|
||||
WORD sft_stclust; /* 0b - Starting cluster */
|
||||
time sft_time; /* 0d - File time */
|
||||
date sft_date; /* 0f - File date */
|
||||
@ -74,36 +66,30 @@ typedef struct
|
||||
WORD sft_dirdlust; /* 1d - Sector containing cluster */
|
||||
BYTE sft_diridx; /* 1f - directory index */
|
||||
BYTE sft_name[11]; /* 20 - dir style file name */
|
||||
BYTE FAR *
|
||||
sft_bshare; /* 2b - backward link of file sharing sft */
|
||||
BYTE FAR *sft_bshare; /* 2b - backward link of file sharing sft */
|
||||
WORD sft_mach; /* 2f - machine number - network apps */
|
||||
WORD sft_psp; /* 31 - owner psp */
|
||||
WORD sft_shroff; /* 33 - Sharing offset */
|
||||
WORD sft_status; /* 35 - this sft status */
|
||||
BYTE FAR * sft_ifsptr; /* 37 - pointer to IFS driver for file, 0000000h if native DOS */
|
||||
}
|
||||
sft;
|
||||
BYTE FAR *sft_ifsptr; /* 37 - pointer to IFS driver for file, 0000000h if native DOS */
|
||||
} sft;
|
||||
|
||||
/* SFT Table header definition */
|
||||
typedef struct _sftheader
|
||||
{
|
||||
typedef struct _sftheader {
|
||||
struct _sfttbl FAR * /* link to next table in list */
|
||||
sftt_next;
|
||||
WORD sftt_count; /* # of handle definition */
|
||||
/* entries, this table */
|
||||
}
|
||||
sftheader;
|
||||
} sftheader;
|
||||
|
||||
/* System File Definition List */
|
||||
typedef struct _sfttbl
|
||||
{
|
||||
typedef struct _sfttbl {
|
||||
struct _sfttbl FAR * /* link to next table in list */
|
||||
sftt_next;
|
||||
WORD sftt_count; /* # of handle definition */
|
||||
/* entries, this table */
|
||||
sft sftt_table[SFTMAX]; /* The array of sft for block */
|
||||
}
|
||||
sfttbl;
|
||||
} sfttbl;
|
||||
|
||||
/* defines for sft use */
|
||||
#define SFT_MASK 0x0060 /* splits device data */
|
||||
@ -153,7 +139,6 @@ sfttbl;
|
||||
#define sft_flags_hi sft_flags_union._split_sft_flags._sft_flags_hi
|
||||
#define sft_flags_lo sft_flags_union._split_sft_flags._sft_flags_lo
|
||||
|
||||
|
||||
/*
|
||||
* Log: sft.h,v
|
||||
*
|
||||
|
10
hdr/tail.h
10
hdr/tail.h
@ -30,21 +30,19 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *tail_hRcsId = "$Id$";
|
||||
static BYTE *tail_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef LINESIZE
|
||||
#define LINESIZE 127
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
UBYTE ctCount; /* number of bytes returned */
|
||||
BYTE ctBuffer[LINESIZE]; /* the buffer itself */
|
||||
}
|
||||
CommandTail;
|
||||
} CommandTail;
|
||||
|
||||
/*
|
||||
* Log: tail.h,v
|
||||
|
@ -34,7 +34,8 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *time_hRcsId = "$Id$";
|
||||
static BYTE *time_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -87,4 +88,3 @@ typedef UWORD time;
|
||||
* Rev 1.0 02 Jul 1995 10:39:56 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
@ -28,7 +28,8 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *date_hRcsId = "$Id$";
|
||||
static BYTE *date_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -45,5 +46,5 @@ static BYTE *date_hRcsId = "$Id$";
|
||||
#define REVISION_SEQ 25
|
||||
#define BUILD "2025"
|
||||
#define SUB_BUILD "b"
|
||||
#define KERNEL_VERSION_STRING "1.1.25b" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ*/
|
||||
#define KERNEL_BUILD_STRING "2025b" /*#BUILD SUB_BUILD*/
|
||||
#define KERNEL_VERSION_STRING "1.1.25b" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */
|
||||
#define KERNEL_BUILD_STRING "2025b" /*#BUILD SUB_BUILD */
|
||||
|
@ -8,54 +8,52 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *XStructs_hRcsId = "$Id$";
|
||||
static BYTE *XStructs_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct xdpbdata
|
||||
{
|
||||
UWORD xdd_dpbsize;
|
||||
struct xdpbdata {
|
||||
UWORD xdd_dpbsize;
|
||||
struct dpb xdd_dpb;
|
||||
};
|
||||
|
||||
struct xfreespace
|
||||
{
|
||||
UWORD xfs_datasize; /* size of this structure */
|
||||
struct xfreespace {
|
||||
UWORD xfs_datasize; /* size of this structure */
|
||||
union {
|
||||
UWORD requested; /* requested structure version */
|
||||
UWORD actual; /* actual structure version */
|
||||
UWORD requested; /* requested structure version */
|
||||
UWORD actual; /* actual structure version */
|
||||
} xfs_version;
|
||||
ULONG xfs_clussize; /* number of sectors per cluster */
|
||||
ULONG xfs_secsize; /* number of bytes per sector */
|
||||
ULONG xfs_freeclusters; /* number of available clusters */
|
||||
ULONG xfs_totalclusters; /* total number of clusters on the drive */
|
||||
ULONG xfs_freesectors; /* number of physical sectors available */
|
||||
ULONG xfs_totalsectors; /* total number of physical sectors */
|
||||
ULONG xfs_freeunits; /* number of available allocation units */
|
||||
ULONG xfs_totalunits; /* total allocation units */
|
||||
ULONG xfs_clussize; /* number of sectors per cluster */
|
||||
ULONG xfs_secsize; /* number of bytes per sector */
|
||||
ULONG xfs_freeclusters; /* number of available clusters */
|
||||
ULONG xfs_totalclusters; /* total number of clusters on the drive */
|
||||
ULONG xfs_freesectors; /* number of physical sectors available */
|
||||
ULONG xfs_totalsectors; /* total number of physical sectors */
|
||||
ULONG xfs_freeunits; /* number of available allocation units */
|
||||
ULONG xfs_totalunits; /* total allocation units */
|
||||
UBYTE xfs_reserved[8];
|
||||
};
|
||||
|
||||
struct xdpbforformat
|
||||
{
|
||||
UWORD xdff_datasize; /* size of this structure */
|
||||
struct xdpbforformat {
|
||||
UWORD xdff_datasize; /* size of this structure */
|
||||
union {
|
||||
UWORD requested; /* requested structure version */
|
||||
UWORD actual; /* actual structure version */
|
||||
UWORD requested; /* requested structure version */
|
||||
UWORD actual; /* actual structure version */
|
||||
} xdff_version;
|
||||
UDWORD xdff_function; /* function number:
|
||||
00h invalidate DPB counts
|
||||
01h rebuild DPB from BPB
|
||||
02h force media change
|
||||
03h get/set active FAT number and mirroring
|
||||
04h get/set root directory cluster number
|
||||
*/
|
||||
UDWORD xdff_function; /* function number:
|
||||
00h invalidate DPB counts
|
||||
01h rebuild DPB from BPB
|
||||
02h force media change
|
||||
03h get/set active FAT number and mirroring
|
||||
04h get/set root directory cluster number
|
||||
*/
|
||||
union {
|
||||
struct {
|
||||
DWORD nfreeclst; /* # free clusters
|
||||
(-1 - unknown, 0 - don't change) */
|
||||
DWORD cluster; /* cluster # of first free
|
||||
(-1 - unknown, 0 - don't change) */
|
||||
DWORD nfreeclst; /* # free clusters
|
||||
(-1 - unknown, 0 - don't change) */
|
||||
DWORD cluster; /* cluster # of first free
|
||||
(-1 - unknown, 0 - don't change) */
|
||||
UDWORD reserved[2];
|
||||
} setdpbcounts;
|
||||
|
||||
@ -66,18 +64,18 @@ struct xdpbforformat
|
||||
} rebuilddpb;
|
||||
|
||||
struct {
|
||||
DWORD newmirroring; /* new active FAT/mirroring state, or -1 to get
|
||||
bits 3-0: the 0-based FAT number of the active FAT
|
||||
bits 6-4: reserved (0)
|
||||
bit 7: do not mirror active FAT to inactive FATs
|
||||
*/
|
||||
DWORD oldmirroring; /* previous active FAT/mirroring state (as above) */
|
||||
DWORD newmirroring; /* new active FAT/mirroring state, or -1 to get
|
||||
bits 3-0: the 0-based FAT number of the active FAT
|
||||
bits 6-4: reserved (0)
|
||||
bit 7: do not mirror active FAT to inactive FATs
|
||||
*/
|
||||
DWORD oldmirroring; /* previous active FAT/mirroring state (as above) */
|
||||
UDWORD reserved[2];
|
||||
} setmirroring;
|
||||
|
||||
struct {
|
||||
DWORD newrootclst; /* set new root directory cluster, -1 - get current */
|
||||
DWORD oldrootclst; /* get previous root directory cluster */
|
||||
DWORD newrootclst; /* set new root directory cluster, -1 - get current */
|
||||
DWORD oldrootclst; /* get previous root directory cluster */
|
||||
UDWORD reserved[2];
|
||||
} setroot;
|
||||
} xdff_f;
|
||||
|
297
kernel/blockio.c
297
kernel/blockio.c
@ -32,9 +32,10 @@
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *blockioRcsId = "$Id$";
|
||||
static BYTE *blockioRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* block cache routines */
|
||||
@ -42,7 +43,6 @@ static BYTE *blockioRcsId = "$Id$";
|
||||
/************************************************************************/
|
||||
/* #define DISPLAY_GETBLOCK */
|
||||
|
||||
|
||||
/* */
|
||||
/* Initialize the buffer structure */
|
||||
/* */
|
||||
@ -75,7 +75,7 @@ VOID FAR reloc_call_init_buffers(void)
|
||||
*/
|
||||
/* Extract the block number from a buffer structure. */
|
||||
#if 0 /*TE*/
|
||||
ULONG getblkno(struct buffer FAR * bp)
|
||||
ULONG getblkno(struct buffer FAR * bp)
|
||||
{
|
||||
if (bp->b_blkno == 0xffffu)
|
||||
return bp->b_huge_blkno;
|
||||
@ -89,7 +89,7 @@ ULONG getblkno(struct buffer FAR * bp)
|
||||
/* Set the block number of a buffer structure. (The caller should */
|
||||
/* set the unit number before calling this function.) */
|
||||
#if 0 /*TE*/
|
||||
VOID setblkno(struct buffer FAR * bp, ULONG blkno)
|
||||
VOID setblkno(struct buffer FAR * bp, ULONG blkno)
|
||||
{
|
||||
if (blkno >= 0xffffu)
|
||||
{
|
||||
@ -101,7 +101,7 @@ VOID setblkno(struct buffer FAR * bp, ULONG blkno)
|
||||
bp->b_blkno = blkno;
|
||||
/* bp->b_dpbp = &blk_devices[bp->b_unit]; */
|
||||
|
||||
bp->b_dpbp = CDSp->cds_table[bp->b_unit].cdsDpb;
|
||||
bp->b_dpbp = CDSp->cds_table[bp->b_unit].cdsDpb;
|
||||
|
||||
}
|
||||
}
|
||||
@ -124,38 +124,34 @@ VOID setblkno(struct buffer FAR * bp, ULONG blkno)
|
||||
UNCACHE buffers are recycled first.
|
||||
intended to be used for full sector reads into application buffer
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
BOOL searchblock(ULONG blkno, COUNT dsk,
|
||||
struct buffer FAR ** pBuffp)
|
||||
BOOL searchblock(ULONG blkno, COUNT dsk, struct buffer FAR ** pBuffp)
|
||||
{
|
||||
int fat_count = 0;
|
||||
struct buffer FAR *bp;
|
||||
struct buffer FAR *lbp = NULL;
|
||||
struct buffer FAR *lastNonFat = NULL;
|
||||
struct buffer FAR *uncacheBuf = NULL;
|
||||
int fat_count = 0;
|
||||
struct buffer FAR *bp;
|
||||
struct buffer FAR *lbp = NULL;
|
||||
struct buffer FAR *lastNonFat = NULL;
|
||||
struct buffer FAR *uncacheBuf = NULL;
|
||||
|
||||
|
||||
#ifdef DISPLAY_GETBLOCK
|
||||
printf("[searchblock %d, blk %ld, buf ", dsk, blkno);
|
||||
printf("[searchblock %d, blk %ld, buf ", dsk, blkno);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Search through buffers to see if the required block */
|
||||
/* is already in a buffer */
|
||||
|
||||
for (bp = firstbuf; bp != NULL;lbp = bp, bp = bp->b_next)
|
||||
for (bp = firstbuf; bp != NULL; lbp = bp, bp = bp->b_next)
|
||||
{
|
||||
if ((getblkno(bp) == blkno) &&
|
||||
if ((getblkno(bp) == blkno) &&
|
||||
(bp->b_flag & BFR_VALID) && (bp->b_unit == dsk))
|
||||
{
|
||||
/* found it -- rearrange LRU links */
|
||||
if (lbp != NULL)
|
||||
{
|
||||
lbp->b_next = bp->b_next;
|
||||
bp->b_next = firstbuf;
|
||||
firstbuf = bp;
|
||||
lbp->b_next = bp->b_next;
|
||||
bp->b_next = firstbuf;
|
||||
firstbuf = bp;
|
||||
}
|
||||
#ifdef DISPLAY_GETBLOCK
|
||||
printf("HIT %04x:%04x]\n", FP_SEG(bp), FP_OFF(bp));
|
||||
@ -165,92 +161,87 @@ BOOL searchblock(ULONG blkno, COUNT dsk,
|
||||
}
|
||||
|
||||
if (bp->b_flag & BFR_UNCACHE)
|
||||
uncacheBuf = bp;
|
||||
|
||||
uncacheBuf = bp;
|
||||
|
||||
if (bp->b_flag & BFR_FAT)
|
||||
fat_count++;
|
||||
fat_count++;
|
||||
else
|
||||
lastNonFat = bp;
|
||||
lastNonFat = bp;
|
||||
}
|
||||
|
||||
/*
|
||||
now take either the last buffer in chain (not used recently)
|
||||
or, if we are low on FAT buffers, the last non FAT buffer
|
||||
*/
|
||||
|
||||
if (uncacheBuf)
|
||||
/*
|
||||
now take either the last buffer in chain (not used recently)
|
||||
or, if we are low on FAT buffers, the last non FAT buffer
|
||||
*/
|
||||
|
||||
if (uncacheBuf)
|
||||
{
|
||||
lbp = uncacheBuf;
|
||||
}
|
||||
else
|
||||
lbp = uncacheBuf;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lbp ->b_flag & BFR_FAT && fat_count < 3 && lastNonFat)
|
||||
if (lbp->b_flag & BFR_FAT && fat_count < 3 && lastNonFat)
|
||||
{
|
||||
lbp = lastNonFat;
|
||||
lbp = lastNonFat;
|
||||
}
|
||||
}
|
||||
|
||||
lbp->b_flag &= ~BFR_UNCACHE; /* reset uncache attribute */
|
||||
|
||||
}
|
||||
|
||||
lbp->b_flag &= ~BFR_UNCACHE; /* reset uncache attribute */
|
||||
|
||||
*pBuffp = lbp;
|
||||
|
||||
|
||||
#ifdef DISPLAY_GETBLOCK
|
||||
printf("MISS, replace %04x:%04x]\n", FP_SEG(lbp), FP_OFF(lbp));
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (lbp != firstbuf) /* move to front */
|
||||
{
|
||||
if (lbp != firstbuf) /* move to front */
|
||||
{
|
||||
for (bp = firstbuf; bp->b_next != lbp; bp = bp->b_next)
|
||||
;
|
||||
;
|
||||
bp->b_next = bp->b_next->b_next;
|
||||
lbp->b_next = firstbuf;
|
||||
firstbuf = lbp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL DeleteBlockInBufferCache(ULONG blknolow, ULONG blknohigh, COUNT dsk)
|
||||
{
|
||||
struct buffer FAR *bp;
|
||||
struct buffer FAR *bp;
|
||||
|
||||
/* Search through buffers to see if the required block */
|
||||
/* is already in a buffer */
|
||||
|
||||
for (bp = firstbuf; bp != NULL; bp = bp->b_next)
|
||||
{
|
||||
if (blknolow <= getblkno(bp) &&
|
||||
if (blknolow <= getblkno(bp) &&
|
||||
getblkno(bp) <= blknohigh &&
|
||||
(bp->b_flag & BFR_VALID) && (bp->b_unit == dsk))
|
||||
(bp->b_flag & BFR_VALID) && (bp->b_unit == dsk))
|
||||
{
|
||||
flush1(bp);
|
||||
flush1(bp);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void dumpBufferCache(void)
|
||||
{
|
||||
struct buffer FAR *bp;
|
||||
int printed = 0;
|
||||
struct buffer FAR *bp;
|
||||
int printed = 0;
|
||||
|
||||
/* Search through buffers to see if the required block */
|
||||
/* is already in a buffer */
|
||||
|
||||
for (bp = firstbuf; bp != NULL;bp = bp->b_next)
|
||||
for (bp = firstbuf; bp != NULL; bp = bp->b_next)
|
||||
{
|
||||
printf("%8lx %02x ",getblkno(bp),bp->b_flag);
|
||||
printf("%8lx %02x ", getblkno(bp), bp->b_flag);
|
||||
if (++printed % 6 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* */
|
||||
/* Return the address of a buffer structure containing the */
|
||||
@ -263,37 +254,34 @@ void dumpBufferCache(void)
|
||||
/* */
|
||||
struct buffer FAR *getblock(ULONG blkno, COUNT dsk)
|
||||
{
|
||||
struct buffer FAR *bp;
|
||||
|
||||
|
||||
struct buffer FAR *bp;
|
||||
|
||||
/* Search through buffers to see if the required block */
|
||||
/* is already in a buffer */
|
||||
|
||||
if (searchblock(blkno, dsk, &bp))
|
||||
{
|
||||
return (bp);
|
||||
}
|
||||
if (searchblock(blkno, dsk, &bp))
|
||||
{
|
||||
return (bp);
|
||||
}
|
||||
|
||||
/* The block we need is not in a buffer, we must make a buffer */
|
||||
/* available, and fill it with the desired block */
|
||||
|
||||
|
||||
/* take the buffer that lbp points to and flush it, then read new block. */
|
||||
if (!flush1(bp))
|
||||
return NULL;
|
||||
|
||||
/* Fill the indicated disk buffer with the current track and sector */
|
||||
return NULL;
|
||||
|
||||
/* Fill the indicated disk buffer with the current track and sector */
|
||||
|
||||
if (dskxfer(dsk, blkno, (VOID FAR *) bp->b_buffer, 1, DSKREAD))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bp->b_flag = BFR_VALID | BFR_DATA;
|
||||
bp->b_unit = dsk;
|
||||
setblkno(bp, blkno);
|
||||
|
||||
|
||||
return bp;
|
||||
|
||||
}
|
||||
@ -302,23 +290,23 @@ struct buffer FAR *getblock(ULONG blkno, COUNT dsk)
|
||||
exactly the same as getblock(), but the data will be completely
|
||||
overwritten. so there is no need to read from disk first
|
||||
*/
|
||||
struct buffer FAR * getblockOver(ULONG blkno, COUNT dsk)
|
||||
struct buffer FAR *getblockOver(ULONG blkno, COUNT dsk)
|
||||
{
|
||||
struct buffer FAR *bp;
|
||||
struct buffer FAR *bp;
|
||||
|
||||
/* Search through buffers to see if the required block */
|
||||
/* is already in a buffer */
|
||||
|
||||
if (searchblock(blkno, dsk, &bp))
|
||||
{
|
||||
return bp;
|
||||
}
|
||||
if (searchblock(blkno, dsk, &bp))
|
||||
{
|
||||
return bp;
|
||||
}
|
||||
|
||||
/* The block we need is not in a buffer, we must make a buffer */
|
||||
/* available. */
|
||||
|
||||
/* take the buffer than lbp points to and flush it, then make it available. */
|
||||
if (flush1(bp)) /* success */
|
||||
if (flush1(bp)) /* success */
|
||||
{
|
||||
bp->b_flag = 0;
|
||||
bp->b_unit = dsk;
|
||||
@ -331,6 +319,7 @@ struct buffer FAR * getblockOver(ULONG blkno, COUNT dsk)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* */
|
||||
/* Mark all buffers for a disk as not valid */
|
||||
/* */
|
||||
@ -374,14 +363,13 @@ BOOL flush_buffers(REG COUNT dsk)
|
||||
/* */
|
||||
BOOL flush1(struct buffer FAR * bp)
|
||||
{
|
||||
/* All lines with changes on 9/4/00 by BER marked below */
|
||||
|
||||
UWORD result; /* BER 9/4/00 */
|
||||
/* All lines with changes on 9/4/00 by BER marked below */
|
||||
|
||||
UWORD result; /* BER 9/4/00 */
|
||||
|
||||
if ((bp->b_flag & BFR_VALID) && (bp->b_flag & BFR_DIRTY))
|
||||
{
|
||||
result = dskxfer(bp->b_unit, getblkno(bp),
|
||||
(VOID FAR *) bp->b_buffer, 1, DSKWRITE); /* BER 9/4/00 */
|
||||
result = dskxfer(bp->b_unit, getblkno(bp), (VOID FAR *) bp->b_buffer, 1, DSKWRITE); /* BER 9/4/00 */
|
||||
if (bp->b_flag & BFR_FAT)
|
||||
{
|
||||
int i = bp->b_copies;
|
||||
@ -390,19 +378,18 @@ BOOL flush1(struct buffer FAR * bp)
|
||||
while (--i > 0)
|
||||
{
|
||||
blkno += bp->b_offset;
|
||||
result = dskxfer(bp->b_unit, blkno,
|
||||
(VOID FAR *) bp->b_buffer, 1, DSKWRITE); /* BER 9/4/00 */
|
||||
result = dskxfer(bp->b_unit, blkno, (VOID FAR *) bp->b_buffer, 1, DSKWRITE); /* BER 9/4/00 */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
result = 0; /* This negates any error code returned in result...BER */
|
||||
/* and 0 returned, if no errors occurred - tom */
|
||||
result = 0; /* This negates any error code returned in result...BER */
|
||||
/* and 0 returned, if no errors occurred - tom */
|
||||
bp->b_flag &= ~BFR_DIRTY; /* even if error, mark not dirty */
|
||||
if (result != 0) /* otherwise system has trouble */
|
||||
bp->b_flag &= ~BFR_VALID; /* continuing. */
|
||||
return (TRUE); /* Forced to TRUE...was like this before dskxfer() */
|
||||
/* returned error codes...BER */
|
||||
return (TRUE); /* Forced to TRUE...was like this before dskxfer() */
|
||||
/* returned error codes...BER */
|
||||
}
|
||||
|
||||
/* */
|
||||
@ -428,7 +415,6 @@ BOOL flush(void)
|
||||
return (ok);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* Device Driver Interface Functions */
|
||||
@ -439,32 +425,33 @@ BOOL flush(void)
|
||||
/* */
|
||||
|
||||
/* Changed to UWORD 9/4/00 BER */
|
||||
UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, COUNT mode)
|
||||
UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
|
||||
COUNT mode)
|
||||
/* End of change */
|
||||
{
|
||||
/* REG struct dpb *dpbp = &blk_devices[dsk]; */
|
||||
|
||||
REG struct dpb FAR *dpbp = CDSp->cds_table[dsk].cdsDpb;
|
||||
|
||||
|
||||
if ((UCOUNT)dsk >= lastdrive )
|
||||
{
|
||||
return 0x0201; /* illegal command */
|
||||
}
|
||||
if ((UCOUNT) dsk >= lastdrive)
|
||||
{
|
||||
return 0x0201; /* illegal command */
|
||||
}
|
||||
if (!(CDSp->cds_table[dsk].cdsFlags & CDSPHYSDRV))
|
||||
{
|
||||
return 0x0201; /* illegal command */
|
||||
}
|
||||
|
||||
{
|
||||
return 0x0201; /* illegal command */
|
||||
}
|
||||
|
||||
#if TOM
|
||||
#define KeyboardShiftState() (*(BYTE FAR *)(MK_FP(0x40,0x17)))
|
||||
|
||||
if (KeyboardShiftState() & 0x01)
|
||||
{
|
||||
printf("dskxfer:%s %x - %lx %u\n", mode == DSKWRITE ? "write" : "read", dsk, blkno, numblocks);
|
||||
{
|
||||
printf("dskxfer:%s %x - %lx %u\n", mode == DSKWRITE ? "write" : "read",
|
||||
dsk, blkno, numblocks);
|
||||
if ((KeyboardShiftState() & 0x03) == 3)
|
||||
dumpBufferCache();
|
||||
}
|
||||
dumpBufferCache();
|
||||
}
|
||||
#endif
|
||||
|
||||
for (;;)
|
||||
@ -472,18 +459,27 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, COUNT mod
|
||||
IoReqHdr.r_length = sizeof(request);
|
||||
IoReqHdr.r_unit = dpbp->dpb_subunit;
|
||||
|
||||
switch(mode)
|
||||
switch (mode)
|
||||
{
|
||||
case DSKWRITE:
|
||||
if (verify_ena)
|
||||
{
|
||||
case DSKWRITE : if (verify_ena) { IoReqHdr.r_command = C_OUTVFY; break; }
|
||||
/* else fall through */
|
||||
case DSKWRITEINT26: IoReqHdr.r_command = C_OUTPUT; break;
|
||||
|
||||
case DSKREADINT25:
|
||||
case DSKREAD : IoReqHdr.r_command = C_INPUT; break;
|
||||
default:
|
||||
return 0x0100; /* illegal command */
|
||||
}
|
||||
|
||||
IoReqHdr.r_command = C_OUTVFY;
|
||||
break;
|
||||
}
|
||||
/* else fall through */
|
||||
case DSKWRITEINT26:
|
||||
IoReqHdr.r_command = C_OUTPUT;
|
||||
break;
|
||||
|
||||
case DSKREADINT25:
|
||||
case DSKREAD:
|
||||
IoReqHdr.r_command = C_INPUT;
|
||||
break;
|
||||
default:
|
||||
return 0x0100; /* illegal command */
|
||||
}
|
||||
|
||||
IoReqHdr.r_status = 0;
|
||||
IoReqHdr.r_meddesc = dpbp->dpb_mdb;
|
||||
IoReqHdr.r_trans = (BYTE FAR *) buf;
|
||||
@ -499,46 +495,43 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, COUNT mod
|
||||
if (!(IoReqHdr.r_status & S_ERROR) && (IoReqHdr.r_status & S_DONE))
|
||||
break;
|
||||
|
||||
/* INT25/26 (_SEEMS_ TO) return immediately with 0x8002,
|
||||
if drive is not online,...
|
||||
|
||||
normal operations (DIR) wait for ABORT/RETRY
|
||||
|
||||
other condition codes not tested
|
||||
*/
|
||||
/* INT25/26 (_SEEMS_ TO) return immediately with 0x8002,
|
||||
if drive is not online,...
|
||||
|
||||
normal operations (DIR) wait for ABORT/RETRY
|
||||
|
||||
other condition codes not tested
|
||||
*/
|
||||
if (mode >= DSKWRITEINT26)
|
||||
return (IoReqHdr.r_status);
|
||||
return (IoReqHdr.r_status);
|
||||
|
||||
/* Changed 9/4/00 BER
|
||||
return (IoReqHdr.r_status);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/* Skip the abort, retry, fail code...it needs fixed...BER */
|
||||
/* End of change */
|
||||
|
||||
loop:
|
||||
switch (block_error(&IoReqHdr, dpbp->dpb_unit, dpbp->dpb_device))
|
||||
{
|
||||
case ABORT:
|
||||
case FAIL:
|
||||
return (IoReqHdr.r_status);
|
||||
loop:
|
||||
switch (block_error(&IoReqHdr, dpbp->dpb_unit, dpbp->dpb_device))
|
||||
{
|
||||
case ABORT:
|
||||
case FAIL:
|
||||
return (IoReqHdr.r_status);
|
||||
|
||||
case RETRY:
|
||||
continue;
|
||||
case RETRY:
|
||||
continue;
|
||||
|
||||
case CONTINUE:
|
||||
break;
|
||||
case CONTINUE:
|
||||
break;
|
||||
|
||||
default:
|
||||
goto loop;
|
||||
}
|
||||
default:
|
||||
goto loop;
|
||||
}
|
||||
|
||||
} /* retry loop */
|
||||
} /* retry loop */
|
||||
/* *** Changed 9/4/00 BER */
|
||||
return 0; /* Success! Return 0 for a successful operation. */
|
||||
return 0; /* Success! Return 0 for a successful operation. */
|
||||
/* End of change */
|
||||
|
||||
}
|
||||
@ -547,7 +540,7 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, COUNT mod
|
||||
* 2000/9/04 Brian Reifsnyder
|
||||
* Modified dskxfer() such that error codes are now returned.
|
||||
* Functions that rely on dskxfer() have also been modified accordingly.
|
||||
*/
|
||||
*/
|
||||
|
||||
/*
|
||||
* Log: blockio.c,v - for newer entries do "cvs log blockio.c"
|
||||
|
@ -33,7 +33,8 @@
|
||||
extern void ASMCFUNC spawn_int23(void);
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId = "$Id$";
|
||||
static BYTE *RcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#define CB_FLG *(UBYTE FAR*)MK_FP(0x40, 0x71)
|
||||
@ -67,7 +68,7 @@ void handle_break(void)
|
||||
if (!ErrorMode) /* within int21_handler, InDOS is not incremented */
|
||||
if (InDOS)
|
||||
--InDOS; /* fail-safe */
|
||||
|
||||
|
||||
spawn_int23(); /* invoke user INT-23 and never come back */
|
||||
}
|
||||
|
||||
@ -81,4 +82,3 @@ void handle_break(void)
|
||||
* Steffen contributed.
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -31,7 +31,8 @@
|
||||
#include "portab.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *charioRcsId = "$Id$";
|
||||
static BYTE *charioRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#include "globals.h"
|
||||
@ -67,26 +68,28 @@ struct dhdr FAR *finddev(UWORD attr_mask)
|
||||
|
||||
VOID _cso(COUNT c)
|
||||
{
|
||||
if (syscon->dh_attr & ATTR_FASTCON) {
|
||||
#if defined(__TURBOC__)
|
||||
_AL = c;
|
||||
__int__(0x29);
|
||||
#else
|
||||
asm {
|
||||
mov al, byte ptr c;
|
||||
int 0x29;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
CharReqHdr.r_command = C_OUTPUT;
|
||||
CharReqHdr.r_count = 1;
|
||||
CharReqHdr.r_trans = (BYTE FAR *) (&c);
|
||||
CharReqHdr.r_status = 0;
|
||||
execrh((request FAR *) & CharReqHdr, syscon);
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
char_error(&CharReqHdr, syscon);
|
||||
if (syscon->dh_attr & ATTR_FASTCON)
|
||||
{
|
||||
#if defined(__TURBOC__)
|
||||
_AL = c;
|
||||
__int__(0x29);
|
||||
#else
|
||||
asm
|
||||
{
|
||||
mov al, byte ptr c;
|
||||
int 0x29;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
CharReqHdr.r_command = C_OUTPUT;
|
||||
CharReqHdr.r_count = 1;
|
||||
CharReqHdr.r_trans = (BYTE FAR *) (&c);
|
||||
CharReqHdr.r_status = 0;
|
||||
execrh((request FAR *) & CharReqHdr, syscon);
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
char_error(&CharReqHdr, syscon);
|
||||
}
|
||||
|
||||
VOID cso(COUNT c)
|
||||
@ -95,7 +98,7 @@ VOID cso(COUNT c)
|
||||
con_hold();
|
||||
|
||||
if (PrinterEcho)
|
||||
DosWrite(STDPRN, 1, (BYTE FAR *) & c, (COUNT FAR *) &UnusedRetVal);
|
||||
DosWrite(STDPRN, 1, (BYTE FAR *) & c, (COUNT FAR *) & UnusedRetVal);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
@ -106,20 +109,24 @@ VOID cso(COUNT c)
|
||||
case BELL:
|
||||
break;
|
||||
case BS:
|
||||
if (scr_pos > 0) scr_pos--;
|
||||
if (scr_pos > 0)
|
||||
scr_pos--;
|
||||
break;
|
||||
case HT:
|
||||
do _cso(' '); while ((++scr_pos) & 7);
|
||||
do
|
||||
_cso(' ');
|
||||
while ((++scr_pos) & 7);
|
||||
break;
|
||||
default:
|
||||
scr_pos++;
|
||||
}
|
||||
if (c != HT) _cso(c);
|
||||
if (c != HT)
|
||||
_cso(c);
|
||||
}
|
||||
|
||||
VOID sto(COUNT c)
|
||||
{
|
||||
DosWrite(STDOUT, 1, (BYTE FAR *) & c, (COUNT FAR *) &UnusedRetVal);
|
||||
DosWrite(STDOUT, 1, (BYTE FAR *) & c, (COUNT FAR *) & UnusedRetVal);
|
||||
}
|
||||
|
||||
VOID mod_cso(REG UCOUNT c)
|
||||
@ -169,11 +176,11 @@ COUNT ndread(void)
|
||||
COUNT con_read(void)
|
||||
{
|
||||
BYTE c;
|
||||
|
||||
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
CharReqHdr.r_command = C_INPUT;
|
||||
CharReqHdr.r_count = 1;
|
||||
CharReqHdr.r_trans = (BYTE FAR *)&c;
|
||||
CharReqHdr.r_trans = (BYTE FAR *) & c;
|
||||
CharReqHdr.r_status = 0;
|
||||
execrh((request FAR *) & CharReqHdr, syscon);
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
@ -186,7 +193,7 @@ COUNT con_read(void)
|
||||
VOID con_hold(void)
|
||||
{
|
||||
UBYTE c = ndread();
|
||||
if(c == CTL_S)
|
||||
if (c == CTL_S)
|
||||
{
|
||||
con_read();
|
||||
Do_DosIdle_loop();
|
||||
@ -210,8 +217,9 @@ UCOUNT _sti(BOOL check_break)
|
||||
Do_DosIdle_loop();
|
||||
if (check_break)
|
||||
con_hold();
|
||||
while (GenericRead(STDIN, 1, (BYTE FAR *) & c, (COUNT FAR *) & UnusedRetVal, TRUE)
|
||||
!= 1) ;
|
||||
while (GenericRead
|
||||
(STDIN, 1, (BYTE FAR *) & c, (COUNT FAR *) & UnusedRetVal,
|
||||
TRUE) != 1) ;
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -285,11 +293,9 @@ static VOID kbfill(keyboard FAR * kp, UCOUNT c, BOOL ctlf, UWORD * vp)
|
||||
/* return number of characters before EOF if there is one, else just the total */
|
||||
UCOUNT sti_0a(keyboard FAR * kp)
|
||||
{
|
||||
REG UWORD c,
|
||||
cu_pos = scr_pos;
|
||||
UWORD
|
||||
virt_pos = scr_pos;
|
||||
UWORD init_count = 0; /* kp->kb_count; */
|
||||
REG UWORD c, cu_pos = scr_pos;
|
||||
UWORD virt_pos = scr_pos;
|
||||
UWORD init_count = 0; /* kp->kb_count; */
|
||||
BOOL eof = FALSE;
|
||||
#ifndef NOSPCL
|
||||
static BYTE local_buffer[LINESIZE];
|
||||
@ -327,7 +333,7 @@ UCOUNT sti_0a(keyboard FAR * kp)
|
||||
break;
|
||||
}
|
||||
|
||||
case F1:
|
||||
case F1:
|
||||
case RIGHT:
|
||||
c = local_buffer[kp->kb_count];
|
||||
if (c)
|
||||
@ -377,7 +383,7 @@ UCOUNT sti_0a(keyboard FAR * kp)
|
||||
return eof;
|
||||
else
|
||||
return kp->kb_count--;
|
||||
|
||||
|
||||
case LF:
|
||||
break;
|
||||
|
||||
@ -406,7 +412,7 @@ UCOUNT sti(keyboard * kp)
|
||||
UCOUNT ReadCount = sti_0a(kp);
|
||||
kp->kb_count++;
|
||||
|
||||
if (ReadCount >= kp->kb_count && kp->kb_count < kp->kb_size)
|
||||
if (ReadCount >= kp->kb_count && kp->kb_count < kp->kb_size)
|
||||
{
|
||||
kp->kb_buf[kp->kb_count++] = LF;
|
||||
cso(LF);
|
||||
@ -483,4 +489,3 @@ UCOUNT sti(keyboard * kp)
|
||||
* Initial revision.
|
||||
*
|
||||
*/
|
||||
|
||||
|
1177
kernel/config.c
1177
kernel/config.c
File diff suppressed because it is too large
Load Diff
@ -27,12 +27,11 @@
|
||||
/* Cambridge, MA 02139, USA. */
|
||||
/****************************************************************/
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Enable debugging of NLS part */
|
||||
/* Enable debugging of NLS part */
|
||||
|
||||
/* Caution: Enabling NLS debugging usually generates
|
||||
_a_lot_ of noise. */
|
||||
/* Caution: Enabling NLS debugging usually generates
|
||||
_a_lot_ of noise. */
|
||||
/*& #define NLS_DEBUG */
|
||||
|
||||
#endif
|
||||
|
1333
kernel/dosfns.c
1333
kernel/dosfns.c
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,8 @@
|
||||
#include "portab.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *dosnamesRcsId = "$Id$";
|
||||
static BYTE *dosnamesRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#include "globals.h"
|
||||
@ -79,16 +80,10 @@ VOID SpacePad(BYTE * szString, COUNT nChars)
|
||||
COUNT ParseDosName(BYTE * lpszFileName,
|
||||
COUNT * pnDrive,
|
||||
BYTE * pszDir,
|
||||
BYTE * pszFile,
|
||||
BYTE * pszExt,
|
||||
BOOL bAllowWildcards)
|
||||
BYTE * pszFile, BYTE * pszExt, BOOL bAllowWildcards)
|
||||
{
|
||||
COUNT nDirCnt,
|
||||
nFileCnt,
|
||||
nExtCnt;
|
||||
BYTE *lpszLclDir,
|
||||
*lpszLclFile,
|
||||
*lpszLclExt;
|
||||
COUNT nDirCnt, nFileCnt, nExtCnt;
|
||||
BYTE *lpszLclDir, *lpszLclFile, *lpszLclExt;
|
||||
|
||||
/* Initialize the users data fields */
|
||||
if (pszDir)
|
||||
@ -118,12 +113,13 @@ COUNT ParseDosName(BYTE * lpszFileName,
|
||||
}
|
||||
nDirCnt = FP_OFF(lpszLclFile) - FP_OFF(lpszLclDir);
|
||||
/* Fix lengths to maximums allowed by MS-DOS. */
|
||||
if (nDirCnt > PARSE_MAX-1)
|
||||
nDirCnt = PARSE_MAX-1;
|
||||
if (nDirCnt > PARSE_MAX - 1)
|
||||
nDirCnt = PARSE_MAX - 1;
|
||||
|
||||
/* Parse out the file name portion. */
|
||||
lpszFileName = lpszLclFile;
|
||||
while (bAllowWildcards ? WildChar(*lpszFileName) : NameChar(*lpszFileName))
|
||||
while (bAllowWildcards ? WildChar(*lpszFileName) :
|
||||
NameChar(*lpszFileName))
|
||||
{
|
||||
++nFileCnt;
|
||||
++lpszFileName;
|
||||
@ -131,26 +127,25 @@ COUNT ParseDosName(BYTE * lpszFileName,
|
||||
|
||||
if (nFileCnt == 0)
|
||||
/* Lixing Yuan Patch */
|
||||
if (bAllowWildcards) /* for find first */
|
||||
{
|
||||
if (*lpszFileName != '\0')
|
||||
return DE_FILENOTFND;
|
||||
if (nDirCnt == 1) /* for d:\ */
|
||||
return DE_NFILES;
|
||||
if (pszDir)
|
||||
{
|
||||
memcpy(pszDir, lpszLclDir, nDirCnt);
|
||||
pszDir[nDirCnt] = '\0';
|
||||
}
|
||||
if (pszFile)
|
||||
memcpy(pszFile, "????????", FNAME_SIZE+1);
|
||||
if (pszExt)
|
||||
memcpy(pszExt, "???", FEXT_SIZE+1);
|
||||
return SUCCESS;
|
||||
}
|
||||
else
|
||||
return DE_FILENOTFND;
|
||||
|
||||
if (bAllowWildcards) /* for find first */
|
||||
{
|
||||
if (*lpszFileName != '\0')
|
||||
return DE_FILENOTFND;
|
||||
if (nDirCnt == 1) /* for d:\ */
|
||||
return DE_NFILES;
|
||||
if (pszDir)
|
||||
{
|
||||
memcpy(pszDir, lpszLclDir, nDirCnt);
|
||||
pszDir[nDirCnt] = '\0';
|
||||
}
|
||||
if (pszFile)
|
||||
memcpy(pszFile, "????????", FNAME_SIZE + 1);
|
||||
if (pszExt)
|
||||
memcpy(pszExt, "???", FEXT_SIZE + 1);
|
||||
return SUCCESS;
|
||||
}
|
||||
else
|
||||
return DE_FILENOTFND;
|
||||
|
||||
/* Now we have pointers set to the directory portion and the */
|
||||
/* file portion. Now determine the existance of an extension. */
|
||||
@ -160,14 +155,16 @@ COUNT ParseDosName(BYTE * lpszFileName,
|
||||
lpszLclExt = ++lpszFileName;
|
||||
while (*lpszFileName)
|
||||
{
|
||||
if (bAllowWildcards ? WildChar(*lpszFileName) : NameChar(*lpszFileName))
|
||||
if (bAllowWildcards ? WildChar(*lpszFileName) :
|
||||
NameChar(*lpszFileName))
|
||||
{
|
||||
++nExtCnt;
|
||||
++lpszFileName;
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
return DE_FILENOTFND;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*lpszFileName)
|
||||
@ -199,14 +196,10 @@ COUNT ParseDosName(BYTE * lpszFileName,
|
||||
#if 0
|
||||
/* not necessary anymore because of truename */
|
||||
COUNT ParseDosPath(BYTE * lpszFileName,
|
||||
COUNT * pnDrive,
|
||||
BYTE * pszDir,
|
||||
BYTE * pszCurPath)
|
||||
COUNT * pnDrive, BYTE * pszDir, BYTE * pszCurPath)
|
||||
{
|
||||
COUNT nDirCnt,
|
||||
nPathCnt;
|
||||
BYTE *lpszLclDir,
|
||||
*pszBase = pszDir;
|
||||
COUNT nDirCnt, nPathCnt;
|
||||
BYTE *lpszLclDir, *pszBase = pszDir;
|
||||
|
||||
/* Initialize the users data fields */
|
||||
*pszDir = '\0';
|
||||
@ -237,10 +230,10 @@ COUNT ParseDosPath(BYTE * lpszFileName,
|
||||
lpszLclDir = lpszFileName;
|
||||
if (!PathSep(*lpszLclDir))
|
||||
{
|
||||
fstrncpy(pszDir, pszCurPath, PARSE_MAX - 1); /*TE*/
|
||||
nPathCnt = fstrlen(pszCurPath);
|
||||
if (!PathSep(pszDir[nPathCnt - 1]) && nPathCnt < PARSE_MAX - 1) /*TE*/
|
||||
pszDir[nPathCnt++] = '\\';
|
||||
fstrncpy(pszDir, pszCurPath, PARSE_MAX - 1);
|
||||
/*TE*/ nPathCnt = fstrlen(pszCurPath);
|
||||
if (!PathSep(pszDir[nPathCnt - 1]) && nPathCnt < PARSE_MAX - 1)
|
||||
/*TE*/ pszDir[nPathCnt++] = '\\';
|
||||
if (nPathCnt > PARSE_MAX)
|
||||
nPathCnt = PARSE_MAX;
|
||||
pszDir += nPathCnt;
|
||||
@ -248,16 +241,15 @@ COUNT ParseDosPath(BYTE * lpszFileName,
|
||||
|
||||
/* Now see how long a directory component we have. */
|
||||
while (NameChar(*lpszFileName)
|
||||
|| PathSep(*lpszFileName)
|
||||
|| '.' == *lpszFileName)
|
||||
|| PathSep(*lpszFileName) || '.' == *lpszFileName)
|
||||
{
|
||||
++nDirCnt;
|
||||
++lpszFileName;
|
||||
}
|
||||
|
||||
/* Fix lengths to maximums allowed by MS-DOS. */
|
||||
if ((nDirCnt + nPathCnt) > PARSE_MAX - 1) /*TE*/
|
||||
nDirCnt = PARSE_MAX - 1 - nPathCnt;
|
||||
if ((nDirCnt + nPathCnt) > PARSE_MAX - 1)
|
||||
/*TE*/ nDirCnt = PARSE_MAX - 1 - nPathCnt;
|
||||
|
||||
/* Finally copy whatever the user wants extracted to the user's */
|
||||
/* buffers. */
|
||||
@ -289,11 +281,8 @@ COUNT ParseDosPath(BYTE * lpszFileName,
|
||||
|
||||
VOID DosTrimPath(BYTE * lpszPathNamep)
|
||||
{
|
||||
BYTE *lpszLast,
|
||||
*lpszNext,
|
||||
*lpszRoot = NULL;
|
||||
COUNT nChars,
|
||||
flDotDot;
|
||||
BYTE *lpszLast, *lpszNext, *lpszRoot = NULL;
|
||||
COUNT nChars, flDotDot;
|
||||
|
||||
/* First, convert all '/' to '\'. Look for root as we scan */
|
||||
if (*lpszPathNamep == '\\')
|
||||
@ -302,14 +291,13 @@ VOID DosTrimPath(BYTE * lpszPathNamep)
|
||||
{
|
||||
if (*lpszNext == '/')
|
||||
*lpszNext = '\\';
|
||||
if (!lpszRoot &&
|
||||
*lpszNext == ':' && *(lpszNext + 1) == '\\')
|
||||
if (!lpszRoot && *lpszNext == ':' && *(lpszNext + 1) == '\\')
|
||||
lpszRoot = lpszNext + 1;
|
||||
}
|
||||
|
||||
/* NAMEMAX + 2, must include C: TE*/
|
||||
/* NAMEMAX + 2, must include C: TE */
|
||||
for (lpszLast = lpszNext = lpszPathNamep, nChars = 0;
|
||||
*lpszNext != '\0' && nChars < NAMEMAX+2;)
|
||||
*lpszNext != '\0' && nChars < NAMEMAX + 2;)
|
||||
{
|
||||
/* Initialize flag for loop. */
|
||||
flDotDot = FALSE;
|
||||
@ -325,8 +313,7 @@ VOID DosTrimPath(BYTE * lpszPathNamep)
|
||||
/* as appropriate. */
|
||||
else if (*(lpszNext + 1) == '.')
|
||||
{
|
||||
if (*(lpszNext + 2) == '.'
|
||||
&& !(*(lpszNext + 3)))
|
||||
if (*(lpszNext + 2) == '.' && !(*(lpszNext + 3)))
|
||||
{
|
||||
/* At the end, just truncate */
|
||||
/* and exit. */
|
||||
@ -337,8 +324,7 @@ VOID DosTrimPath(BYTE * lpszPathNamep)
|
||||
return;
|
||||
}
|
||||
|
||||
if (*(lpszNext + 2) == '.'
|
||||
&& *(lpszNext + 3) == '\\')
|
||||
if (*(lpszNext + 2) == '.' && *(lpszNext + 3) == '\\')
|
||||
{
|
||||
fstrncpy(lpszLast, lpszNext + 3, NAMEMAX);
|
||||
/* bump back to the last */
|
||||
@ -351,8 +337,7 @@ VOID DosTrimPath(BYTE * lpszPathNamep)
|
||||
{
|
||||
--lpszLast;
|
||||
}
|
||||
while (lpszLast != lpszPathNamep
|
||||
&& *lpszLast != '\\');
|
||||
while (lpszLast != lpszPathNamep && *lpszLast != '\\');
|
||||
flDotDot = TRUE;
|
||||
}
|
||||
/* Note: we skip strange stuff that */
|
||||
@ -360,7 +345,7 @@ VOID DosTrimPath(BYTE * lpszPathNamep)
|
||||
else if (*(lpszNext + 2) == '\\')
|
||||
{
|
||||
fstrncpy(lpszNext, lpszNext + 2, NAMEMAX);
|
||||
flDotDot = TRUE;
|
||||
flDotDot = TRUE;
|
||||
}
|
||||
/* If we're at the end of a string, */
|
||||
/* just exit. */
|
||||
@ -460,4 +445,3 @@ VOID DosTrimPath(BYTE * lpszPathNamep)
|
||||
* Initial revision.
|
||||
*
|
||||
*/
|
||||
|
||||
|
1170
kernel/dsk.c
1170
kernel/dsk.c
File diff suppressed because it is too large
Load Diff
@ -5,9 +5,9 @@
|
||||
|
||||
alll data herein goes to special segment
|
||||
DYN_DATA AFTER BSS, but immediately before HMA_TEXT
|
||||
*/
|
||||
*/
|
||||
#include "portab.h"
|
||||
#include "init-mod.h"
|
||||
#include "dyndata.h"
|
||||
|
||||
struct DynS Dyn = {0};
|
||||
struct DynS Dyn = { 0 };
|
||||
|
@ -14,6 +14,6 @@ void far *DynLast(void);
|
||||
void DynFree(void *ptr);
|
||||
|
||||
struct DynS {
|
||||
unsigned Allocated;
|
||||
char Buffer[1];
|
||||
};
|
||||
unsigned Allocated;
|
||||
char Buffer[1];
|
||||
};
|
||||
|
@ -4,7 +4,6 @@
|
||||
this serves requests from the INIT modules to
|
||||
allocate dynamic data.
|
||||
|
||||
|
||||
kernel layout:
|
||||
00000H 000FFH 00100H PSP PSP
|
||||
00100H 004E1H 003E2H _TEXT CODE
|
||||
@ -28,7 +27,6 @@ additionally:
|
||||
122E0H 12AA5H 007C6H ID ID
|
||||
12AA6H 12CBFH 0021AH IB IB
|
||||
|
||||
|
||||
purpose is to move the HMA_TEXT = resident kernel
|
||||
around, so that below it - after BSS, there is data
|
||||
addressable near by the kernel, to hold some arrays
|
||||
@ -36,62 +34,61 @@ additionally:
|
||||
|
||||
making f_nodes near saves ~2.150 code in HMA
|
||||
|
||||
*/
|
||||
*/
|
||||
#include "portab.h"
|
||||
#include "init-mod.h"
|
||||
#include "dyndata.h"
|
||||
#include "dyndata.h"
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define DebugPrintf(x) printf x
|
||||
#define DebugPrintf(x) printf x
|
||||
#else
|
||||
#define DebugPrintf(x)
|
||||
#define DebugPrintf(x)
|
||||
#endif
|
||||
|
||||
|
||||
/*extern struct DynS FAR Dyn;*/
|
||||
|
||||
#ifndef __TURBOC__
|
||||
#include "init-dat.h"
|
||||
extern struct DynS DOSFAR Dyn;
|
||||
#include "init-dat.h"
|
||||
extern struct DynS DOSFAR Dyn;
|
||||
#else
|
||||
extern struct DynS FAR Dyn;
|
||||
#endif
|
||||
|
||||
|
||||
extern struct DynS FAR Dyn;
|
||||
#endif
|
||||
|
||||
void far *DynAlloc(char *what, unsigned num, unsigned size)
|
||||
{
|
||||
void far *now;
|
||||
unsigned total = num * size;
|
||||
void far *now;
|
||||
unsigned total = num * size;
|
||||
#ifndef DEBUG
|
||||
UNREFERENCED_PARAMETER(what);
|
||||
UNREFERENCED_PARAMETER(what);
|
||||
#endif
|
||||
|
||||
if ((ULONG)total + Dyn.Allocated > 0xffff)
|
||||
{
|
||||
printf("PANIC:Dyn %lu\n", (ULONG)total + Dyn.Allocated);
|
||||
for (;;);
|
||||
}
|
||||
|
||||
DebugPrintf(("DYNDATA:allocating %s - %u * %u bytes, total %u, %u..%u\n",
|
||||
what, num, size, total, Dyn.Allocated,Dyn.Allocated+total));
|
||||
|
||||
now = (void far *)&Dyn.Buffer[Dyn.Allocated];
|
||||
fmemset(now, 0, total);
|
||||
|
||||
Dyn.Allocated += total;
|
||||
|
||||
return now;
|
||||
}
|
||||
if ((ULONG) total + Dyn.Allocated > 0xffff)
|
||||
{
|
||||
printf("PANIC:Dyn %lu\n", (ULONG) total + Dyn.Allocated);
|
||||
for (;;) ;
|
||||
}
|
||||
|
||||
DebugPrintf(("DYNDATA:allocating %s - %u * %u bytes, total %u, %u..%u\n",
|
||||
what, num, size, total, Dyn.Allocated,
|
||||
Dyn.Allocated + total));
|
||||
|
||||
now = (void far *)&Dyn.Buffer[Dyn.Allocated];
|
||||
fmemset(now, 0, total);
|
||||
|
||||
Dyn.Allocated += total;
|
||||
|
||||
return now;
|
||||
}
|
||||
|
||||
void DynFree(void *ptr)
|
||||
{
|
||||
Dyn.Allocated = (char *)ptr - (char *)Dyn.Buffer;
|
||||
Dyn.Allocated = (char *)ptr - (char *)Dyn.Buffer;
|
||||
}
|
||||
|
||||
void FAR *DynLast()
|
||||
{
|
||||
DebugPrintf(("dynamic data end at %p\n",(void FAR *)(Dyn.Buffer+Dyn.Allocated)));
|
||||
DebugPrintf(("dynamic data end at %p\n",
|
||||
(void FAR *)(Dyn.Buffer + Dyn.Allocated)));
|
||||
|
||||
return Dyn.Buffer+Dyn.Allocated;
|
||||
}
|
||||
return Dyn.Buffer + Dyn.Allocated;
|
||||
}
|
||||
|
@ -29,7 +29,8 @@
|
||||
#include "portab.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *errorRcsId = "$Id$";
|
||||
static BYTE *errorRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#include "globals.h"
|
||||
@ -39,19 +40,11 @@ static BYTE *errorRcsId = "$Id$";
|
||||
VOID dump(void)
|
||||
{
|
||||
printf("Register Dump [AH = %02x CS:IP = %04x:%04x]\n",
|
||||
error_regs.AH,
|
||||
error_regs.CS,
|
||||
error_regs.IP);
|
||||
error_regs.AH, error_regs.CS, error_regs.IP);
|
||||
printf("AX:%04x BX:%04x CX:%04x DX:%04x\n",
|
||||
error_regs.AX,
|
||||
error_regs.BX,
|
||||
error_regs.CX,
|
||||
error_regs.DX);
|
||||
error_regs.AX, error_regs.BX, error_regs.CX, error_regs.DX);
|
||||
printf("SI:%04x DI:%04x DS:%04x ES:%04x\n",
|
||||
error_regs.SI,
|
||||
error_regs.DI,
|
||||
error_regs.DS,
|
||||
error_regs.ES);
|
||||
error_regs.SI, error_regs.DI, error_regs.DS, error_regs.ES);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -82,21 +75,15 @@ VOID fatal(BYTE * err_msg)
|
||||
/* Abort, retry or fail for character devices */
|
||||
COUNT char_error(request * rq, struct dhdr FAR * lpDevice)
|
||||
{
|
||||
return CriticalError(
|
||||
EFLG_CHAR | EFLG_ABORT | EFLG_RETRY | EFLG_IGNORE,
|
||||
0,
|
||||
rq->r_status & S_MASK,
|
||||
lpDevice);
|
||||
return CriticalError(EFLG_CHAR | EFLG_ABORT | EFLG_RETRY | EFLG_IGNORE,
|
||||
0, rq->r_status & S_MASK, lpDevice);
|
||||
}
|
||||
|
||||
/* Abort, retry or fail for block devices */
|
||||
COUNT block_error(request * rq, COUNT nDrive, struct dhdr FAR * lpDevice)
|
||||
{
|
||||
return CriticalError(
|
||||
EFLG_ABORT | EFLG_RETRY | EFLG_IGNORE,
|
||||
nDrive,
|
||||
rq->r_status & S_MASK,
|
||||
lpDevice);
|
||||
return CriticalError(EFLG_ABORT | EFLG_RETRY | EFLG_IGNORE,
|
||||
nDrive, rq->r_status & S_MASK, lpDevice);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -139,4 +126,3 @@ COUNT block_error(request * rq, COUNT nDrive, struct dhdr FAR * lpDevice)
|
||||
* Rev 1.0 02 Jul 1995 8:06:14 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
229
kernel/fatdir.c
229
kernel/fatdir.c
@ -31,7 +31,8 @@
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *fatdirRcsId = "$Id$";
|
||||
static BYTE *fatdirRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
/* Description.
|
||||
@ -45,24 +46,25 @@ VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart)
|
||||
fnp->f_flags.f_droot = FALSE;
|
||||
fnp->f_flags.f_ddir = TRUE;
|
||||
fnp->f_flags.f_dnew = TRUE;
|
||||
fnp->f_diroff = fnp->f_offset = fnp->f_cluster_offset = fnp->f_highwater = 0l;
|
||||
fnp->f_diroff = fnp->f_offset = fnp->f_cluster_offset =
|
||||
fnp->f_highwater = 0l;
|
||||
|
||||
/* root directory */
|
||||
if (dirstart == 0)
|
||||
{
|
||||
{
|
||||
#ifdef WITHFAT32
|
||||
if (ISFAT32(fnp->f_dpb))
|
||||
{
|
||||
fnp->f_cluster = fnp->f_dirstart = fnp->f_dpb->dpb_xrootclst;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
fnp->f_dirstart = 0l;
|
||||
fnp->f_flags.f_droot = TRUE;
|
||||
}
|
||||
if (ISFAT32(fnp->f_dpb))
|
||||
{
|
||||
fnp->f_cluster = fnp->f_dirstart = fnp->f_dpb->dpb_xrootclst;
|
||||
}
|
||||
else /* non-root */
|
||||
else
|
||||
#endif
|
||||
{
|
||||
fnp->f_dirstart = 0l;
|
||||
fnp->f_flags.f_droot = TRUE;
|
||||
}
|
||||
}
|
||||
else /* non-root */
|
||||
fnp->f_cluster = fnp->f_dirstart = dirstart;
|
||||
}
|
||||
|
||||
@ -76,17 +78,18 @@ f_node_ptr dir_open(BYTE * dirname)
|
||||
BYTE *pszPath = dirname + 2;
|
||||
|
||||
/* Allocate an fnode if possible - error return (0) if not. */
|
||||
if ((fnp = get_f_node()) == (f_node_ptr)0)
|
||||
if ((fnp = get_f_node()) == (f_node_ptr) 0)
|
||||
{
|
||||
return (f_node_ptr)0;
|
||||
return (f_node_ptr) 0;
|
||||
}
|
||||
|
||||
/* Force the fnode into read-write mode */
|
||||
fnp->f_mode = RDWR;
|
||||
|
||||
/* determine what drive we are using... */
|
||||
if (ParseDosName(dirname, &drive, (BYTE *) 0, (BYTE *) 0, (BYTE *) 0, FALSE)
|
||||
!= SUCCESS)
|
||||
if (ParseDosName
|
||||
(dirname, &drive, (BYTE *) 0, (BYTE *) 0, (BYTE *) 0,
|
||||
FALSE) != SUCCESS)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return NULL;
|
||||
@ -104,7 +107,8 @@ f_node_ptr dir_open(BYTE * dirname)
|
||||
{
|
||||
drive = default_drive;
|
||||
}
|
||||
if (drive >= lastdrive) {
|
||||
if (drive >= lastdrive)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return NULL;
|
||||
}
|
||||
@ -113,7 +117,7 @@ f_node_ptr dir_open(BYTE * dirname)
|
||||
|
||||
/* Generate full path name */
|
||||
/* not necessary anymore, since truename did that already
|
||||
i = cdsp->cdsJoinOffset;
|
||||
i = cdsp->cdsJoinOffset;
|
||||
ParseDosPath(dirname, (COUNT *) 0, pszPath, (BYTE FAR *) & cdsp->cdsCurrentPath[i]); */
|
||||
|
||||
/* for testing only for now */
|
||||
@ -139,7 +143,7 @@ f_node_ptr dir_open(BYTE * dirname)
|
||||
if (media_check(fnp->f_dpb) < 0)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return (f_node_ptr)0;
|
||||
return (f_node_ptr) 0;
|
||||
}
|
||||
|
||||
/* Walk the directory tree to find the starting cluster */
|
||||
@ -161,8 +165,8 @@ f_node_ptr dir_open(BYTE * dirname)
|
||||
/* comparison... */
|
||||
/* first the file name with trailing spaces... */
|
||||
|
||||
memset(TempBuffer, ' ', FNAME_SIZE+FEXT_SIZE);
|
||||
|
||||
memset(TempBuffer, ' ', FNAME_SIZE + FEXT_SIZE);
|
||||
|
||||
for (i = 0; i < FNAME_SIZE; i++)
|
||||
{
|
||||
if (*p != '\0' && *p != '.' && *p != '/' && *p != '\\')
|
||||
@ -191,9 +195,12 @@ f_node_ptr dir_open(BYTE * dirname)
|
||||
|
||||
while (dir_read(fnp) == 1)
|
||||
{
|
||||
if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED)
|
||||
if (fnp->f_dir.dir_name[0] != '\0'
|
||||
&& fnp->f_dir.dir_name[0] != DELETED)
|
||||
{
|
||||
if (fcmp(TempBuffer, (BYTE *)fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE))
|
||||
if (fcmp
|
||||
(TempBuffer, (BYTE *) fnp->f_dir.dir_name,
|
||||
FNAME_SIZE + FEXT_SIZE))
|
||||
{
|
||||
i = TRUE;
|
||||
break;
|
||||
@ -205,7 +212,7 @@ f_node_ptr dir_open(BYTE * dirname)
|
||||
{
|
||||
|
||||
release_f_node(fnp);
|
||||
return (f_node_ptr)0;
|
||||
return (f_node_ptr) 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -250,7 +257,7 @@ COUNT dir_read(REG f_node_ptr fnp)
|
||||
|
||||
if (fnp->f_flags.f_droot)
|
||||
{
|
||||
if (new_diroff >= DIRENT_SIZE * (ULONG)fnp->f_dpb->dpb_dirents)
|
||||
if (new_diroff >= DIRENT_SIZE * (ULONG) fnp->f_dpb->dpb_dirents)
|
||||
return DE_SEEK;
|
||||
|
||||
bp = getblock((ULONG) (new_diroff / secsize
|
||||
@ -294,14 +301,15 @@ COUNT dir_read(REG f_node_ptr fnp)
|
||||
bp->b_flag &= ~(BFR_DATA | BFR_FAT);
|
||||
bp->b_flag |= BFR_DIR | BFR_VALID;
|
||||
|
||||
getdirent((BYTE FAR *) & bp->b_buffer[((UWORD)new_diroff) % fnp->f_dpb->dpb_secsize],
|
||||
(struct dirent FAR *)&fnp->f_dir);
|
||||
getdirent((BYTE FAR *) & bp->
|
||||
b_buffer[((UWORD) new_diroff) % fnp->f_dpb->dpb_secsize],
|
||||
(struct dirent FAR *)&fnp->f_dir);
|
||||
|
||||
/* Update the fnode's directory info */
|
||||
fnp->f_flags.f_dmod = FALSE;
|
||||
fnp->f_flags.f_dnew = FALSE;
|
||||
fnp->f_diroff = new_diroff;
|
||||
|
||||
|
||||
/* and for efficiency, stop when we hit the first */
|
||||
/* unused entry. */
|
||||
/* either returns 1 or 0 */
|
||||
@ -328,10 +336,9 @@ BOOL dir_write(REG f_node_ptr fnp)
|
||||
/* simple. */
|
||||
if (fnp->f_flags.f_droot)
|
||||
{
|
||||
bp = getblock(
|
||||
(ULONG) ((UWORD)fnp->f_diroff / secsize
|
||||
+ fnp->f_dpb->dpb_dirstrt),
|
||||
fnp->f_dpb->dpb_unit);
|
||||
bp = getblock((ULONG) ((UWORD) fnp->f_diroff / secsize
|
||||
+ fnp->f_dpb->dpb_dirstrt),
|
||||
fnp->f_dpb->dpb_unit);
|
||||
#ifdef DISPLAY_GETBLOCK
|
||||
printf("DIR (dir_write)\n");
|
||||
#endif
|
||||
@ -348,7 +355,7 @@ BOOL dir_write(REG f_node_ptr fnp)
|
||||
fnp->f_offset = fnp->f_diroff;
|
||||
fnp->f_back = LONG_LAST_CLUSTER;
|
||||
fnp->f_cluster = fnp->f_dirstart;
|
||||
fnp->f_cluster_offset = 0l; /*JPP */
|
||||
fnp->f_cluster_offset = 0l; /*JPP */
|
||||
|
||||
/* Search through the FAT to find the block */
|
||||
/* that this entry is in. */
|
||||
@ -383,11 +390,12 @@ BOOL dir_write(REG f_node_ptr fnp)
|
||||
release_f_node(fnp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (fnp->f_flags.f_dnew && fnp->f_dir.dir_attrib != D_LFN)
|
||||
fmemset(&fnp->f_dir.dir_case, 0, 8);
|
||||
fmemset(&fnp->f_dir.dir_case, 0, 8);
|
||||
putdirent((struct dirent FAR *)&fnp->f_dir,
|
||||
(VOID FAR *) & bp->b_buffer[(UWORD)fnp->f_diroff % fnp->f_dpb->dpb_secsize]);
|
||||
(VOID FAR *) & bp->b_buffer[(UWORD) fnp->f_diroff %
|
||||
fnp->f_dpb->dpb_secsize]);
|
||||
|
||||
bp->b_flag &= ~(BFR_DATA | BFR_FAT);
|
||||
bp->b_flag |= BFR_DIR | BFR_DIRTY | BFR_VALID;
|
||||
@ -417,7 +425,7 @@ VOID dir_close(REG f_node_ptr fnp)
|
||||
}
|
||||
|
||||
#ifndef IPL
|
||||
COUNT dos_findfirst(UCOUNT attr, BYTE *name)
|
||||
COUNT dos_findfirst(UCOUNT attr, BYTE * name)
|
||||
{
|
||||
REG f_node_ptr fnp;
|
||||
REG dmatch *dmp = (dmatch *) TempBuffer;
|
||||
@ -425,8 +433,7 @@ COUNT dos_findfirst(UCOUNT attr, BYTE *name)
|
||||
COUNT nDrive;
|
||||
BYTE *p;
|
||||
|
||||
BYTE local_name[FNAME_SIZE + 1],
|
||||
local_ext[FEXT_SIZE + 1];
|
||||
BYTE local_name[FNAME_SIZE + 1], local_ext[FEXT_SIZE + 1];
|
||||
|
||||
/* printf("ff %Fs\n", name);*/
|
||||
|
||||
@ -438,7 +445,8 @@ COUNT dos_findfirst(UCOUNT attr, BYTE *name)
|
||||
/* current directory, do a seek and read, then close the fnode. */
|
||||
|
||||
/* Parse out the drive, file name and file extension. */
|
||||
i = ParseDosName(name, &nDrive, &szDirName[2], local_name, local_ext, TRUE);
|
||||
i = ParseDosName(name, &nDrive, &szDirName[2], local_name, local_ext,
|
||||
TRUE);
|
||||
if (i != SUCCESS)
|
||||
return i;
|
||||
/*
|
||||
@ -453,14 +461,14 @@ COUNT dos_findfirst(UCOUNT attr, BYTE *name)
|
||||
SearchDir.dir_name[i] = *p;
|
||||
|
||||
for (; i < FNAME_SIZE; ++i)
|
||||
SearchDir.dir_name[i] = ' ';
|
||||
SearchDir.dir_name[i] = ' ';
|
||||
|
||||
/* and the extension (don't forget to add trailing spaces)... */
|
||||
for (p = local_ext, i = 0; i < FEXT_SIZE && *p; ++p, ++i)
|
||||
SearchDir.dir_ext[i] = *p;
|
||||
|
||||
for (; i < FEXT_SIZE; ++i)
|
||||
SearchDir.dir_ext[i] = ' ';
|
||||
SearchDir.dir_ext[i] = ' ';
|
||||
|
||||
/* Convert everything to uppercase. */
|
||||
DosUpFMem(SearchDir.dir_name, FNAME_SIZE + FEXT_SIZE);
|
||||
@ -471,7 +479,7 @@ COUNT dos_findfirst(UCOUNT attr, BYTE *name)
|
||||
/* name */
|
||||
szDirName[0] = 'A' + nDrive;
|
||||
szDirName[1] = ':';
|
||||
|
||||
|
||||
/* Special handling - the volume id is only in the root */
|
||||
/* directory and only searched for once. So we need to open */
|
||||
/* the root and return only the first entry that contains the */
|
||||
@ -483,16 +491,16 @@ COUNT dos_findfirst(UCOUNT attr, BYTE *name)
|
||||
}
|
||||
/* Now open this directory so that we can read the */
|
||||
/* fnode entry and do a match on it. */
|
||||
|
||||
|
||||
/* printf("dir_open %s\n", szDirName);*/
|
||||
if ((fnp = dir_open(szDirName)) == NULL)
|
||||
return DE_PATHNOTFND;
|
||||
|
||||
/* Now initialize the dirmatch structure. */
|
||||
|
||||
nDrive=get_verify_drive(name);
|
||||
|
||||
nDrive = get_verify_drive(name);
|
||||
if (nDrive < 0)
|
||||
return nDrive;
|
||||
return nDrive;
|
||||
dmp->dm_drive = nDrive;
|
||||
dmp->dm_attr_srch = attr;
|
||||
|
||||
@ -507,7 +515,7 @@ COUNT dos_findfirst(UCOUNT attr, BYTE *name)
|
||||
/* Test the attribute and return first found */
|
||||
if ((fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE)) == D_VOLID)
|
||||
{
|
||||
dmp->dm_dircluster = fnp->f_dirstart; /* TE */
|
||||
dmp->dm_dircluster = fnp->f_dirstart; /* TE */
|
||||
memcpy(&SearchDir, &fnp->f_dir, sizeof(struct dirent));
|
||||
dir_close(fnp);
|
||||
return SUCCESS;
|
||||
@ -531,6 +539,7 @@ COUNT dos_findfirst(UCOUNT attr, BYTE *name)
|
||||
return dos_findnext();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
BUGFIX TE 06/28/01
|
||||
|
||||
@ -547,11 +556,11 @@ COUNT dos_findnext(void)
|
||||
BOOL found = FALSE;
|
||||
|
||||
/* Allocate an fnode if possible - error return (0) if not. */
|
||||
if ((fnp = get_f_node()) == (f_node_ptr)0)
|
||||
if ((fnp = get_f_node()) == (f_node_ptr) 0)
|
||||
{
|
||||
return DE_NFILES;
|
||||
}
|
||||
|
||||
|
||||
memset(fnp, 0, sizeof(*fnp));
|
||||
|
||||
/* Force the fnode into read-write mode */
|
||||
@ -571,35 +580,38 @@ COUNT dos_findnext(void)
|
||||
/* Search through the directory to find the entry, but do a */
|
||||
/* seek first. */
|
||||
if (dmp->dm_entry > 0)
|
||||
{
|
||||
fnp->f_diroff = (ULONG)(dmp->dm_entry - 1) * DIRENT_SIZE;
|
||||
{
|
||||
fnp->f_diroff = (ULONG) (dmp->dm_entry - 1) * DIRENT_SIZE;
|
||||
fnp->f_flags.f_dnew = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
fnp->f_diroff = 0;
|
||||
fnp->f_flags.f_dnew = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop through the directory */
|
||||
while (dir_read(fnp) == 1)
|
||||
{
|
||||
++dmp->dm_entry;
|
||||
if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED
|
||||
&& (fnp->f_dir.dir_attrib & D_VOLID) != D_VOLID )
|
||||
&& (fnp->f_dir.dir_attrib & D_VOLID) != D_VOLID)
|
||||
{
|
||||
if (fcmp_wild((BYTE FAR *)dmp->dm_name_pat, (BYTE FAR *)fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE))
|
||||
if (fcmp_wild
|
||||
((BYTE FAR *) dmp->dm_name_pat, (BYTE FAR *) fnp->f_dir.dir_name,
|
||||
FNAME_SIZE + FEXT_SIZE))
|
||||
{
|
||||
/*
|
||||
MSD Command.com uses FCB FN 11 & 12 with attrib set to 0x16.
|
||||
Bits 0x21 seem to get set some where in MSD so Rd and Arc
|
||||
files are returned.
|
||||
RdOnly + Archive bits are ignored
|
||||
MSD Command.com uses FCB FN 11 & 12 with attrib set to 0x16.
|
||||
Bits 0x21 seem to get set some where in MSD so Rd and Arc
|
||||
files are returned.
|
||||
RdOnly + Archive bits are ignored
|
||||
*/
|
||||
|
||||
|
||||
/* Test the attribute as the final step */
|
||||
if (!(fnp->f_dir.dir_attrib & D_VOLID) &&
|
||||
((~dmp->dm_attr_srch & fnp->f_dir.dir_attrib & (D_DIR | D_SYSTEM | D_HIDDEN)) == 0))
|
||||
((~dmp->dm_attr_srch & fnp->f_dir.
|
||||
dir_attrib & (D_DIR | D_SYSTEM | D_HIDDEN)) == 0))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
@ -612,10 +624,10 @@ COUNT dos_findnext(void)
|
||||
|
||||
/* If found, transfer it to the dmatch structure */
|
||||
if (found)
|
||||
{
|
||||
{
|
||||
dmp->dm_dircluster = fnp->f_dirstart;
|
||||
memcpy(&SearchDir, &fnp->f_dir, sizeof(struct dirent));
|
||||
}
|
||||
}
|
||||
|
||||
/* return the result */
|
||||
release_f_node(fnp);
|
||||
@ -631,61 +643,57 @@ COUNT dos_findnext(void)
|
||||
"test e", " test .y z",...
|
||||
|
||||
so we have to work from the last blank backward
|
||||
*/
|
||||
void ConvertName83ToNameSZ(BYTE FAR *destSZ, BYTE FAR *srcFCBName)
|
||||
*/
|
||||
void ConvertName83ToNameSZ(BYTE FAR * destSZ, BYTE FAR * srcFCBName)
|
||||
{
|
||||
int loop;
|
||||
int noExtension = FALSE;
|
||||
|
||||
if (*srcFCBName == '.')
|
||||
{
|
||||
noExtension = TRUE;
|
||||
}
|
||||
|
||||
|
||||
int loop;
|
||||
int noExtension = FALSE;
|
||||
|
||||
fmemcpy(destSZ,srcFCBName,FNAME_SIZE);
|
||||
if (*srcFCBName == '.')
|
||||
{
|
||||
noExtension = TRUE;
|
||||
}
|
||||
|
||||
srcFCBName += FNAME_SIZE;
|
||||
|
||||
for (loop = FNAME_SIZE; --loop >= 0; )
|
||||
{
|
||||
if (destSZ[loop] != ' ')
|
||||
break;
|
||||
}
|
||||
destSZ += loop + 1;
|
||||
|
||||
|
||||
|
||||
if (!noExtension) /* not for ".", ".." */
|
||||
fmemcpy(destSZ, srcFCBName, FNAME_SIZE);
|
||||
|
||||
srcFCBName += FNAME_SIZE;
|
||||
|
||||
for (loop = FNAME_SIZE; --loop >= 0;)
|
||||
{
|
||||
if (destSZ[loop] != ' ')
|
||||
break;
|
||||
}
|
||||
destSZ += loop + 1;
|
||||
|
||||
if (!noExtension) /* not for ".", ".." */
|
||||
{
|
||||
|
||||
for (loop = FEXT_SIZE; --loop >= 0;)
|
||||
{
|
||||
|
||||
for (loop = FEXT_SIZE; --loop >= 0; )
|
||||
{
|
||||
if (srcFCBName[loop] != ' ')
|
||||
break;
|
||||
}
|
||||
if (loop >= 0)
|
||||
{
|
||||
*destSZ++ = '.';
|
||||
fmemcpy(destSZ,srcFCBName,loop+1);
|
||||
destSZ += loop+1;
|
||||
}
|
||||
if (srcFCBName[loop] != ' ')
|
||||
break;
|
||||
}
|
||||
*destSZ = '\0';
|
||||
if (loop >= 0)
|
||||
{
|
||||
*destSZ++ = '.';
|
||||
fmemcpy(destSZ, srcFCBName, loop + 1);
|
||||
destSZ += loop + 1;
|
||||
}
|
||||
}
|
||||
*destSZ = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
returns the asciiSZ length of a 8.3 filename
|
||||
*/
|
||||
*/
|
||||
|
||||
int FileName83Length(BYTE *filename83)
|
||||
int FileName83Length(BYTE * filename83)
|
||||
{
|
||||
BYTE buff[13];
|
||||
BYTE buff[13];
|
||||
|
||||
ConvertName83ToNameSZ(buff, filename83);
|
||||
|
||||
return strlen(buff);
|
||||
ConvertName83ToNameSZ(buff, filename83);
|
||||
|
||||
return strlen(buff);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -777,4 +785,3 @@ int FileName83Length(BYTE *filename83)
|
||||
* Rev 1.0 02 Jul 1995 8:04:34 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
818
kernel/fatfs.c
818
kernel/fatfs.c
File diff suppressed because it is too large
Load Diff
188
kernel/fattab.c
188
kernel/fattab.c
@ -30,7 +30,8 @@
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId = "$Id$";
|
||||
static BYTE *RcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#ifdef PROTO
|
||||
@ -56,43 +57,43 @@ CLUSTER next_cl32();
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef ISFAT32
|
||||
int ISFAT32(struct dpb FAR *dpbp)
|
||||
int ISFAT32(struct dpb FAR * dpbp)
|
||||
{
|
||||
return _ISFAT32(dpbp);
|
||||
return _ISFAT32(dpbp);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct buffer FAR *getFATblock(CLUSTER cluster, struct dpb FAR *dpbp)
|
||||
struct buffer FAR *getFATblock(CLUSTER cluster, struct dpb FAR * dpbp)
|
||||
{
|
||||
ULONG sector;
|
||||
ULONG sector;
|
||||
struct buffer FAR *bp;
|
||||
|
||||
if (ISFAT12(dpbp))
|
||||
{
|
||||
sector = ((cluster << 1) + cluster) >> 1;
|
||||
}
|
||||
{
|
||||
sector = ((cluster << 1) + cluster) >> 1;
|
||||
}
|
||||
#ifdef WITHFAT32
|
||||
else if (ISFAT32(dpbp))
|
||||
{
|
||||
sector = (ULONG)cluster * SIZEOF_CLST32;
|
||||
}
|
||||
{
|
||||
sector = (ULONG) cluster *SIZEOF_CLST32;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
sector = (ULONG)cluster * SIZEOF_CLST16;
|
||||
}
|
||||
sector = sector / dpbp->dpb_secsize + dpbp->dpb_fatstrt;
|
||||
{
|
||||
sector = (ULONG) cluster *SIZEOF_CLST16;
|
||||
}
|
||||
sector = sector / dpbp->dpb_secsize + dpbp->dpb_fatstrt;
|
||||
#ifdef WITHFAT32
|
||||
if (ISFAT32(dpbp) && (dpbp->dpb_xflags & FAT_NO_MIRRORING)) {
|
||||
if (ISFAT32(dpbp) && (dpbp->dpb_xflags & FAT_NO_MIRRORING))
|
||||
{
|
||||
/* we must modify the active fat,
|
||||
it's number is in the 0-3 bits of dpb_xflags */
|
||||
sector += (dpbp->dpb_xflags & 0xf) * dpbp->dpb_xfatsize;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bp = getblock(sector, dpbp->dpb_unit);
|
||||
|
||||
|
||||
if (bp)
|
||||
{
|
||||
bp->b_flag &= ~(BFR_DATA | BFR_DIR);
|
||||
@ -108,11 +109,11 @@ struct buffer FAR *getFATblock(CLUSTER cluster, struct dpb FAR *dpbp)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return bp;
|
||||
return bp;
|
||||
}
|
||||
|
||||
#ifdef WITHFAT32
|
||||
void read_fsinfo(struct dpb FAR *dpbp)
|
||||
void read_fsinfo(struct dpb FAR * dpbp)
|
||||
{
|
||||
struct buffer FAR *bp;
|
||||
struct fsinfo FAR *fip;
|
||||
@ -121,12 +122,12 @@ void read_fsinfo(struct dpb FAR *dpbp)
|
||||
bp->b_flag &= ~(BFR_DATA | BFR_DIR | BFR_FAT | BFR_DIRTY);
|
||||
bp->b_flag |= BFR_VALID;
|
||||
|
||||
fip = (struct fsinfo FAR *) & bp->b_buffer[0x1e4];
|
||||
fip = (struct fsinfo FAR *)&bp->b_buffer[0x1e4];
|
||||
dpbp->dpb_xnfreeclst = fip->fi_nfreeclst;
|
||||
dpbp->dpb_xcluster = fip->fi_cluster;
|
||||
}
|
||||
|
||||
void write_fsinfo(struct dpb FAR *dpbp)
|
||||
void write_fsinfo(struct dpb FAR * dpbp)
|
||||
{
|
||||
struct buffer FAR *bp;
|
||||
struct fsinfo FAR *fip;
|
||||
@ -135,7 +136,7 @@ void write_fsinfo(struct dpb FAR *dpbp)
|
||||
bp->b_flag &= ~(BFR_DATA | BFR_DIR | BFR_FAT);
|
||||
bp->b_flag |= BFR_VALID | BFR_DIRTY;
|
||||
|
||||
fip = (struct fsinfo FAR *) & bp->b_buffer[0x1e4];
|
||||
fip = (struct fsinfo FAR *)&bp->b_buffer[0x1e4];
|
||||
fip->fi_nfreeclst = dpbp->dpb_xnfreeclst;
|
||||
fip->fi_cluster = dpbp->dpb_xcluster;
|
||||
}
|
||||
@ -157,10 +158,11 @@ void write_fsinfo(struct dpb FAR *dpbp)
|
||||
/* 12 bytes are compressed to 9 bytes */
|
||||
/* */
|
||||
|
||||
UCOUNT link_fat(struct dpb FAR *dpbp, CLUSTER Cluster1, REG CLUSTER Cluster2)
|
||||
UCOUNT link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
REG CLUSTER Cluster2)
|
||||
{
|
||||
UCOUNT res;
|
||||
|
||||
|
||||
if (ISFAT12(dpbp))
|
||||
res = link_fat12(dpbp, Cluster1, Cluster2);
|
||||
else if (ISFAT16(dpbp))
|
||||
@ -172,7 +174,6 @@ UCOUNT link_fat(struct dpb FAR *dpbp, CLUSTER Cluster1, REG CLUSTER Cluster2)
|
||||
else
|
||||
return DE_BLKINVLD;
|
||||
|
||||
|
||||
/* update the free space count */
|
||||
|
||||
if (res == SUCCESS && Cluster2 == FREE)
|
||||
@ -181,36 +182,38 @@ UCOUNT link_fat(struct dpb FAR *dpbp, CLUSTER Cluster1, REG CLUSTER Cluster2)
|
||||
if (ISFAT32(dpbp) && dpbp->dpb_xnfreeclst != XUNKNCLSTFREE)
|
||||
{
|
||||
/* update the free space count for returned */
|
||||
/* cluster */
|
||||
/* cluster */
|
||||
++dpbp->dpb_xnfreeclst;
|
||||
write_fsinfo(dpbp);
|
||||
} else
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (dpbp->dpb_nfreeclst != UNKNCLSTFREE)
|
||||
++dpbp->dpb_nfreeclst;
|
||||
}
|
||||
|
||||
/*if (Cluster2 == FREE)
|
||||
{ */
|
||||
/* update the free space count for returned */
|
||||
/* cluster */
|
||||
/* ++dpbp->dpb_nfreeclst;
|
||||
}*/
|
||||
/*if (Cluster2 == FREE)
|
||||
{ */
|
||||
/* update the free space count for returned */
|
||||
/* cluster */
|
||||
/* ++dpbp->dpb_nfreeclst;
|
||||
} */
|
||||
|
||||
/* update the free space count for removed */
|
||||
/* cluster */
|
||||
/* BUG: was counted twice for 2nd,.. cluster. moved to find_fat_free() */
|
||||
/* BO: don't completely understand this yet - leave here for now as
|
||||
a comment */
|
||||
/* else
|
||||
{
|
||||
--dpbp->dpb_nfreeclst;
|
||||
} */
|
||||
return res;
|
||||
/* update the free space count for removed */
|
||||
/* cluster */
|
||||
/* BUG: was counted twice for 2nd,.. cluster. moved to find_fat_free() */
|
||||
/* BO: don't completely understand this yet - leave here for now as
|
||||
a comment */
|
||||
/* else
|
||||
{
|
||||
--dpbp->dpb_nfreeclst;
|
||||
} */
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef WITHFAT32
|
||||
UCOUNT link_fat32(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2)
|
||||
UCOUNT link_fat32(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
CLUSTER Cluster2)
|
||||
{
|
||||
UCOUNT idx;
|
||||
struct buffer FAR *bp;
|
||||
@ -223,7 +226,7 @@ UCOUNT link_fat32(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2)
|
||||
|
||||
/* form an index so that we can read the block as a */
|
||||
/* byte array */
|
||||
idx = (UWORD)((Cluster1 * SIZEOF_CLST32) % dpbp->dpb_secsize);
|
||||
idx = (UWORD) ((Cluster1 * SIZEOF_CLST32) % dpbp->dpb_secsize);
|
||||
|
||||
/* Finally, put the word into the buffer and mark the */
|
||||
/* buffer as dirty. */
|
||||
@ -237,7 +240,8 @@ UCOUNT link_fat32(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2)
|
||||
|
||||
#endif
|
||||
|
||||
UCOUNT link_fat16(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2)
|
||||
UCOUNT link_fat16(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
CLUSTER Cluster2)
|
||||
{
|
||||
UCOUNT idx;
|
||||
struct buffer FAR *bp;
|
||||
@ -250,7 +254,7 @@ UCOUNT link_fat16(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2)
|
||||
|
||||
/* form an index so that we can read the block as a */
|
||||
/* byte array */
|
||||
idx = (UWORD)(( Cluster1 * SIZEOF_CLST16) % dpbp->dpb_secsize);
|
||||
idx = (UWORD) ((Cluster1 * SIZEOF_CLST16) % dpbp->dpb_secsize);
|
||||
|
||||
/* Finally, put the word into the buffer and mark the */
|
||||
/* buffer as dirty. */
|
||||
@ -262,22 +266,21 @@ UCOUNT link_fat16(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
UCOUNT link_fat12(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2)
|
||||
UCOUNT link_fat12(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
CLUSTER Cluster2)
|
||||
{
|
||||
REG UBYTE FAR *fbp0,
|
||||
FAR * fbp1;
|
||||
REG UBYTE FAR *fbp0, FAR * fbp1;
|
||||
UCOUNT idx;
|
||||
struct buffer FAR *bp,
|
||||
FAR * bp1;
|
||||
struct buffer FAR *bp, FAR * bp1;
|
||||
|
||||
/* Get the block that this cluster is in */
|
||||
bp = getFATblock(Cluster1 , dpbp);
|
||||
bp = getFATblock(Cluster1, dpbp);
|
||||
if (bp == NULL)
|
||||
return DE_BLKINVLD;
|
||||
|
||||
/* form an index so that we can read the block as a */
|
||||
/* byte array */
|
||||
idx = (UCOUNT)(((Cluster1 << 1) + Cluster1) >> 1) % dpbp->dpb_secsize;
|
||||
idx = (UCOUNT) (((Cluster1 << 1) + Cluster1) >> 1) % dpbp->dpb_secsize;
|
||||
|
||||
/* Test to see if the cluster straddles the block. If */
|
||||
/* it does, get the next block and use both to form the */
|
||||
@ -285,7 +288,7 @@ UCOUNT link_fat12(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2)
|
||||
/* block. */
|
||||
if (idx >= dpbp->dpb_secsize - 1)
|
||||
{
|
||||
bp1 = getFATblock(Cluster1 + 1,dpbp);
|
||||
bp1 = getFATblock(Cluster1 + 1, dpbp);
|
||||
if (bp1 == 0)
|
||||
return DE_BLKINVLD;
|
||||
|
||||
@ -315,12 +318,14 @@ UCOUNT link_fat12(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2)
|
||||
|
||||
/* Given the disk parameters, and a cluster number, this function
|
||||
looks at the FAT, and returns the next cluster in the clain. */
|
||||
CLUSTER next_cluster(struct dpb FAR *dpbp, CLUSTER ClusterNum)
|
||||
CLUSTER next_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
|
||||
{
|
||||
struct buffer FAR *bp;
|
||||
#ifdef DEBUG
|
||||
if (ClusterNum == LONG_LAST_CLUSTER) printf("fatal error: trying to do next_cluster(dpbp, EOC)!\n");
|
||||
if (ClusterNum == 0) printf("fatal error: trying to do next_cluster(dpbp, 0)!\n");
|
||||
if (ClusterNum == LONG_LAST_CLUSTER)
|
||||
printf("fatal error: trying to do next_cluster(dpbp, EOC)!\n");
|
||||
if (ClusterNum == 0)
|
||||
printf("fatal error: trying to do next_cluster(dpbp, 0)!\n");
|
||||
#endif
|
||||
|
||||
/* Get the block that this cluster is in */
|
||||
@ -332,20 +337,22 @@ CLUSTER next_cluster(struct dpb FAR *dpbp, CLUSTER ClusterNum)
|
||||
if (ISFAT12(dpbp))
|
||||
{
|
||||
union {
|
||||
UBYTE bytes[2];
|
||||
UCOUNT word;
|
||||
UBYTE bytes[2];
|
||||
UCOUNT word;
|
||||
} clusterbuff;
|
||||
|
||||
|
||||
UCOUNT idx;
|
||||
|
||||
/* form an index so that we can read the block as a */
|
||||
/* byte array */
|
||||
idx = (UCOUNT)(((ClusterNum << 1) + ClusterNum) >> 1) % dpbp->dpb_secsize;
|
||||
idx =
|
||||
(UCOUNT) (((ClusterNum << 1) +
|
||||
ClusterNum) >> 1) % dpbp->dpb_secsize;
|
||||
|
||||
clusterbuff.bytes[0] = bp->b_buffer[idx];
|
||||
|
||||
clusterbuff.bytes[1] = bp->b_buffer[idx+1]; /* next byte, will be overwritten,
|
||||
if not valid */
|
||||
clusterbuff.bytes[1] = bp->b_buffer[idx + 1]; /* next byte, will be overwritten,
|
||||
if not valid */
|
||||
|
||||
/* Test to see if the cluster straddles the block. If it */
|
||||
/* does, get the next block and use both to form the */
|
||||
@ -353,7 +360,7 @@ CLUSTER next_cluster(struct dpb FAR *dpbp, CLUSTER ClusterNum)
|
||||
/* block. */
|
||||
if (idx >= dpbp->dpb_secsize - 1)
|
||||
{
|
||||
bp = getFATblock(ClusterNum +1, dpbp);
|
||||
bp = getFATblock(ClusterNum + 1, dpbp);
|
||||
|
||||
if (bp == 0)
|
||||
return LONG_BAD;
|
||||
@ -363,19 +370,20 @@ CLUSTER next_cluster(struct dpb FAR *dpbp, CLUSTER ClusterNum)
|
||||
|
||||
/* Now to unpack the contents of the FAT entry. Odd and */
|
||||
/* even bytes are packed differently. */
|
||||
|
||||
#ifndef I86 /* the latter assumes byte ordering */
|
||||
|
||||
#ifndef I86 /* the latter assumes byte ordering */
|
||||
if (ClusterNum & 0x01)
|
||||
idx = ((clusterbuff.byte[0] & 0xf0) >> 4) | (clusterbuff.byte[1] << 4);
|
||||
idx =
|
||||
((clusterbuff.byte[0] & 0xf0) >> 4) | (clusterbuff.byte[1] << 4);
|
||||
else
|
||||
idx = clusterbuff.byte[0] | ((clusterbuff.byte[0] & 0x0f) << 8);
|
||||
#else
|
||||
|
||||
|
||||
if (ClusterNum & 0x01)
|
||||
idx = (unsigned short)clusterbuff.word >> 4;
|
||||
else
|
||||
idx = clusterbuff.word & 0x0fff;
|
||||
#endif
|
||||
idx = clusterbuff.word & 0x0fff;
|
||||
#endif
|
||||
|
||||
if (idx >= MASK12)
|
||||
return LONG_LAST_CLUSTER;
|
||||
@ -384,7 +392,7 @@ CLUSTER next_cluster(struct dpb FAR *dpbp, CLUSTER ClusterNum)
|
||||
return idx;
|
||||
}
|
||||
else if (ISFAT16(dpbp))
|
||||
{
|
||||
{
|
||||
UWORD res;
|
||||
|
||||
#ifndef I86
|
||||
@ -395,16 +403,22 @@ CLUSTER next_cluster(struct dpb FAR *dpbp, CLUSTER ClusterNum)
|
||||
idx = (ClusterNum * SIZEOF_CLST16) % dpbp->dpb_secsize;
|
||||
|
||||
/* Get the cluster number, */
|
||||
|
||||
|
||||
fgetword((VOID FAR *) & (bp->b_buffer[idx]), (WORD FAR *) & res);
|
||||
|
||||
#else
|
||||
/* this saves 2 WORDS of stack :-) */
|
||||
|
||||
res = *(UWORD FAR *)&(bp->b_buffer[(UCOUNT)((ClusterNum * SIZEOF_CLST16) % dpbp->dpb_secsize)]);
|
||||
#endif
|
||||
if (res >= MASK16) return LONG_LAST_CLUSTER;
|
||||
if (res == BAD16) return LONG_BAD;
|
||||
|
||||
res =
|
||||
*(UWORD FAR *) & (bp->
|
||||
b_buffer[(UCOUNT)
|
||||
((ClusterNum * SIZEOF_CLST16) %
|
||||
dpbp->dpb_secsize)]);
|
||||
#endif
|
||||
if (res >= MASK16)
|
||||
return LONG_LAST_CLUSTER;
|
||||
if (res == BAD16)
|
||||
return LONG_BAD;
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -413,10 +427,15 @@ CLUSTER next_cluster(struct dpb FAR *dpbp, CLUSTER ClusterNum)
|
||||
{
|
||||
UDWORD res;
|
||||
|
||||
res = *(UDWORD FAR *)&(bp->b_buffer[(UCOUNT)((ClusterNum * SIZEOF_CLST32) % dpbp->dpb_secsize)]);
|
||||
if (res > LONG_BAD) return LONG_LAST_CLUSTER;
|
||||
res =
|
||||
*(UDWORD FAR *) & (bp->
|
||||
b_buffer[(UCOUNT)
|
||||
((ClusterNum * SIZEOF_CLST32) %
|
||||
dpbp->dpb_secsize)]);
|
||||
if (res > LONG_BAD)
|
||||
return LONG_LAST_CLUSTER;
|
||||
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
return LONG_LAST_CLUSTER;
|
||||
@ -477,6 +496,3 @@ CLUSTER next_cluster(struct dpb FAR *dpbp, CLUSTER ClusterNum)
|
||||
* Rev 1.0 02 Jul 1995 8:04:56 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
148
kernel/fcbfns.c
148
kernel/fcbfns.c
@ -30,7 +30,8 @@
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId = "$Id$";
|
||||
static BYTE *RcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#define FCB_SUCCESS 0
|
||||
@ -41,7 +42,8 @@ static BYTE *RcsId = "$Id$";
|
||||
|
||||
#ifdef PROTO
|
||||
fcb FAR *ExtFcbToFcb(xfcb FAR * lpExtFcb);
|
||||
fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer, COUNT * pCurDrive);
|
||||
fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,
|
||||
COUNT * pCurDrive);
|
||||
void FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
|
||||
VOID FcbNextRecord(fcb FAR * lpFcb);
|
||||
BOOL FcbCalcRec(xfcb FAR * lpXfcb);
|
||||
@ -53,9 +55,8 @@ VOID FcbNextRecord();
|
||||
BOOL FcbCalcRec();
|
||||
#endif
|
||||
|
||||
#define TestCmnSeps(lpFileName) (strchr(":<|>+=,", *lpFileName) != NULL)
|
||||
#define TestFieldSeps(lpFileName) (*(lpFileName) <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)
|
||||
|
||||
#define TestCmnSeps(lpFileName) (strchr(":<|>+=,", *lpFileName) != NULL)
|
||||
#define TestFieldSeps(lpFileName) (*(lpFileName) <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)
|
||||
|
||||
static dmatch Dmatch;
|
||||
|
||||
@ -63,12 +64,12 @@ VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
|
||||
UCOUNT FAR * nc, BYTE FAR ** mdp)
|
||||
{
|
||||
UCOUNT navc;
|
||||
|
||||
|
||||
/* get the data available from dpb */
|
||||
*nc = 0xffff; /* pass 0xffff to skip free count */
|
||||
if (DosGetFree((UBYTE)drive, spc, &navc, bps, nc))
|
||||
/* Point to the media desctriptor for this drive */
|
||||
*mdp = (BYTE FAR*)&(CDSp->cds_table[drive].cdsDpb->dpb_mdb);
|
||||
*nc = 0xffff; /* pass 0xffff to skip free count */
|
||||
if (DosGetFree((UBYTE) drive, spc, &navc, bps, nc))
|
||||
/* Point to the media desctriptor for this drive */
|
||||
*mdp = (BYTE FAR *) & (CDSp->cds_table[drive].cdsDpb->dpb_mdb);
|
||||
}
|
||||
|
||||
#define PARSE_SEP_STOP 0x01
|
||||
@ -84,7 +85,7 @@ VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
|
||||
WORD FcbParseFname(int wTestMode, BYTE FAR ** lpFileName, fcb FAR * lpFcb)
|
||||
{
|
||||
COUNT nIndex;
|
||||
WORD wRetCodeName,wRetCodeExt;
|
||||
WORD wRetCodeName, wRetCodeExt;
|
||||
|
||||
/* pjv -- ExtFcbToFcb? */
|
||||
/* Start out with some simple stuff first. Check if we are */
|
||||
@ -131,24 +132,28 @@ WORD FcbParseFname(int wTestMode, BYTE FAR ** lpFileName, fcb FAR * lpFcb)
|
||||
/* special cases: '.' and '..' */
|
||||
if (**lpFileName == '.')
|
||||
{
|
||||
lpFcb->fcb_fname[0]='.';
|
||||
lpFcb->fcb_fname[0] = '.';
|
||||
++*lpFileName;
|
||||
if (**lpFileName == '.')
|
||||
{
|
||||
lpFcb->fcb_fname[1] = '.';
|
||||
++*lpFileName;
|
||||
if (**lpFileName == '.')
|
||||
{
|
||||
lpFcb->fcb_fname[1]='.';
|
||||
++*lpFileName;
|
||||
}
|
||||
return PARSE_RET_NOWILD;
|
||||
}
|
||||
return PARSE_RET_NOWILD;
|
||||
}
|
||||
|
||||
|
||||
/* Now to format the file name into the string */
|
||||
*lpFileName = GetNameField(*lpFileName, (BYTE FAR *) lpFcb->fcb_fname, FNAME_SIZE, (BOOL *) & wRetCodeName);
|
||||
*lpFileName =
|
||||
GetNameField(*lpFileName, (BYTE FAR *) lpFcb->fcb_fname, FNAME_SIZE,
|
||||
(BOOL *) & wRetCodeName);
|
||||
|
||||
/* Do we have an extension? If do, format it else return */
|
||||
if (**lpFileName == '.')
|
||||
*lpFileName = GetNameField(++*lpFileName, (BYTE FAR *) lpFcb->fcb_fext, FEXT_SIZE, (BOOL *) & wRetCodeExt);
|
||||
*lpFileName =
|
||||
GetNameField(++*lpFileName, (BYTE FAR *) lpFcb->fcb_fext,
|
||||
FEXT_SIZE, (BOOL *) & wRetCodeExt);
|
||||
|
||||
return (wRetCodeName|wRetCodeExt) ? PARSE_RET_WILD : PARSE_RET_NOWILD;
|
||||
return (wRetCodeName | wRetCodeExt) ? PARSE_RET_WILD : PARSE_RET_NOWILD;
|
||||
}
|
||||
|
||||
BYTE FAR *ParseSkipWh(BYTE FAR * lpFileName)
|
||||
@ -158,24 +163,22 @@ BYTE FAR *ParseSkipWh(BYTE FAR * lpFileName)
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
#if 0 /* defined above */
|
||||
#if 0 /* defined above */
|
||||
BOOL TestCmnSeps(BYTE FAR * lpFileName)
|
||||
{
|
||||
BYTE *pszTest,
|
||||
*pszCmnSeps = ":<|>+=,";
|
||||
BYTE *pszTest, *pszCmnSeps = ":<|>+=,";
|
||||
|
||||
for (pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)
|
||||
if (*lpFileName == *pszTest)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
BOOL TestFieldSeps(BYTE FAR * lpFileName)
|
||||
{
|
||||
BYTE *pszTest,
|
||||
*pszCmnSeps = "/\"[]<>|.";
|
||||
BYTE *pszTest, *pszCmnSeps = "/\"[]<>|.";
|
||||
|
||||
/* Another non-portable construct */
|
||||
if (*lpFileName <= ' ')
|
||||
@ -188,7 +191,6 @@ BOOL TestFieldSeps(BYTE FAR * lpFileName)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
BYTE FAR *GetNameField(BYTE FAR * lpFileName, BYTE FAR * lpDestField,
|
||||
COUNT nFieldSize, BOOL * pbWildCard)
|
||||
{
|
||||
@ -196,7 +198,8 @@ BYTE FAR *GetNameField(BYTE FAR * lpFileName, BYTE FAR * lpDestField,
|
||||
BYTE cFill = ' ';
|
||||
|
||||
*pbWildCard = FALSE;
|
||||
while (*lpFileName != '\0' && !TestFieldSeps(lpFileName) && nIndex < nFieldSize)
|
||||
while (*lpFileName != '\0' && !TestFieldSeps(lpFileName)
|
||||
&& nIndex < nFieldSize)
|
||||
{
|
||||
if (*lpFileName == ' ')
|
||||
break;
|
||||
@ -231,8 +234,8 @@ static VOID FcbNextRecord(fcb FAR * lpFcb)
|
||||
static ULONG FcbRec(VOID)
|
||||
{
|
||||
UWORD tmp = 128;
|
||||
|
||||
return ((ULONG)lpFcb->fcb_cublock * tmp) + lpFcb->fcb_curec;
|
||||
|
||||
return ((ULONG) lpFcb->fcb_cublock * tmp) + lpFcb->fcb_curec;
|
||||
}
|
||||
|
||||
BOOL FcbRead(xfcb FAR * lpXfcb, COUNT * nErrorCode)
|
||||
@ -395,7 +398,8 @@ BOOL FcbCalcRec(xfcb FAR * lpXfcb)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FcbRandomBlockRead(xfcb FAR * lpXfcb, COUNT nRecords, COUNT * nErrorCode)
|
||||
BOOL FcbRandomBlockRead(xfcb FAR * lpXfcb, COUNT nRecords,
|
||||
COUNT * nErrorCode)
|
||||
{
|
||||
FcbCalcRec(lpXfcb);
|
||||
|
||||
@ -412,7 +416,8 @@ BOOL FcbRandomBlockRead(xfcb FAR * lpXfcb, COUNT nRecords, COUNT * nErrorCode)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FcbRandomBlockWrite(xfcb FAR * lpXfcb, COUNT nRecords, COUNT * nErrorCode)
|
||||
BOOL FcbRandomBlockWrite(xfcb FAR * lpXfcb, COUNT nRecords,
|
||||
COUNT * nErrorCode)
|
||||
{
|
||||
FcbCalcRec(lpXfcb);
|
||||
|
||||
@ -430,7 +435,7 @@ BOOL FcbRandomBlockWrite(xfcb FAR * lpXfcb, COUNT nRecords, COUNT * nErrorCode)
|
||||
}
|
||||
|
||||
BOOL FcbRandomIO(xfcb FAR * lpXfcb, COUNT * nErrorCode,
|
||||
BOOL (*FcbFunc)(xfcb FAR *, COUNT *))
|
||||
BOOL(*FcbFunc) (xfcb FAR *, COUNT *))
|
||||
{
|
||||
UWORD uwCurrentBlock;
|
||||
UBYTE ucCurrentRecord;
|
||||
@ -443,7 +448,7 @@ BOOL FcbRandomIO(xfcb FAR * lpXfcb, COUNT * nErrorCode,
|
||||
uwCurrentBlock = lpFcb->fcb_cublock;
|
||||
ucCurrentRecord = lpFcb->fcb_curec;
|
||||
|
||||
(*FcbFunc)(lpXfcb, nErrorCode);
|
||||
(*FcbFunc) (lpXfcb, nErrorCode);
|
||||
|
||||
lpFcb->fcb_cublock = uwCurrentBlock;
|
||||
lpFcb->fcb_curec = ucCurrentRecord;
|
||||
@ -466,7 +471,7 @@ BOOL FcbCreate(xfcb FAR * lpXfcb)
|
||||
|
||||
sft_idx = DosCreatSft(PriPathName, 0);
|
||||
if (sft_idx < 0)
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
|
||||
sftp = idx_to_sft(sft_idx);
|
||||
sftp->sft_mode |= SFT_MFCB;
|
||||
@ -476,7 +481,8 @@ BOOL FcbCreate(xfcb FAR * lpXfcb)
|
||||
lpFcb->fcb_sftno = sft_idx;
|
||||
lpFcb->fcb_curec = 0;
|
||||
lpFcb->fcb_recsiz = (dhp ? 0 : 128);
|
||||
if (!dhp) lpFcb->fcb_drive = FcbDrive;
|
||||
if (!dhp)
|
||||
lpFcb->fcb_drive = FcbDrive;
|
||||
lpFcb->fcb_fsize = 0;
|
||||
lpFcb->fcb_date = dos_getdate();
|
||||
lpFcb->fcb_time = dos_gettime();
|
||||
@ -509,9 +515,9 @@ STATIC fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,
|
||||
|
||||
void FcbNameInit(fcb FAR * lpFcb, BYTE * szBuffer, COUNT * pCurDrive)
|
||||
{
|
||||
BYTE loc_szBuffer[2+FNAME_SIZE+1+FEXT_SIZE+1]; /* 'A:' + '.' + '\0' */
|
||||
BYTE loc_szBuffer[2 + FNAME_SIZE + 1 + FEXT_SIZE + 1]; /* 'A:' + '.' + '\0' */
|
||||
BYTE *pszBuffer = loc_szBuffer;
|
||||
|
||||
|
||||
/* Build a traditional DOS file name */
|
||||
if (lpFcb->fcb_drive != 0)
|
||||
{
|
||||
@ -540,30 +546,30 @@ BOOL FcbOpen(xfcb FAR * lpXfcb)
|
||||
|
||||
sft_idx = DosOpenSft(PriPathName, O_RDWR);
|
||||
if (sft_idx < 0)
|
||||
return FALSE;
|
||||
|
||||
return FALSE;
|
||||
|
||||
sftp = idx_to_sft(sft_idx);
|
||||
sftp->sft_mode |= SFT_MFCB;
|
||||
|
||||
|
||||
/* check for a device */
|
||||
lpFcb->fcb_curec = 0;
|
||||
lpFcb->fcb_rndm = 0;
|
||||
lpFcb->fcb_sftno = sft_idx;
|
||||
dhp = IsDevice(PriPathName);
|
||||
if (dhp )
|
||||
if (dhp)
|
||||
{
|
||||
lpFcb->fcb_recsiz = 0;
|
||||
lpFcb->fcb_fsize = 0;
|
||||
lpFcb->fcb_date = dos_getdate();
|
||||
lpFcb->fcb_time = dos_gettime();
|
||||
lpFcb->fcb_recsiz = 0;
|
||||
lpFcb->fcb_fsize = 0;
|
||||
lpFcb->fcb_date = dos_getdate();
|
||||
lpFcb->fcb_time = dos_gettime();
|
||||
}
|
||||
else
|
||||
{
|
||||
lpFcb->fcb_drive = FcbDrive;
|
||||
lpFcb->fcb_recsiz = 128;
|
||||
lpFcb->fcb_fsize = sftp->sft_size;
|
||||
lpFcb->fcb_date = sftp->sft_date;
|
||||
lpFcb->fcb_time = sftp->sft_time;
|
||||
lpFcb->fcb_drive = FcbDrive;
|
||||
lpFcb->fcb_recsiz = 128;
|
||||
lpFcb->fcb_fsize = sftp->sft_size;
|
||||
lpFcb->fcb_date = sftp->sft_date;
|
||||
lpFcb->fcb_time = sftp->sft_time;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -586,7 +592,9 @@ BOOL FcbDelete(xfcb FAR * lpXfcb)
|
||||
dmatch Dmatch;
|
||||
|
||||
dta = (BYTE FAR *) & Dmatch;
|
||||
if (DosFindFirst(D_ALL, SecPathName[1] == ':' ? &SecPathName[2] : SecPathName) != SUCCESS)
|
||||
if (DosFindFirst
|
||||
(D_ALL,
|
||||
SecPathName[1] == ':' ? &SecPathName[2] : SecPathName) != SUCCESS)
|
||||
{
|
||||
dta = lpOldDta;
|
||||
return FALSE;
|
||||
@ -625,7 +633,9 @@ BOOL FcbRename(xfcb FAR * lpXfcb)
|
||||
dmatch Dmatch;
|
||||
|
||||
dta = (BYTE FAR *) & Dmatch;
|
||||
if (DosFindFirst(D_ALL, SecPathName[1] == ':' ? &SecPathName[2] : SecPathName) != SUCCESS)
|
||||
if (DosFindFirst
|
||||
(D_ALL,
|
||||
SecPathName[1] == ':' ? &SecPathName[2] : SecPathName) != SUCCESS)
|
||||
{
|
||||
dta = lpOldDta;
|
||||
return FALSE;
|
||||
@ -634,8 +644,7 @@ BOOL FcbRename(xfcb FAR * lpXfcb)
|
||||
do
|
||||
{
|
||||
fcb LocalFcb;
|
||||
BYTE *pToName,
|
||||
*pszFrom;
|
||||
BYTE *pToName, *pszFrom;
|
||||
BYTE FAR *pFromPattern;
|
||||
COUNT nIndex;
|
||||
|
||||
@ -718,7 +727,7 @@ BOOL FcbClose(xfcb FAR * lpXfcb)
|
||||
lpFcb = ExtFcbToFcb(lpXfcb);
|
||||
|
||||
/* An already closed FCB can be closed again without error */
|
||||
if (lpFcb->fcb_sftno == (BYTE)0xff)
|
||||
if (lpFcb->fcb_sftno == (BYTE) 0xff)
|
||||
return TRUE;
|
||||
|
||||
/* Get the SFT block that contains the SFT */
|
||||
@ -730,8 +739,9 @@ BOOL FcbClose(xfcb FAR * lpXfcb)
|
||||
if (!(s->sft_flags & SFT_FSHARED))
|
||||
dos_setfsize(s->sft_status, lpFcb->fcb_fsize);
|
||||
DosSetFtimeSft(lpFcb->fcb_sftno, lpFcb->fcb_date, lpFcb->fcb_time);
|
||||
if (DosCloseSft(lpFcb->fcb_sftno) == SUCCESS) {
|
||||
lpFcb->fcb_sftno = (BYTE)0xff;
|
||||
if (DosCloseSft(lpFcb->fcb_sftno) == SUCCESS)
|
||||
{
|
||||
lpFcb->fcb_sftno = (BYTE) 0xff;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@ -743,7 +753,7 @@ VOID FcbCloseAll()
|
||||
COUNT idx = 0;
|
||||
sft FAR *sftp;
|
||||
|
||||
for (idx = 0; (sftp = idx_to_sft(idx)) != (sft FAR *) -1; idx++)
|
||||
for (idx = 0; (sftp = idx_to_sft(idx)) != (sft FAR *) - 1; idx++)
|
||||
if ((sftp->sft_mode & SFT_MFCB) && sftp->sft_psp == cu_psp)
|
||||
DosCloseSft(idx);
|
||||
}
|
||||
@ -764,8 +774,8 @@ BOOL FcbFindFirst(xfcb FAR * lpXfcb)
|
||||
if (lpXfcb->xfcb_flag == 0xff)
|
||||
{
|
||||
wAttr = lpXfcb->xfcb_attrib;
|
||||
fmemcpy(lpDir, lpXfcb, 7);
|
||||
lpDir += 7;
|
||||
fmemcpy(lpDir, lpXfcb, 7);
|
||||
lpDir += 7;
|
||||
}
|
||||
else
|
||||
wAttr = D_ALL;
|
||||
@ -776,10 +786,10 @@ BOOL FcbFindFirst(xfcb FAR * lpXfcb)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*lpDir++ = FcbDrive;
|
||||
*lpDir++ = FcbDrive;
|
||||
fmemcpy(lpDir, &SearchDir, sizeof(struct dirent));
|
||||
|
||||
lpFcb->fcb_dirclst = (UWORD)Dmatch.dm_dircluster;
|
||||
lpFcb->fcb_dirclst = (UWORD) Dmatch.dm_dircluster;
|
||||
lpFcb->fcb_strtclst = Dmatch.dm_entry;
|
||||
|
||||
/*
|
||||
@ -787,7 +797,7 @@ BOOL FcbFindFirst(xfcb FAR * lpXfcb)
|
||||
The First byte is the current directory count and the second seems
|
||||
to be the attribute byte.
|
||||
*/
|
||||
lpFcb->fcb_sftno = Dmatch.dm_drive; /* MSD seems to save this @ fcb_date.*/
|
||||
lpFcb->fcb_sftno = Dmatch.dm_drive; /* MSD seems to save this @ fcb_date. */
|
||||
#if 0
|
||||
lpFcb->fcb_cublock = Dmatch.dm_entry;
|
||||
lpFcb->fcb_cublock *= 0x100;
|
||||
@ -838,10 +848,10 @@ BOOL FcbFindNext(xfcb FAR * lpXfcb)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*lpDir++ = FcbDrive;
|
||||
*lpDir++ = FcbDrive;
|
||||
fmemcpy((struct dirent FAR *)lpDir, &SearchDir, sizeof(struct dirent));
|
||||
|
||||
lpFcb->fcb_dirclst = (UWORD)Dmatch.dm_dircluster;
|
||||
lpFcb->fcb_dirclst = (UWORD) Dmatch.dm_dircluster;
|
||||
lpFcb->fcb_strtclst = Dmatch.dm_entry;
|
||||
|
||||
lpFcb->fcb_sftno = Dmatch.dm_drive;
|
||||
@ -917,5 +927,3 @@ BOOL FcbFindNext(xfcb FAR * lpXfcb)
|
||||
* Rev 1.0 02 Jul 1995 8:06:06 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
||||
|
196
kernel/globals.h
196
kernel/globals.h
@ -29,11 +29,11 @@
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
#ifdef MAIN
|
||||
static BYTE *Globals_hRcsId = "$Id$";
|
||||
static BYTE *Globals_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#include "device.h"
|
||||
#include "mcb.h"
|
||||
#include "pcb.h"
|
||||
@ -86,7 +86,7 @@ static BYTE *Globals_hRcsId = "$Id$";
|
||||
/* */
|
||||
/* Defaults and limits - System wide */
|
||||
#define PARSE_MAX MAX_CDSPATH /* maximum # of bytes in path */
|
||||
#define NAMEMAX PARSE_MAX /* Maximum path for CDS */
|
||||
#define NAMEMAX PARSE_MAX /* Maximum path for CDS */
|
||||
|
||||
/* internal error from failure or aborted operation */
|
||||
#define ERROR -1
|
||||
@ -127,8 +127,6 @@ static BYTE *Globals_hRcsId = "$Id$";
|
||||
#define DSKWRITEINT26 3
|
||||
#define DSKREADINT25 4
|
||||
|
||||
|
||||
|
||||
/* FAT cluster special flags */
|
||||
#define FREE 0x000
|
||||
|
||||
@ -162,86 +160,79 @@ FAR clk_dev, /* Clock device driver */
|
||||
FAR prn_dev, /* Generic printer device driver */
|
||||
FAR aux_dev, /* Generic aux device driver */
|
||||
FAR blk_dev; /* Block device (Disk) driver */
|
||||
extern UWORD
|
||||
ram_top; /* How much ram in Kbytes */
|
||||
extern COUNT *
|
||||
error_tos, /* error stack */
|
||||
extern UWORD ram_top; /* How much ram in Kbytes */
|
||||
extern COUNT *error_tos, /* error stack */
|
||||
disk_api_tos, /* API handler stack - disk fns */
|
||||
char_api_tos; /* API handler stack - char fns */
|
||||
extern BYTE
|
||||
FAR _InitTextStart; /* first available byte of ram */
|
||||
extern BYTE
|
||||
FAR _HMATextAvailable, /* first byte of available CODE area */
|
||||
extern BYTE FAR _InitTextStart; /* first available byte of ram */
|
||||
extern BYTE FAR _HMATextAvailable, /* first byte of available CODE area */
|
||||
FAR _HMATextStart[], /* first byte of HMAable CODE area */
|
||||
FAR _HMATextEnd[]; /* and the last byte of it */
|
||||
extern
|
||||
BYTE DosLoadedInHMA; /* if InitHMA has moved DOS up */
|
||||
|
||||
extern
|
||||
BYTE DosLoadedInHMA; /* if InitHMA has moved DOS up */
|
||||
|
||||
extern struct ClockRecord
|
||||
ClkRecord;
|
||||
|
||||
/* */
|
||||
/* Global variables */
|
||||
/* */
|
||||
GLOBAL BYTE
|
||||
os_major, /* major version number */
|
||||
GLOBAL BYTE os_major, /* major version number */
|
||||
os_minor, /* minor version number */
|
||||
|
||||
rev_number /* minor version number */
|
||||
#ifdef MAIN
|
||||
= REV_NUMBER,
|
||||
= REV_NUMBER,
|
||||
#else
|
||||
,
|
||||
#endif
|
||||
|
||||
version_flags /* minor version number */
|
||||
#ifdef MAIN
|
||||
= 0;
|
||||
= 0;
|
||||
#else
|
||||
;
|
||||
;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
GLOBAL WORD bDumpRegs
|
||||
#ifdef MAIN
|
||||
= FALSE;
|
||||
= FALSE;
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
GLOBAL WORD bDumpRdWrParms
|
||||
#ifdef MAIN
|
||||
= FALSE;
|
||||
= FALSE;
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 0 /* defined in MAIN.C now to save low memory */
|
||||
#if 0 /* defined in MAIN.C now to save low memory */
|
||||
|
||||
GLOBAL BYTE copyright[] =
|
||||
GLOBAL BYTE copyright[] =
|
||||
"(C) Copyright 1995-2001 Pasquale J. Villani and The FreeDOS Project.\n"
|
||||
"All Rights Reserved. This is free software and comes with ABSOLUTELY NO\n"
|
||||
"WARRANTY; you can redistribute it and/or modify it under the terms of the\n"
|
||||
"GNU General Public License as published by the Free Software Foundation;\n"
|
||||
"either version 2, or (at your option) any later version.\n";
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
GLOBAL BYTE os_release[]
|
||||
#ifdef MAIN
|
||||
#if 0
|
||||
= "DOS-C version %d.%d Beta %d [FreeDOS Release] (Build %d).\n"
|
||||
= "DOS-C version %d.%d Beta %d [FreeDOS Release] (Build %d).\n"
|
||||
#endif
|
||||
= "FreeDOS kernel version " KERNEL_VERSION_STRING \
|
||||
" (Build " KERNEL_BUILD_STRING ") [" __DATE__ " " __TIME__ "]\n"
|
||||
= "FreeDOS kernel version " KERNEL_VERSION_STRING
|
||||
" (Build " KERNEL_BUILD_STRING ") [" __DATE__ " " __TIME__ "]\n"
|
||||
#if 0
|
||||
"For technical information and description of the DOS-C operating system\n\
|
||||
"For technical information and description of the DOS-C operating system\n\
|
||||
consult \"FreeDOS Kernel\" by Pat Villani, published by Miller\n\
|
||||
Freeman Publishing, Lawrence KS, USA (ISBN 0-87930-436-7).\n\
|
||||
\n"
|
||||
#endif
|
||||
#endif
|
||||
;
|
||||
;
|
||||
|
||||
/* Globally referenced variables - WARNING: ORDER IS DEFINED IN */
|
||||
/* KERNAL.ASM AND MUST NOT BE CHANGED. DO NOT CHANGE ORDER BECAUSE THEY */
|
||||
@ -251,109 +242,81 @@ Freeman Publishing, Lawrence KS, USA (ISBN 0-87930-436-7).\n\
|
||||
extern UWORD NetBios;
|
||||
extern BYTE *net_name;
|
||||
extern BYTE net_set_count;
|
||||
extern BYTE NetDelay,
|
||||
NetRetry;
|
||||
extern BYTE NetDelay, NetRetry;
|
||||
|
||||
extern UWORD
|
||||
first_mcb, /* Start of user memory */
|
||||
UMB_top,
|
||||
umb_start,
|
||||
uppermem_root; /* Start of umb chain ? */
|
||||
extern UWORD first_mcb, /* Start of user memory */
|
||||
UMB_top, umb_start, uppermem_root; /* Start of umb chain ? */
|
||||
extern struct dpb
|
||||
FAR *DPBp; /* First drive Parameter Block */
|
||||
extern sfttbl
|
||||
FAR * sfthead; /* System File Table head */
|
||||
extern sfttbl FAR * sfthead; /* System File Table head */
|
||||
extern struct dhdr
|
||||
FAR *clock, /* CLOCK$ device */
|
||||
FAR * syscon; /* console device */
|
||||
extern WORD
|
||||
maxbksize; /* Number of Drives in system */
|
||||
extern WORD maxbksize; /* Number of Drives in system */
|
||||
extern struct buffer
|
||||
FAR *firstbuf; /* head of buffers linked list */
|
||||
extern cdstbl
|
||||
FAR * CDSp; /* Current Directory Structure */
|
||||
extern cdstbl FAR * CDSp; /* Current Directory Structure */
|
||||
extern
|
||||
struct cds FAR *current_ldt;
|
||||
extern LONG current_filepos; /* current file position */
|
||||
extern sfttbl
|
||||
FAR * FCBp; /* FCB table pointer */
|
||||
extern WORD
|
||||
nprotfcb; /* number of protected fcbs */
|
||||
extern UBYTE
|
||||
nblkdev, /* number of block devices */
|
||||
extern sfttbl FAR * FCBp; /* FCB table pointer */
|
||||
extern WORD nprotfcb; /* number of protected fcbs */
|
||||
extern UBYTE nblkdev, /* number of block devices */
|
||||
lastdrive, /* value of last drive */
|
||||
uppermem_link, /* UMB Link flag */
|
||||
PrinterEcho; /* Printer Echo Flag */
|
||||
PrinterEcho; /* Printer Echo Flag */
|
||||
|
||||
extern UWORD LoL_nbuffers; /* Number of buffers */
|
||||
|
||||
extern UWORD
|
||||
LoL_nbuffers; /* Number of buffers */
|
||||
|
||||
extern struct dhdr
|
||||
nul_dev;
|
||||
extern UBYTE
|
||||
mem_access_mode; /* memory allocation scheme */
|
||||
extern BYTE
|
||||
ErrorMode, /* Critical error flag */
|
||||
extern UBYTE mem_access_mode; /* memory allocation scheme */
|
||||
extern BYTE ErrorMode, /* Critical error flag */
|
||||
InDOS, /* In DOS critical section */
|
||||
OpenMode, /* File Open Attributes */
|
||||
SAttr, /* Attrib Mask for Dir Search */
|
||||
dosidle_flag,
|
||||
Server_Call,
|
||||
CritErrLocus,
|
||||
CritErrAction,
|
||||
CritErrClass,
|
||||
VgaSet,
|
||||
njoined; /* number of joined devices */
|
||||
dosidle_flag, Server_Call, CritErrLocus, CritErrAction, CritErrClass, VgaSet, njoined; /* number of joined devices */
|
||||
|
||||
extern UWORD Int21AX;
|
||||
extern COUNT CritErrCode;
|
||||
extern BYTE FAR * CritErrDev;
|
||||
extern BYTE FAR *CritErrDev;
|
||||
|
||||
extern struct dirent
|
||||
SearchDir;
|
||||
|
||||
extern struct
|
||||
{
|
||||
extern struct {
|
||||
COUNT nDrive;
|
||||
BYTE szName[FNAME_SIZE + 1];
|
||||
BYTE szExt[FEXT_SIZE + 1];
|
||||
}
|
||||
FcbSearchBuffer;
|
||||
} FcbSearchBuffer;
|
||||
|
||||
extern struct /* Path name parsing buffer */
|
||||
extern struct /* Path name parsing buffer */
|
||||
{
|
||||
BYTE _PriPathName[128];
|
||||
}
|
||||
_PriPathBuffer;
|
||||
} _PriPathBuffer;
|
||||
|
||||
extern struct
|
||||
{
|
||||
extern struct {
|
||||
BYTE _fname[FNAME_SIZE];
|
||||
BYTE _fext[FEXT_SIZE+1]; /* space for 0 */
|
||||
}
|
||||
szNames;
|
||||
BYTE _fext[FEXT_SIZE + 1]; /* space for 0 */
|
||||
} szNames;
|
||||
|
||||
#define PriPathName _PriPathBuffer._PriPathName
|
||||
#define szDirName TempCDS.cdsCurrentPath
|
||||
#define szFileName szNames._fname
|
||||
#define szFileExt szNames._fext
|
||||
|
||||
extern struct /* Alternate path name parsing buffer */
|
||||
extern struct /* Alternate path name parsing buffer */
|
||||
{
|
||||
BYTE _SecPathName[128];
|
||||
}
|
||||
_SecPathBuffer;
|
||||
} _SecPathBuffer;
|
||||
|
||||
#define SecPathName _SecPathBuffer._SecPathName
|
||||
|
||||
extern UWORD
|
||||
wAttr;
|
||||
extern UWORD wAttr;
|
||||
|
||||
extern BYTE
|
||||
default_drive; /* default drive for dos */
|
||||
extern BYTE default_drive; /* default drive for dos */
|
||||
|
||||
extern BYTE
|
||||
TempBuffer[], /* Temporary general purpose buffer */
|
||||
extern BYTE TempBuffer[], /* Temporary general purpose buffer */
|
||||
FAR internal_data[], /* sda areas */
|
||||
FAR swap_always[], /* " " */
|
||||
FAR swap_indos[], /* " " */
|
||||
@ -361,57 +324,46 @@ extern BYTE
|
||||
break_flg, /* true if break was detected */
|
||||
break_ena, /* break enabled flag */
|
||||
FAR * dta; /* Disk transfer area (kludge) */
|
||||
extern seg
|
||||
cu_psp; /* current psp segment */
|
||||
extern iregs
|
||||
FAR * user_r; /* User registers for int 21h call */
|
||||
extern seg cu_psp; /* current psp segment */
|
||||
extern iregs FAR * user_r; /* User registers for int 21h call */
|
||||
|
||||
extern struct dirent /* Temporary directory entry */
|
||||
DirEntBuffer;
|
||||
|
||||
extern request /* I/O Request packets */
|
||||
CharReqHdr,
|
||||
IoReqHdr,
|
||||
MediaReqHdr;
|
||||
CharReqHdr, IoReqHdr, MediaReqHdr;
|
||||
|
||||
extern fcb
|
||||
FAR * lpFcb; /* Pointer to users fcb */
|
||||
extern fcb FAR * lpFcb; /* Pointer to users fcb */
|
||||
|
||||
extern sft
|
||||
FAR * lpCurSft;
|
||||
extern sft FAR * lpCurSft;
|
||||
|
||||
extern BYTE
|
||||
verify_ena, /* verify enabled flag */
|
||||
extern BYTE verify_ena, /* verify enabled flag */
|
||||
switchar, /* switch char */
|
||||
return_mode, /* Process termination rets */
|
||||
return_code; /* " " " */
|
||||
|
||||
extern BYTE
|
||||
BootDrive, /* Drive we came up from */
|
||||
extern BYTE BootDrive, /* Drive we came up from */
|
||||
scr_pos; /* screen position for bs, ht, etc */
|
||||
/*extern WORD
|
||||
NumFloppies; !!*/ /* How many floppies we have */
|
||||
NumFloppies; !!*//* How many floppies we have */
|
||||
|
||||
extern keyboard
|
||||
kb_buf;
|
||||
extern keyboard kb_buf;
|
||||
|
||||
extern struct cds
|
||||
TempCDS;
|
||||
|
||||
/* start of uncontrolled variables */
|
||||
GLOBAL seg
|
||||
RootPsp; /* Root process -- do not abort */
|
||||
GLOBAL seg RootPsp; /* Root process -- do not abort */
|
||||
|
||||
/* don't know what it should do, but its no longer in use TE
|
||||
GLOBAL struct f_node
|
||||
*pDirFileNode;
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
GLOBAL iregs error_regs; /* registers for dump */
|
||||
|
||||
GLOBAL WORD
|
||||
dump_regs; /* dump registers of bad call */
|
||||
GLOBAL WORD dump_regs; /* dump registers of bad call */
|
||||
|
||||
#endif
|
||||
|
||||
@ -421,7 +373,7 @@ GLOBAL UWORD f_nodes_cnt; /* number of allocated f_nodes */
|
||||
|
||||
/*!! GLOBAL iregs
|
||||
FAR * ustackp, /* user stack */
|
||||
/*!! FAR * kstackp; */ /* kernel stack */
|
||||
/*!! FAR * kstackp; *//* kernel stack */
|
||||
|
||||
/* */
|
||||
/* Function prototypes - automatically generated */
|
||||
@ -430,21 +382,18 @@ GLOBAL UWORD f_nodes_cnt; /* number of allocated f_nodes */
|
||||
|
||||
/* Process related functions - not under automatic generation. */
|
||||
/* Typically, these are in ".asm" files. */
|
||||
VOID
|
||||
FAR ASMCFUNC cpm_entry(VOID)
|
||||
VOID FAR ASMCFUNC cpm_entry(VOID)
|
||||
/*INRPT FAR handle_break(VOID) */ ;
|
||||
VOID
|
||||
enable(VOID),
|
||||
disable(VOID);
|
||||
VOID enable(VOID), disable(VOID);
|
||||
COUNT
|
||||
ASMCFUNC CriticalError(
|
||||
COUNT nFlag, COUNT nDrive, COUNT nError, struct dhdr FAR * lpDevice);
|
||||
ASMCFUNC CriticalError(COUNT nFlag, COUNT nDrive, COUNT nError,
|
||||
struct dhdr FAR * lpDevice);
|
||||
|
||||
#ifdef PROTO
|
||||
VOID FAR ASMCFUNC CharMapSrvc(VOID);
|
||||
VOID FAR ASMCFUNC set_stack(VOID);
|
||||
VOID FAR ASMCFUNC restore_stack(VOID);
|
||||
WORD ASMCFUNC execrh(request FAR *, struct dhdr FAR *);
|
||||
WORD ASMCFUNC execrh(request FAR *, struct dhdr FAR *);
|
||||
VOID exit(COUNT);
|
||||
/*VOID INRPT FAR handle_break(VOID); */
|
||||
VOID ASMCFUNC tmark(VOID);
|
||||
@ -515,14 +464,13 @@ VOID fputbyte();
|
||||
/*#define is_leap_year(y) ((y) & 3 ? 0 : (y) % 100 ? 1 : (y) % 400 ? 0 : 1) */
|
||||
|
||||
/* ^Break handling */
|
||||
void ASMCFUNC spawn_int23(void); /* procsupt.asm */
|
||||
void ASMCFUNC spawn_int23(void); /* procsupt.asm */
|
||||
int control_break(void); /* break.c */
|
||||
void handle_break(void); /* break.c */
|
||||
|
||||
|
||||
GLOBAL BYTE ReturnAnyDosVersionExpected;
|
||||
|
||||
GLOBAL COUNT UnusedRetVal; /* put unused errors here (to save stack space) */
|
||||
GLOBAL COUNT UnusedRetVal; /* put unused errors here (to save stack space) */
|
||||
|
||||
/*
|
||||
* Log: globals.h,v
|
||||
|
@ -1,31 +1,27 @@
|
||||
/* Included by initialisation functions */
|
||||
|
||||
#if _MSC_VER != 0
|
||||
extern __segment DosDataSeg;/* serves for all references to the DOS DATA segment
|
||||
necessary for MSC+our funny linking model
|
||||
*/
|
||||
extern __segment DosDataSeg; /* serves for all references to the DOS DATA segment
|
||||
necessary for MSC+our funny linking model
|
||||
*/
|
||||
|
||||
extern __segment DosTextSeg;
|
||||
extern __segment DosTextSeg;
|
||||
|
||||
#define DOSFAR __based(DosDataSeg)
|
||||
#define DOSTEXTFAR __based(DosTextSeg)
|
||||
#define DOSFAR __based(DosDataSeg)
|
||||
#define DOSTEXTFAR __based(DosTextSeg)
|
||||
|
||||
#elif defined(__TURBOC__)
|
||||
|
||||
#define DOSFAR FAR
|
||||
#define DOSTEXTFAR FAR
|
||||
#define DOSFAR FAR
|
||||
#define DOSTEXTFAR FAR
|
||||
|
||||
#elif defined(__WATCOMC__)
|
||||
|
||||
#define DOSFAR FAR
|
||||
#define DOSTEXTFAR FAR
|
||||
#define DOSFAR FAR
|
||||
#define DOSTEXTFAR FAR
|
||||
|
||||
#else
|
||||
#pragma error("unknown compiler - please adjust")
|
||||
this should simply not compile !!
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
extern BYTE DOSFAR version_flags; /* minor version number */
|
||||
|
||||
#pragma error("unknown compiler - please adjust")
|
||||
this should simply not compile ! !
|
||||
#endif
|
||||
extern BYTE DOSFAR version_flags; /* minor version number */
|
||||
|
@ -22,8 +22,7 @@
|
||||
#include "buffer.h"
|
||||
|
||||
#include "KConfig.h"
|
||||
extern struct _KernelConfig InitKernelConfig;
|
||||
|
||||
extern struct _KernelConfig InitKernelConfig;
|
||||
|
||||
/*
|
||||
* The null macro `INIT' can be used to allow the reader to differentiate
|
||||
@ -58,7 +57,7 @@ COUNT ASMCFUNC strlen(REG BYTE * s);
|
||||
|
||||
/*inithma.c*/
|
||||
extern BYTE DosLoadedInHMA;
|
||||
extern fmemcmp(BYTE far *s1, BYTE FAR *s2, unsigned len);
|
||||
extern fmemcmp(BYTE far * s1, BYTE FAR * s2, unsigned len);
|
||||
|
||||
#define setvec(n, isr) (void)(*(VOID (FAR * FAR *)())(MK_FP(0,4 * (n))) = (isr))
|
||||
|
||||
@ -75,46 +74,43 @@ extern fmemcmp(BYTE far *s1, BYTE FAR *s2, unsigned len);
|
||||
#define MAX_HARD_DRIVE 8
|
||||
#define NDEV 26 /* up to Z: */
|
||||
|
||||
|
||||
|
||||
/* Start of configuration variables */
|
||||
struct config
|
||||
{
|
||||
BYTE cfgBuffers;
|
||||
/* number of buffers in the system */
|
||||
UBYTE cfgFiles;
|
||||
/* number of available files */
|
||||
UBYTE cfgFcbs;
|
||||
/* number of available FCBs */
|
||||
UBYTE cfgProtFcbs;
|
||||
/* number of protected FCBs */
|
||||
BYTE cfgInit[NAMEMAX];
|
||||
/* init of command.com */
|
||||
BYTE cfgInitTail[NAMEMAX];
|
||||
/* command.com's tail */
|
||||
UBYTE cfgLastdrive;
|
||||
/* last drive */
|
||||
BYTE cfgStacks;
|
||||
/* number of stacks */
|
||||
UWORD cfgStackSize;
|
||||
/* stacks size for each stack */
|
||||
/* COUNTRY=
|
||||
In Pass #1 these information is collected and in PostConfig()
|
||||
the NLS package is loaded into memory.
|
||||
-- 2000/06/11 ska*/
|
||||
WORD cfgCSYS_cntry;
|
||||
/* country ID to be loaded */
|
||||
WORD cfgCSYS_cp;
|
||||
/* requested codepage; NLS_DEFAULT if default */
|
||||
BYTE cfgCSYS_fnam[NAMEMAX];
|
||||
/* filename of COUNTRY= */
|
||||
WORD cfgCSYS_memory;
|
||||
/* number of bytes required for the NLS pkg;
|
||||
0 if none */
|
||||
VOID FAR *cfgCSYS_data;
|
||||
/* where the loaded data is for PostConfig() */
|
||||
UBYTE cfgP_0_startmode;
|
||||
/* load command.com high or not */
|
||||
struct config {
|
||||
BYTE cfgBuffers;
|
||||
/* number of buffers in the system */
|
||||
UBYTE cfgFiles;
|
||||
/* number of available files */
|
||||
UBYTE cfgFcbs;
|
||||
/* number of available FCBs */
|
||||
UBYTE cfgProtFcbs;
|
||||
/* number of protected FCBs */
|
||||
BYTE cfgInit[NAMEMAX];
|
||||
/* init of command.com */
|
||||
BYTE cfgInitTail[NAMEMAX];
|
||||
/* command.com's tail */
|
||||
UBYTE cfgLastdrive;
|
||||
/* last drive */
|
||||
BYTE cfgStacks;
|
||||
/* number of stacks */
|
||||
UWORD cfgStackSize;
|
||||
/* stacks size for each stack */
|
||||
/* COUNTRY=
|
||||
In Pass #1 these information is collected and in PostConfig()
|
||||
the NLS package is loaded into memory.
|
||||
-- 2000/06/11 ska */
|
||||
WORD cfgCSYS_cntry;
|
||||
/* country ID to be loaded */
|
||||
WORD cfgCSYS_cp;
|
||||
/* requested codepage; NLS_DEFAULT if default */
|
||||
BYTE cfgCSYS_fnam[NAMEMAX];
|
||||
/* filename of COUNTRY= */
|
||||
WORD cfgCSYS_memory;
|
||||
/* number of bytes required for the NLS pkg;
|
||||
0 if none */
|
||||
VOID FAR *cfgCSYS_data;
|
||||
/* where the loaded data is for PostConfig() */
|
||||
UBYTE cfgP_0_startmode;
|
||||
/* load command.com high or not */
|
||||
};
|
||||
|
||||
extern struct config Config;
|
||||
@ -134,7 +130,7 @@ INIT VOID mcb_init(UCOUNT seg, UWORD size);
|
||||
INIT VOID strcat(REG BYTE * d, REG BYTE * s);
|
||||
INIT BYTE FAR *KernelAlloc(WORD nBytes);
|
||||
INIT COUNT ASMCFUNC Umb_Test(void);
|
||||
INIT COUNT ASMCFUNC UMB_get_largest(UCOUNT *seg, UCOUNT *size);
|
||||
INIT COUNT ASMCFUNC UMB_get_largest(UCOUNT * seg, UCOUNT * size);
|
||||
INIT BYTE *GetStringArg(BYTE * pLine, BYTE * pszString);
|
||||
|
||||
/* diskinit.c */
|
||||
@ -152,27 +148,28 @@ UWORD init_oem(void);
|
||||
|
||||
/* intr.asm */
|
||||
|
||||
void ASMCFUNC init_call_intr(int nr, iregs *rp);
|
||||
UCOUNT ASMCFUNC read(int fd, void *buf, UCOUNT count);
|
||||
void ASMCFUNC init_call_intr(int nr, iregs * rp);
|
||||
UCOUNT ASMCFUNC read(int fd, void *buf, UCOUNT count);
|
||||
int ASMCFUNC open(const char *pathname, int flags);
|
||||
int ASMCFUNC close(int fd);
|
||||
int ASMCFUNC dup2(int oldfd, int newfd);
|
||||
int ASMCFUNC allocmem(UWORD size, seg *segp);
|
||||
int ASMCFUNC allocmem(UWORD size, seg * segp);
|
||||
INIT VOID ASMCFUNC init_PSPInit(seg psp_seg);
|
||||
INIT VOID ASMCFUNC init_PSPSet(seg psp_seg);
|
||||
INIT COUNT ASMCFUNC init_DosExec(COUNT mode, exec_blk * ep, BYTE * lp);
|
||||
INIT VOID ASMCFUNC keycheck(VOID);
|
||||
|
||||
/* irqstack.asm */
|
||||
VOID ASMCFUNC init_stacks(VOID FAR * stack_base, COUNT nStacks, WORD stackSize);
|
||||
VOID ASMCFUNC init_stacks(VOID FAR * stack_base, COUNT nStacks,
|
||||
WORD stackSize);
|
||||
|
||||
/* inthndlr.c */
|
||||
VOID far ASMCFUNC int21_entry(iregs UserRegs);
|
||||
VOID ASMCFUNC int21_service(iregs far * r);
|
||||
VOID far ASMCFUNC int21_entry(iregs UserRegs);
|
||||
VOID ASMCFUNC int21_service(iregs far * r);
|
||||
VOID FAR ASMCFUNC int0_handler(void);
|
||||
VOID FAR ASMCFUNC int6_handler(void);
|
||||
VOID FAR ASMCFUNC empty_handler(void);
|
||||
VOID far ASMCFUNC got_cbreak(void); /* procsupt.asm */
|
||||
VOID far ASMCFUNC got_cbreak(void); /* procsupt.asm */
|
||||
VOID far ASMCFUNC int20_handler(iregs UserRegs);
|
||||
VOID far ASMCFUNC int21_handler(iregs UserRegs);
|
||||
VOID FAR ASMCFUNC int22_handler(void);
|
||||
@ -187,21 +184,22 @@ VOID FAR ASMCFUNC int2f_handler(void);
|
||||
|
||||
/* main.c */
|
||||
INIT VOID ASMCFUNC FreeDOSmain(void);
|
||||
INIT BOOL init_device(struct dhdr FAR * dhp, BYTE FAR * cmdLine, COUNT mode, COUNT top);
|
||||
INIT BOOL init_device(struct dhdr FAR * dhp, BYTE FAR * cmdLine,
|
||||
COUNT mode, COUNT top);
|
||||
INIT VOID init_fatal(BYTE * err_msg);
|
||||
|
||||
/* prf.c */
|
||||
WORD init_printf(CONST BYTE * fmt,...);
|
||||
WORD init_printf(CONST BYTE * fmt, ...);
|
||||
WORD init_sprintf(BYTE * buff, CONST BYTE * fmt, ...);
|
||||
|
||||
void MoveKernel(unsigned NewKernelSegment);
|
||||
extern WORD HMAFree; /* first byte in HMA not yet used */
|
||||
extern WORD HMAFree; /* first byte in HMA not yet used */
|
||||
|
||||
extern unsigned CurrentKernelSegment;
|
||||
|
||||
#if defined(WATCOM) && 0
|
||||
ULONG FAR ASMCFUNC MULULUS(ULONG mul1, UWORD mul2); /* MULtiply ULong by UShort */
|
||||
ULONG FAR ASMCFUNC MULULUL(ULONG mul1, ULONG mul2); /* MULtiply ULong by ULong */
|
||||
ULONG FAR ASMCFUNC DIVULUS(ULONG mul1, UWORD mul2); /* DIVide ULong by UShort */
|
||||
ULONG FAR ASMCFUNC DIVMODULUS(ULONG mul1, UWORD mul2,UWORD *rem); /* DIVide ULong by UShort */
|
||||
ULONG FAR ASMCFUNC MULULUS(ULONG mul1, UWORD mul2); /* MULtiply ULong by UShort */
|
||||
ULONG FAR ASMCFUNC MULULUL(ULONG mul1, ULONG mul2); /* MULtiply ULong by ULong */
|
||||
ULONG FAR ASMCFUNC DIVULUS(ULONG mul1, UWORD mul2); /* DIVide ULong by UShort */
|
||||
ULONG FAR ASMCFUNC DIVMODULUS(ULONG mul1, UWORD mul2, UWORD * rem); /* DIVide ULong by UShort */
|
||||
#endif
|
||||
|
1608
kernel/initdisk.c
1608
kernel/initdisk.c
File diff suppressed because it is too large
Load Diff
678
kernel/inithma.c
678
kernel/inithma.c
@ -63,89 +63,80 @@
|
||||
parameter is forced.
|
||||
*/
|
||||
|
||||
|
||||
#include "portab.h"
|
||||
#include "init-mod.h"
|
||||
#include "init-dat.h"
|
||||
|
||||
|
||||
|
||||
extern BYTE
|
||||
FAR _HMATextAvailable, /* first byte of available CODE area */
|
||||
FAR _HMATextStart[], /* first byte of HMAable CODE area */
|
||||
FAR _HMATextEnd[]; /* and the last byte of it */
|
||||
extern BYTE FAR _HMATextAvailable, /* first byte of available CODE area */
|
||||
FAR _HMATextStart[], /* first byte of HMAable CODE area */
|
||||
FAR _HMATextEnd[]; /* and the last byte of it */
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId = "$Id$";
|
||||
static BYTE *RcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
BYTE DosLoadedInHMA = FALSE; /* set to TRUE if loaded HIGH */
|
||||
BYTE HMAclaimed = FALSE; /* set to TRUE if claimed from HIMEM */
|
||||
WORD HMAFree = 0; /* first byte in HMA not yet used */
|
||||
|
||||
BYTE DosLoadedInHMA=FALSE; /* set to TRUE if loaded HIGH */
|
||||
BYTE HMAclaimed=FALSE; /* set to TRUE if claimed from HIMEM */
|
||||
WORD HMAFree = 0; /* first byte in HMA not yet used */
|
||||
|
||||
|
||||
extern BYTE FAR * DOSTEXTFAR ASMCFUNC XMSDriverAddress;
|
||||
extern BYTE FAR *DOSTEXTFAR ASMCFUNC XMSDriverAddress;
|
||||
extern FAR ASMCFUNC _EnableA20(VOID);
|
||||
extern FAR ASMCFUNC _DisableA20(VOID);
|
||||
|
||||
|
||||
extern void FAR *ASMCFUNC DetectXMSDriver(VOID);
|
||||
extern int ASMCFUNC init_call_XMScall( void FAR * driverAddress, UWORD ax, UWORD dx);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef __TURBOC__
|
||||
#define int3() __int__(3);
|
||||
#else
|
||||
void int3()
|
||||
{ __asm int 3;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#define int3()
|
||||
#endif
|
||||
|
||||
extern int ASMCFUNC init_call_XMScall(void FAR * driverAddress, UWORD ax,
|
||||
UWORD dx);
|
||||
|
||||
#ifdef DEBUG
|
||||
#define HMAInitPrintf(x) printf x
|
||||
#ifdef __TURBOC__
|
||||
#define int3() __int__(3);
|
||||
#else
|
||||
#define HMAInitPrintf(x)
|
||||
#endif
|
||||
void int3()
|
||||
{
|
||||
__asm int 3;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#define int3()
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define HMAInitPrintf(x) printf x
|
||||
#else
|
||||
#define HMAInitPrintf(x)
|
||||
#endif
|
||||
|
||||
void MoveKernel(unsigned NewKernelSegment);
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
VOID hdump(BYTE FAR *p)
|
||||
VOID hdump(BYTE FAR * p)
|
||||
{
|
||||
int loop;
|
||||
HMAInitPrintf(("%p", p));
|
||||
|
||||
for (loop = 0; loop < 16; loop++)
|
||||
HMAInitPrintf(("%02x ", p[loop]));
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
int loop;
|
||||
HMAInitPrintf(("%p", p));
|
||||
|
||||
for (loop = 0; loop < 16; loop++)
|
||||
HMAInitPrintf(("%02x ", p[loop]));
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
#else
|
||||
#define hdump(ptr)
|
||||
#endif
|
||||
|
||||
#define hdump(ptr)
|
||||
#endif
|
||||
|
||||
#define KeyboardShiftState() (*(BYTE FAR *)(MK_FP(0x40,0x17)))
|
||||
|
||||
|
||||
/* of course, this should go to ASMSUPT */
|
||||
fmemcmp(BYTE far *s1, BYTE FAR *s2, unsigned len)
|
||||
fmemcmp(BYTE far * s1, BYTE FAR * s2, unsigned len)
|
||||
{
|
||||
for ( ; len ; s1++,s2++,--len)
|
||||
{
|
||||
if (*s1 - *s2)
|
||||
return *s1-*s2;
|
||||
}
|
||||
return 0;
|
||||
for (; len; s1++, s2++, --len)
|
||||
{
|
||||
if (*s1 - *s2)
|
||||
return *s1 - *s2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
this tests, if the HMA area can be enabled.
|
||||
if so, it simply leaves it on
|
||||
@ -153,39 +144,35 @@ fmemcmp(BYTE far *s1, BYTE FAR *s2, unsigned len)
|
||||
|
||||
int EnableHMA(VOID)
|
||||
{
|
||||
|
||||
_EnableA20();
|
||||
|
||||
if (fmemcmp(MK_FP(0x0000,0x0000), MK_FP(0xffff,0x0010),128) == 0)
|
||||
{
|
||||
printf("HMA can't be enabled\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_EnableA20();
|
||||
|
||||
_DisableA20();
|
||||
|
||||
if (fmemcmp(MK_FP(0x0000,0x0000), MK_FP(0xffff,0x0010),128) != 0)
|
||||
{
|
||||
printf("HMA can't be disabled - no problem for us\n");
|
||||
}
|
||||
|
||||
_EnableA20();
|
||||
if (fmemcmp(MK_FP(0x0000,0x0000), MK_FP(0xffff,0x0010),128) == 0)
|
||||
{
|
||||
printf("HMA can't be enabled second time\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HMAInitPrintf(("HMA success - leaving enabled\n"));
|
||||
if (fmemcmp(MK_FP(0x0000, 0x0000), MK_FP(0xffff, 0x0010), 128) == 0)
|
||||
{
|
||||
printf("HMA can't be enabled\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_DisableA20();
|
||||
|
||||
if (fmemcmp(MK_FP(0x0000, 0x0000), MK_FP(0xffff, 0x0010), 128) != 0)
|
||||
{
|
||||
printf("HMA can't be disabled - no problem for us\n");
|
||||
}
|
||||
|
||||
_EnableA20();
|
||||
if (fmemcmp(MK_FP(0x0000, 0x0000), MK_FP(0xffff, 0x0010), 128) == 0)
|
||||
{
|
||||
printf("HMA can't be enabled second time\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HMAInitPrintf(("HMA success - leaving enabled\n"));
|
||||
|
||||
return TRUE;
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
move the kernel up to high memory
|
||||
this is very unportable
|
||||
@ -196,70 +183,68 @@ int EnableHMA(VOID)
|
||||
#define HMAOFFSET 0x20
|
||||
#define HMASEGMENT 0xffff
|
||||
|
||||
|
||||
int MoveKernelToHMA()
|
||||
{
|
||||
|
||||
if (DosLoadedInHMA)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((XMSDriverAddress = DetectXMSDriver()) == NULL)
|
||||
return FALSE;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* A) for debugging purpose, suppress this,
|
||||
if any shift key is pressed
|
||||
*/
|
||||
if (KeyboardShiftState() & 0x0f)
|
||||
{
|
||||
printf("Keyboard state is %0x, NOT moving to HMA\n",KeyboardShiftState());
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* B) check out, if we can have HMA */
|
||||
|
||||
if (!EnableHMA())
|
||||
{
|
||||
printf("Can't enable HMA area (the famous A20), NOT moving to HMA\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* allocate HMA through XMS driver */
|
||||
|
||||
if (HMAclaimed == 0 &&
|
||||
(HMAclaimed = init_call_XMScall( XMSDriverAddress, 0x0100, 0xffff)) == 0)
|
||||
{
|
||||
printf("Can't reserve HMA area ??\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MoveKernel(0xffff);
|
||||
|
||||
|
||||
{
|
||||
/* E) up to now, nothing really bad was done.
|
||||
but now, we reuse the HMA area. bad things will happen
|
||||
|
||||
to find bugs early,
|
||||
cause INT 3 on all accesses to this area
|
||||
*/
|
||||
|
||||
|
||||
DosLoadedInHMA = TRUE;
|
||||
}
|
||||
|
||||
/* report the fact we are running high thorugh int 21, ax=3306 */
|
||||
version_flags |= 0x10;
|
||||
|
||||
if (DosLoadedInHMA)
|
||||
{
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((XMSDriverAddress = DetectXMSDriver()) == NULL)
|
||||
return FALSE;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* A) for debugging purpose, suppress this,
|
||||
if any shift key is pressed
|
||||
*/
|
||||
if (KeyboardShiftState() & 0x0f)
|
||||
{
|
||||
printf("Keyboard state is %0x, NOT moving to HMA\n",
|
||||
KeyboardShiftState());
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* B) check out, if we can have HMA */
|
||||
|
||||
if (!EnableHMA())
|
||||
{
|
||||
printf("Can't enable HMA area (the famous A20), NOT moving to HMA\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* allocate HMA through XMS driver */
|
||||
|
||||
if (HMAclaimed == 0 &&
|
||||
(HMAclaimed =
|
||||
init_call_XMScall(XMSDriverAddress, 0x0100, 0xffff)) == 0)
|
||||
{
|
||||
printf("Can't reserve HMA area ??\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MoveKernel(0xffff);
|
||||
|
||||
{
|
||||
/* E) up to now, nothing really bad was done.
|
||||
but now, we reuse the HMA area. bad things will happen
|
||||
|
||||
to find bugs early,
|
||||
cause INT 3 on all accesses to this area
|
||||
*/
|
||||
|
||||
DosLoadedInHMA = TRUE;
|
||||
}
|
||||
|
||||
/* report the fact we are running high thorugh int 21, ax=3306 */
|
||||
version_flags |= 0x10;
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
/* not necessary anymore : BO */
|
||||
/*
|
||||
@ -271,39 +256,40 @@ int MoveKernelToHMA()
|
||||
*/
|
||||
#if 0
|
||||
void InstallVDISK(VOID)
|
||||
{
|
||||
static struct { /* Boot-Sektor of a RAM-Disk */
|
||||
UBYTE dummy1[3]; /* HIMEM.SYS uses 3, but FDXMS uses 2 */
|
||||
char Name[5];
|
||||
BYTE dummy2[3];
|
||||
WORD BpS;
|
||||
BYTE dummy3[6];
|
||||
WORD Sektoren;
|
||||
BYTE dummy4;
|
||||
} VDISK_BOOT_SEKTOR = {
|
||||
{
|
||||
static struct { /* Boot-Sektor of a RAM-Disk */
|
||||
UBYTE dummy1[3]; /* HIMEM.SYS uses 3, but FDXMS uses 2 */
|
||||
char Name[5];
|
||||
BYTE dummy2[3];
|
||||
WORD BpS;
|
||||
BYTE dummy3[6];
|
||||
WORD Sektoren;
|
||||
BYTE dummy4;
|
||||
} VDISK_BOOT_SEKTOR =
|
||||
{
|
||||
{ 0xcf, ' ', ' '},
|
||||
{ 'V', 'D', 'I', 'S', 'K'},
|
||||
{ ' ', ' ', ' '},
|
||||
512,
|
||||
{ 'F', 'D', 'O', 'S', ' ', ' '},
|
||||
128, /* 128*512 = 64K */
|
||||
' '
|
||||
};
|
||||
0xcf, ' ', ' '},
|
||||
{
|
||||
'V', 'D', 'I', 'S', 'K'},
|
||||
{
|
||||
' ', ' ', ' '}, 512,
|
||||
{
|
||||
'F', 'D', 'O', 'S', ' ', ' '}, 128, /* 128*512 = 64K */
|
||||
' '};
|
||||
|
||||
if (!DosLoadedInHMA) return;
|
||||
if (HMAclaimed) return;
|
||||
|
||||
|
||||
fmemcpy(MK_FP(0xffff,0x0010), &VDISK_BOOT_SEKTOR, sizeof(VDISK_BOOT_SEKTOR));
|
||||
if (!DosLoadedInHMA)
|
||||
return;
|
||||
if (HMAclaimed)
|
||||
return;
|
||||
|
||||
setvec(0x19, MK_FP(0xffff,0x0010)); /* let INT 19 point to VDISK */
|
||||
|
||||
*(WORD FAR *)MK_FP(0xffff,0x002e) = 1024+64;
|
||||
}
|
||||
fmemcpy(MK_FP(0xffff, 0x0010), &VDISK_BOOT_SEKTOR,
|
||||
sizeof(VDISK_BOOT_SEKTOR));
|
||||
|
||||
setvec(0x19, MK_FP(0xffff, 0x0010)); /* let INT 19 point to VDISK */
|
||||
|
||||
*(WORD FAR *) MK_FP(0xffff, 0x002e) = 1024 + 64;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
this should be called, after each device driver
|
||||
has been loaded with FALSE
|
||||
@ -312,204 +298,210 @@ void InstallVDISK(VOID)
|
||||
will try to grab HMA;
|
||||
|
||||
on finalize, will install a VDISK
|
||||
*/
|
||||
|
||||
#if 0 /* not necessary anymore */
|
||||
*/
|
||||
|
||||
#if 0 /* not necessary anymore */
|
||||
|
||||
void HMAconfig(int finalize)
|
||||
{
|
||||
ClaimHMA();
|
||||
|
||||
if (finalize)
|
||||
InstallVDISK();
|
||||
ClaimHMA();
|
||||
|
||||
if (finalize)
|
||||
InstallVDISK();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
this allocates some bytes from the HMA area
|
||||
only available if DOS=HIGH was successful
|
||||
*/
|
||||
*/
|
||||
|
||||
VOID FAR *HMAalloc(COUNT bytesToAllocate)
|
||||
{
|
||||
VOID FAR *HMAptr;
|
||||
|
||||
if (!DosLoadedInHMA) return NULL;
|
||||
VOID FAR *HMAptr;
|
||||
|
||||
if (HMAFree >= 0xfff0 - bytesToAllocate) return NULL;
|
||||
|
||||
HMAptr = MK_FP(0xffff, HMAFree);
|
||||
|
||||
/* align on 16 byte boundary */
|
||||
HMAFree = (HMAFree + bytesToAllocate + 0xf) & 0xfff0;
|
||||
if (!DosLoadedInHMA)
|
||||
return NULL;
|
||||
|
||||
/*printf("HMA allocated %d byte at %x\n", bytesToAllocate, HMAptr); */
|
||||
|
||||
fmemset( HMAptr,0, bytesToAllocate);
|
||||
|
||||
return HMAptr;
|
||||
if (HMAFree >= 0xfff0 - bytesToAllocate)
|
||||
return NULL;
|
||||
|
||||
HMAptr = MK_FP(0xffff, HMAFree);
|
||||
|
||||
/* align on 16 byte boundary */
|
||||
HMAFree = (HMAFree + bytesToAllocate + 0xf) & 0xfff0;
|
||||
|
||||
/*printf("HMA allocated %d byte at %x\n", bytesToAllocate, HMAptr); */
|
||||
|
||||
fmemset(HMAptr, 0, bytesToAllocate);
|
||||
|
||||
return HMAptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned CurrentKernelSegment = 0;
|
||||
|
||||
void MoveKernel(unsigned NewKernelSegment)
|
||||
{
|
||||
UBYTE FAR *HMADest;
|
||||
UBYTE FAR *HMASource;
|
||||
unsigned len;
|
||||
UBYTE FAR *HMADest;
|
||||
UBYTE FAR *HMASource;
|
||||
unsigned len;
|
||||
|
||||
int3();
|
||||
if (CurrentKernelSegment == 0)
|
||||
CurrentKernelSegment = FP_SEG(_HMATextEnd);
|
||||
|
||||
if (CurrentKernelSegment == 0xffff)
|
||||
return;
|
||||
|
||||
|
||||
HMASource = MK_FP(CurrentKernelSegment,(FP_OFF(_HMATextStart) & 0xfff0));
|
||||
HMADest = MK_FP(NewKernelSegment,0x0000);
|
||||
|
||||
len = (FP_OFF(_HMATextEnd) | 0x000f) - (FP_OFF(_HMATextStart) & 0xfff0);
|
||||
|
||||
if (NewKernelSegment == 0xffff)
|
||||
{
|
||||
HMASource += HMAOFFSET;
|
||||
HMADest += HMAOFFSET;
|
||||
len -= HMAOFFSET;
|
||||
}
|
||||
|
||||
HMAInitPrintf(("HMA moving %p up to %p for %04x bytes\n",
|
||||
HMASource, HMADest, len));
|
||||
int3();
|
||||
if (CurrentKernelSegment == 0)
|
||||
CurrentKernelSegment = FP_SEG(_HMATextEnd);
|
||||
|
||||
if (NewKernelSegment < CurrentKernelSegment ||
|
||||
NewKernelSegment == 0xffff)
|
||||
{
|
||||
unsigned i; UBYTE FAR *s,FAR *d;
|
||||
|
||||
for (i = 0, s = HMASource,d = HMADest; i < len; i++)
|
||||
d[i] = s[i];
|
||||
}
|
||||
else {
|
||||
/* might overlap */
|
||||
unsigned i; UBYTE FAR *s,FAR *d;
|
||||
|
||||
for (i = len, s = HMASource,d = HMADest; i != 0; i--)
|
||||
d[i] = s[i];
|
||||
}
|
||||
|
||||
HMAFree = FP_OFF(HMADest)+len; /* first free byte after HMA_TEXT */
|
||||
|
||||
{
|
||||
/* D) but it only makes sense, if we can relocate
|
||||
all our entries to make use of HMA
|
||||
*/
|
||||
|
||||
/* this is for a
|
||||
call near enableA20
|
||||
jmp far kernelentry
|
||||
style table
|
||||
*/
|
||||
|
||||
struct RelocationTable {
|
||||
UBYTE jmpFar;
|
||||
UWORD jmpOffset;
|
||||
UWORD jmpSegment;
|
||||
UBYTE callNear;
|
||||
UWORD callOffset;
|
||||
};
|
||||
struct RelocatedEntry {
|
||||
UBYTE callNear;
|
||||
UWORD callOffset;
|
||||
UBYTE jmpFar;
|
||||
UWORD jmpOffset;
|
||||
UWORD jmpSegment;
|
||||
};
|
||||
extern struct RelocationTable
|
||||
DOSTEXTFAR _HMARelocationTableStart[],
|
||||
DOSTEXTFAR _HMARelocationTableEnd[];
|
||||
|
||||
struct RelocationTable FAR *rp, rtemp ;
|
||||
|
||||
/* verify, that all entries are valid */
|
||||
|
||||
for (rp = _HMARelocationTableStart; rp < _HMARelocationTableEnd; rp++)
|
||||
{
|
||||
if (rp->jmpFar != 0xea || /* jmp FAR */
|
||||
rp->jmpSegment != CurrentKernelSegment || /* will only relocate HMA_TEXT */
|
||||
rp->callNear != 0xe8 || /* call NEAR */
|
||||
0)
|
||||
{
|
||||
printf("illegal relocation entry # %d\n",(FP_OFF(rp) - FP_OFF(_HMARelocationTableStart))/sizeof(struct RelocationTable));
|
||||
int3();
|
||||
goto errorReturn;
|
||||
}
|
||||
}
|
||||
|
||||
/* OK, all valid, go to relocate*/
|
||||
|
||||
for (rp = _HMARelocationTableStart; rp < _HMARelocationTableEnd; rp++)
|
||||
{
|
||||
if (NewKernelSegment == 0xffff)
|
||||
{
|
||||
struct RelocatedEntry FAR *rel = (struct RelocatedEntry FAR *)rp;
|
||||
|
||||
fmemcpy(&rtemp, rp, sizeof(rtemp));
|
||||
|
||||
rel->jmpFar = rtemp.jmpFar;
|
||||
rel->jmpSegment = NewKernelSegment;
|
||||
rel->jmpOffset = rtemp.jmpOffset;
|
||||
rel->callNear = rtemp.callNear;
|
||||
rel->callOffset = rtemp.callOffset+5; /* near calls are relative */
|
||||
}
|
||||
else
|
||||
rp->jmpSegment = NewKernelSegment;
|
||||
|
||||
}
|
||||
}
|
||||
{
|
||||
struct initRelocationTable {
|
||||
UBYTE callNear;
|
||||
UWORD callOffset;
|
||||
UBYTE jmpFar;
|
||||
UWORD jmpOffset;
|
||||
UWORD jmpSegment;
|
||||
};
|
||||
extern struct initRelocationTable
|
||||
_HMAinitRelocationTableStart[],
|
||||
_HMAinitRelocationTableEnd[];
|
||||
struct initRelocationTable *rp;
|
||||
|
||||
/* verify, that all entries are valid */
|
||||
|
||||
for (rp = _HMAinitRelocationTableStart; rp < _HMAinitRelocationTableEnd; rp++)
|
||||
{
|
||||
if (
|
||||
rp->callNear != 0xe8 || /* call NEAR */
|
||||
rp->jmpFar != 0xea || /* jmp FAR */
|
||||
rp->jmpSegment != CurrentKernelSegment || /* will only relocate HMA_TEXT */
|
||||
0)
|
||||
{
|
||||
printf("illegal init relocation entry # %d\n",
|
||||
rp - _HMAinitRelocationTableStart);
|
||||
goto errorReturn;
|
||||
}
|
||||
}
|
||||
|
||||
/* OK, all valid, go to relocate*/
|
||||
|
||||
for (rp = _HMAinitRelocationTableStart; rp < _HMAinitRelocationTableEnd; rp++)
|
||||
{
|
||||
rp->jmpSegment = NewKernelSegment;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentKernelSegment = NewKernelSegment;
|
||||
if (CurrentKernelSegment == 0xffff)
|
||||
return;
|
||||
|
||||
|
||||
HMASource =
|
||||
MK_FP(CurrentKernelSegment, (FP_OFF(_HMATextStart) & 0xfff0));
|
||||
HMADest = MK_FP(NewKernelSegment, 0x0000);
|
||||
|
||||
len = (FP_OFF(_HMATextEnd) | 0x000f) - (FP_OFF(_HMATextStart) & 0xfff0);
|
||||
|
||||
if (NewKernelSegment == 0xffff)
|
||||
{
|
||||
HMASource += HMAOFFSET;
|
||||
HMADest += HMAOFFSET;
|
||||
len -= HMAOFFSET;
|
||||
}
|
||||
|
||||
HMAInitPrintf(("HMA moving %p up to %p for %04x bytes\n",
|
||||
HMASource, HMADest, len));
|
||||
|
||||
if (NewKernelSegment < CurrentKernelSegment ||
|
||||
NewKernelSegment == 0xffff)
|
||||
{
|
||||
unsigned i;
|
||||
UBYTE FAR *s, FAR * d;
|
||||
|
||||
for (i = 0, s = HMASource, d = HMADest; i < len; i++)
|
||||
d[i] = s[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* might overlap */
|
||||
unsigned i;
|
||||
UBYTE FAR *s, FAR * d;
|
||||
|
||||
for (i = len, s = HMASource, d = HMADest; i != 0; i--)
|
||||
d[i] = s[i];
|
||||
}
|
||||
|
||||
HMAFree = FP_OFF(HMADest) + len; /* first free byte after HMA_TEXT */
|
||||
|
||||
{
|
||||
/* D) but it only makes sense, if we can relocate
|
||||
all our entries to make use of HMA
|
||||
*/
|
||||
|
||||
/* this is for a
|
||||
call near enableA20
|
||||
jmp far kernelentry
|
||||
style table
|
||||
*/
|
||||
|
||||
struct RelocationTable {
|
||||
UBYTE jmpFar;
|
||||
UWORD jmpOffset;
|
||||
UWORD jmpSegment;
|
||||
UBYTE callNear;
|
||||
UWORD callOffset;
|
||||
};
|
||||
struct RelocatedEntry {
|
||||
UBYTE callNear;
|
||||
UWORD callOffset;
|
||||
UBYTE jmpFar;
|
||||
UWORD jmpOffset;
|
||||
UWORD jmpSegment;
|
||||
};
|
||||
extern struct RelocationTable
|
||||
DOSTEXTFAR _HMARelocationTableStart[],
|
||||
DOSTEXTFAR _HMARelocationTableEnd[];
|
||||
|
||||
struct RelocationTable FAR *rp, rtemp;
|
||||
|
||||
/* verify, that all entries are valid */
|
||||
|
||||
for (rp = _HMARelocationTableStart; rp < _HMARelocationTableEnd; rp++)
|
||||
{
|
||||
if (rp->jmpFar != 0xea || /* jmp FAR */
|
||||
rp->jmpSegment != CurrentKernelSegment || /* will only relocate HMA_TEXT */
|
||||
rp->callNear != 0xe8 || /* call NEAR */
|
||||
0)
|
||||
{
|
||||
printf("illegal relocation entry # %d\n",
|
||||
(FP_OFF(rp) -
|
||||
FP_OFF(_HMARelocationTableStart)) /
|
||||
sizeof(struct RelocationTable));
|
||||
int3();
|
||||
goto errorReturn;
|
||||
}
|
||||
}
|
||||
|
||||
/* OK, all valid, go to relocate */
|
||||
|
||||
for (rp = _HMARelocationTableStart; rp < _HMARelocationTableEnd; rp++)
|
||||
{
|
||||
if (NewKernelSegment == 0xffff)
|
||||
{
|
||||
struct RelocatedEntry FAR *rel = (struct RelocatedEntry FAR *)rp;
|
||||
|
||||
fmemcpy(&rtemp, rp, sizeof(rtemp));
|
||||
|
||||
rel->jmpFar = rtemp.jmpFar;
|
||||
rel->jmpSegment = NewKernelSegment;
|
||||
rel->jmpOffset = rtemp.jmpOffset;
|
||||
rel->callNear = rtemp.callNear;
|
||||
rel->callOffset = rtemp.callOffset + 5; /* near calls are relative */
|
||||
}
|
||||
else
|
||||
rp->jmpSegment = NewKernelSegment;
|
||||
|
||||
}
|
||||
}
|
||||
{
|
||||
struct initRelocationTable {
|
||||
UBYTE callNear;
|
||||
UWORD callOffset;
|
||||
UBYTE jmpFar;
|
||||
UWORD jmpOffset;
|
||||
UWORD jmpSegment;
|
||||
};
|
||||
extern struct initRelocationTable
|
||||
_HMAinitRelocationTableStart[], _HMAinitRelocationTableEnd[];
|
||||
struct initRelocationTable *rp;
|
||||
|
||||
/* verify, that all entries are valid */
|
||||
|
||||
for (rp = _HMAinitRelocationTableStart;
|
||||
rp < _HMAinitRelocationTableEnd; rp++)
|
||||
{
|
||||
if (rp->callNear != 0xe8 || /* call NEAR */
|
||||
rp->jmpFar != 0xea || /* jmp FAR */
|
||||
rp->jmpSegment != CurrentKernelSegment || /* will only relocate HMA_TEXT */
|
||||
0)
|
||||
{
|
||||
printf("illegal init relocation entry # %d\n",
|
||||
rp - _HMAinitRelocationTableStart);
|
||||
goto errorReturn;
|
||||
}
|
||||
}
|
||||
|
||||
/* OK, all valid, go to relocate */
|
||||
|
||||
for (rp = _HMAinitRelocationTableStart;
|
||||
rp < _HMAinitRelocationTableEnd; rp++)
|
||||
{
|
||||
rp->jmpSegment = NewKernelSegment;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentKernelSegment = NewKernelSegment;
|
||||
return;
|
||||
|
||||
errorReturn:
|
||||
for (;;);
|
||||
for (;;) ;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,8 @@
|
||||
#include "init-mod.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId = "$Id$";
|
||||
static BYTE *RcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
UWORD init_oem(void)
|
||||
@ -42,7 +43,7 @@ UWORD init_oem(void)
|
||||
asm
|
||||
{
|
||||
int 0x12;
|
||||
mov top_k,ax;
|
||||
mov top_k, ax;
|
||||
}
|
||||
#else
|
||||
__int__(0x12);
|
||||
@ -94,4 +95,3 @@ UWORD init_oem(void)
|
||||
* Rev 1.0 02 Jul 1995 8:31:54 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
1304
kernel/inthndlr.c
1304
kernel/inthndlr.c
File diff suppressed because it is too large
Load Diff
@ -2,8 +2,8 @@
|
||||
*/
|
||||
|
||||
struct REGPACK {
|
||||
unsigned r_ax, r_bx, r_cx, r_dx;
|
||||
unsigned r_bp, r_di, r_si, r_ds, r_es, r_flags;
|
||||
unsigned r_ax, r_bx, r_cx, r_dx;
|
||||
unsigned r_bp, r_di, r_si, r_ds, r_es, r_flags;
|
||||
};
|
||||
|
||||
extern void ASMCFUNC intr(int intrnr, struct REGPACK *rp);
|
||||
|
165
kernel/ioctl.c
165
kernel/ioctl.c
@ -30,7 +30,8 @@
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId = "$Id$";
|
||||
static BYTE *RcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -53,21 +54,18 @@ static BYTE *RcsId = "$Id$";
|
||||
|
||||
*/
|
||||
|
||||
|
||||
COUNT DosDevIOctl(iregs FAR * r)
|
||||
{
|
||||
sft FAR *s;
|
||||
struct dpb FAR *dpbp;
|
||||
COUNT nMode;
|
||||
|
||||
/* commonly used, shouldn't harm to do front up */
|
||||
/* commonly used, shouldn't harm to do front up */
|
||||
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
CharReqHdr.r_trans = MK_FP(r->DS, r->DX);
|
||||
CharReqHdr.r_trans = MK_FP(r->DS, r->DX);
|
||||
CharReqHdr.r_status = 0;
|
||||
CharReqHdr.r_count = r->CX;
|
||||
|
||||
|
||||
CharReqHdr.r_count = r->CX;
|
||||
|
||||
/* Test that the handle is valid */
|
||||
switch (r->AL)
|
||||
@ -106,7 +104,7 @@ COUNT DosDevIOctl(iregs FAR * r)
|
||||
/* JPP - changed to use default drive if drive=0 */
|
||||
/* JT Fixed it */
|
||||
|
||||
CharReqHdr.r_unit = ( r->BL == 0 ? default_drive : r->BL - 1);
|
||||
CharReqHdr.r_unit = (r->BL == 0 ? default_drive : r->BL - 1);
|
||||
|
||||
if (CharReqHdr.r_unit >= lastdrive)
|
||||
return DE_INVLDDRV;
|
||||
@ -133,12 +131,12 @@ COUNT DosDevIOctl(iregs FAR * r)
|
||||
{
|
||||
case 0x00:
|
||||
/* Get the flags from the SFT */
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
r->AX = (s->sft_dev->dh_attr & 0xff00) | s->sft_flags_lo;
|
||||
else
|
||||
r->AX = s->sft_flags;
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
r->AX = (s->sft_dev->dh_attr & 0xff00) | s->sft_flags_lo;
|
||||
else
|
||||
r->AX = s->sft_flags;
|
||||
/* Undocumented result, Ax = Dx seen using Pcwatch */
|
||||
r->DX = r->AX;
|
||||
r->DX = r->AX;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
@ -165,36 +163,36 @@ COUNT DosDevIOctl(iregs FAR * r)
|
||||
nMode = C_IOCTLOUT;
|
||||
IoCharCommon:
|
||||
if ((s->sft_flags & SFT_FDEVICE)
|
||||
|| ((r->AL == 0x02 ) && (s->sft_dev->dh_attr & SFT_FIOCTL))
|
||||
|| ((r->AL == 0x03 ) && (s->sft_dev->dh_attr & SFT_FIOCTL))
|
||||
|| ((r->AL == 0x10) && (s->sft_dev->dh_attr & ATTR_QRYIOCTL))
|
||||
|| ((r->AL == 0x0c) && (s->sft_dev->dh_attr & ATTR_GENIOCTL)))
|
||||
|| ((r->AL == 0x02) && (s->sft_dev->dh_attr & SFT_FIOCTL))
|
||||
|| ((r->AL == 0x03) && (s->sft_dev->dh_attr & SFT_FIOCTL))
|
||||
|| ((r->AL == 0x10) && (s->sft_dev->dh_attr & ATTR_QRYIOCTL))
|
||||
|| ((r->AL == 0x0c) && (s->sft_dev->dh_attr & ATTR_GENIOCTL)))
|
||||
{
|
||||
CharReqHdr.r_unit = 0;
|
||||
CharReqHdr.r_command = nMode;
|
||||
execrh((request FAR *) & CharReqHdr, s->sft_dev);
|
||||
CharReqHdr.r_unit = 0;
|
||||
CharReqHdr.r_command = nMode;
|
||||
execrh((request FAR *) & CharReqHdr, s->sft_dev);
|
||||
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
|
||||
return DE_DEVICE;
|
||||
}
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
|
||||
return DE_DEVICE;
|
||||
}
|
||||
|
||||
if (r->AL == 0x07)
|
||||
{
|
||||
r->AL = CharReqHdr.r_status & S_BUSY ? 00 : 0xff;
|
||||
if (r->AL == 0x07)
|
||||
{
|
||||
r->AL = CharReqHdr.r_status & S_BUSY ? 00 : 0xff;
|
||||
|
||||
}
|
||||
else if (r->AL == 0x02 || r->AL == 0x03)
|
||||
{
|
||||
r->AX = CharReqHdr.r_count;
|
||||
}
|
||||
}
|
||||
else if (r->AL == 0x02 || r->AL == 0x03)
|
||||
{
|
||||
r->AX = CharReqHdr.r_count;
|
||||
}
|
||||
|
||||
else if (r->AL == 0x0c || r->AL == 0x10)
|
||||
{
|
||||
r->AX = CharReqHdr.r_status;
|
||||
}
|
||||
break;
|
||||
else if (r->AL == 0x0c || r->AL == 0x10)
|
||||
{
|
||||
r->AX = CharReqHdr.r_status;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return DE_INVLDFUNC;
|
||||
|
||||
@ -210,44 +208,44 @@ COUNT DosDevIOctl(iregs FAR * r)
|
||||
case 0x05:
|
||||
nMode = C_IOCTLOUT;
|
||||
IoBlockCommon:
|
||||
if(!dpbp)
|
||||
if (!dpbp)
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
if ( ((r->AL == 0x04 ) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
|
||||
|| ((r->AL == 0x05 ) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
|
||||
|| ((r->AL == 0x11) && !(dpbp->dpb_device->dh_attr & ATTR_QRYIOCTL))
|
||||
|| ((r->AL == 0x0d) && !(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL)))
|
||||
if (((r->AL == 0x04) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
|
||||
|| ((r->AL == 0x05) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
|
||||
|| ((r->AL == 0x11)
|
||||
&& !(dpbp->dpb_device->dh_attr & ATTR_QRYIOCTL))
|
||||
|| ((r->AL == 0x0d)
|
||||
&& !(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL)))
|
||||
{
|
||||
return DE_INVLDFUNC;
|
||||
}
|
||||
|
||||
|
||||
CharReqHdr.r_command = nMode;
|
||||
execrh((request FAR *) & CharReqHdr,
|
||||
dpbp->dpb_device);
|
||||
execrh((request FAR *) & CharReqHdr, dpbp->dpb_device);
|
||||
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
|
||||
return DE_DEVICE;
|
||||
}
|
||||
if (r->AL == 0x08)
|
||||
{
|
||||
r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
|
||||
return DE_DEVICE;
|
||||
}
|
||||
if (r->AL == 0x08)
|
||||
{
|
||||
r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
else if (r->AL == 0x04 || r->AL == 0x05)
|
||||
{
|
||||
r->AX = CharReqHdr.r_count;
|
||||
else if (r->AL == 0x04 || r->AL == 0x05)
|
||||
{
|
||||
r->AX = CharReqHdr.r_count;
|
||||
|
||||
}
|
||||
else if (r->AL == 0x0d || r->AL == 0x11)
|
||||
{
|
||||
r->AX = CharReqHdr.r_status;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (r->AL == 0x0d || r->AL == 0x11)
|
||||
{
|
||||
r->AX = CharReqHdr.r_status;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
@ -268,7 +266,7 @@ COUNT DosDevIOctl(iregs FAR * r)
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
if(!dpbp)
|
||||
if (!dpbp)
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
@ -280,21 +278,21 @@ COUNT DosDevIOctl(iregs FAR * r)
|
||||
return DE_INVLDFUNC;
|
||||
|
||||
case 0x09:
|
||||
if(CDSp->cds_table[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV)
|
||||
if (CDSp->cds_table[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
r->DX = ATTR_REMOTE;
|
||||
r->AX = S_DONE | S_BUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!dpbp)
|
||||
{
|
||||
r->DX = ATTR_REMOTE ;
|
||||
r->AX = S_DONE|S_BUSY;
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!dpbp)
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
/* Need to add subst bit 15 */
|
||||
r->DX = dpbp->dpb_device->dh_attr;
|
||||
r->AX = S_DONE|S_BUSY;
|
||||
}
|
||||
r->DX = dpbp->dpb_device->dh_attr;
|
||||
r->AX = S_DONE | S_BUSY;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0a:
|
||||
@ -308,17 +306,15 @@ COUNT DosDevIOctl(iregs FAR * r)
|
||||
case 0x0f:
|
||||
nMode = C_SETLDEV;
|
||||
IoLogCommon:
|
||||
if(!dpbp)
|
||||
if (!dpbp)
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
if ((dpbp->dpb_device->dh_attr & ATTR_GENIOCTL))
|
||||
{
|
||||
|
||||
|
||||
CharReqHdr.r_command = nMode;
|
||||
execrh((request FAR *) & CharReqHdr,
|
||||
dpbp->dpb_device);
|
||||
execrh((request FAR *) & CharReqHdr, dpbp->dpb_device);
|
||||
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
@ -327,8 +323,8 @@ COUNT DosDevIOctl(iregs FAR * r)
|
||||
}
|
||||
else
|
||||
{
|
||||
r->AL = CharReqHdr.r_unit;
|
||||
return SUCCESS;
|
||||
r->AL = CharReqHdr.r_unit;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
return DE_INVLDFUNC;
|
||||
@ -391,6 +387,3 @@ COUNT DosDevIOctl(iregs FAR * r)
|
||||
* Rev 1.0 02 Jul 1995 8:32:04 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
227
kernel/lfnapi.c
227
kernel/lfnapi.c
@ -10,7 +10,8 @@
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *lfnaidRcsId = "$Id$";
|
||||
static BYTE *lfnaidRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#ifdef WITHLFNAPI
|
||||
@ -27,7 +28,7 @@ static BYTE *lfnaidRcsId = "$Id$";
|
||||
#define CHARS_IN_LFN_ENTRY 13
|
||||
#define UNICODE_FILLER 0xffff
|
||||
|
||||
COUNT ufstrlen(REG UNICODE FAR *); /* fstrlen for UNICODE strings */
|
||||
COUNT ufstrlen(REG UNICODE FAR *); /* fstrlen for UNICODE strings */
|
||||
UBYTE lfn_checksum(UBYTE *);
|
||||
COUNT extend_dir(f_node_ptr);
|
||||
COUNT remove_lfn_entries(f_node_ptr fnp);
|
||||
@ -36,23 +37,24 @@ COUNT lfn_allocate_inode(VOID)
|
||||
{
|
||||
f_node_ptr fnp = get_f_node();
|
||||
struct cds FAR *cdsp;
|
||||
if (fnp == 0) return LHE_NOFREEHNDL;
|
||||
if (fnp == 0)
|
||||
return LHE_NOFREEHNDL;
|
||||
|
||||
cdsp = &CDSp->cds_table[default_drive];
|
||||
|
||||
if (cdsp->cdsDpb == 0)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return LHE_INVLDDRV;
|
||||
}
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return LHE_INVLDDRV;
|
||||
}
|
||||
|
||||
fnp->f_dpb = cdsp->cdsDpb;
|
||||
|
||||
if (media_check(fnp->f_dpb) < 0)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return LHE_INVLDDRV;
|
||||
}
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return LHE_INVLDDRV;
|
||||
}
|
||||
|
||||
return xlt_fnp(fnp);
|
||||
}
|
||||
@ -60,7 +62,8 @@ COUNT lfn_allocate_inode(VOID)
|
||||
COUNT lfn_free_inode(COUNT handle)
|
||||
{
|
||||
f_node_ptr fnp = xlt_fd(handle);
|
||||
if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL;
|
||||
if (fnp == 0 || fnp->f_count <= 0)
|
||||
return LHE_INVLDHNDL;
|
||||
|
||||
release_f_node(fnp);
|
||||
|
||||
@ -70,7 +73,8 @@ COUNT lfn_free_inode(COUNT handle)
|
||||
COUNT lfn_setup_inode(COUNT handle, CLUSTER dirstart, ULONG diroff)
|
||||
{
|
||||
f_node_ptr fnp = xlt_fd(handle);
|
||||
if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL;
|
||||
if (fnp == 0 || fnp->f_count <= 0)
|
||||
return LHE_INVLDHNDL;
|
||||
|
||||
dir_init_fnode(fnp, dirstart);
|
||||
fnp->f_diroff = diroff;
|
||||
@ -78,39 +82,46 @@ COUNT lfn_setup_inode(COUNT handle, CLUSTER dirstart, ULONG diroff)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
BOOL transfer_unicode(UNICODE FAR **dptr, UNICODE FAR **sptr, COUNT count)
|
||||
BOOL transfer_unicode(UNICODE FAR ** dptr, UNICODE FAR ** sptr,
|
||||
COUNT count)
|
||||
{
|
||||
COUNT j;
|
||||
BOOL found_zerro = FALSE;
|
||||
|
||||
for (j = 0; j < count; j++, (*dptr)++, (*sptr)++)
|
||||
{
|
||||
if (found_zerro) **dptr = UNICODE_FILLER;
|
||||
else **dptr = **sptr;
|
||||
if (**sptr == 0) found_zerro = TRUE;
|
||||
}
|
||||
{
|
||||
if (found_zerro)
|
||||
**dptr = UNICODE_FILLER;
|
||||
else
|
||||
**dptr = **sptr;
|
||||
if (**sptr == 0)
|
||||
found_zerro = TRUE;
|
||||
}
|
||||
|
||||
return found_zerro;
|
||||
}
|
||||
|
||||
BOOL lfn_to_unicode(UNICODE FAR **name, struct lfn_entry FAR *lep)
|
||||
BOOL lfn_to_unicode(UNICODE FAR ** name, struct lfn_entry FAR * lep)
|
||||
{
|
||||
UNICODE FAR *ptr;
|
||||
|
||||
|
||||
ptr = lep->lfn_name0_4;
|
||||
if (!transfer_unicode(name, &ptr, 5)) return FALSE;
|
||||
if (!transfer_unicode(name, &ptr, 5))
|
||||
return FALSE;
|
||||
ptr = lep->lfn_name5_10;
|
||||
if (!transfer_unicode(name, &ptr, 6)) return FALSE;
|
||||
if (!transfer_unicode(name, &ptr, 6))
|
||||
return FALSE;
|
||||
ptr = lep->lfn_name11_12;
|
||||
if (!transfer_unicode(name, &ptr, 2)) return FALSE;
|
||||
if (!transfer_unicode(name, &ptr, 2))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID unicode_to_lfn(UNICODE FAR **name, struct lfn_entry FAR *lep)
|
||||
VOID unicode_to_lfn(UNICODE FAR ** name, struct lfn_entry FAR * lep)
|
||||
{
|
||||
UNICODE FAR *ptr;
|
||||
|
||||
|
||||
ptr = lep->lfn_name0_4;
|
||||
transfer_unicode(&ptr, name, 5);
|
||||
ptr = lep->lfn_name5_10;
|
||||
@ -127,45 +138,54 @@ COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip)
|
||||
ULONG sfn_diroff;
|
||||
BOOL name_tail = FALSE;
|
||||
f_node_ptr fnp = xlt_fd(handle);
|
||||
if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL;
|
||||
if (fnp == 0 || fnp->f_count <= 0)
|
||||
return LHE_INVLDHNDL;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
rc = dir_read(fnp);
|
||||
if (rc == 0)
|
||||
return SUCCESS;
|
||||
else if (rc == DE_SEEK)
|
||||
return LHE_SEEK;
|
||||
else if (rc == DE_BLKINVLD)
|
||||
return LHE_IOERROR;
|
||||
if (fnp->f_dir.dir_name[0] != DELETED
|
||||
&& fnp->f_dir.dir_attrib != D_LFN)
|
||||
{
|
||||
rc = dir_read(fnp);
|
||||
if (rc == 0) return SUCCESS;
|
||||
else if (rc == DE_SEEK) return LHE_SEEK;
|
||||
else if (rc == DE_BLKINVLD) return LHE_IOERROR;
|
||||
if (fnp->f_dir.dir_name[0] != DELETED && fnp->f_dir.dir_attrib != D_LFN)
|
||||
{
|
||||
fmemcpy(&lip->l_dir, &fnp->f_dir, sizeof(struct dirent));
|
||||
sfn_diroff = fnp->f_diroff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fmemcpy(&lip->l_dir, &fnp->f_dir, sizeof(struct dirent));
|
||||
sfn_diroff = fnp->f_diroff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fnp->f_diroff = lip->l_diroff;
|
||||
|
||||
fmemset(lip->name, 0, 256 * sizeof(UNICODE));
|
||||
while (TRUE)
|
||||
{
|
||||
if (fnp->f_diroff == 0)
|
||||
break;
|
||||
fnp->f_diroff -= 2 * DIRENT_SIZE;
|
||||
rc = dir_read(fnp);
|
||||
if (rc == DE_BLKINVLD)
|
||||
return LHE_IOERROR;
|
||||
if (fnp->f_dir.dir_name[0] == DELETED
|
||||
|| fnp->f_dir.dir_attrib != D_LFN)
|
||||
break;
|
||||
name_tail = lfn_to_unicode(&lfn_name, lfn(fnp));
|
||||
real_id = lfn(fnp)->lfn_id;
|
||||
if (real_id & 0x40)
|
||||
{
|
||||
if (fnp->f_diroff == 0) break;
|
||||
fnp->f_diroff -= 2*DIRENT_SIZE;
|
||||
rc = dir_read(fnp);
|
||||
if (rc == DE_BLKINVLD) return LHE_IOERROR;
|
||||
if (fnp->f_dir.dir_name[0] == DELETED
|
||||
|| fnp->f_dir.dir_attrib != D_LFN) break;
|
||||
name_tail = lfn_to_unicode(&lfn_name, lfn(fnp));
|
||||
real_id = lfn(fnp)->lfn_id;
|
||||
if (real_id & 0x40)
|
||||
{
|
||||
if ((real_id | 0x40) != id) return LHE_DAMAGEDFS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (name_tail || real_id != id
|
||||
|| lfn(fnp)->lfn_checksum != lfn_checksum(fnp->f_dir.dir_name))
|
||||
return LHE_DAMAGEDFS;
|
||||
}
|
||||
if ((real_id | 0x40) != id)
|
||||
return LHE_DAMAGEDFS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (name_tail || real_id != id
|
||||
|| lfn(fnp)->lfn_checksum != lfn_checksum(fnp->f_dir.dir_name))
|
||||
return LHE_DAMAGEDFS;
|
||||
}
|
||||
}
|
||||
|
||||
fnp->f_diroff = lip->l_diroff = sfn_diroff;
|
||||
fnp->f_flags.f_dnew = TRUE;
|
||||
@ -176,16 +196,17 @@ COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip)
|
||||
COUNT lfn_dir_write(COUNT handle)
|
||||
{
|
||||
f_node_ptr fnp = xlt_fd(handle);
|
||||
if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL;
|
||||
if (fnp == 0 || fnp->f_count <= 0)
|
||||
return LHE_INVLDHNDL;
|
||||
|
||||
if (!dir_write(fnp))
|
||||
{
|
||||
lfn_allocate_inode(); /* protection against dir_write fault
|
||||
* this must restore things to the state before
|
||||
* the call */
|
||||
/* Yes, it's a hack! */
|
||||
return LHE_IOERROR;
|
||||
}
|
||||
{
|
||||
lfn_allocate_inode(); /* protection against dir_write fault
|
||||
* this must restore things to the state before
|
||||
* the call */
|
||||
/* Yes, it's a hack! */
|
||||
return LHE_IOERROR;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -196,52 +217,58 @@ COUNT lfn_create_entries(COUNT handle, lfn_inode_ptr lip)
|
||||
COUNT entries_needed, free_entries, i, rc;
|
||||
UNICODE FAR *lfn_name = lip->name;
|
||||
ULONG sfn_offset;
|
||||
if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL;
|
||||
if (fnp == 0 || fnp->f_count <= 0)
|
||||
return LHE_INVLDHNDL;
|
||||
|
||||
entries_needed = (ufstrlen(lfn_name) + CHARS_IN_LFN_ENTRY - 1) / CHARS_IN_LFN_ENTRY + 1; /* We want to create SFN entry too */
|
||||
|
||||
entries_needed = (ufstrlen(lfn_name) + CHARS_IN_LFN_ENTRY - 1)
|
||||
/ CHARS_IN_LFN_ENTRY + 1; /* We want to create SFN entry too */
|
||||
|
||||
/* Scan the directory from the very begining for the free directory entries */
|
||||
lfn_setup_inode(handle, fnp->f_dirstart, 0);
|
||||
|
||||
free_entries = 0;
|
||||
while ((rc = dir_read(fnp)) == 1)
|
||||
{
|
||||
if (fnp->f_dir.dir_name[0] == DELETED)
|
||||
{
|
||||
if (fnp->f_dir.dir_name[0] == DELETED)
|
||||
{
|
||||
free_entries++;
|
||||
if (free_entries == entries_needed)
|
||||
break;
|
||||
}
|
||||
else free_entries = 0;
|
||||
free_entries++;
|
||||
if (free_entries == entries_needed)
|
||||
break;
|
||||
}
|
||||
if (rc == DE_BLKINVLD) return LHE_IOERROR;
|
||||
else
|
||||
free_entries = 0;
|
||||
}
|
||||
if (rc == DE_BLKINVLD)
|
||||
return LHE_IOERROR;
|
||||
/* We have reached the end of the directory here. */
|
||||
|
||||
if (free_entries != entries_needed) free_entries = 0;
|
||||
|
||||
if (free_entries != entries_needed)
|
||||
free_entries = 0;
|
||||
while (free_entries != entries_needed)
|
||||
{
|
||||
rc = dir_read(fnp);
|
||||
if (rc == 0)
|
||||
free_entries++;
|
||||
else if (rc == DE_BLKINVLD)
|
||||
return LHE_IOERROR;
|
||||
else if (rc == DE_SEEK && extend_dir(fnp) != SUCCESS)
|
||||
{
|
||||
rc = dir_read(fnp);
|
||||
if (rc == 0) free_entries++;
|
||||
else if (rc == DE_BLKINVLD) return LHE_IOERROR;
|
||||
else if (rc == DE_SEEK && extend_dir(fnp) != SUCCESS)
|
||||
{
|
||||
lfn_allocate_inode(); /* Another hack. */
|
||||
return LHE_IOERROR;
|
||||
}
|
||||
lfn_allocate_inode(); /* Another hack. */
|
||||
return LHE_IOERROR;
|
||||
}
|
||||
}
|
||||
sfn_offset = fnp->f_diroff;
|
||||
fnp->f_diroff -= DIRENT_SIZE;
|
||||
|
||||
for (i = entries_needed - 2; i >= 0; i++)
|
||||
{
|
||||
lfn_name = &lip->name[i * CHARS_IN_LFN_ENTRY];
|
||||
unicode_to_lfn(&lfn_name, lfn(fnp));
|
||||
fnp->f_dir.dir_attrib = D_LFN;
|
||||
if (!dir_write(fnp)) return LHE_IOERROR;
|
||||
fnp->f_diroff -= DIRENT_SIZE;
|
||||
}
|
||||
|
||||
{
|
||||
lfn_name = &lip->name[i * CHARS_IN_LFN_ENTRY];
|
||||
unicode_to_lfn(&lfn_name, lfn(fnp));
|
||||
fnp->f_dir.dir_attrib = D_LFN;
|
||||
if (!dir_write(fnp))
|
||||
return LHE_IOERROR;
|
||||
fnp->f_diroff -= DIRENT_SIZE;
|
||||
}
|
||||
|
||||
fnp->f_diroff = sfn_offset;
|
||||
|
||||
return SUCCESS;
|
||||
@ -250,15 +277,17 @@ COUNT lfn_create_entries(COUNT handle, lfn_inode_ptr lip)
|
||||
COUNT lfn_remove_entries(COUNT handle)
|
||||
{
|
||||
f_node_ptr fnp = xlt_fd(handle);
|
||||
if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL;
|
||||
if (fnp == 0 || fnp->f_count <= 0)
|
||||
return LHE_INVLDHNDL;
|
||||
|
||||
if (remove_lfn_entries(fnp) < 0)
|
||||
return LHE_IOERROR;
|
||||
|
||||
if(remove_lfn_entries(fnp) < 0) return LHE_IOERROR;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Calculate checksum for the 8.3 name */
|
||||
UBYTE lfn_checksum(UBYTE *sfn_name)
|
||||
UBYTE lfn_checksum(UBYTE * sfn_name)
|
||||
{
|
||||
UBYTE sum;
|
||||
COUNT i;
|
||||
@ -269,7 +298,7 @@ UBYTE lfn_checksum(UBYTE *sfn_name)
|
||||
return sum;
|
||||
}
|
||||
|
||||
COUNT ufstrlen(REG UNICODE FAR *s)
|
||||
COUNT ufstrlen(REG UNICODE FAR * s)
|
||||
{
|
||||
REG COUNT cnt = 0;
|
||||
|
||||
|
331
kernel/main.c
331
kernel/main.c
@ -30,16 +30,15 @@
|
||||
#include "portab.h"
|
||||
#include "init-mod.h"
|
||||
#include "dyndata.h"
|
||||
#include "init-dat.h"
|
||||
#include "init-dat.h"
|
||||
|
||||
GLOBAL BYTE copyright[] =
|
||||
GLOBAL BYTE copyright[] =
|
||||
"(C) Copyright 1995-2001 Pasquale J. Villani and The FreeDOS Project.\n"
|
||||
"All Rights Reserved. This is free software and comes with ABSOLUTELY NO\n"
|
||||
"WARRANTY; you can redistribute it and/or modify it under the terms of the\n"
|
||||
"GNU General Public License as published by the Free Software Foundation;\n"
|
||||
"either version 2, or (at your option) any later version.\n";
|
||||
|
||||
|
||||
/*
|
||||
These are the far variables from the DOS data segment that we need here. The
|
||||
init procedure uses a different default DS data segment, which is discarded
|
||||
@ -48,45 +47,41 @@ GLOBAL BYTE copyright[] =
|
||||
|
||||
-- Bart
|
||||
*/
|
||||
extern UBYTE DOSFAR nblkdev,
|
||||
DOSFAR lastdrive; /* value of last drive */
|
||||
extern UBYTE DOSFAR nblkdev, DOSFAR lastdrive; /* value of last drive */
|
||||
|
||||
GLOBAL BYTE
|
||||
DOSFAR os_major, /* major version number */
|
||||
DOSFAR os_minor, /* minor version number */
|
||||
DOSFAR dosidle_flag,
|
||||
DOSFAR BootDrive, /* Drive we came up from */
|
||||
DOSFAR default_drive; /* default drive for dos */
|
||||
GLOBAL BYTE DOSFAR os_major, /* major version number */
|
||||
DOSFAR os_minor, /* minor version number */
|
||||
DOSFAR dosidle_flag, DOSFAR BootDrive, /* Drive we came up from */
|
||||
DOSFAR default_drive; /* default drive for dos */
|
||||
|
||||
GLOBAL BYTE DOSFAR os_release[];
|
||||
/* GLOBAL BYTE DOSFAR copyright[]; */
|
||||
GLOBAL seg DOSFAR RootPsp; /* Root process -- do not abort */
|
||||
GLOBAL seg DOSFAR RootPsp; /* Root process -- do not abort */
|
||||
|
||||
extern struct dpb FAR * DOSFAR DPBp; /* First drive Parameter Block */
|
||||
extern cdstbl FAR * DOSFAR CDSp; /* Current Directory Structure */
|
||||
extern struct dpb FAR *DOSFAR DPBp; /* First drive Parameter Block */
|
||||
extern cdstbl FAR *DOSFAR CDSp; /* Current Directory Structure */
|
||||
|
||||
extern struct dhdr FAR * DOSFAR clock, /* CLOCK$ device */
|
||||
FAR * DOSFAR syscon; /* console device */
|
||||
extern struct dhdr DOSTEXTFAR con_dev, /* console device drive */
|
||||
DOSTEXTFAR clk_dev, /* Clock device driver */
|
||||
DOSTEXTFAR blk_dev; /* Block device (Disk) driver */
|
||||
extern UWORD
|
||||
DOSFAR ram_top; /* How much ram in Kbytes */
|
||||
extern iregs FAR * DOSFAR user_r; /* User registers for int 21h call */
|
||||
extern struct dhdr FAR *DOSFAR clock, /* CLOCK$ device */
|
||||
FAR * DOSFAR syscon; /* console device */
|
||||
extern struct dhdr DOSTEXTFAR con_dev, /* console device drive */
|
||||
DOSTEXTFAR clk_dev, /* Clock device driver */
|
||||
DOSTEXTFAR blk_dev; /* Block device (Disk) driver */
|
||||
extern UWORD DOSFAR ram_top; /* How much ram in Kbytes */
|
||||
extern iregs FAR *DOSFAR user_r; /* User registers for int 21h call */
|
||||
extern BYTE FAR _HMATextEnd[];
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *mainRcsId = "$Id$";
|
||||
static BYTE *mainRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
struct _KernelConfig InitKernelConfig = {"", 0, 0, 0, 0, 0, 0};
|
||||
|
||||
struct _KernelConfig InitKernelConfig = { "", 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
extern WORD days[2][13];
|
||||
extern BYTE FAR * lpBase;
|
||||
extern BYTE FAR * lpOldTop;
|
||||
extern BYTE FAR * lpTop;
|
||||
extern BYTE FAR * upBase;
|
||||
extern BYTE FAR *lpBase;
|
||||
extern BYTE FAR *lpOldTop;
|
||||
extern BYTE FAR *lpTop;
|
||||
extern BYTE FAR *upBase;
|
||||
extern BYTE _ib_start[], _ib_end[], _init_end[];
|
||||
|
||||
INIT VOID configDone(VOID);
|
||||
@ -100,38 +95,36 @@ INIT VOID FsConfig(VOID);
|
||||
INIT VOID InitPrinters(VOID);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
BYTE _acrtused = 0;
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__segment DosDataSeg = 0; /* serves for all references to the DOS DATA segment
|
||||
necessary for MSC+our funny linking model
|
||||
*/
|
||||
__segment DosTextSeg = 0;
|
||||
|
||||
BYTE _acrtused = 0;
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__segment DosDataSeg = 0; /* serves for all references to the DOS DATA segment
|
||||
necessary for MSC+our funny linking model
|
||||
*/
|
||||
__segment DosTextSeg = 0;
|
||||
|
||||
#endif
|
||||
|
||||
INIT VOID ASMCFUNC FreeDOSmain(void)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
extern FAR DATASTART;
|
||||
extern FAR prn_dev;
|
||||
DosDataSeg = (__segment)&DATASTART;
|
||||
DosTextSeg = (__segment)&prn_dev;
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
extern FAR DATASTART;
|
||||
extern FAR prn_dev;
|
||||
DosDataSeg = (__segment) & DATASTART;
|
||||
DosTextSeg = (__segment) & prn_dev;
|
||||
#endif
|
||||
|
||||
fmemcpy(&InitKernelConfig,&LowKernelConfig,sizeof(InitKernelConfig));
|
||||
fmemcpy(&InitKernelConfig, &LowKernelConfig, sizeof(InitKernelConfig));
|
||||
|
||||
setvec(0, int0_handler); /* zero divide */
|
||||
setvec(1, empty_handler); /* single step */
|
||||
setvec(3, empty_handler); /* debug breakpoint */
|
||||
setvec(6, empty_handler); /* invalid opcode */
|
||||
|
||||
/* clear the Init BSS area (what normally the RTL does */
|
||||
memset(_ib_start, 0, _ib_end - _ib_start);
|
||||
|
||||
|
||||
setvec(0, int0_handler); /* zero divide */
|
||||
setvec(1, empty_handler); /* single step */
|
||||
setvec(3, empty_handler); /* debug breakpoint */
|
||||
setvec(6, empty_handler); /* invalid opcode */
|
||||
|
||||
/* clear the Init BSS area (what normally the RTL does */
|
||||
memset(_ib_start, 0, _ib_end - _ib_start);
|
||||
|
||||
init_kernel();
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -155,19 +148,19 @@ INIT VOID ASMCFUNC FreeDOSmain(void)
|
||||
void InitializeAllBPBs(VOID)
|
||||
{
|
||||
static char filename[] = "A:-@JUNK@-.TMP";
|
||||
int drive,fileno;
|
||||
for (drive = 'C'; drive < 'A'+nblkdev; drive++)
|
||||
{
|
||||
filename[0] = drive;
|
||||
if ((fileno = open(filename, O_RDONLY)) >= 0)
|
||||
close(fileno);
|
||||
}
|
||||
}
|
||||
int drive, fileno;
|
||||
for (drive = 'C'; drive < 'A' + nblkdev; drive++)
|
||||
{
|
||||
filename[0] = drive;
|
||||
if ((fileno = open(filename, O_RDONLY)) >= 0)
|
||||
close(fileno);
|
||||
}
|
||||
}
|
||||
|
||||
INIT void init_kernel(void)
|
||||
{
|
||||
COUNT i;
|
||||
|
||||
|
||||
os_major = MAJOR_RELEASE;
|
||||
os_minor = MINOR_RELEASE;
|
||||
|
||||
@ -175,14 +168,14 @@ INIT void init_kernel(void)
|
||||
ram_top = init_oem();
|
||||
|
||||
/* move kernel to high conventional RAM, just below the init code */
|
||||
lpTop = MK_FP(ram_top * 64 - (FP_OFF(_init_end)+15)/16 -
|
||||
(FP_OFF(_HMATextEnd)+15)/16, 0);
|
||||
|
||||
lpTop = MK_FP(ram_top * 64 - (FP_OFF(_init_end) + 15) / 16 -
|
||||
(FP_OFF(_HMATextEnd) + 15) / 16, 0);
|
||||
|
||||
MoveKernel(FP_SEG(lpTop));
|
||||
lpOldTop = lpTop = MK_FP(FP_SEG(lpTop) - 0xfff, 0xfff0);
|
||||
|
||||
/* Fake int 21h stack frame */
|
||||
user_r = (iregs FAR *) MK_FP(DOS_PSP,0xD0);
|
||||
user_r = (iregs FAR *) MK_FP(DOS_PSP, 0xD0);
|
||||
|
||||
#ifndef KDB
|
||||
for (i = 0x20; i <= 0x3f; i++)
|
||||
@ -223,7 +216,7 @@ INIT void init_kernel(void)
|
||||
|
||||
/* Number of units */
|
||||
if (blk_dev.dh_name[0] > 0)
|
||||
update_dcb(&blk_dev);
|
||||
update_dcb(&blk_dev);
|
||||
|
||||
/* Now config the temporary file system */
|
||||
FsConfig();
|
||||
@ -235,7 +228,7 @@ INIT void init_kernel(void)
|
||||
/* Close all (device) files */
|
||||
for (i = 0; i < lastdrive; i++)
|
||||
close(i);
|
||||
|
||||
|
||||
/* and do final buffer allocation. */
|
||||
PostConfig();
|
||||
nblkdev = 0;
|
||||
@ -251,7 +244,7 @@ INIT void init_kernel(void)
|
||||
/* Close all (device) files */
|
||||
for (i = 0; i < lastdrive; i++)
|
||||
close(i);
|
||||
|
||||
|
||||
/* Now config the final file system */
|
||||
FsConfig();
|
||||
|
||||
@ -274,7 +267,7 @@ INIT VOID FsConfig(VOID)
|
||||
dup2(STDIN, STDOUT);
|
||||
|
||||
/* 2 is /dev/con (stderr) */
|
||||
dup2(STDIN, STDERR);
|
||||
dup2(STDIN, STDERR);
|
||||
|
||||
/* 3 is /dev/aux */
|
||||
open("AUX", O_RDWR);
|
||||
@ -288,15 +281,15 @@ INIT VOID FsConfig(VOID)
|
||||
dpb = DPBp;
|
||||
|
||||
/* Initialize the current directory structures */
|
||||
for (i = 0; i < lastdrive ; i++)
|
||||
for (i = 0; i < lastdrive; i++)
|
||||
{
|
||||
struct cds FAR *pcds_table = &CDSp->cds_table[i];
|
||||
struct cds FAR *pcds_table = &CDSp->cds_table[i];
|
||||
|
||||
fmemcpy(pcds_table->cdsCurrentPath, "A:\\\0", 4);
|
||||
|
||||
pcds_table->cdsCurrentPath[0] += i;
|
||||
|
||||
if (i < nblkdev && (ULONG)dpb != 0xffffffffl)
|
||||
if (i < nblkdev && (ULONG) dpb != 0xffffffffl)
|
||||
{
|
||||
pcds_table->cdsDpb = dpb;
|
||||
pcds_table->cdsFlags = CDSPHYSDRV;
|
||||
@ -318,39 +311,36 @@ INIT VOID FsConfig(VOID)
|
||||
|
||||
INIT VOID signon()
|
||||
{
|
||||
printf("\n%S" ,(void FAR *)os_release);
|
||||
printf("\n%S", (void FAR *)os_release);
|
||||
|
||||
printf("Kernel compatibility %d.%d",
|
||||
os_major, os_minor );
|
||||
printf("Kernel compatibility %d.%d", os_major, os_minor);
|
||||
|
||||
#if defined(__TURBOC__)
|
||||
printf(" - TURBOC");
|
||||
printf(" - TURBOC");
|
||||
#elif defined(_MSC_VER)
|
||||
printf(" - MSC");
|
||||
printf(" - MSC");
|
||||
#elif defined(__WATCOMC__)
|
||||
printf(" - WATCOMC");
|
||||
printf(" - WATCOMC");
|
||||
#else
|
||||
generate some bullshit error here, as the compiler should be known
|
||||
generate some bullshit error here, as the compiler should be known
|
||||
#endif
|
||||
#if defined (I386)
|
||||
printf(" - 80386 CPU required");
|
||||
#elif defined (I186)
|
||||
printf(" - 80186 CPU required");
|
||||
#endif
|
||||
|
||||
#if defined (I386)
|
||||
printf(" - 80386 CPU required");
|
||||
#elif defined (I186)
|
||||
printf(" - 80186 CPU required");
|
||||
#endif
|
||||
|
||||
#ifdef WITHFAT32
|
||||
printf(" - FAT32 support");
|
||||
#endif
|
||||
printf("\n\n%S",(void FAR *)copyright);
|
||||
printf(" - FAT32 support");
|
||||
#endif
|
||||
printf("\n\n%S", (void FAR *)copyright);
|
||||
}
|
||||
|
||||
INIT void kernel()
|
||||
{
|
||||
#if 0
|
||||
BYTE FAR *ep,
|
||||
*sp;
|
||||
#endif
|
||||
#if 0
|
||||
BYTE FAR *ep, *sp;
|
||||
#endif
|
||||
exec_blk exb;
|
||||
CommandTail Cmd;
|
||||
int rc;
|
||||
@ -365,7 +355,7 @@ INIT void kernel()
|
||||
#else
|
||||
#if 0
|
||||
/* create the master environment area */
|
||||
|
||||
|
||||
if (allocmem(0x2, &exb.exec.env_seg))
|
||||
init_fatal("cannot allocate master environment space");
|
||||
|
||||
@ -381,67 +371,60 @@ INIT void kernel()
|
||||
*((int FAR *)ep) = 0;
|
||||
ep += sizeof(int);
|
||||
#else
|
||||
exb.exec.env_seg = DOS_PSP+8;
|
||||
exb.exec.env_seg = DOS_PSP + 8;
|
||||
fmemcpy(MK_FP(exb.exec.env_seg, 0), master_env, sizeof(master_env));
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
RootPsp = ~0;
|
||||
|
||||
|
||||
|
||||
/* process 0 */
|
||||
/* Execute command.com /P from the drive we just booted from */
|
||||
fstrncpy(Cmd.ctBuffer, Config.cfgInitTail,
|
||||
sizeof(Config.cfgInitTail)-1);
|
||||
fstrncpy(Cmd.ctBuffer, Config.cfgInitTail,
|
||||
sizeof(Config.cfgInitTail) - 1);
|
||||
|
||||
for (Cmd.ctCount = 0; Cmd.ctCount < 127; Cmd.ctCount++)
|
||||
if (Cmd.ctBuffer[Cmd.ctCount] == '\r')
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
/* if stepping CONFIG.SYS (F5/F8), tell COMMAND.COM about it */
|
||||
/* if stepping CONFIG.SYS (F5/F8), tell COMMAND.COM about it */
|
||||
|
||||
if (Cmd.ctCount < 127 - 3)
|
||||
{
|
||||
extern int singleStep ;
|
||||
extern int SkipAllConfig;
|
||||
char *insertString = NULL;
|
||||
{
|
||||
extern int singleStep;
|
||||
extern int SkipAllConfig;
|
||||
char *insertString = NULL;
|
||||
|
||||
if (singleStep) insertString = " /Y"; /* single step AUTOEXEC */
|
||||
|
||||
if (SkipAllConfig) insertString = " /D"; /* disable AUTOEXEC */
|
||||
|
||||
if (insertString)
|
||||
if (singleStep)
|
||||
insertString = " /Y"; /* single step AUTOEXEC */
|
||||
|
||||
if (SkipAllConfig)
|
||||
insertString = " /D"; /* disable AUTOEXEC */
|
||||
|
||||
if (insertString)
|
||||
{
|
||||
|
||||
/* insert /D, /Y as first argument */
|
||||
int cmdEnd, i, slen = strlen(insertString);
|
||||
|
||||
for (cmdEnd = 0; cmdEnd < 127; cmdEnd++)
|
||||
{
|
||||
|
||||
/* insert /D, /Y as first argument */
|
||||
int cmdEnd,i,slen = strlen(insertString);
|
||||
|
||||
for (cmdEnd = 0;cmdEnd < 127; cmdEnd++)
|
||||
if (Cmd.ctBuffer[cmdEnd] == ' ' ||
|
||||
Cmd.ctBuffer[cmdEnd] == '\t' || Cmd.ctBuffer[cmdEnd] == '\r')
|
||||
{
|
||||
if (Cmd.ctBuffer[cmdEnd] == ' ' ||
|
||||
Cmd.ctBuffer[cmdEnd] == '\t' ||
|
||||
Cmd.ctBuffer[cmdEnd] == '\r')
|
||||
{
|
||||
for (i = 127 - slen; i >= cmdEnd; i--)
|
||||
Cmd.ctBuffer[i+slen] = Cmd.ctBuffer[i];
|
||||
|
||||
fmemcpy(&Cmd.ctBuffer[cmdEnd], insertString,slen);
|
||||
for (i = 127 - slen; i >= cmdEnd; i--)
|
||||
Cmd.ctBuffer[i + slen] = Cmd.ctBuffer[i];
|
||||
|
||||
Cmd.ctCount += slen;
|
||||
fmemcpy(&Cmd.ctBuffer[cmdEnd], insertString, slen);
|
||||
|
||||
break;
|
||||
}
|
||||
Cmd.ctCount += slen;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
exb.exec.cmd_line = (CommandTail FAR *) & Cmd;
|
||||
exb.exec.fcb_1 = exb.exec.fcb_2 = (fcb FAR *) 0;
|
||||
|
||||
@ -449,13 +432,17 @@ INIT void kernel()
|
||||
printf("Process 0 starting: %s\n\n", Config.cfgInit);
|
||||
#endif
|
||||
|
||||
while ((rc = init_DosExec(Config.cfgP_0_startmode, &exb, Config.cfgInit)) != SUCCESS)
|
||||
while ((rc =
|
||||
init_DosExec(Config.cfgP_0_startmode, &exb,
|
||||
Config.cfgInit)) != SUCCESS)
|
||||
{
|
||||
BYTE *pLine;
|
||||
printf("\nBad or missing Command Interpreter: %d - %s\n", rc, Cmd.ctBuffer);
|
||||
printf("\nPlease enter the correct location (for example C:\\COMMAND.COM):\n");
|
||||
rc = read(STDIN, Cmd.ctBuffer, sizeof(Cmd.ctBuffer)-1);
|
||||
Cmd.ctBuffer[rc]='\0';
|
||||
printf("\nBad or missing Command Interpreter: %d - %s\n", rc,
|
||||
Cmd.ctBuffer);
|
||||
printf
|
||||
("\nPlease enter the correct location (for example C:\\COMMAND.COM):\n");
|
||||
rc = read(STDIN, Cmd.ctBuffer, sizeof(Cmd.ctBuffer) - 1);
|
||||
Cmd.ctBuffer[rc] = '\0';
|
||||
|
||||
/* Get the string argument that represents the new init pgm */
|
||||
pLine = GetStringArg(Cmd.ctBuffer, Config.cfgInit);
|
||||
@ -466,8 +453,8 @@ INIT void kernel()
|
||||
|
||||
/* and add a DOS new line just to be safe */
|
||||
strcat(Cmd.ctBuffer, "\r\n");
|
||||
|
||||
Cmd.ctCount = rc-(pLine-Cmd.ctBuffer);
|
||||
|
||||
Cmd.ctCount = rc - (pLine - Cmd.ctBuffer);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Process 0 starting: %s\n\n", Config.cfgInit);
|
||||
@ -484,17 +471,20 @@ static VOID update_dcb(struct dhdr FAR * dhp)
|
||||
COUNT nunits = dhp->dh_name[0];
|
||||
struct dpb FAR *dpb;
|
||||
|
||||
if (nblkdev==0)
|
||||
if (nblkdev == 0)
|
||||
dpb = DPBp;
|
||||
else {
|
||||
for (dpb = DPBp; (ULONG)dpb->dpb_next != 0xffffffffl; dpb = dpb->dpb_next)
|
||||
else
|
||||
{
|
||||
for (dpb = DPBp; (ULONG) dpb->dpb_next != 0xffffffffl;
|
||||
dpb = dpb->dpb_next)
|
||||
;
|
||||
dpb = dpb->dpb_next = (struct dpb FAR *)KernelAlloc(nunits*sizeof(struct dpb));
|
||||
dpb = dpb->dpb_next =
|
||||
(struct dpb FAR *)KernelAlloc(nunits * sizeof(struct dpb));
|
||||
}
|
||||
|
||||
for(Index = 0; Index < nunits; Index++)
|
||||
{
|
||||
dpb->dpb_next = dpb+1;
|
||||
for (Index = 0; Index < nunits; Index++)
|
||||
{
|
||||
dpb->dpb_next = dpb + 1;
|
||||
dpb->dpb_unit = nblkdev;
|
||||
dpb->dpb_subunit = Index;
|
||||
dpb->dpb_device = dhp;
|
||||
@ -507,17 +497,17 @@ static VOID update_dcb(struct dhdr FAR * dhp)
|
||||
++dpb;
|
||||
++nblkdev;
|
||||
}
|
||||
(dpb-1)->dpb_next = (void FAR *)0xFFFFFFFFl;
|
||||
(dpb - 1)->dpb_next = (void FAR *)0xFFFFFFFFl;
|
||||
}
|
||||
|
||||
|
||||
/* If cmdLine is NULL, this is an internal driver */
|
||||
|
||||
BOOL init_device(struct dhdr FAR * dhp, BYTE FAR * cmdLine, COUNT mode, COUNT r_top)
|
||||
BOOL init_device(struct dhdr FAR * dhp, BYTE FAR * cmdLine, COUNT mode,
|
||||
COUNT r_top)
|
||||
{
|
||||
request rq;
|
||||
|
||||
UCOUNT maxmem = ((UCOUNT)r_top << 6) - FP_SEG(dhp);
|
||||
UCOUNT maxmem = ((UCOUNT) r_top << 6) - FP_SEG(dhp);
|
||||
|
||||
if (maxmem >= 0x1000)
|
||||
maxmem = 0xFFFF;
|
||||
@ -540,25 +530,27 @@ BOOL init_device(struct dhdr FAR * dhp, BYTE FAR * cmdLine, COUNT mode, COUNT r_
|
||||
if (rq.r_status & S_ERROR)
|
||||
return TRUE;
|
||||
|
||||
if(cmdLine){
|
||||
if (cmdLine)
|
||||
{
|
||||
if (mode)
|
||||
{
|
||||
/* Don't link in device drivers which do not take up memory */
|
||||
if (rq.r_endaddr == (BYTE FAR *)dhp)
|
||||
if (rq.r_endaddr == (BYTE FAR *) dhp)
|
||||
return TRUE;
|
||||
else
|
||||
upBase = rq.r_endaddr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rq.r_endaddr == (BYTE FAR *)dhp)
|
||||
if (rq.r_endaddr == (BYTE FAR *) dhp)
|
||||
return TRUE;
|
||||
else
|
||||
lpBase = rq.r_endaddr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(dhp->dh_attr & ATTR_CHAR) && (rq.r_nunits != 0)) {
|
||||
if (!(dhp->dh_attr & ATTR_CHAR) && (rq.r_nunits != 0))
|
||||
{
|
||||
dhp->dh_name[0] = rq.r_nunits;
|
||||
update_dcb(dhp);
|
||||
}
|
||||
@ -571,7 +563,6 @@ BOOL init_device(struct dhdr FAR * dhp, BYTE FAR * cmdLine, COUNT mode, COUNT r_
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
INIT static void InitIO(void)
|
||||
{
|
||||
/* Initialize driver chain */
|
||||
@ -598,19 +589,19 @@ VOID init_fatal(BYTE * err_msg)
|
||||
|
||||
INIT VOID InitPrinters(VOID)
|
||||
{
|
||||
iregs r;
|
||||
int num_printers,i;
|
||||
iregs r;
|
||||
int num_printers, i;
|
||||
|
||||
init_call_intr(0x11,&r); /* get equipment list */
|
||||
init_call_intr(0x11, &r); /* get equipment list */
|
||||
|
||||
num_printers = (r.a.x >> 14) & 3; /* bits 15-14 */
|
||||
|
||||
for (i = 0;i < num_printers;i++)
|
||||
{
|
||||
r.a.x = 0x0100; /* initialize printer */
|
||||
r.d.x = i;
|
||||
init_call_intr(0x17,&r);
|
||||
}
|
||||
num_printers = (r.a.x >> 14) & 3; /* bits 15-14 */
|
||||
|
||||
for (i = 0; i < num_printers; i++)
|
||||
{
|
||||
r.a.x = 0x0100; /* initialize printer */
|
||||
r.d.x = i;
|
||||
init_call_intr(0x17, &r);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -705,5 +696,3 @@ INIT VOID InitPrinters(VOID)
|
||||
* Rev 1.0 02 Jul 1995 8:33:18 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
||||
|
248
kernel/memmgr.c
248
kernel/memmgr.c
@ -30,7 +30,8 @@
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRING
|
||||
static BYTE *memmgrRcsId = "$Id$";
|
||||
static BYTE *memmgrRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
VOID mcb_init();
|
||||
@ -40,9 +41,9 @@ VOID show_chain();
|
||||
/*#define nxtMCBsize(mcb,size) \
|
||||
MK_FP(far2para((VOID FAR *) (mcb)) + (size) + 1, 0) */
|
||||
|
||||
void FAR *nxtMCBsize(mcb FAR *Mcb, int size)
|
||||
void FAR *nxtMCBsize(mcb FAR * Mcb, int size)
|
||||
{
|
||||
return MK_FP(far2para((VOID FAR *) (Mcb)) + (size) + 1, 0);
|
||||
return MK_FP(far2para((VOID FAR *) (Mcb)) + (size) + 1, 0);
|
||||
}
|
||||
|
||||
#define nxtMCB(mcb) nxtMCBsize((mcb), (mcb)->m_size)
|
||||
@ -85,10 +86,10 @@ seg far2para(VOID FAR * p)
|
||||
|
||||
seg long2para(ULONG size)
|
||||
{
|
||||
UWORD high = size>>16;
|
||||
if ((UWORD)size > 0xfff0)
|
||||
high++;
|
||||
return (((UWORD)size + 0x0f) >> 4) + (high << 12);
|
||||
UWORD high = size >> 16;
|
||||
if ((UWORD) size > 0xfff0)
|
||||
high++;
|
||||
return (((UWORD) size + 0x0f) >> 4) + (high << 12);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -97,11 +98,12 @@ seg long2para(ULONG size)
|
||||
VOID FAR *add_far(VOID FAR * fp, ULONG off)
|
||||
{
|
||||
UWORD off2;
|
||||
|
||||
if (FP_SEG(fp) == 0xffff) return ((BYTE FAR *)fp) + FP_OFF(off);
|
||||
|
||||
|
||||
if (FP_SEG(fp) == 0xffff)
|
||||
return ((BYTE FAR *) fp) + FP_OFF(off);
|
||||
|
||||
off += FP_OFF(fp);
|
||||
off2 = ((off >> 16) << 12) + ((UWORD)off >> 4);
|
||||
off2 = ((off >> 16) << 12) + ((UWORD) off >> 4);
|
||||
|
||||
return MK_FP(FP_SEG(fp) + off2, (UWORD) off & 0xf);
|
||||
}
|
||||
@ -113,16 +115,17 @@ VOID FAR *adjust_far(VOID FAR * fp)
|
||||
{
|
||||
/* and return an adddress adjusted to the nearest paragraph */
|
||||
/* boundary. */
|
||||
|
||||
if (FP_SEG(fp) == 0xffff) return fp;
|
||||
|
||||
|
||||
if (FP_SEG(fp) == 0xffff)
|
||||
return fp;
|
||||
|
||||
return MK_FP(FP_SEG(fp) + (FP_OFF(fp) >> 4), FP_OFF(fp) & 0xf);
|
||||
}
|
||||
|
||||
#undef REG
|
||||
#define REG
|
||||
|
||||
#if 1 /* #ifdef KERNEL KERNEL */
|
||||
#if 1 /* #ifdef KERNEL KERNEL */
|
||||
/* Allocate a new memory area. *para is assigned to the segment of the
|
||||
MCB rather then the segment of the data portion */
|
||||
/* If mode == LARGEST, asize MUST be != NULL and will always recieve the
|
||||
@ -132,7 +135,8 @@ VOID FAR *adjust_far(VOID FAR * fp)
|
||||
size is the minimum size of the block to search for,
|
||||
even if mode == LARGEST.
|
||||
*/
|
||||
COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para, UWORD FAR * asize)
|
||||
COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para,
|
||||
UWORD FAR * asize)
|
||||
{
|
||||
REG mcb FAR *p;
|
||||
mcb FAR *foundSeg;
|
||||
@ -140,16 +144,16 @@ COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para, UWORD FAR * asize)
|
||||
/* Initialize */
|
||||
|
||||
searchAgain:
|
||||
|
||||
|
||||
p = para2far(first_mcb);
|
||||
|
||||
biggestSeg = foundSeg = NULL;
|
||||
/*
|
||||
Hack to the Umb Region direct for now. Save time and program space.
|
||||
*/
|
||||
if((mode != LARGEST) && (mode & (FIRST_FIT_UO | FIRST_FIT_U)) &&
|
||||
uppermem_link && uppermem_root)
|
||||
p = para2far(uppermem_root);
|
||||
if ((mode != LARGEST) && (mode & (FIRST_FIT_UO | FIRST_FIT_U)) &&
|
||||
uppermem_link && uppermem_root)
|
||||
p = para2far(uppermem_root);
|
||||
|
||||
/* Search through memory blocks */
|
||||
FOREVER
|
||||
@ -157,10 +161,10 @@ searchAgain:
|
||||
/* check for corruption */
|
||||
if (!mcbValid(p))
|
||||
return DE_MCBDESTRY;
|
||||
|
||||
|
||||
if (mcbFree(p))
|
||||
{ /* unused block, check if it applies to the rule */
|
||||
if (joinMCBs(p) != SUCCESS) /* join following unused blocks */
|
||||
if (joinMCBs(p) != SUCCESS) /* join following unused blocks */
|
||||
return DE_MCBDESTRY; /* error */
|
||||
|
||||
if (!biggestSeg || biggestSeg->m_size < p->m_size)
|
||||
@ -191,7 +195,7 @@ searchAgain:
|
||||
foundSeg = p;
|
||||
break;
|
||||
|
||||
case FIRST_FIT: /* first possible */
|
||||
case FIRST_FIT: /* first possible */
|
||||
case FIRST_FIT_U:
|
||||
case FIRST_FIT_UO:
|
||||
foundSeg = p;
|
||||
@ -212,11 +216,12 @@ searchAgain:
|
||||
|
||||
if (!foundSeg || !foundSeg->m_size)
|
||||
{ /* no block to fullfill the request */
|
||||
if((mode != LARGEST) && (mode & FIRST_FIT_U) &&
|
||||
uppermem_link && uppermem_root) {
|
||||
if ((mode != LARGEST) && (mode & FIRST_FIT_U) &&
|
||||
uppermem_link && uppermem_root)
|
||||
{
|
||||
mode &= ~FIRST_FIT_U;
|
||||
goto searchAgain;
|
||||
}
|
||||
}
|
||||
if (asize)
|
||||
*asize = biggestSeg ? biggestSeg->m_size : 0;
|
||||
return DE_NOMEM;
|
||||
@ -230,7 +235,8 @@ stopIt: /* reached from FIRST_FIT on match */
|
||||
/* foundSeg := pointer to allocated block
|
||||
p := pointer to MCB that will form the rest of the block
|
||||
*/
|
||||
if ((mode == LAST_FIT)||(mode == LAST_FIT_UO)||(mode == LAST_FIT_U))
|
||||
if ((mode == LAST_FIT) || (mode == LAST_FIT_UO)
|
||||
|| (mode == LAST_FIT_U))
|
||||
{
|
||||
/* allocate the block from the end of the found block */
|
||||
p = foundSeg;
|
||||
@ -283,9 +289,8 @@ COUNT DosMemLargest(UWORD FAR * size)
|
||||
REG mcb FAR *p;
|
||||
|
||||
/* Initialize */
|
||||
p = ((mem_access_mode & (FIRST_FIT_UO | FIRST_FIT_U)) && uppermem_link && uppermem_root)
|
||||
? para2far(uppermem_root)
|
||||
: para2far(first_mcb);
|
||||
p = ((mem_access_mode & (FIRST_FIT_UO | FIRST_FIT_U)) && uppermem_link
|
||||
&& uppermem_root) ? para2far(uppermem_root) : para2far(first_mcb);
|
||||
|
||||
/* Cycle through the whole MCB chain to find the largest unused
|
||||
area. Join all unused areas together. */
|
||||
@ -384,8 +389,7 @@ COUNT DosMemFree(UWORD para)
|
||||
*/
|
||||
COUNT DosMemChange(UWORD para, UWORD size, UWORD * maxSize)
|
||||
{
|
||||
REG mcb FAR *p,
|
||||
FAR * q;
|
||||
REG mcb FAR *p, FAR * q;
|
||||
REG COUNT i;
|
||||
|
||||
/* Initialize */
|
||||
@ -435,9 +439,9 @@ COUNT DosMemChange(UWORD para, UWORD size, UWORD * maxSize)
|
||||
|
||||
/* MS network client NET.EXE: DosMemChange sets the PSP *
|
||||
* not tested, if always, or only on success TE*
|
||||
* only on success seems more logical to me - Bart */
|
||||
* only on success seems more logical to me - Bart */
|
||||
p->m_psp = cu_psp;
|
||||
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -457,12 +461,12 @@ COUNT DosMemCheck(void)
|
||||
{
|
||||
/* check for corruption */
|
||||
if (p->m_type != MCB_NORMAL)
|
||||
{
|
||||
{
|
||||
printf("dos mem corrupt, first_mcb=%04x\n", first_mcb);
|
||||
hexd("prev " ,pprev,16);
|
||||
hexd("notMZ",p,16);
|
||||
hexd("prev ", pprev, 16);
|
||||
hexd("notMZ", p, 16);
|
||||
return DE_MCBDESTRY;
|
||||
}
|
||||
}
|
||||
|
||||
/* not corrupted - but not end, bump the pointer */
|
||||
pprev = p;
|
||||
@ -476,31 +480,31 @@ COUNT FreeProcessMem(UWORD ps)
|
||||
mcb FAR *p;
|
||||
BYTE oldumbstate = uppermem_link;
|
||||
|
||||
/* link in upper memory to free those , too */
|
||||
/* link in upper memory to free those , too */
|
||||
DosUmbLink(1);
|
||||
|
||||
/* Search through all memory blocks */
|
||||
for (p = para2far(first_mcb);; p = nxtMCB(p))
|
||||
{
|
||||
for (p = para2far(first_mcb);; p = nxtMCB(p))
|
||||
{
|
||||
|
||||
if (!mcbValid(p)) /* check for corruption */
|
||||
return DE_MCBDESTRY;
|
||||
return DE_MCBDESTRY;
|
||||
|
||||
if (p->m_psp == ps)
|
||||
DosMemFree(FP_SEG(p));
|
||||
|
||||
if (p->m_type == MCB_LAST)
|
||||
break;
|
||||
}
|
||||
DosMemFree(FP_SEG(p));
|
||||
|
||||
if (p->m_type == MCB_LAST)
|
||||
break;
|
||||
}
|
||||
|
||||
DosUmbLink(oldumbstate);
|
||||
|
||||
DosUmbLink(oldumbstate);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* seems to be superceeded by DosMemLargest
|
||||
-- 1999/04/21 ska */
|
||||
#if 0
|
||||
/* seems to be superceeded by DosMemLargest
|
||||
-- 1999/04/21 ska */
|
||||
COUNT DosGetLargestBlock(UWORD FAR * block)
|
||||
{
|
||||
UWORD sz = 0;
|
||||
@ -552,60 +556,57 @@ VOID mcb_print(mcb FAR * mcbp)
|
||||
|
||||
fmemcpy((BYTE FAR *) buff, (BYTE FAR *) (mcbp->m_name), 8);
|
||||
buff[8] = '\0';
|
||||
printf("%04x:%04x -> |%s| m_type = 0x%02x '%c'; m_psp = 0x%04x; m_size = 0x%04x\n",
|
||||
FP_SEG(mcbp),
|
||||
FP_OFF(mcbp),
|
||||
*buff == '\0' ? "*NO-ID*" : buff,
|
||||
mcbp->m_type, mcbp->m_type > ' ' ? mcbp->m_type : ' ',
|
||||
mcbp->m_psp,
|
||||
mcbp->m_size);
|
||||
printf
|
||||
("%04x:%04x -> |%s| m_type = 0x%02x '%c'; m_psp = 0x%04x; m_size = 0x%04x\n",
|
||||
FP_SEG(mcbp), FP_OFF(mcbp), *buff == '\0' ? "*NO-ID*" : buff,
|
||||
mcbp->m_type, mcbp->m_type > ' ' ? mcbp->m_type : ' ', mcbp->m_psp,
|
||||
mcbp->m_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
VOID DosUmbLink(BYTE n)
|
||||
{
|
||||
REG mcb FAR *p;
|
||||
REG mcb FAR *q;
|
||||
mcb FAR *end_of_conv_mem = para2far(ram_top*64-1);
|
||||
|
||||
if (uppermem_root == 0)
|
||||
return;
|
||||
REG mcb FAR *p;
|
||||
REG mcb FAR *q;
|
||||
mcb FAR *end_of_conv_mem = para2far(ram_top * 64 - 1);
|
||||
|
||||
q = p = para2far(first_mcb);
|
||||
/* like a xor thing! */
|
||||
if((uppermem_link == 1) && (n == 0))
|
||||
{
|
||||
while ( p != end_of_conv_mem )
|
||||
{
|
||||
if (mcbFree(p))
|
||||
joinMCBs(p);
|
||||
if (!mcbValid(p))
|
||||
goto DUL_exit;
|
||||
q = p;
|
||||
p = nxtMCB(p);
|
||||
}
|
||||
|
||||
if(q->m_type == MCB_NORMAL)
|
||||
q->m_type = MCB_LAST;
|
||||
uppermem_link = n;
|
||||
|
||||
}
|
||||
else
|
||||
if((uppermem_link == 0) && (n == 1))
|
||||
{
|
||||
while( q->m_type != MCB_LAST)
|
||||
{
|
||||
if (!mcbValid(q))
|
||||
goto DUL_exit;
|
||||
q = nxtMCB(q);
|
||||
}
|
||||
|
||||
if(q->m_type == MCB_LAST)
|
||||
q->m_type = MCB_NORMAL;
|
||||
uppermem_link = n;
|
||||
}
|
||||
DUL_exit:
|
||||
if (uppermem_root == 0)
|
||||
return;
|
||||
|
||||
q = p = para2far(first_mcb);
|
||||
/* like a xor thing! */
|
||||
if ((uppermem_link == 1) && (n == 0))
|
||||
{
|
||||
while (p != end_of_conv_mem)
|
||||
{
|
||||
if (mcbFree(p))
|
||||
joinMCBs(p);
|
||||
if (!mcbValid(p))
|
||||
goto DUL_exit;
|
||||
q = p;
|
||||
p = nxtMCB(p);
|
||||
}
|
||||
|
||||
if (q->m_type == MCB_NORMAL)
|
||||
q->m_type = MCB_LAST;
|
||||
uppermem_link = n;
|
||||
|
||||
}
|
||||
else if ((uppermem_link == 0) && (n == 1))
|
||||
{
|
||||
while (q->m_type != MCB_LAST)
|
||||
{
|
||||
if (!mcbValid(q))
|
||||
goto DUL_exit;
|
||||
q = nxtMCB(q);
|
||||
}
|
||||
|
||||
if (q->m_type == MCB_LAST)
|
||||
q->m_type = MCB_NORMAL;
|
||||
uppermem_link = n;
|
||||
}
|
||||
DUL_exit:
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -620,44 +621,42 @@ DUL_exit:
|
||||
|
||||
*/
|
||||
#if 0
|
||||
BYTE INITDataSegmentClaimed = 1; /* must be enabled by CONFIG.SYS */
|
||||
BYTE INITDataSegmentClaimed = 1; /* must be enabled by CONFIG.SYS */
|
||||
extern BYTE _INIT_DATA_START[], _INIT_DATA_END[];
|
||||
|
||||
VOID ClaimINITDataSegment()
|
||||
{
|
||||
unsigned ilow,ihigh;
|
||||
VOID FAR * p;
|
||||
unsigned ilow, ihigh;
|
||||
VOID FAR *p;
|
||||
|
||||
if (INITDataSegmentClaimed)
|
||||
return;
|
||||
INITDataSegmentClaimed = 1;
|
||||
if (INITDataSegmentClaimed)
|
||||
return;
|
||||
INITDataSegmentClaimed = 1;
|
||||
|
||||
ilow = (unsigned)_INIT_DATA_START;
|
||||
ilow = (ilow + 0x0f) & ~0x000f;
|
||||
ihigh = (unsigned)_INIT_DATA_END;
|
||||
ihigh = ((ihigh + 0x0f) & ~0x000f) - 0x20;
|
||||
|
||||
ilow = (unsigned)_INIT_DATA_START;
|
||||
ilow = (ilow+0x0f) & ~0x000f;
|
||||
ihigh = (unsigned)_INIT_DATA_END;
|
||||
ihigh = ((ihigh + 0x0f) & ~0x000f) - 0x20;
|
||||
if (ilow + 0x10 < ihigh)
|
||||
{
|
||||
printf("CLAIMING INIT_DATA memory - %u bytes\n", ihigh - ilow);
|
||||
}
|
||||
|
||||
if (ilow +0x10 < ihigh)
|
||||
{
|
||||
printf("CLAIMING INIT_DATA memory - %u bytes\n",ihigh - ilow);
|
||||
}
|
||||
((mcb *) ilow)->m_type = MCB_NORMAL; /* 'M' */
|
||||
((mcb *) ilow)->m_psp = FREE_PSP; /* '0' */
|
||||
((mcb *) ilow)->m_size = (ihigh - ilow - 0x10) >> 4; /* '0' */
|
||||
|
||||
((mcb *) ihigh)->m_type = MCB_NORMAL; /* 'M' */
|
||||
((mcb *) ihigh)->m_psp = 0x0008; /* system */
|
||||
|
||||
((mcb*)ilow)->m_type = MCB_NORMAL; /* 'M' */
|
||||
((mcb*)ilow)->m_psp = FREE_PSP; /* '0' */
|
||||
((mcb*)ilow)->m_size = (ihigh-ilow-0x10)>>4; /* '0' */
|
||||
p = (void FAR *)(void *)ihigh;
|
||||
|
||||
((mcb*)ihigh)->m_type = MCB_NORMAL; /* 'M' */
|
||||
((mcb*)ihigh)->m_psp = 0x0008; /* system */
|
||||
((mcb *) ihigh)->m_size = first_mcb - 1 - FP_SEG(p) - (FP_OFF(p) >> 4);
|
||||
|
||||
p = (void FAR*)(void*)ihigh;
|
||||
p = (void FAR *)(void *)ilow;
|
||||
|
||||
((mcb*)ihigh)->m_size = first_mcb -1 - FP_SEG(p) - (FP_OFF(p) >> 4);
|
||||
|
||||
p = (void FAR*)(void*)ilow;
|
||||
|
||||
first_mcb = FP_SEG(p) + (FP_OFF(p) >> 4);
|
||||
first_mcb = FP_SEG(p) + (FP_OFF(p) >> 4);
|
||||
|
||||
}
|
||||
#endif
|
||||
@ -712,4 +711,3 @@ VOID ClaimINITDataSegment()
|
||||
* Rev 1.0 02 Jul 1995 8:33:08 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
@ -29,7 +29,8 @@
|
||||
#include "portab.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *miscRcsId = "$Id$";
|
||||
static BYTE *miscRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#include "globals.h"
|
||||
@ -119,4 +120,3 @@ VOID fmemset(REG VOID FAR * s, REG int ch, REG COUNT n)
|
||||
* Rev 1.0 02 Jul 1995 8:06:28 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
@ -31,7 +31,8 @@
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId = "$Id$";
|
||||
static BYTE *RcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
/* see RBIL D-2152 and D-215D06 before attempting
|
||||
@ -66,4 +67,3 @@ VOID set_machine_name(BYTE FAR * netname, UWORD name_num)
|
||||
* *** empty log message ***
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -26,7 +26,8 @@
|
||||
/****************************************************************/
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *mainRcsId = "$Id$";
|
||||
static BYTE *mainRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#include "portab.h"
|
||||
@ -39,8 +40,7 @@ static BYTE *mainRcsId = "$Id$";
|
||||
*/
|
||||
int SetJFTSize(UWORD nHandles)
|
||||
{
|
||||
UWORD block,
|
||||
maxBlock;
|
||||
UWORD block, maxBlock;
|
||||
psp FAR *ppsp = MK_FP(cu_psp, 0);
|
||||
UBYTE FAR *newtab;
|
||||
COUNT i;
|
||||
@ -51,7 +51,8 @@ int SetJFTSize(UWORD nHandles)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if ((DosMemAlloc((nHandles + 0xf) >> 4, mem_access_mode, &block, &maxBlock)) < 0)
|
||||
if ((DosMemAlloc
|
||||
((nHandles + 0xf) >> 4, mem_access_mode, &block, &maxBlock)) < 0)
|
||||
return DE_NOMEM;
|
||||
|
||||
++block;
|
||||
@ -74,13 +75,8 @@ int DosMkTmp(BYTE FAR * pathname, UWORD attr)
|
||||
{
|
||||
/* create filename from current date and time */
|
||||
char FAR *ptmp = pathname;
|
||||
BYTE wd,
|
||||
month,
|
||||
day;
|
||||
BYTE h,
|
||||
m,
|
||||
s,
|
||||
hund;
|
||||
BYTE wd, month, day;
|
||||
BYTE h, m, s, hund;
|
||||
WORD sh;
|
||||
WORD year;
|
||||
int rc;
|
||||
@ -98,40 +94,39 @@ int DosMkTmp(BYTE FAR * pathname, UWORD attr)
|
||||
|
||||
sh = s * 100 + hund;
|
||||
|
||||
for ( loop = 0; loop < 0xfff; loop++)
|
||||
{
|
||||
sprintf(name83,"%x%x%x%x%x%03x.%03x",
|
||||
for (loop = 0; loop < 0xfff; loop++)
|
||||
{
|
||||
sprintf(name83, "%x%x%x%x%x%03x.%03x",
|
||||
year & 0xf, month & 0xf, day & 0xf, h & 0xf, m & 0xf,
|
||||
sh & 0xfff, loop & 0xfff);
|
||||
|
||||
year & 0xf,month & 0xf, day & 0xf,h & 0xf,m & 0xf, sh&0xfff,
|
||||
loop & 0xfff);
|
||||
fmemcpy(ptmp, name83, 13);
|
||||
|
||||
fmemcpy(ptmp, name83, 13);
|
||||
if ((rc = DosOpen(pathname, 0)) < 0 && rc != DE_ACCESS /* subdirectory ?? */
|
||||
/* todo: sharing collision on
|
||||
network drive
|
||||
*/
|
||||
)
|
||||
break;
|
||||
|
||||
if ((rc = DosOpen(pathname, 0)) < 0 &&
|
||||
rc != DE_ACCESS /* subdirectory ?? */
|
||||
/* todo: sharing collision on
|
||||
network drive
|
||||
*/
|
||||
)
|
||||
break;
|
||||
if (rc >= 0)
|
||||
DosClose(rc);
|
||||
}
|
||||
|
||||
if (rc >= 0) DosClose(rc);
|
||||
}
|
||||
|
||||
if (rc == DE_FILENOTFND)
|
||||
{
|
||||
rc = DosCreat(pathname, attr);
|
||||
}
|
||||
return rc;
|
||||
if (rc == DE_FILENOTFND)
|
||||
{
|
||||
rc = DosCreat(pathname, attr);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
COUNT get_verify_drive(char FAR *src)
|
||||
COUNT get_verify_drive(char FAR * src)
|
||||
{
|
||||
UBYTE drive;
|
||||
|
||||
/* Do we have a drive? */
|
||||
if (src[1] == ':')
|
||||
drive = ((src[0]-1) | 0x20) - ('a'-1);
|
||||
drive = ((src[0] - 1) | 0x20) - ('a' - 1);
|
||||
else
|
||||
return default_drive;
|
||||
if (drive < lastdrive && CDSp->cds_table[drive].cdsFlags & CDSVALID)
|
||||
@ -147,7 +142,7 @@ COUNT get_verify_drive(char FAR *src)
|
||||
* MSD returns \\D.\A.\????????.??? with SHSUCDX. So, this code is not
|
||||
* compatible MSD Func 60h.
|
||||
*/
|
||||
|
||||
|
||||
/*TE TODO:
|
||||
|
||||
experimenting with NUL on MSDOS 7.0 (win95)
|
||||
@ -161,13 +156,13 @@ COUNT get_verify_drive(char FAR *src)
|
||||
TRUENAME A:NUL A:/NUL OK
|
||||
TRUENAME A:\NUL A:\NUL
|
||||
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t)
|
||||
{
|
||||
static char buf[128] = "A:\\\0\0\0\0\0\0\0\0\0";
|
||||
char *bufp = buf + 3;
|
||||
COUNT i, rootEndPos = 2; /* renamed x to rootEndPos - Ron Cemer */
|
||||
COUNT i, rootEndPos = 2; /* renamed x to rootEndPos - Ron Cemer */
|
||||
struct dhdr FAR *dhp;
|
||||
BYTE FAR *froot;
|
||||
WORD d;
|
||||
@ -176,10 +171,10 @@ COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t)
|
||||
|
||||
i = get_verify_drive(src);
|
||||
if (i < 0)
|
||||
return DE_INVLDDRV;
|
||||
|
||||
return DE_INVLDDRV;
|
||||
|
||||
buf[0] = i + 'A';
|
||||
buf[1] = ':'; /* Just to be sure */
|
||||
buf[1] = ':'; /* Just to be sure */
|
||||
|
||||
/* First, adjust the source pointer */
|
||||
src = adjust_far(src);
|
||||
@ -193,42 +188,51 @@ COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t)
|
||||
MSD returns X:/CON for truename con. Not X:\CON
|
||||
*/
|
||||
/* check for a device */
|
||||
|
||||
if ((*src != '.') && (*src != '\\') && (*src != '/') && ((dhp = IsDevice(src)) != NULL))
|
||||
{
|
||||
|
||||
|
||||
if ((*src != '.') && (*src != '\\') && (*src != '/')
|
||||
&& ((dhp = IsDevice(src)) != NULL))
|
||||
{
|
||||
|
||||
froot = get_root(src);
|
||||
|
||||
/* /// Bugfix: NUL.LST is the same as NUL. This is true for all
|
||||
devices. On a device name, the extension is irrelevant
|
||||
as long as the name matches.
|
||||
- Ron Cemer */
|
||||
|
||||
buf[2] ='/';
|
||||
/* /// Bug: should be only copying up to first space.
|
||||
- Ron Cemer */
|
||||
|
||||
for (d = 0; d < FNAME_SIZE && dhp->dh_name[d] != 0 && dhp->dh_name[d] != ' '; d++)
|
||||
*bufp++ = dhp->dh_name[d];
|
||||
/* /// DOS will return C:/NUL.LST if you pass NUL.LST in.
|
||||
DOS will also return C:/NUL.??? if you pass NUL.* in.
|
||||
Code added here to support this.
|
||||
- Ron Cemer */
|
||||
while ( (*froot != '.') && (*froot != '\0') ) froot++;
|
||||
if (*froot) froot++;
|
||||
if (*froot) {
|
||||
*bufp++ = '.';
|
||||
for (i = 0; i < FEXT_SIZE; i++) {
|
||||
if ( (*froot == '\0') || (*froot == '.') )
|
||||
break;
|
||||
if (*froot == '*') {
|
||||
for (; i < FEXT_SIZE; i++) *bufp++ = '?';
|
||||
break;
|
||||
}
|
||||
*bufp++ = *froot++;
|
||||
devices. On a device name, the extension is irrelevant
|
||||
as long as the name matches.
|
||||
- Ron Cemer */
|
||||
|
||||
buf[2] = '/';
|
||||
/* /// Bug: should be only copying up to first space.
|
||||
- Ron Cemer */
|
||||
|
||||
for (d = 0;
|
||||
d < FNAME_SIZE && dhp->dh_name[d] != 0 && dhp->dh_name[d] != ' ';
|
||||
d++)
|
||||
*bufp++ = dhp->dh_name[d];
|
||||
/* /// DOS will return C:/NUL.LST if you pass NUL.LST in.
|
||||
DOS will also return C:/NUL.??? if you pass NUL.* in.
|
||||
Code added here to support this.
|
||||
- Ron Cemer */
|
||||
while ((*froot != '.') && (*froot != '\0'))
|
||||
froot++;
|
||||
if (*froot)
|
||||
froot++;
|
||||
if (*froot)
|
||||
{
|
||||
*bufp++ = '.';
|
||||
for (i = 0; i < FEXT_SIZE; i++)
|
||||
{
|
||||
if ((*froot == '\0') || (*froot == '.'))
|
||||
break;
|
||||
if (*froot == '*')
|
||||
{
|
||||
for (; i < FEXT_SIZE; i++)
|
||||
*bufp++ = '?';
|
||||
break;
|
||||
}
|
||||
*bufp++ = *froot++;
|
||||
}
|
||||
}
|
||||
/* /// End of code additions. - Ron Cemer */
|
||||
/* /// End of code additions. - Ron Cemer */
|
||||
goto exit_tn;
|
||||
}
|
||||
|
||||
@ -240,28 +244,33 @@ COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t)
|
||||
* path to the executable file.
|
||||
* Jun 11, 2000 - rbc */
|
||||
/* /// Changed to "while" from "if". - Ron Cemer */
|
||||
while ( (src[0] == '.') && (src[1] == '\\') ) src += 2;
|
||||
|
||||
while ((src[0] == '.') && (src[1] == '\\'))
|
||||
src += 2;
|
||||
|
||||
current_ldt = &CDSp->cds_table[i];
|
||||
|
||||
/* Always give the redirector a chance to rewrite the filename */
|
||||
fstrncpy(bufp - 1, src, sizeof(buf) - (bufp - buf));
|
||||
if ((t == FALSE) && (QRemote_Fn(buf, dest) == SUCCESS) && (dest[0] != '\0')) {
|
||||
if ((t == FALSE) && (QRemote_Fn(buf, dest) == SUCCESS)
|
||||
&& (dest[0] != '\0'))
|
||||
{
|
||||
return SUCCESS;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
bufp[-1] = '\\';
|
||||
}
|
||||
if (t == FALSE)
|
||||
{
|
||||
fstrncpy(buf, current_ldt->cdsCurrentPath, current_ldt->cdsJoinOffset);
|
||||
bufp = buf + current_ldt->cdsJoinOffset;
|
||||
rootEndPos = current_ldt->cdsJoinOffset; /* renamed x to rootEndPos - Ron Cemer */
|
||||
*bufp++ = '\\';
|
||||
}
|
||||
|
||||
if (*src != '\\' && *src != '/') /* append current dir */
|
||||
if (t == FALSE)
|
||||
{
|
||||
DosGetCuDir((UBYTE)(i+1), bufp);
|
||||
fstrncpy(buf, current_ldt->cdsCurrentPath, current_ldt->cdsJoinOffset);
|
||||
bufp = buf + current_ldt->cdsJoinOffset;
|
||||
rootEndPos = current_ldt->cdsJoinOffset; /* renamed x to rootEndPos - Ron Cemer */
|
||||
*bufp++ = '\\';
|
||||
}
|
||||
|
||||
if (*src != '\\' && *src != '/') /* append current dir */
|
||||
{
|
||||
DosGetCuDir((UBYTE) (i + 1), bufp);
|
||||
if (*bufp)
|
||||
{
|
||||
while (*bufp)
|
||||
@ -274,16 +283,16 @@ COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t)
|
||||
|
||||
/*move_name:*/
|
||||
|
||||
/* /// The block inside the "#if (0) ... #endif" is
|
||||
seriously broken. New code added below to replace it.
|
||||
This eliminates many serious bugs, specifically
|
||||
with FreeCOM where truename is required to work
|
||||
according to the DOS specification in order for
|
||||
the COPY and other file-related commands to work
|
||||
properly.
|
||||
This should be a major improvement to all apps which
|
||||
use truename.
|
||||
- Ron Cemer */
|
||||
/* /// The block inside the "#if (0) ... #endif" is
|
||||
seriously broken. New code added below to replace it.
|
||||
This eliminates many serious bugs, specifically
|
||||
with FreeCOM where truename is required to work
|
||||
according to the DOS specification in order for
|
||||
the COPY and other file-related commands to work
|
||||
properly.
|
||||
This should be a major improvement to all apps which
|
||||
use truename.
|
||||
- Ron Cemer */
|
||||
|
||||
#if (0)
|
||||
/*
|
||||
@ -291,14 +300,14 @@ COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t)
|
||||
* function are operating with in normal parms.
|
||||
* jt
|
||||
*/
|
||||
n = 9;
|
||||
n = 9;
|
||||
/* convert all forward slashes to backslashes, and uppercase all characters */
|
||||
while (*src)
|
||||
{
|
||||
char c;
|
||||
c = *src++;
|
||||
if(!n)
|
||||
return DE_PATHNOTFND; /* do this for now */
|
||||
if (!n)
|
||||
return DE_PATHNOTFND; /* do this for now */
|
||||
n--;
|
||||
switch (c)
|
||||
{
|
||||
@ -327,9 +336,10 @@ COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t)
|
||||
case '/': /* convert to backslash */
|
||||
case '\\':
|
||||
|
||||
if (bufp[-1] != '\\'){
|
||||
*bufp++ = '\\';
|
||||
n = 9;
|
||||
if (bufp[-1] != '\\')
|
||||
{
|
||||
*bufp++ = '\\';
|
||||
n = 9;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -343,7 +353,7 @@ COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t)
|
||||
|
||||
for (bufp -= 2; *bufp != '\\'; bufp--)
|
||||
{
|
||||
if (bufp < buf + rootEndPos) /* '..' illegal in root dir */
|
||||
if (bufp < buf + rootEndPos) /* '..' illegal in root dir */
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
src++;
|
||||
@ -351,20 +361,20 @@ COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t)
|
||||
bufp++;
|
||||
}
|
||||
else if (*src == '/' || *src == '\\' || *src == 0)
|
||||
break;
|
||||
/* --bufp;*/
|
||||
else
|
||||
return DE_PATHNOTFND;
|
||||
break;
|
||||
/* --bufp; */
|
||||
else
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
else if (*src == '/' || *src == '\\' || *src == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = 4;
|
||||
*bufp++ = c;
|
||||
}
|
||||
else if ( *src == '/' || *src == '\\' || *src == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = 4;
|
||||
*bufp++ = c;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -379,110 +389,138 @@ COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t)
|
||||
#endif
|
||||
|
||||
/* /// Beginning of new code. - Ron Cemer */
|
||||
bufp--;
|
||||
bufp--;
|
||||
{
|
||||
char c, *bufend = buf + (sizeof(buf) - 1);
|
||||
int gotAnyWildcards = 0;
|
||||
int seglen, copylen, state;
|
||||
while ((*src) && (bufp < bufend))
|
||||
{
|
||||
char c, *bufend = buf+(sizeof(buf)-1);
|
||||
int gotAnyWildcards = 0;
|
||||
int seglen, copylen, state;
|
||||
while ( (*src) && (bufp < bufend) ) {
|
||||
/* Skip duplicated slashes. */
|
||||
while ( (*src == '/') || (*src == '\\') ) src++;
|
||||
if (!(*src)) break;
|
||||
/* Find the end of this segment in the source string. */
|
||||
for (seglen = 0; ; seglen++) {
|
||||
c = src[seglen];
|
||||
if ( (c == '\0') || (c == '/') || (c == '\\') )
|
||||
break;
|
||||
/* Skip duplicated slashes. */
|
||||
while ((*src == '/') || (*src == '\\'))
|
||||
src++;
|
||||
if (!(*src))
|
||||
break;
|
||||
/* Find the end of this segment in the source string. */
|
||||
for (seglen = 0;; seglen++)
|
||||
{
|
||||
c = src[seglen];
|
||||
if ((c == '\0') || (c == '/') || (c == '\\'))
|
||||
break;
|
||||
}
|
||||
if (seglen > 0)
|
||||
{
|
||||
/* Ignore all ".\" or "\." path segments. */
|
||||
if ((seglen != 1) || (*src != '.'))
|
||||
{
|
||||
/* Apply ".." to the path by removing
|
||||
last path segment from buf. */
|
||||
if ((seglen == 2) && (src[0] == '.') && (src[1] == '.'))
|
||||
{
|
||||
if (bufp > (buf + rootEndPos))
|
||||
{
|
||||
bufp--;
|
||||
while ((bufp > (buf + rootEndPos))
|
||||
&& (*bufp != '/') && (*bufp != '\\'))
|
||||
bufp--;
|
||||
}
|
||||
if (seglen > 0) {
|
||||
/* Ignore all ".\" or "\." path segments. */
|
||||
if ( (seglen != 1) || (*src != '.') ) {
|
||||
/* Apply ".." to the path by removing
|
||||
last path segment from buf. */
|
||||
if ( (seglen==2) && (src[0] == '.') && (src[1] == '.') ) {
|
||||
if (bufp > (buf+rootEndPos)) {
|
||||
bufp--;
|
||||
while ( (bufp > (buf+rootEndPos))
|
||||
&& (*bufp != '/')
|
||||
&& (*bufp != '\\') )
|
||||
bufp--;
|
||||
} else {
|
||||
/* .. in root dir illegal */
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
} else {
|
||||
/* New segment. If any wildcards in previous
|
||||
segment(s), this is an invalid path. */
|
||||
if (gotAnyWildcards || src[0]=='.') return DE_PATHNOTFND;
|
||||
/* Append current path segment to result. */
|
||||
*(bufp++) = '\\';
|
||||
if (bufp >= bufend) break;
|
||||
copylen = state = 0;
|
||||
for (i=0; ( (i < seglen) && (bufp < bufend) ); i++) {
|
||||
c = src[i];
|
||||
gotAnyWildcards |= ( (c == '?') || (c == '*') );
|
||||
switch (state) {
|
||||
case 0: /* Copying filename (excl. extension) */
|
||||
if (c == '*') {
|
||||
while (copylen < FNAME_SIZE) {
|
||||
*(bufp++) = '?';
|
||||
if (bufp >= bufend) break;
|
||||
copylen++;
|
||||
}
|
||||
copylen = 0;
|
||||
state = 1; /* Go wait for dot */
|
||||
break;
|
||||
}
|
||||
if (c == '.') {
|
||||
if (src[i+1] != '.' && i+1 < seglen) *(bufp++) = '.';
|
||||
copylen = 0;
|
||||
state = 2; /* Copy extension next */
|
||||
break;
|
||||
}
|
||||
*(bufp++) = c;
|
||||
copylen++;
|
||||
if (copylen >= FNAME_SIZE) {
|
||||
copylen = 0;
|
||||
state = 1; /* Go wait for dot */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1: /* Looking for dot so we can copy exten */
|
||||
if (src[i] == '.' && src[i+1] != '.' && i+1 < seglen) {
|
||||
*(bufp++) = '.';
|
||||
state = 2;
|
||||
}
|
||||
break;
|
||||
case 2: /* Copying extension */
|
||||
if (c == '*') {
|
||||
while (copylen < FEXT_SIZE) {
|
||||
*(bufp++) = '?';
|
||||
if (bufp >= bufend) break;
|
||||
copylen++;
|
||||
}
|
||||
i = seglen; /* Done with segment */
|
||||
break;
|
||||
}
|
||||
if (c == '.') {
|
||||
i = seglen; /* Done with segment */
|
||||
break;
|
||||
}
|
||||
*(bufp++) = c;
|
||||
copylen++;
|
||||
if (copylen >= FEXT_SIZE) {
|
||||
i = seglen; /* Done with segment */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* .. in root dir illegal */
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* New segment. If any wildcards in previous
|
||||
segment(s), this is an invalid path. */
|
||||
if (gotAnyWildcards || src[0] == '.')
|
||||
return DE_PATHNOTFND;
|
||||
/* Append current path segment to result. */
|
||||
*(bufp++) = '\\';
|
||||
if (bufp >= bufend)
|
||||
break;
|
||||
copylen = state = 0;
|
||||
for (i = 0; ((i < seglen) && (bufp < bufend)); i++)
|
||||
{
|
||||
c = src[i];
|
||||
gotAnyWildcards |= ((c == '?') || (c == '*'));
|
||||
switch (state)
|
||||
{
|
||||
case 0: /* Copying filename (excl. extension) */
|
||||
if (c == '*')
|
||||
{
|
||||
while (copylen < FNAME_SIZE)
|
||||
{
|
||||
*(bufp++) = '?';
|
||||
if (bufp >= bufend)
|
||||
break;
|
||||
copylen++;
|
||||
}
|
||||
}
|
||||
} /* if (seglen > 0) */
|
||||
src += seglen;
|
||||
if (*src) src++;
|
||||
} /* while ( (*src) && (bufp < bufend) ) */
|
||||
}
|
||||
copylen = 0;
|
||||
state = 1; /* Go wait for dot */
|
||||
break;
|
||||
}
|
||||
if (c == '.')
|
||||
{
|
||||
if (src[i + 1] != '.' && i + 1 < seglen)
|
||||
*(bufp++) = '.';
|
||||
copylen = 0;
|
||||
state = 2; /* Copy extension next */
|
||||
break;
|
||||
}
|
||||
*(bufp++) = c;
|
||||
copylen++;
|
||||
if (copylen >= FNAME_SIZE)
|
||||
{
|
||||
copylen = 0;
|
||||
state = 1; /* Go wait for dot */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1: /* Looking for dot so we can copy exten */
|
||||
if (src[i] == '.' && src[i + 1] != '.' && i + 1 < seglen)
|
||||
{
|
||||
*(bufp++) = '.';
|
||||
state = 2;
|
||||
}
|
||||
break;
|
||||
case 2: /* Copying extension */
|
||||
if (c == '*')
|
||||
{
|
||||
while (copylen < FEXT_SIZE)
|
||||
{
|
||||
*(bufp++) = '?';
|
||||
if (bufp >= bufend)
|
||||
break;
|
||||
copylen++;
|
||||
}
|
||||
i = seglen; /* Done with segment */
|
||||
break;
|
||||
}
|
||||
if (c == '.')
|
||||
{
|
||||
i = seglen; /* Done with segment */
|
||||
break;
|
||||
}
|
||||
*(bufp++) = c;
|
||||
copylen++;
|
||||
if (copylen >= FEXT_SIZE)
|
||||
{
|
||||
i = seglen; /* Done with segment */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* if (seglen > 0) */
|
||||
src += seglen;
|
||||
if (*src)
|
||||
src++;
|
||||
} /* while ( (*src) && (bufp < bufend) ) */
|
||||
}
|
||||
/* /// End of new code. - Ron Cemer */
|
||||
|
||||
if (bufp == buf + 2)
|
||||
@ -553,4 +591,3 @@ exit_tn:
|
||||
* Rev 1.1 22 Jan 1997 13:21:22 patv
|
||||
* pre-0.92 Svante Frey bug fixes.
|
||||
*/
|
||||
|
||||
|
616
kernel/nls.c
616
kernel/nls.c
@ -39,7 +39,8 @@
|
||||
#include <nls.h>
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId = "$Id$";
|
||||
static BYTE *RcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -50,8 +51,10 @@ static BYTE *RcsId = "$Id$";
|
||||
#ifdef NLS_DEBUG
|
||||
#define assertDSeqSS() if(_DS != _SS) assertDSneSS();
|
||||
void assertDSneSS(void)
|
||||
{ panic("DS unequal to SS");
|
||||
{
|
||||
panic("DS unequal to SS");
|
||||
}
|
||||
|
||||
#define log(a) printf a
|
||||
#define log1(a) printf a
|
||||
#else
|
||||
@ -64,25 +67,23 @@ void assertDSneSS(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
struct nlsInfoBlock nlsInfo = {
|
||||
(char FAR *)0 /* filename to COUNTRY.SYS */
|
||||
,437 /* system code page */
|
||||
/* Implementation flags */
|
||||
,0
|
||||
(char FAR *)0 /* filename to COUNTRY.SYS */
|
||||
, 437 /* system code page */
|
||||
/* Implementation flags */
|
||||
, 0
|
||||
#ifdef NLS_MODIFYABLE_DATA
|
||||
| NLS_CODE_MODIFYABLE_DATA
|
||||
| NLS_CODE_MODIFYABLE_DATA
|
||||
#endif
|
||||
#ifdef NLS_REORDER_POINTERS
|
||||
| NLS_CODE_REORDER_POINTERS
|
||||
| NLS_CODE_REORDER_POINTERS
|
||||
#endif
|
||||
,&nlsPackageHardcoded /* hardcoded first package */
|
||||
,&nlsPackageHardcoded /* first item in chain */
|
||||
, &nlsPackageHardcoded /* hardcoded first package */
|
||||
, &nlsPackageHardcoded /* first item in chain */
|
||||
};
|
||||
|
||||
|
||||
/* getTableX return the pointer to the X'th table; X==subfct */
|
||||
/* subfct 2: normal upcase table; 4: filename upcase table */
|
||||
/* getTableX return the pointer to the X'th table; X==subfct */
|
||||
/* subfct 2: normal upcase table; 4: filename upcase table */
|
||||
#ifdef NLS_REORDER_POINTERS
|
||||
#define getTable2(nls) ((nls)->nlsPointers[0].pointer)
|
||||
#define getTable4(nls) ((nls)->nlsPointers[1].pointer)
|
||||
@ -91,74 +92,74 @@ struct nlsInfoBlock nlsInfo = {
|
||||
#define getTable4(nls) getTable(4, (nls))
|
||||
#define NEED_GET_TABLE
|
||||
#endif
|
||||
/*== both chartables must be 128 bytes long and lower range is
|
||||
/*== both chartables must be 128 bytes long and lower range is
|
||||
identical to 7bit-US-ASCII ==ska*/
|
||||
#define getCharTbl2(nls) \
|
||||
(((struct nlsCharTbl FAR*)getTable2(nls))->tbl - 0x80)
|
||||
#define getCharTbl4(nls) \
|
||||
(((struct nlsCharTbl FAR*)getTable4(nls))->tbl - 0x80)
|
||||
|
||||
|
||||
/********************************************************************
|
||||
***** MUX calling functions ****************************************
|
||||
********************************************************************/
|
||||
|
||||
/*== DS:SI _always_ points to global NLS info structure <-> no
|
||||
* subfct can use these registers for anything different. ==ska*/
|
||||
STATIC COUNT muxGo(int subfct, iregs *rp)
|
||||
STATIC COUNT muxGo(int subfct, iregs * rp)
|
||||
{
|
||||
log( ("NLS: muxGo(): subfct=%x, cntry=%u, cp=%u, ES:DI=%04x:%04x\n", subfct
|
||||
, rp->DX, rp->BX, rp->ES, rp->DI) );
|
||||
rp->SI = FP_OFF(&nlsInfo);
|
||||
rp->DS = FP_SEG(&nlsInfo);
|
||||
rp->AX = 0x1400 | subfct;
|
||||
intr(0x2f, rp);
|
||||
log( ("NLS: muxGo(): return value = %d\n", rp->AX) );
|
||||
return rp->AX;
|
||||
log(("NLS: muxGo(): subfct=%x, cntry=%u, cp=%u, ES:DI=%04x:%04x\n",
|
||||
subfct, rp->DX, rp->BX, rp->ES, rp->DI));
|
||||
rp->SI = FP_OFF(&nlsInfo);
|
||||
rp->DS = FP_SEG(&nlsInfo);
|
||||
rp->AX = 0x1400 | subfct;
|
||||
intr(0x2f, rp);
|
||||
log(("NLS: muxGo(): return value = %d\n", rp->AX));
|
||||
return rp->AX;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call NLSFUNC to load the NLS package
|
||||
*/
|
||||
COUNT muxLoadPkg(UWORD cp, UWORD cntry)
|
||||
{ iregs r;
|
||||
{
|
||||
iregs r;
|
||||
|
||||
assertDSeqSS(); /* because "&r" */
|
||||
assertDSeqSS(); /* because "&r" */
|
||||
|
||||
/* 0x1400 == not installed, ok to install */
|
||||
/* 0x1401 == not installed, not ok to install */
|
||||
/* 0x14FF == installed */
|
||||
/* 0x1400 == not installed, ok to install */
|
||||
/* 0x1401 == not installed, not ok to install */
|
||||
/* 0x14FF == installed */
|
||||
|
||||
r.BX = 0; /* make sure the NLSFUNC ID is updated */
|
||||
if(muxGo(0, &r) != 0x14ff)
|
||||
return DE_FILENOTFND; /* No NLSFUNC --> no load */
|
||||
if(r.BX != NLS_FREEDOS_NLSFUNC_ID) /* FreeDOS NLSFUNC will return */
|
||||
return DE_INVLDACC; /* This magic number */
|
||||
r.BX = 0; /* make sure the NLSFUNC ID is updated */
|
||||
if (muxGo(0, &r) != 0x14ff)
|
||||
return DE_FILENOTFND; /* No NLSFUNC --> no load */
|
||||
if (r.BX != NLS_FREEDOS_NLSFUNC_ID) /* FreeDOS NLSFUNC will return */
|
||||
return DE_INVLDACC; /* This magic number */
|
||||
|
||||
/* OK, the correct NLSFUNC is available --> load pkg */
|
||||
/* If BX == -1 on entry, NLSFUNC updates BX to the codepage loaded
|
||||
into memory. The system must then change to this one later */
|
||||
r.DX = cntry;
|
||||
r.BX = cp;
|
||||
return muxGo(NLSFUNC_LOAD_PKG, &r);
|
||||
/* OK, the correct NLSFUNC is available --> load pkg */
|
||||
/* If BX == -1 on entry, NLSFUNC updates BX to the codepage loaded
|
||||
into memory. The system must then change to this one later */
|
||||
r.DX = cntry;
|
||||
r.BX = cp;
|
||||
return muxGo(NLSFUNC_LOAD_PKG, &r);
|
||||
}
|
||||
|
||||
STATIC int muxBufGo(int subfct, int bp, UWORD cp, UWORD cntry, UWORD bufsize
|
||||
, VOID FAR *buf)
|
||||
{ iregs r;
|
||||
STATIC int muxBufGo(int subfct, int bp, UWORD cp, UWORD cntry,
|
||||
UWORD bufsize, VOID FAR * buf)
|
||||
{
|
||||
iregs r;
|
||||
|
||||
assertDSeqSS(); /* because "&r" */
|
||||
assertDSeqSS(); /* because "&r" */
|
||||
|
||||
log( ("NLS: muxBufGo(): subfct=%x, BP=%u, cp=%u, cntry=%u, len=%u, buf=%04x:%04x\n",
|
||||
subfct, bp, cp, cntry, bufsize, FP_SEG(buf), FP_OFF(buf)) );
|
||||
log(("NLS: muxBufGo(): subfct=%x, BP=%u, cp=%u, cntry=%u, len=%u, buf=%04x:%04x\n", subfct, bp, cp, cntry, bufsize, FP_SEG(buf), FP_OFF(buf)));
|
||||
|
||||
r.DX = cntry;
|
||||
r.BX = cp;
|
||||
r.ES = FP_SEG(buf);
|
||||
r.DI = FP_OFF(buf);
|
||||
r.CX = bufsize;
|
||||
r.BP = bp;
|
||||
return muxGo(subfct, &r);
|
||||
r.DX = cntry;
|
||||
r.BX = cp;
|
||||
r.ES = FP_SEG(buf);
|
||||
r.DI = FP_OFF(buf);
|
||||
r.CX = bufsize;
|
||||
r.BP = bp;
|
||||
return muxGo(subfct, &r);
|
||||
}
|
||||
|
||||
#define mux65(s,cp,cc,bs,b) muxBufGo(2, (s), (cp), (cc), (bs), (b))
|
||||
@ -170,40 +171,41 @@ log( ("NLS: muxBufGo(): subfct=%x, BP=%u, cp=%u, cntry=%u, len=%u, buf=%04x:%04x
|
||||
***** Helper functions**********************************************
|
||||
********************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* Search for the NLS package within the chain
|
||||
* Also resolves the default values (-1) into the currently
|
||||
* active codepage/country code.
|
||||
*/
|
||||
STATIC struct nlsPackage FAR *searchPackage(UWORD cp, UWORD cntry)
|
||||
{ struct nlsPackage FAR *nls;
|
||||
{
|
||||
struct nlsPackage FAR *nls;
|
||||
|
||||
if(cp == NLS_DEFAULT)
|
||||
cp = nlsInfo.actPkg->cp;
|
||||
if(cntry == NLS_DEFAULT)
|
||||
cntry = nlsInfo.actPkg->cntry;
|
||||
if (cp == NLS_DEFAULT)
|
||||
cp = nlsInfo.actPkg->cp;
|
||||
if (cntry == NLS_DEFAULT)
|
||||
cntry = nlsInfo.actPkg->cntry;
|
||||
|
||||
nls = nlsInfo.chain;
|
||||
while((nls->cp != cp || nls->cntry != cntry)
|
||||
&& (nls = nls->nxt) != NULL);
|
||||
nls = nlsInfo.chain;
|
||||
while ((nls->cp != cp || nls->cntry != cntry)
|
||||
&& (nls = nls->nxt) != NULL) ;
|
||||
|
||||
return nls;
|
||||
return nls;
|
||||
}
|
||||
|
||||
/* For various robustnesses reasons and to simplify the implementation
|
||||
at other places, locateSubfct() returns NULL (== "not found"),
|
||||
if nls == NULL on entry. */
|
||||
STATIC VOID FAR *locateSubfct(struct nlsPackage FAR *nls, int subfct)
|
||||
{ int cnt;
|
||||
struct nlsPointer FAR *p;
|
||||
STATIC VOID FAR *locateSubfct(struct nlsPackage FAR * nls, int subfct)
|
||||
{
|
||||
int cnt;
|
||||
struct nlsPointer FAR *p;
|
||||
|
||||
if(nls) for(cnt = nls->numSubfct, p = &nls->nlsPointers[0]
|
||||
; cnt--; ++p)
|
||||
if(p->subfct == (UBYTE)subfct)
|
||||
return p;
|
||||
if (nls)
|
||||
for (cnt = nls->numSubfct, p = &nls->nlsPointers[0]; cnt--; ++p)
|
||||
if (p->subfct == (UBYTE) subfct)
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef NEED_GET_TABLE
|
||||
@ -213,19 +215,23 @@ STATIC VOID FAR *locateSubfct(struct nlsPackage FAR *nls, int subfct)
|
||||
function is guaranteed to return valid pointers, rather than
|
||||
to let the user (some kernel function) deal with non-existing
|
||||
tables -- 2000/02/26 ska*/
|
||||
STATIC VOID FAR *getTable(UBYTE subfct, struct nlsPackage FAR *nls)
|
||||
{ struct nlsPointer FAR *poi;
|
||||
STATIC VOID FAR *getTable(UBYTE subfct, struct nlsPackage FAR * nls)
|
||||
{
|
||||
struct nlsPointer FAR *poi;
|
||||
|
||||
if((poi = locateSubfct(nls, subfct)) != NULL)
|
||||
return poi;
|
||||
if ((poi = locateSubfct(nls, subfct)) != NULL)
|
||||
return poi;
|
||||
|
||||
/* Failed --> return the hardcoded table */
|
||||
switch(subfct) {
|
||||
case 2: return &nlsUpHardcodedTable;
|
||||
case 4: return &nlsFnameUpHardcodedTable;
|
||||
/* case 5: return &nlsFnameTermHardcodedTable; */
|
||||
/* case 6: return &nlsCollHardcodedTable; */
|
||||
}
|
||||
/* Failed --> return the hardcoded table */
|
||||
switch (subfct)
|
||||
{
|
||||
case 2:
|
||||
return &nlsUpHardcodedTable;
|
||||
case 4:
|
||||
return &nlsFnameUpHardcodedTable;
|
||||
/* case 5: return &nlsFnameTermHardcodedTable; */
|
||||
/* case 6: return &nlsCollHardcodedTable; */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -239,36 +245,36 @@ STATIC VOID FAR *getTable(UBYTE subfct, struct nlsPackage FAR *nls)
|
||||
* the code to push bufsize, buf, call cpyBuf() and return its result.
|
||||
* The parameter were ordered to allow this code optimization.
|
||||
*/
|
||||
STATIC COUNT cpyBuf(VOID FAR *dst, UWORD dstlen
|
||||
, VOID FAR *src, UWORD srclen)
|
||||
STATIC COUNT cpyBuf(VOID FAR * dst, UWORD dstlen, VOID FAR * src,
|
||||
UWORD srclen)
|
||||
{
|
||||
if(srclen <= dstlen) {
|
||||
fmemcpy(dst, src, srclen);
|
||||
return SUCCESS;
|
||||
}
|
||||
return DE_INVLDFUNC; /* buffer too small */
|
||||
if (srclen <= dstlen)
|
||||
{
|
||||
fmemcpy(dst, src, srclen);
|
||||
return SUCCESS;
|
||||
}
|
||||
return DE_INVLDFUNC; /* buffer too small */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This function assumes that 'map' is adjusted such that
|
||||
* map[0x80] is the uppercase of character 0x80.
|
||||
*== 128 byte chartables, lower range conform to 7bit-US-ASCII ==ska*/
|
||||
STATIC VOID upMMem(UBYTE FAR *map, UBYTE FAR * str, unsigned len)
|
||||
STATIC VOID upMMem(UBYTE FAR * map, UBYTE FAR * str, unsigned len)
|
||||
{
|
||||
REG unsigned c;
|
||||
|
||||
#ifdef NLS_DEBUG
|
||||
UBYTE FAR *oldStr;
|
||||
unsigned oldLen;
|
||||
UBYTE FAR *oldStr;
|
||||
unsigned oldLen;
|
||||
|
||||
oldStr = str;
|
||||
oldLen = len;
|
||||
log( ("NLS: upMMem(): len=%u, %04x:%04x=\"", len, FP_SEG(str), FP_OFF(str)) );
|
||||
for(c = 0; c < len; ++c)
|
||||
printf("%c", str[c] > 32? str[c]: '.');
|
||||
printf("\"\n");
|
||||
oldStr = str;
|
||||
oldLen = len;
|
||||
log(("NLS: upMMem(): len=%u, %04x:%04x=\"", len, FP_SEG(str),
|
||||
FP_OFF(str)));
|
||||
for (c = 0; c < len; ++c)
|
||||
printf("%c", str[c] > 32 ? str[c] : '.');
|
||||
printf("\"\n");
|
||||
#endif
|
||||
if (len)
|
||||
do
|
||||
@ -281,14 +287,13 @@ log( ("NLS: upMMem(): len=%u, %04x:%04x=\"", len, FP_SEG(str), FP_OFF(str)) );
|
||||
}
|
||||
while (--len);
|
||||
#ifdef NLS_DEBUG
|
||||
printf("NLS: upMMem(): result=\"");
|
||||
for(c = 0; c < oldLen; ++c)
|
||||
printf("%c", oldStr[c] > 32? oldStr[c]: '.');
|
||||
printf("\"\n");
|
||||
printf("NLS: upMMem(): result=\"");
|
||||
for (c = 0; c < oldLen; ++c)
|
||||
printf("%c", oldStr[c] > 32 ? oldStr[c] : '.');
|
||||
printf("\"\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
***** Lowlevel interface *******************************************
|
||||
********************************************************************/
|
||||
@ -297,52 +302,53 @@ printf("NLS: upMMem(): result=\"");
|
||||
the direct-access interface.
|
||||
subfct == NLS_DOS_38 is a value > 0xff in order to not clash
|
||||
with subfunctions valid to be passed as DOS-65-XX. */
|
||||
STATIC int nlsGetData(struct nlsPackage FAR *nls, int subfct, UBYTE FAR *buf
|
||||
, unsigned bufsize)
|
||||
{ VOID FAR *poi;
|
||||
STATIC int nlsGetData(struct nlsPackage FAR * nls, int subfct,
|
||||
UBYTE FAR * buf, unsigned bufsize)
|
||||
{
|
||||
VOID FAR *poi;
|
||||
|
||||
log( ("NLS: nlsGetData(): subfct=%x, bufsize=%u, cp=%u, cntry=%u\n",
|
||||
subfct, bufsize, nls->cp, nls->cntry) );
|
||||
log(("NLS: nlsGetData(): subfct=%x, bufsize=%u, cp=%u, cntry=%u\n",
|
||||
subfct, bufsize, nls->cp, nls->cntry));
|
||||
|
||||
/* Theoretically tables 1 and, if NLS_REORDER_POINTERS is enabled,
|
||||
2 and 4 could be hard-coded, because their
|
||||
data is located at predictable (calculatable) locations.
|
||||
However, 1 and subfct NLS_DOS_38 are to handle the same
|
||||
data and the "locateSubfct()" call has to be implemented anyway,
|
||||
in order to handle all subfunctions.
|
||||
Also, NLS is often NOT used in any case, so this code is more
|
||||
size than speed optimized. */
|
||||
if((poi = locateSubfct(nls, subfct)) != NULL) {
|
||||
log( ("NLS: nlsGetData(): subfunction found\n") );
|
||||
switch(subfct) {
|
||||
case 1: /* Extended Country Information */
|
||||
return cpyBuf(buf, bufsize, poi
|
||||
, ((struct nlsExtCntryInfo FAR*)poi)->size + 3);
|
||||
case NLS_DOS_38: /* Normal Country Information */
|
||||
return cpyBuf(buf, bufsize
|
||||
, &(((struct nlsExtCntryInfo FAR*)poi)->dateFmt)
|
||||
, 24); /* standard cinfo has no more 34 _used_ bytes */
|
||||
/* don't copy 34, copy only 0x18 instead,
|
||||
see comment at DosGetCountryInformation TE */
|
||||
default:
|
||||
/* All other subfunctions just return the found nlsPoinerInf
|
||||
structure */
|
||||
return cpyBuf(buf, bufsize, poi, sizeof(struct nlsPointer));
|
||||
}
|
||||
}
|
||||
/* Theoretically tables 1 and, if NLS_REORDER_POINTERS is enabled,
|
||||
2 and 4 could be hard-coded, because their
|
||||
data is located at predictable (calculatable) locations.
|
||||
However, 1 and subfct NLS_DOS_38 are to handle the same
|
||||
data and the "locateSubfct()" call has to be implemented anyway,
|
||||
in order to handle all subfunctions.
|
||||
Also, NLS is often NOT used in any case, so this code is more
|
||||
size than speed optimized. */
|
||||
if ((poi = locateSubfct(nls, subfct)) != NULL)
|
||||
{
|
||||
log(("NLS: nlsGetData(): subfunction found\n"));
|
||||
switch (subfct)
|
||||
{
|
||||
case 1: /* Extended Country Information */
|
||||
return cpyBuf(buf, bufsize, poi,
|
||||
((struct nlsExtCntryInfo FAR *)poi)->size + 3);
|
||||
case NLS_DOS_38: /* Normal Country Information */
|
||||
return cpyBuf(buf, bufsize, &(((struct nlsExtCntryInfo FAR *)poi)->dateFmt), 24); /* standard cinfo has no more 34 _used_ bytes */
|
||||
/* don't copy 34, copy only 0x18 instead,
|
||||
see comment at DosGetCountryInformation TE */
|
||||
default:
|
||||
/* All other subfunctions just return the found nlsPoinerInf
|
||||
structure */
|
||||
return cpyBuf(buf, bufsize, poi, sizeof(struct nlsPointer));
|
||||
}
|
||||
}
|
||||
|
||||
/* The requested subfunction could not been located within the
|
||||
NLS pkg --> error. Because the data corresponds to the subfunction
|
||||
number passed to the API, the failure is the same as that a wrong
|
||||
API function has been called. */
|
||||
log( ("NLS: nlsGetData(): Subfunction not found\n") );
|
||||
return DE_INVLDFUNC;
|
||||
/* The requested subfunction could not been located within the
|
||||
NLS pkg --> error. Because the data corresponds to the subfunction
|
||||
number passed to the API, the failure is the same as that a wrong
|
||||
API function has been called. */
|
||||
log(("NLS: nlsGetData(): Subfunction not found\n"));
|
||||
return DE_INVLDFUNC;
|
||||
}
|
||||
|
||||
VOID nlsCPchange(UWORD cp)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(cp);
|
||||
printf("\7\nchange codepage not yet done ska\n");
|
||||
UNREFERENCED_PARAMETER(cp);
|
||||
printf("\7\nchange codepage not yet done ska\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -366,74 +372,75 @@ VOID nlsCPchange(UWORD cp)
|
||||
* appropriate codepage on its own.
|
||||
*/
|
||||
|
||||
STATIC COUNT nlsSetPackage(struct nlsPackage FAR *nls)
|
||||
STATIC COUNT nlsSetPackage(struct nlsPackage FAR * nls)
|
||||
{
|
||||
if(nls->cp != nlsInfo.actPkg->cp) /* Codepage gets changed -->
|
||||
inform all character drivers thereabout.
|
||||
If this fails, it would be possible that the old
|
||||
NLS pkg had been removed from memory by NLSFUNC. */
|
||||
nlsCPchange(nls->cp);
|
||||
if (nls->cp != nlsInfo.actPkg->cp) /* Codepage gets changed -->
|
||||
inform all character drivers thereabout.
|
||||
If this fails, it would be possible that the old
|
||||
NLS pkg had been removed from memory by NLSFUNC. */
|
||||
nlsCPchange(nls->cp);
|
||||
|
||||
nlsInfo.actPkg = nls;
|
||||
nlsInfo.actPkg = nls;
|
||||
|
||||
return SUCCESS;
|
||||
return SUCCESS;
|
||||
}
|
||||
STATIC COUNT DosSetPackage(UWORD cp, UWORD cntry)
|
||||
{ struct nlsPackage FAR*nls; /* NLS package to use to return the info from */
|
||||
|
||||
/* nls := NLS package of cntry/codepage */
|
||||
if((nls = searchPackage(cp, cntry)) != NULL)
|
||||
/* OK the NLS pkg is loaded --> activate it */
|
||||
return nlsSetPackage(nls);
|
||||
|
||||
/* not loaded --> invoke NLSFUNC to load it */
|
||||
return muxLoadPkg(cp, cntry);
|
||||
}
|
||||
|
||||
STATIC void nlsUpMem(struct nlsPackage FAR *nls, VOID FAR *str, int len)
|
||||
{
|
||||
log( ("NLS: nlsUpMem()\n") );
|
||||
upMMem(getCharTbl2(nls), (UBYTE FAR*)str, len);
|
||||
}
|
||||
STATIC void nlsFUpMem(struct nlsPackage FAR *nls, VOID FAR *str, int len)
|
||||
{
|
||||
log( ("NLS: nlsFUpMem()\n") );
|
||||
upMMem(getCharTbl4(nls), (UBYTE FAR*)str, len);
|
||||
struct nlsPackage FAR *nls; /* NLS package to use to return the info from */
|
||||
|
||||
/* nls := NLS package of cntry/codepage */
|
||||
if ((nls = searchPackage(cp, cntry)) != NULL)
|
||||
/* OK the NLS pkg is loaded --> activate it */
|
||||
return nlsSetPackage(nls);
|
||||
|
||||
/* not loaded --> invoke NLSFUNC to load it */
|
||||
return muxLoadPkg(cp, cntry);
|
||||
}
|
||||
|
||||
STATIC VOID xUpMem(struct nlsPackage FAR *nls, VOID FAR * str, unsigned len)
|
||||
STATIC void nlsUpMem(struct nlsPackage FAR * nls, VOID FAR * str, int len)
|
||||
{
|
||||
log(("NLS: nlsUpMem()\n"));
|
||||
upMMem(getCharTbl2(nls), (UBYTE FAR *) str, len);
|
||||
}
|
||||
STATIC void nlsFUpMem(struct nlsPackage FAR * nls, VOID FAR * str, int len)
|
||||
{
|
||||
log(("NLS: nlsFUpMem()\n"));
|
||||
upMMem(getCharTbl4(nls), (UBYTE FAR *) str, len);
|
||||
}
|
||||
|
||||
STATIC VOID xUpMem(struct nlsPackage FAR * nls, VOID FAR * str,
|
||||
unsigned len)
|
||||
/* upcase a memory area */
|
||||
{
|
||||
log( ("NLS: xUpMem(): cp=%u, cntry=%u\n", nls->cp, nls->cntry) );
|
||||
log(("NLS: xUpMem(): cp=%u, cntry=%u\n", nls->cp, nls->cntry));
|
||||
|
||||
if(nls->flags & NLS_FLAG_DIRECT_UPCASE)
|
||||
nlsUpMem(nls, str, len);
|
||||
else
|
||||
muxBufGo(NLSFUNC_UPMEM, 0, nls->cp, nls->cntry, len, str);
|
||||
if (nls->flags & NLS_FLAG_DIRECT_UPCASE)
|
||||
nlsUpMem(nls, str, len);
|
||||
else
|
||||
muxBufGo(NLSFUNC_UPMEM, 0, nls->cp, nls->cntry, len, str);
|
||||
}
|
||||
|
||||
STATIC int nlsYesNo(struct nlsPackage FAR *nls, unsigned char ch)
|
||||
STATIC int nlsYesNo(struct nlsPackage FAR * nls, unsigned char ch)
|
||||
{
|
||||
assertDSeqSS(); /* because "&ch" */
|
||||
assertDSeqSS(); /* because "&ch" */
|
||||
|
||||
log( ("NLS: nlsYesNo(): in ch=%u (%c)\n", ch, ch>32? ch: ' ') );
|
||||
log(("NLS: nlsYesNo(): in ch=%u (%c)\n", ch, ch > 32 ? ch : ' '));
|
||||
|
||||
xUpMem(nls, &ch, 1); /* Upcase character */
|
||||
/* Cannot use DosUpChar(), because
|
||||
maybe: nls != current NLS pkg
|
||||
However: Upcase character within lowlevel
|
||||
function to allow a yesNo() function
|
||||
catched by external MUX-14 handler, which
|
||||
does NOT upcase character. */
|
||||
log( ("NLS: nlsYesNo(): upcased ch=%u (%c)\n", ch, ch>32? ch: ' ') );
|
||||
if(ch == nls->yeschar)
|
||||
return 1;
|
||||
if(ch == nls->nochar)
|
||||
return 0;
|
||||
return 2;
|
||||
xUpMem(nls, &ch, 1); /* Upcase character */
|
||||
/* Cannot use DosUpChar(), because
|
||||
maybe: nls != current NLS pkg
|
||||
However: Upcase character within lowlevel
|
||||
function to allow a yesNo() function
|
||||
catched by external MUX-14 handler, which
|
||||
does NOT upcase character. */
|
||||
log(("NLS: nlsYesNo(): upcased ch=%u (%c)\n", ch, ch > 32 ? ch : ' '));
|
||||
if (ch == nls->yeschar)
|
||||
return 1;
|
||||
if (ch == nls->nochar)
|
||||
return 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
***** DOS API ******************************************************
|
||||
********************************************************************/
|
||||
@ -441,16 +448,16 @@ log( ("NLS: nlsYesNo(): upcased ch=%u (%c)\n", ch, ch>32? ch: ' ') );
|
||||
BYTE DosYesNo(unsigned char ch)
|
||||
/* returns: 0: ch == "No", 1: ch == "Yes", 2: ch crap */
|
||||
{
|
||||
if(nlsInfo.actPkg->flags & NLS_FLAG_DIRECT_YESNO)
|
||||
return nlsYesNo(nlsInfo.actPkg, ch);
|
||||
else
|
||||
return muxYesNo(ch);
|
||||
if (nlsInfo.actPkg->flags & NLS_FLAG_DIRECT_YESNO)
|
||||
return nlsYesNo(nlsInfo.actPkg, ch);
|
||||
else
|
||||
return muxYesNo(ch);
|
||||
}
|
||||
|
||||
|
||||
#ifndef DosUpMem
|
||||
VOID DosUpMem(VOID FAR * str, unsigned len)
|
||||
{ xUpMem(nlsInfo.actPkg, str, len);
|
||||
{
|
||||
xUpMem(nlsInfo.actPkg, str, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -463,47 +470,48 @@ VOID DosUpMem(VOID FAR * str, unsigned len)
|
||||
unsigned char ASMCFUNC DosUpChar(unsigned char ch)
|
||||
/* upcase a single character */
|
||||
{
|
||||
assertDSeqSS(); /* because "&ch" */
|
||||
log( ("NLS: DosUpChar(): in ch=%u (%c)\n", ch, ch>32? ch: ' ') );
|
||||
DosUpMem((UBYTE FAR*)&ch, 1);
|
||||
log( ("NLS: DosUpChar(): upcased ch=%u (%c)\n", ch, ch>32? ch: ' ') );
|
||||
return ch;
|
||||
assertDSeqSS(); /* because "&ch" */
|
||||
log(("NLS: DosUpChar(): in ch=%u (%c)\n", ch, ch > 32 ? ch : ' '));
|
||||
DosUpMem((UBYTE FAR *) & ch, 1);
|
||||
log(("NLS: DosUpChar(): upcased ch=%u (%c)\n", ch, ch > 32 ? ch : ' '));
|
||||
return ch;
|
||||
}
|
||||
|
||||
VOID DosUpString(char FAR *str)
|
||||
VOID DosUpString(char FAR * str)
|
||||
/* upcase a string */
|
||||
{
|
||||
DosUpMem(str, fstrlen(str));
|
||||
DosUpMem(str, fstrlen(str));
|
||||
}
|
||||
|
||||
VOID DosUpFMem(VOID FAR *str, unsigned len)
|
||||
VOID DosUpFMem(VOID FAR * str, unsigned len)
|
||||
/* upcase a memory area for file names */
|
||||
{
|
||||
#ifdef NLS_DEBUG
|
||||
unsigned c;
|
||||
log( ("NLS: DosUpFMem(): len=%u, %04x:%04x=\"", len, FP_SEG(str), FP_OFF(str)) );
|
||||
for(c = 0; c < len; ++c)
|
||||
printf("%c", str[c] > 32? str[c]: '.');
|
||||
printf("\"\n");
|
||||
unsigned c;
|
||||
log(("NLS: DosUpFMem(): len=%u, %04x:%04x=\"", len, FP_SEG(str),
|
||||
FP_OFF(str)));
|
||||
for (c = 0; c < len; ++c)
|
||||
printf("%c", str[c] > 32 ? str[c] : '.');
|
||||
printf("\"\n");
|
||||
#endif
|
||||
if(nlsInfo.actPkg->flags & NLS_FLAG_DIRECT_FUPCASE)
|
||||
nlsFUpMem(nlsInfo.actPkg, str, len);
|
||||
else
|
||||
muxUpMem(NLSFUNC_FILE_UPMEM, str, len);
|
||||
if (nlsInfo.actPkg->flags & NLS_FLAG_DIRECT_FUPCASE)
|
||||
nlsFUpMem(nlsInfo.actPkg, str, len);
|
||||
else
|
||||
muxUpMem(NLSFUNC_FILE_UPMEM, str, len);
|
||||
}
|
||||
|
||||
unsigned char DosUpFChar(unsigned char ch)
|
||||
/* upcase a single character for file names */
|
||||
{
|
||||
assertDSeqSS(); /* because "&ch" */
|
||||
DosUpFMem((UBYTE FAR*)&ch, 1);
|
||||
return ch;
|
||||
assertDSeqSS(); /* because "&ch" */
|
||||
DosUpFMem((UBYTE FAR *) & ch, 1);
|
||||
return ch;
|
||||
}
|
||||
|
||||
VOID DosUpFString(char FAR *str)
|
||||
VOID DosUpFString(char FAR * str)
|
||||
/* upcase a string for file names */
|
||||
{
|
||||
DosUpFMem(str, fstrlen(str));
|
||||
DosUpFMem(str, fstrlen(str));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -514,34 +522,35 @@ VOID DosUpFString(char FAR *str)
|
||||
* loaded, MUX-14 is invoked; otherwise the pkg's NLS_Fct_buf
|
||||
* function is invoked.
|
||||
*/
|
||||
COUNT DosGetData(int subfct, UWORD cp, UWORD cntry
|
||||
, UWORD bufsize, VOID FAR * buf)
|
||||
{ struct nlsPackage FAR*nls; /* NLS package to use to return the info from */
|
||||
COUNT DosGetData(int subfct, UWORD cp, UWORD cntry, UWORD bufsize,
|
||||
VOID FAR * buf)
|
||||
{
|
||||
struct nlsPackage FAR *nls; /* NLS package to use to return the info from */
|
||||
|
||||
log( ("NLS: GetData(): subfct=%x, cp=%u, cntry=%u, bufsize=%u\n",
|
||||
subfct, cp, cntry, bufsize) );
|
||||
log(("NLS: GetData(): subfct=%x, cp=%u, cntry=%u, bufsize=%u\n",
|
||||
subfct, cp, cntry, bufsize));
|
||||
|
||||
if(!buf || !bufsize)
|
||||
return DE_INVLDDATA;
|
||||
if(subfct == 0) /* Currently not supported */
|
||||
return DE_INVLDFUNC;
|
||||
if (!buf || !bufsize)
|
||||
return DE_INVLDDATA;
|
||||
if (subfct == 0) /* Currently not supported */
|
||||
return DE_INVLDFUNC;
|
||||
|
||||
/* nls := NLS package of cntry/codepage */
|
||||
if((nls = searchPackage(cp, cntry)) == NULL
|
||||
|| (nls->flags & NLS_FLAG_DIRECT_GETDATA) == 0) {
|
||||
/* If the NLS pkg is not loaded into memory or the
|
||||
direct-access flag is disabled, the request must
|
||||
be passed through MUX */
|
||||
return (subfct == NLS_DOS_38)
|
||||
? mux38(nls->cp, nls->cntry, bufsize, buf)
|
||||
: mux65(subfct, nls->cp, nls->cntry, bufsize, buf);
|
||||
}
|
||||
/* nls := NLS package of cntry/codepage */
|
||||
if ((nls = searchPackage(cp, cntry)) == NULL
|
||||
|| (nls->flags & NLS_FLAG_DIRECT_GETDATA) == 0)
|
||||
{
|
||||
/* If the NLS pkg is not loaded into memory or the
|
||||
direct-access flag is disabled, the request must
|
||||
be passed through MUX */
|
||||
return (subfct == NLS_DOS_38)
|
||||
? mux38(nls->cp, nls->cntry, bufsize, buf)
|
||||
: mux65(subfct, nls->cp, nls->cntry, bufsize, buf);
|
||||
}
|
||||
|
||||
/* Direct access to the data */
|
||||
return nlsGetData(nls, subfct, buf, bufsize);
|
||||
/* Direct access to the data */
|
||||
return nlsGetData(nls, subfct, buf, bufsize);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called for DOS-38 get info
|
||||
*
|
||||
@ -556,10 +565,11 @@ log( ("NLS: GetData(): subfct=%x, cp=%u, cntry=%u, bufsize=%u\n",
|
||||
* RBIL documents 0x18 bytes and calls 10 bytes 'reserved'
|
||||
* so we change the amount of copied bytes to 0x18
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DosGetCountryInformation
|
||||
COUNT DosGetCountryInformation(UWORD cntry, VOID FAR *buf)
|
||||
{ return DosGetData(NLS_DOS_38, NLS_DEFAULT, cntry, 0x18, buf);
|
||||
COUNT DosGetCountryInformation(UWORD cntry, VOID FAR * buf)
|
||||
{
|
||||
return DosGetData(NLS_DOS_38, NLS_DEFAULT, cntry, 0x18, buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -568,17 +578,19 @@ COUNT DosGetCountryInformation(UWORD cntry, VOID FAR *buf)
|
||||
*/
|
||||
#ifndef DosSetCountry
|
||||
COUNT DosSetCountry(UWORD cntry)
|
||||
{ return DosSetPackage(NLS_DEFAULT, cntry);
|
||||
{
|
||||
return DosSetPackage(NLS_DEFAULT, cntry);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Called for DOS-66-01 get CP
|
||||
*/
|
||||
COUNT DosGetCodepage(UWORD FAR* actCP, UWORD FAR* sysCP)
|
||||
{ *sysCP = nlsInfo.sysCodePage;
|
||||
*actCP = nlsInfo.actPkg->cp;
|
||||
return SUCCESS;
|
||||
COUNT DosGetCodepage(UWORD FAR * actCP, UWORD FAR * sysCP)
|
||||
{
|
||||
*sysCP = nlsInfo.sysCodePage;
|
||||
*actCP = nlsInfo.actPkg->cp;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -587,9 +599,10 @@ COUNT DosGetCodepage(UWORD FAR* actCP, UWORD FAR* sysCP)
|
||||
* to specify it, is lost to me. (2000/02/13 ska)
|
||||
*/
|
||||
COUNT DosSetCodepage(UWORD actCP, UWORD sysCP)
|
||||
{ if(sysCP == NLS_DEFAULT || sysCP == nlsInfo.sysCodePage)
|
||||
return DosSetPackage(actCP, NLS_DEFAULT);
|
||||
return DE_INVLDDATA;
|
||||
{
|
||||
if (sysCP == NLS_DEFAULT || sysCP == nlsInfo.sysCodePage)
|
||||
return DosSetPackage(actCP, NLS_DEFAULT);
|
||||
return DE_INVLDDATA;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
@ -608,57 +621,59 @@ COUNT DosSetCodepage(UWORD actCP, UWORD sysCP)
|
||||
if AL == 0, Carry must be cleared, otherwise set
|
||||
*/
|
||||
UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS)
|
||||
{ struct nlsPackage FAR*nls; /* addressed NLS package */
|
||||
{
|
||||
struct nlsPackage FAR *nls; /* addressed NLS package */
|
||||
|
||||
UNREFERENCED_PARAMETER (flags);
|
||||
UNREFERENCED_PARAMETER (cs);
|
||||
UNREFERENCED_PARAMETER (ip);
|
||||
UNREFERENCED_PARAMETER (ds);
|
||||
UNREFERENCED_PARAMETER (es);
|
||||
UNREFERENCED_PARAMETER (si);
|
||||
UNREFERENCED_PARAMETER(flags);
|
||||
UNREFERENCED_PARAMETER(cs);
|
||||
UNREFERENCED_PARAMETER(ip);
|
||||
UNREFERENCED_PARAMETER(ds);
|
||||
UNREFERENCED_PARAMETER(es);
|
||||
UNREFERENCED_PARAMETER(si);
|
||||
|
||||
log( ("NLS: MUX14(): subfct=%x, cp=%u, cntry=%u\n",
|
||||
AL, BX, DX) );
|
||||
log(("NLS: MUX14(): subfct=%x, cp=%u, cntry=%u\n", AL, BX, DX));
|
||||
|
||||
if((nls = searchPackage(BX, DX)) == NULL)
|
||||
return DE_INVLDFUNC; /* no such package */
|
||||
if ((nls = searchPackage(BX, DX)) == NULL)
|
||||
return DE_INVLDFUNC; /* no such package */
|
||||
|
||||
log( ("NLS: MUX14(): NLS pkg found\n") );
|
||||
log(("NLS: MUX14(): NLS pkg found\n"));
|
||||
|
||||
switch(AL) {
|
||||
case NLSFUNC_INSTALL_CHECK:
|
||||
BX = NLS_FREEDOS_NLSFUNC_ID;
|
||||
return SUCCESS; /* kernel just simulates default functions */
|
||||
case NLSFUNC_DOS38:
|
||||
return nlsGetData(nls, NLS_DOS_38, MK_FP(ES, DI), 34);
|
||||
case NLSFUNC_GETDATA:
|
||||
return nlsGetData(nls, BP, MK_FP(ES, DI), CX);
|
||||
case NLSFUNC_DRDOS_GETDATA:
|
||||
/* Does not pass buffer length */
|
||||
return nlsGetData(nls, CL, MK_FP(ES, DI), 512);
|
||||
case NLSFUNC_LOAD_PKG:
|
||||
case NLSFUNC_LOAD_PKG2:
|
||||
return nlsSetPackage(nls);
|
||||
case NLSFUNC_YESNO:
|
||||
return nlsYesNo(nls, CL);
|
||||
case NLSFUNC_UPMEM:
|
||||
nlsUpMem(nls, MK_FP(ES, DI), CX);
|
||||
return SUCCESS;
|
||||
case NLSFUNC_FILE_UPMEM:
|
||||
switch (AL)
|
||||
{
|
||||
case NLSFUNC_INSTALL_CHECK:
|
||||
BX = NLS_FREEDOS_NLSFUNC_ID;
|
||||
return SUCCESS; /* kernel just simulates default functions */
|
||||
case NLSFUNC_DOS38:
|
||||
return nlsGetData(nls, NLS_DOS_38, MK_FP(ES, DI), 34);
|
||||
case NLSFUNC_GETDATA:
|
||||
return nlsGetData(nls, BP, MK_FP(ES, DI), CX);
|
||||
case NLSFUNC_DRDOS_GETDATA:
|
||||
/* Does not pass buffer length */
|
||||
return nlsGetData(nls, CL, MK_FP(ES, DI), 512);
|
||||
case NLSFUNC_LOAD_PKG:
|
||||
case NLSFUNC_LOAD_PKG2:
|
||||
return nlsSetPackage(nls);
|
||||
case NLSFUNC_YESNO:
|
||||
return nlsYesNo(nls, CL);
|
||||
case NLSFUNC_UPMEM:
|
||||
nlsUpMem(nls, MK_FP(ES, DI), CX);
|
||||
return SUCCESS;
|
||||
case NLSFUNC_FILE_UPMEM:
|
||||
#ifdef NLS_DEBUG
|
||||
{ unsigned j;
|
||||
BYTE FAR *p;
|
||||
log( ("NLS: MUX14(FILE_UPMEM): len=%u, %04x:%04x=\"", CX, ES, DI) );
|
||||
for(j = 0, p = MK_FP(ES, DI); j < CX; ++j)
|
||||
printf("%c", p[j] > 32? p[j]: '.');
|
||||
printf("\"\n");
|
||||
}
|
||||
{
|
||||
unsigned j;
|
||||
BYTE FAR *p;
|
||||
log(("NLS: MUX14(FILE_UPMEM): len=%u, %04x:%04x=\"", CX, ES, DI));
|
||||
for (j = 0, p = MK_FP(ES, DI); j < CX; ++j)
|
||||
printf("%c", p[j] > 32 ? p[j] : '.');
|
||||
printf("\"\n");
|
||||
}
|
||||
#endif
|
||||
nlsFUpMem(nls, MK_FP(ES, DI), CX);
|
||||
return SUCCESS;
|
||||
}
|
||||
log( ("NLS: MUX14(): Invalid function %x\n", AL) );
|
||||
return DE_INVLDFUNC; /* no such function */
|
||||
nlsFUpMem(nls, MK_FP(ES, DI), CX);
|
||||
return SUCCESS;
|
||||
}
|
||||
log(("NLS: MUX14(): Invalid function %x\n", AL));
|
||||
return DE_INVLDFUNC; /* no such function */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -668,4 +683,3 @@ log( ("NLS: MUX14(): Invalid function %x\n", AL) );
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -28,14 +28,14 @@
|
||||
/* Cambridge, MA 02139, USA. */
|
||||
/****************************************************************/
|
||||
|
||||
|
||||
#include "portab.h"
|
||||
#include "globals.h"
|
||||
//#include "pcb.h"
|
||||
#include <nls.h>
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId = "$Id$";
|
||||
static BYTE *RcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#define filename Config.cfgCSYS_fnam
|
||||
@ -44,79 +44,87 @@ static BYTE *RcsId = "$Id$";
|
||||
|
||||
static int err(void)
|
||||
{
|
||||
printf("Syntax error in or invalid COUNTRY.SYS: \"%s\"\n"
|
||||
, filename);
|
||||
return 0;
|
||||
printf("Syntax error in or invalid COUNTRY.SYS: \"%s\"\n", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define readStruct(s) readStructure(&(s), sizeof(s), fd)
|
||||
static int readStructure(void *buf, int size, COUNT fd)
|
||||
{ if(DosRead(fd, buf, size) == size)
|
||||
return 1;
|
||||
{
|
||||
if (DosRead(fd, buf, size) == size)
|
||||
return 1;
|
||||
|
||||
return err();
|
||||
return err();
|
||||
}
|
||||
/* Evaluate each argument only once */
|
||||
|
||||
/* Evaluate each argument only once */
|
||||
#define readFct(p,f) readFct_((p), (f), fd)
|
||||
int readFct_(void *buf, struct csys_function *fct, COUNT fd)
|
||||
{ if(DosLseek(fd, fct->csys_rpos, 0) >= 0)
|
||||
return readStructure(buf, fct->csys_length, fd);
|
||||
return err();
|
||||
{
|
||||
if (DosLseek(fd, fct->csys_rpos, 0) >= 0)
|
||||
return readStructure(buf, fct->csys_length, fd);
|
||||
return err();
|
||||
}
|
||||
|
||||
#define seek(n) rseek((LONG)(n), fd)
|
||||
static rseek(LONG rpos, COUNT fd)
|
||||
{ if(DosLseek(fd, rpos, 1) >= 0)
|
||||
return 1;
|
||||
{
|
||||
if (DosLseek(fd, rpos, 1) >= 0)
|
||||
return 1;
|
||||
|
||||
return err();
|
||||
return err();
|
||||
}
|
||||
|
||||
|
||||
COUNT csysOpen(void)
|
||||
{ COUNT fd;
|
||||
struct nlsCSys_fileHeader header;
|
||||
{
|
||||
COUNT fd;
|
||||
struct nlsCSys_fileHeader header;
|
||||
|
||||
if((fd = DosOpen((BYTE FAR*)filename, 0)) < 0) {
|
||||
printf("Cannot open: \"%s\"\n", filename);
|
||||
return 1;
|
||||
}
|
||||
if ((fd = DosOpen((BYTE FAR *) filename, 0)) < 0)
|
||||
{
|
||||
printf("Cannot open: \"%s\"\n", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(DosRead(fd, &header, sizeof(header)) != sizeof(header);
|
||||
|| strcmp(header.csys_idstring, CSYS_FD_IDSTRING) != 0
|
||||
|| DosLseek(fd, (LONG)sizeof(csys_completeFileHeader), 0)
|
||||
!= (LONG)sizeof(csys_completeFileHeader)) {
|
||||
printf("No valid COUNTRY.SYS: \"%s\"\n\nTry NLSFUNC /i %s\n"
|
||||
, filename, filename);
|
||||
DosClose(fd);
|
||||
return -1;
|
||||
}
|
||||
if (DosRead(fd, &header, sizeof(header)) != sizeof(header);
|
||||
||strcmp(header.csys_idstring, CSYS_FD_IDSTRING) != 0
|
||||
|| DosLseek(fd, (LONG) sizeof(csys_completeFileHeader), 0)
|
||||
!= (LONG) sizeof(csys_completeFileHeader))
|
||||
{
|
||||
printf("No valid COUNTRY.SYS: \"%s\"\n\nTry NLSFUNC /i %s\n", filename,
|
||||
filename);
|
||||
DosClose(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Searches for function definition of table #fctID and
|
||||
moves it at index idx */
|
||||
static int chkTable(int idx, int fctID, struct csys_function *fcts
|
||||
, int numFct)
|
||||
{ struct csys_function *fct, hfct;
|
||||
int i;
|
||||
static int chkTable(int idx, int fctID, struct csys_function *fcts,
|
||||
int numFct)
|
||||
{
|
||||
struct csys_function *fct, hfct;
|
||||
int i;
|
||||
|
||||
for(i = 0, fct = fcts; i < numFct; ++i, ++fct)
|
||||
if(fct->csys_fctID == fctID) {
|
||||
/* function found */
|
||||
if(i == idx) /* already best place */
|
||||
return 1;
|
||||
/* Swap both places */
|
||||
memcpy(&hfct, fct, sizeof(hfct));
|
||||
memcpy(fct, &fcts[idx], sizeof(hfct));
|
||||
memcpy(&fcts[idx], &hfct, sizeof(hfct));
|
||||
return 1;
|
||||
}
|
||||
for (i = 0, fct = fcts; i < numFct; ++i, ++fct)
|
||||
if (fct->csys_fctID == fctID)
|
||||
{
|
||||
/* function found */
|
||||
if (i == idx) /* already best place */
|
||||
return 1;
|
||||
/* Swap both places */
|
||||
memcpy(&hfct, fct, sizeof(hfct));
|
||||
memcpy(fct, &fcts[idx], sizeof(hfct));
|
||||
memcpy(&fcts[idx], &hfct, sizeof(hfct));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Mandatory table %u not found.\n", fctID);
|
||||
return 0;
|
||||
printf("Mandatory table %u not found.\n", fctID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description of the algorithm the COUNTRY= information is loaded.
|
||||
|
||||
@ -172,7 +180,6 @@ a) The area containing the S3 structures, and
|
||||
b) probably the last loaded data could be found within the memory already,
|
||||
so the nlsPackage structure is larger than necessary.
|
||||
|
||||
|
||||
8) But the memory allocation in pass 1 is temporary anyway, because in
|
||||
the PostConfig() phase, all memory allocations are revoked and created
|
||||
anew. At this point -- immediately after revoking all memory and
|
||||
@ -197,187 +204,208 @@ indicates that the FP_OFF(...) is the offset base-relative to the data
|
||||
offset; which is base-relative to the "nls" pointer.
|
||||
*/
|
||||
int csysLoadPackage(COUNT fd)
|
||||
{ struct csys_numEntries entries;
|
||||
struct csys_ccDefinition entry;
|
||||
struct csys_function *fcts;
|
||||
struct nlsPackage *nls;
|
||||
struct nlsPointer *poi;
|
||||
int highmark, numFct, i, j;
|
||||
int totalSize;
|
||||
{
|
||||
struct csys_numEntries entries;
|
||||
struct csys_ccDefinition entry;
|
||||
struct csys_function *fcts;
|
||||
struct nlsPackage *nls;
|
||||
struct nlsPointer *poi;
|
||||
int highmark, numFct, i, j;
|
||||
int totalSize;
|
||||
#ifndef NLS_MODIFYABLE_DATA
|
||||
BYTE FAR * p;
|
||||
BYTE FAR *p;
|
||||
#endif
|
||||
#define numE entries.csys_entries
|
||||
#define bufp(offset) (((BYTE*)nls) + (offset))
|
||||
#define fct fcts[numFct]
|
||||
|
||||
/* When this function is called, the position of the file is
|
||||
at offset 128 (number of country/codepage pairs) */
|
||||
if(!readStruct(entries))
|
||||
return 0;
|
||||
while(numE--) {
|
||||
if(!readStruct(entry))
|
||||
return 0;
|
||||
if(entry.csys_cntry == cntry
|
||||
&& (cp == NLS_DEFAULT || entry.csys_cp == cp)) {
|
||||
/* Requested entry found! */
|
||||
if(!seek(entry.csys_rpos)
|
||||
|| !readStruct(entries))
|
||||
return 0;
|
||||
/* Now reading the function definitions at this position */
|
||||
if(numE < 5) {
|
||||
printf("Syntax error in COUNTRY.SYS: Too few subfunctions\n");
|
||||
return 0;
|
||||
}
|
||||
/* If the file structure is good, each but one entry (0x23) is
|
||||
one item within nlsPointers[] array */
|
||||
fcts = KernelAlloc(sizeof(struct csys_function) * numE);
|
||||
numFct = 0; /* number of already loaded fct definition */
|
||||
totalSize = 0;
|
||||
{
|
||||
if(!readStruct(fct))
|
||||
return 0;
|
||||
switch(fct.csys_fctID) {
|
||||
case 0: case 0x20: case 0x21: case 0x22:
|
||||
case 0xA0: case 0xA1: case 0xA2:
|
||||
printf("Invalid subfunction %u ignored", fct.csys_fctID);
|
||||
continue;
|
||||
case 0x23:
|
||||
if(fct.csys_length != 2) {
|
||||
printf("Pseudo-table 35 length mismatch\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* Search if the subfunction is already there */
|
||||
for(j = 0; j < numFcts && fcts[j].csys_fctID != fct.csys_fctID
|
||||
; ++j);
|
||||
if(j != numFct) {
|
||||
printf("Subfunction %u defined multiple times, ignored\n"
|
||||
, fct.csys_fctID);
|
||||
continue;
|
||||
}
|
||||
/* When this function is called, the position of the file is
|
||||
at offset 128 (number of country/codepage pairs) */
|
||||
if (!readStruct(entries))
|
||||
return 0;
|
||||
while (numE--)
|
||||
{
|
||||
if (!readStruct(entry))
|
||||
return 0;
|
||||
if (entry.csys_cntry == cntry
|
||||
&& (cp == NLS_DEFAULT || entry.csys_cp == cp))
|
||||
{
|
||||
/* Requested entry found! */
|
||||
if (!seek(entry.csys_rpos) || !readStruct(entries))
|
||||
return 0;
|
||||
/* Now reading the function definitions at this position */
|
||||
if (numE < 5)
|
||||
{
|
||||
printf("Syntax error in COUNTRY.SYS: Too few subfunctions\n");
|
||||
return 0;
|
||||
}
|
||||
/* If the file structure is good, each but one entry (0x23) is
|
||||
one item within nlsPointers[] array */
|
||||
fcts = KernelAlloc(sizeof(struct csys_function) * numE);
|
||||
numFct = 0; /* number of already loaded fct definition */
|
||||
totalSize = 0;
|
||||
{
|
||||
if (!readStruct(fct))
|
||||
return 0;
|
||||
switch (fct.csys_fctID)
|
||||
{
|
||||
case 0:
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
case 0xA0:
|
||||
case 0xA1:
|
||||
case 0xA2:
|
||||
printf("Invalid subfunction %u ignored", fct.csys_fctID);
|
||||
continue;
|
||||
case 0x23:
|
||||
if (fct.csys_length != 2)
|
||||
{
|
||||
printf("Pseudo-table 35 length mismatch\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* Search if the subfunction is already there */
|
||||
for (j = 0; j < numFcts && fcts[j].csys_fctID != fct.csys_fctID;
|
||||
++j) ;
|
||||
if (j != numFct)
|
||||
{
|
||||
printf("Subfunction %u defined multiple times, ignored\n",
|
||||
fct.csys_fctID);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* OK --> update the rpos member */
|
||||
fct.csys_rpos += DosLtell(fd);
|
||||
totalSize += fct.csys_length;
|
||||
++numFct;
|
||||
} while(--numE);
|
||||
/* OK --> update the rpos member */
|
||||
fct.csys_rpos += DosLtell(fd);
|
||||
totalSize += fct.csys_length;
|
||||
++numFct;
|
||||
}
|
||||
while (--numE) ;
|
||||
|
||||
/* i is the number of available function definition */
|
||||
/* check if all mandatory tables are loaded, at the same
|
||||
time re-order the function definitions like that:
|
||||
0x23, 1, 2, 4, 5
|
||||
*/
|
||||
/* i is the number of available function definition */
|
||||
/* check if all mandatory tables are loaded, at the same
|
||||
time re-order the function definitions like that:
|
||||
0x23, 1, 2, 4, 5
|
||||
*/
|
||||
|
||||
/* That's automatically a check that more than 3 definitions
|
||||
are available */
|
||||
if(!chkTable(0, 0x23, fcts, numFct) /* pseudo-table 0x23 yes/no */
|
||||
|| !chkTable(1, 1, fcts, numFct) /* ext cntry info */
|
||||
|| !chkTable(2, 2, fcts, numFct) /* normal upcase */
|
||||
|| !chkTable(3, 4, fcts, numFct) /* filename upcase */
|
||||
|| !chkTable(4, 5, fcts, numFct)) /* filename terminator chars */
|
||||
return 0;
|
||||
/* That's automatically a check that more than 3 definitions
|
||||
are available */
|
||||
if (!chkTable(0, 0x23, fcts, numFct) /* pseudo-table 0x23 yes/no */
|
||||
|| !chkTable(1, 1, fcts, numFct) /* ext cntry info */
|
||||
|| !chkTable(2, 2, fcts, numFct) /* normal upcase */
|
||||
|| !chkTable(3, 4, fcts, numFct) /* filename upcase */
|
||||
|| !chkTable(4, 5, fcts, numFct)) /* filename terminator chars */
|
||||
return 0;
|
||||
|
||||
/* Begin the loading process by to allocate memory as if
|
||||
we had to load every byte */
|
||||
/* One nlsPointers structure is already part of nlsPackage;
|
||||
two function definitions need no nlsPointers entry (0x32, 1);
|
||||
one additional byte is required by table 1, but which is
|
||||
already within totalSize as the length of pseudo-table
|
||||
0x23 has been counted. */
|
||||
nls = KernelAlloc((data = sizeof(nlsPackage)
|
||||
+ (numFct - 3) * sizeof(struct nlsPointer)) + totalSize);
|
||||
/* data := first byte not used by the control area of
|
||||
the nlsPackage structure; at this point it is the
|
||||
offset where table #1 is to be loaded to*/
|
||||
/* Begin the loading process by to allocate memory as if
|
||||
we had to load every byte */
|
||||
/* One nlsPointers structure is already part of nlsPackage;
|
||||
two function definitions need no nlsPointers entry (0x32, 1);
|
||||
one additional byte is required by table 1, but which is
|
||||
already within totalSize as the length of pseudo-table
|
||||
0x23 has been counted. */
|
||||
nls = KernelAlloc((data = sizeof(nlsPackage)
|
||||
+ (numFct - 3) * sizeof(struct nlsPointer)) +
|
||||
totalSize);
|
||||
/* data := first byte not used by the control area of
|
||||
the nlsPackage structure; at this point it is the
|
||||
offset where table #1 is to be loaded to */
|
||||
|
||||
/* Install pseudo-table 0x23 */
|
||||
if(!readFct((BYTE*)&nls->yeschar, fcts))
|
||||
return 0;
|
||||
nls->numSubfct = numFct - 1; /* pseudo-table 0x23 */
|
||||
/* Install pseudo-table 0x23 */
|
||||
if (!readFct((BYTE *) & nls->yeschar, fcts))
|
||||
return 0;
|
||||
nls->numSubfct = numFct - 1; /* pseudo-table 0x23 */
|
||||
|
||||
/* Install table #1 has it must overlay the last nlsPointers[]
|
||||
item */
|
||||
*bufp(data) = 1; /* table #1 starts with the subfctID
|
||||
then the data from the file follows */
|
||||
if(!readFct(bufp(++data), ++fcts))
|
||||
return 0;
|
||||
data += fcts->csys_length; /* first byte of local data area */
|
||||
highmark = data; /* first unused byte */
|
||||
/* Install table #1 has it must overlay the last nlsPointers[]
|
||||
item */
|
||||
*bufp(data) = 1; /* table #1 starts with the subfctID
|
||||
then the data from the file follows */
|
||||
if (!readFct(bufp(++data), ++fcts))
|
||||
return 0;
|
||||
data += fcts->csys_length; /* first byte of local data area */
|
||||
highmark = data; /* first unused byte */
|
||||
|
||||
for(j = 0, poi = nls->nlsPointers; j < numFct - 1; ++j, ++poi) {
|
||||
/* consecutively load all functions */
|
||||
if(!readFct(bufp(data), ++fcts))
|
||||
return 0;
|
||||
poi->subfct = fcts->csys_fctID;
|
||||
/* Now the function data is located at the current top of
|
||||
used memory and, if allowed, the other memory is
|
||||
tested, if such image is already loaded */
|
||||
for (j = 0, poi = nls->nlsPointers; j < numFct - 1; ++j, ++poi)
|
||||
{
|
||||
/* consecutively load all functions */
|
||||
if (!readFct(bufp(data), ++fcts))
|
||||
return 0;
|
||||
poi->subfct = fcts->csys_fctID;
|
||||
/* Now the function data is located at the current top of
|
||||
used memory and, if allowed, the other memory is
|
||||
tested, if such image is already loaded */
|
||||
#ifndef NLS_MODIFYABLE_DATA
|
||||
/* Try to locate the contents of the buffer */
|
||||
/** brute force **/
|
||||
/* For the standard tables one need to match tables
|
||||
2 and 4 only. */
|
||||
for(i = data; i + fcts->csys_length < highmark; ++i) {
|
||||
if(memcmp(bufp(i), bufp(highmark), fcts->csys_length)
|
||||
== 0) {
|
||||
/* found! */
|
||||
/* ==> leave highmark untouch, but modify pointer */
|
||||
poi->pointer = MK_FP(0, i);
|
||||
/* the segment portion == 0 identifies this pointer
|
||||
as local within the current data area */
|
||||
goto nxtEntry;
|
||||
}
|
||||
}
|
||||
/* Now try the hardcoded area */
|
||||
for(p = hcTablesStart; p < hcTablesEnd - fcts->csys_length
|
||||
; ++p) {
|
||||
if(fmemcmp(p, bufp(highmark), fcts->csys_length) == 0) {
|
||||
/* found! */
|
||||
/* ==> leave highmark untouch, but modify pointer */
|
||||
poi->pointer = p;
|
||||
/* the segment portion != 0 identifies this is an
|
||||
absolute pointer */
|
||||
goto nxtEntry;
|
||||
}
|
||||
}
|
||||
/* Try to locate the contents of the buffer */
|
||||
/** brute force **/
|
||||
/* For the standard tables one need to match tables
|
||||
2 and 4 only. */
|
||||
for (i = data; i + fcts->csys_length < highmark; ++i)
|
||||
{
|
||||
if (memcmp(bufp(i), bufp(highmark), fcts->csys_length) == 0)
|
||||
{
|
||||
/* found! */
|
||||
/* ==> leave highmark untouch, but modify pointer */
|
||||
poi->pointer = MK_FP(0, i);
|
||||
/* the segment portion == 0 identifies this pointer
|
||||
as local within the current data area */
|
||||
goto nxtEntry;
|
||||
}
|
||||
}
|
||||
/* Now try the hardcoded area */
|
||||
for (p = hcTablesStart; p < hcTablesEnd - fcts->csys_length; ++p)
|
||||
{
|
||||
if (fmemcmp(p, bufp(highmark), fcts->csys_length) == 0)
|
||||
{
|
||||
/* found! */
|
||||
/* ==> leave highmark untouch, but modify pointer */
|
||||
poi->pointer = p;
|
||||
/* the segment portion != 0 identifies this is an
|
||||
absolute pointer */
|
||||
goto nxtEntry;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Either not found or modifyable data allowed */
|
||||
poi->pointer = MK_FP(0, highmark); /* local address */
|
||||
highmark += fcts->csys_length; /* need to keep the data */
|
||||
nxtEntry:
|
||||
}
|
||||
/* how many memory is really required */
|
||||
Country.cfgCSYS_memory = highmark;
|
||||
Country.cfgCSYS_data = nls;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* Either not found or modifyable data allowed */
|
||||
poi->pointer = MK_FP(0, highmark); /* local address */
|
||||
highmark += fcts->csys_length; /* need to keep the data */
|
||||
nxtEntry:
|
||||
}
|
||||
/* how many memory is really required */
|
||||
Country.cfgCSYS_memory = highmark;
|
||||
Country.cfgCSYS_data = nls;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#undef numE
|
||||
if(cp == NLS_DEFAULT)
|
||||
printf("No definition of country ID %u in file \"%s\"\n",
|
||||
cntry, filename);
|
||||
else
|
||||
printf("No definition of country ID %u for codepage %u in file \"%s\"\n",
|
||||
cntry, cp, filename);
|
||||
if (cp == NLS_DEFAULT)
|
||||
printf("No definition of country ID %u in file \"%s\"\n",
|
||||
cntry, filename);
|
||||
else
|
||||
printf
|
||||
("No definition of country ID %u for codepage %u in file \"%s\"\n",
|
||||
cntry, cp, filename);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
INIT BOOL LoadCountryInfo(char *fnam)
|
||||
{ COUNT fd;
|
||||
int rc;
|
||||
{
|
||||
COUNT fd;
|
||||
int rc;
|
||||
|
||||
if(strlen(fnam) < sizeof(filename)) {
|
||||
strcpy(filename, fnam);
|
||||
if((fd = csysOpen()) >= 0) {
|
||||
rc = csysLoadPackage(fd);
|
||||
DosClose(fd);
|
||||
return rc;
|
||||
}
|
||||
} else
|
||||
printf("Filename too long\n");
|
||||
return 0;
|
||||
if (strlen(fnam) < sizeof(filename))
|
||||
{
|
||||
strcpy(filename, fnam);
|
||||
if ((fd = csysOpen()) >= 0)
|
||||
{
|
||||
rc = csysLoadPackage(fd);
|
||||
DosClose(fd);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
else
|
||||
printf("Filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -387,4 +415,3 @@ INIT BOOL LoadCountryInfo(char *fnam)
|
||||
* Add new files and update cvs with patches and changes
|
||||
*
|
||||
*/
|
||||
|
||||
|
454
kernel/prf.c
454
kernel/prf.c
@ -41,11 +41,11 @@
|
||||
#define hexd init_hexd
|
||||
#endif
|
||||
|
||||
COUNT ASMCFUNC fstrlen (BYTE FAR * s); /* don't want globals.h, sorry */
|
||||
|
||||
COUNT ASMCFUNC fstrlen(BYTE FAR * s); /* don't want globals.h, sorry */
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *prfRcsId = "$Id$";
|
||||
static BYTE *prfRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
static BYTE *charp = 0;
|
||||
@ -70,45 +70,44 @@ VOID cso();
|
||||
#endif
|
||||
|
||||
#ifdef FORSYS
|
||||
COUNT fstrlen (BYTE FAR * s) /* don't want globals.h, sorry */
|
||||
COUNT fstrlen(BYTE FAR * s) /* don't want globals.h, sorry */
|
||||
{
|
||||
int i = 0;
|
||||
int i = 0;
|
||||
|
||||
while (*s++)
|
||||
i++;
|
||||
while (*s++)
|
||||
i++;
|
||||
|
||||
return i;
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* special console output routine */
|
||||
VOID
|
||||
put_console(COUNT c)
|
||||
VOID put_console(COUNT c)
|
||||
{
|
||||
if (c == '\n')
|
||||
put_console('\r');
|
||||
|
||||
#ifdef FORSYS
|
||||
write(1,&c,1); /* write character to stdout */
|
||||
#else
|
||||
#if defined(__TURBOC__)
|
||||
write(1, &c, 1); /* write character to stdout */
|
||||
#else
|
||||
#if defined(__TURBOC__)
|
||||
_AX = 0x0e00 | c;
|
||||
_BX = 0x0070;
|
||||
__int__(0x10);
|
||||
#else
|
||||
__asm {
|
||||
mov al, byte ptr c;
|
||||
mov ah, 0x0e;
|
||||
mov bx, 0x0070;
|
||||
int 0x10;
|
||||
}
|
||||
#endif /* __TURBO__*/
|
||||
#endif
|
||||
__asm
|
||||
{
|
||||
mov al, byte ptr c;
|
||||
mov ah, 0x0e;
|
||||
mov bx, 0x0070;
|
||||
int 0x10;
|
||||
}
|
||||
#endif /* __TURBO__ */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* special handler to switch between sprintf and printf */
|
||||
static VOID
|
||||
handle_char(COUNT c)
|
||||
static VOID handle_char(COUNT c)
|
||||
{
|
||||
if (charp == 0)
|
||||
put_console(c);
|
||||
@ -117,34 +116,33 @@ static VOID
|
||||
}
|
||||
|
||||
/* ltob -- convert an long integer to a string in any base (2-16) */
|
||||
BYTE *
|
||||
ltob(LONG n, BYTE * s, COUNT base)
|
||||
BYTE *ltob(LONG n, BYTE * s, COUNT base)
|
||||
{
|
||||
ULONG u;
|
||||
BYTE *p, *q;
|
||||
int c;
|
||||
int c;
|
||||
|
||||
u = n;
|
||||
u = n;
|
||||
|
||||
if (base == -10) /* signals signed conversion */
|
||||
{
|
||||
{
|
||||
base = 10;
|
||||
if (n < 0 )
|
||||
{
|
||||
u = -n;
|
||||
*s++ = '-';
|
||||
}
|
||||
}
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
u = -n;
|
||||
*s++ = '-';
|
||||
}
|
||||
}
|
||||
|
||||
p = q = s;
|
||||
do
|
||||
{ /* generate digits in reverse order */
|
||||
static char hexDigits[] = "0123456789abcdef";
|
||||
|
||||
*p++ = hexDigits[(UWORD)(u % base)];
|
||||
static char hexDigits[] = "0123456789abcdef";
|
||||
|
||||
*p++ = hexDigits[(UWORD) (u % base)];
|
||||
}
|
||||
while ((u /= base) > 0);
|
||||
|
||||
|
||||
*p = '\0'; /* terminate the string */
|
||||
while (q < --p)
|
||||
{ /* reverse the digits */
|
||||
@ -155,7 +153,6 @@ BYTE *
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
#define LEFT 0
|
||||
#define RIGHT 1
|
||||
|
||||
@ -165,9 +162,9 @@ WORD printf(CONST BYTE * fmt, ...)
|
||||
{
|
||||
WORD ret;
|
||||
|
||||
static char buff[80]; /* adjust if necessary */
|
||||
static char buff[80]; /* adjust if necessary */
|
||||
charp = buff;
|
||||
ret = do_printf(fmt, (BYTE **)&fmt + 1);
|
||||
ret = do_printf(fmt, (BYTE **) & fmt + 1);
|
||||
handle_char(NULL);
|
||||
_ES = FP_SEG(buff);
|
||||
_DX = FP_OFF(buff);
|
||||
@ -179,20 +176,20 @@ WORD printf(CONST BYTE * fmt, ...)
|
||||
WORD printf(CONST BYTE * fmt, ...)
|
||||
{
|
||||
charp = 0;
|
||||
return do_printf(fmt, (BYTE **)&fmt + 1);
|
||||
return do_printf(fmt, (BYTE **) & fmt + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
WORD
|
||||
sprintf(BYTE * buff, CONST BYTE * fmt, ...)
|
||||
WORD sprintf(BYTE * buff, CONST BYTE * fmt, ...)
|
||||
{
|
||||
WORD ret;
|
||||
|
||||
charp = buff;
|
||||
ret = do_printf(fmt, (BYTE **)&fmt + 1);
|
||||
ret = do_printf(fmt, (BYTE **) & fmt + 1);
|
||||
handle_char(NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
ULONG FAR retcs(int i)
|
||||
{
|
||||
@ -202,19 +199,14 @@ ULONG FAR retcs(int i)
|
||||
return *(ULONG *)p;
|
||||
}
|
||||
*/
|
||||
COUNT
|
||||
do_printf(CONST BYTE * fmt, BYTE ** arg)
|
||||
COUNT do_printf(CONST BYTE * fmt, BYTE ** arg)
|
||||
{
|
||||
int base;
|
||||
BYTE s[11],
|
||||
FAR *p;
|
||||
int c,
|
||||
flag,
|
||||
size,
|
||||
fill;
|
||||
int longarg;
|
||||
BYTE s[11], FAR * p;
|
||||
int c, flag, size, fill;
|
||||
int longarg;
|
||||
long currentArg;
|
||||
|
||||
|
||||
/*
|
||||
long cs = retcs(1);
|
||||
put_console("0123456789ABCDEF"[(cs >> 28) & 0x0f]);
|
||||
@ -235,154 +227,148 @@ COUNT
|
||||
continue;
|
||||
}
|
||||
|
||||
longarg = FALSE;
|
||||
size = 0;
|
||||
longarg = FALSE;
|
||||
size = 0;
|
||||
flag = RIGHT;
|
||||
fill = ' ';
|
||||
|
||||
if ( *fmt == '-')
|
||||
if (*fmt == '-')
|
||||
{
|
||||
flag = LEFT;
|
||||
fmt++;
|
||||
}
|
||||
|
||||
if ( *fmt == '0')
|
||||
|
||||
if (*fmt == '0')
|
||||
{
|
||||
fill = '0';
|
||||
fmt++;
|
||||
}
|
||||
|
||||
while (*fmt >= '0' && *fmt <= '9')
|
||||
{
|
||||
while (*fmt >= '0' && *fmt <= '9')
|
||||
{
|
||||
size = size * 10 + (*fmt++ - '0');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (*fmt == 'l')
|
||||
{
|
||||
longarg = TRUE;
|
||||
fmt++;
|
||||
longarg = TRUE;
|
||||
fmt++;
|
||||
}
|
||||
|
||||
|
||||
c = *fmt++;
|
||||
switch (c)
|
||||
{
|
||||
case '\0':
|
||||
return 0;
|
||||
|
||||
case '\0':
|
||||
return 0;
|
||||
|
||||
case 'c':
|
||||
handle_char(*(COUNT *) arg++);
|
||||
continue;
|
||||
handle_char(*(COUNT *) arg++);
|
||||
continue;
|
||||
|
||||
case 'p':
|
||||
{
|
||||
UWORD w[2];
|
||||
static char pointerFormat[] = "%04x:%04x";
|
||||
w[1] = *((UWORD *) arg);
|
||||
arg += sizeof(UWORD)/sizeof(BYTE *);
|
||||
w[0] = *((UWORD *) arg);
|
||||
arg += sizeof(UWORD)/sizeof(BYTE *);
|
||||
do_printf(pointerFormat,(BYTE**)&w);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
UWORD w[2];
|
||||
static char pointerFormat[] = "%04x:%04x";
|
||||
w[1] = *((UWORD *) arg);
|
||||
arg += sizeof(UWORD) / sizeof(BYTE *);
|
||||
w[0] = *((UWORD *) arg);
|
||||
arg += sizeof(UWORD) / sizeof(BYTE *);
|
||||
do_printf(pointerFormat, (BYTE **) & w);
|
||||
continue;
|
||||
}
|
||||
|
||||
case 's':
|
||||
p = *arg++;
|
||||
goto do_outputstring;
|
||||
|
||||
p = *arg++;
|
||||
goto do_outputstring;
|
||||
|
||||
case 'F':
|
||||
fmt++;
|
||||
/* we assume %Fs here */
|
||||
fmt++;
|
||||
/* we assume %Fs here */
|
||||
case 'S':
|
||||
p = *((BYTE FAR **) arg);
|
||||
arg += sizeof(BYTE FAR *)/sizeof(BYTE *);
|
||||
goto do_outputstring;
|
||||
p = *((BYTE FAR **) arg);
|
||||
arg += sizeof(BYTE FAR *) / sizeof(BYTE *);
|
||||
goto do_outputstring;
|
||||
|
||||
case 'i':
|
||||
case 'd':
|
||||
base = -10;
|
||||
goto lprt;
|
||||
base = -10;
|
||||
goto lprt;
|
||||
|
||||
case 'o':
|
||||
base = 8;
|
||||
goto lprt;
|
||||
base = 8;
|
||||
goto lprt;
|
||||
|
||||
case 'u':
|
||||
base = 10;
|
||||
goto lprt;
|
||||
base = 10;
|
||||
goto lprt;
|
||||
|
||||
case 'X':
|
||||
case 'x':
|
||||
base = 16;
|
||||
base = 16;
|
||||
|
||||
lprt:
|
||||
if (longarg)
|
||||
{
|
||||
currentArg = *((LONG *) arg);
|
||||
arg += sizeof(LONG)/sizeof(BYTE *);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (base < 0)
|
||||
{
|
||||
currentArg = *((int*) arg);
|
||||
arg += sizeof(int)/sizeof(BYTE *);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentArg = *((unsigned int*) arg);
|
||||
arg += sizeof(unsigned int)/sizeof(BYTE *);
|
||||
}
|
||||
}
|
||||
|
||||
ltob(currentArg, s, base);
|
||||
lprt:
|
||||
if (longarg)
|
||||
{
|
||||
currentArg = *((LONG *) arg);
|
||||
arg += sizeof(LONG) / sizeof(BYTE *);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (base < 0)
|
||||
{
|
||||
currentArg = *((int *)arg);
|
||||
arg += sizeof(int) / sizeof(BYTE *);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentArg = *((unsigned int *)arg);
|
||||
arg += sizeof(unsigned int) / sizeof(BYTE *);
|
||||
}
|
||||
}
|
||||
|
||||
p = s;
|
||||
do_outputstring:
|
||||
|
||||
size -= fstrlen(p);
|
||||
|
||||
if (flag == RIGHT )
|
||||
{
|
||||
for ( ; size > 0; size--)
|
||||
handle_char(fill);
|
||||
}
|
||||
for (; *p != '\0'; p++)
|
||||
handle_char(*p);
|
||||
ltob(currentArg, s, base);
|
||||
|
||||
for ( ; size > 0; size--)
|
||||
handle_char(fill);
|
||||
|
||||
continue;
|
||||
p = s;
|
||||
do_outputstring:
|
||||
|
||||
default:
|
||||
handle_char('?');
|
||||
|
||||
handle_char(c);
|
||||
break;
|
||||
size -= fstrlen(p);
|
||||
|
||||
if (flag == RIGHT)
|
||||
{
|
||||
for (; size > 0; size--)
|
||||
handle_char(fill);
|
||||
}
|
||||
for (; *p != '\0'; p++)
|
||||
handle_char(*p);
|
||||
|
||||
for (; size > 0; size--)
|
||||
handle_char(fill);
|
||||
|
||||
continue;
|
||||
|
||||
default:
|
||||
handle_char('?');
|
||||
|
||||
handle_char(c);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hexd(char *title,UBYTE FAR *p,COUNT numBytes)
|
||||
void hexd(char *title, UBYTE FAR * p, COUNT numBytes)
|
||||
{
|
||||
int loop;
|
||||
printf("%s%04x|", title, FP_SEG(p));
|
||||
for (loop = 0; loop < numBytes; loop++)
|
||||
printf("%02x ", p[loop]);
|
||||
printf("|");
|
||||
|
||||
for (loop = 0; loop < numBytes; loop++)
|
||||
printf("%c", p[loop] < 0x20 ? '.' : p[loop]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int loop;
|
||||
printf("%s%04x|", title, FP_SEG(p));
|
||||
for (loop = 0; loop < numBytes; loop++)
|
||||
printf("%02x ", p[loop]);
|
||||
printf("|");
|
||||
|
||||
for (loop = 0; loop < numBytes; loop++)
|
||||
printf("%c", p[loop] < 0x20 ? '.' : p[loop]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
/*
|
||||
@ -397,83 +383,108 @@ void hexd(char *title,UBYTE FAR *p,COUNT numBytes)
|
||||
|
||||
*/
|
||||
#include <c:\tc\include\conio.h>
|
||||
void cso(char c) { putch(c); }
|
||||
void cso(char c)
|
||||
{
|
||||
putch(c);
|
||||
}
|
||||
|
||||
struct {
|
||||
char *should;
|
||||
char *format;
|
||||
unsigned lowint;
|
||||
unsigned highint;
|
||||
|
||||
struct {
|
||||
char *should;
|
||||
char *format;
|
||||
unsigned lowint;
|
||||
unsigned highint;
|
||||
|
||||
} testarray[] =
|
||||
{
|
||||
{ "hello world", "%s %s", (unsigned)"hello",(unsigned)"world"},
|
||||
{ "hello", "%3s", (unsigned)"hello",0},
|
||||
{ " hello", "%7s", (unsigned)"hello",0},
|
||||
{ "hello ", "%-7s", (unsigned)"hello",0},
|
||||
{ "hello", "%s", (unsigned)"hello",0},
|
||||
|
||||
|
||||
|
||||
{ "1", "%d", 1, 0},
|
||||
{ "-1", "%d", -1,0},
|
||||
{ "65535", "%u", -1,0},
|
||||
{ "-32768", "%d", 0x8000,0},
|
||||
{ "32767", "%d", 0x7fff,0},
|
||||
{ "-32767", "%d", 0x8001,0},
|
||||
|
||||
{"8000", "%x", 0x8000, 0},
|
||||
{" 1", "%4x", 1, 0},
|
||||
{"0001", "%04x", 1, 0},
|
||||
{"1 ", "%-4x", 1, 0},
|
||||
{"1000", "%-04x", 1, 0},
|
||||
} testarray[] = {
|
||||
{
|
||||
"hello world", "%s %s", (unsigned)"hello", (unsigned)"world"},
|
||||
{
|
||||
"hello", "%3s", (unsigned)"hello", 0},
|
||||
{
|
||||
" hello", "%7s", (unsigned)"hello", 0},
|
||||
{
|
||||
"hello ", "%-7s", (unsigned)"hello", 0},
|
||||
{
|
||||
"hello", "%s", (unsigned)"hello", 0},
|
||||
{
|
||||
"1", "%d", 1, 0},
|
||||
{
|
||||
"-1", "%d", -1, 0},
|
||||
{
|
||||
"65535", "%u", -1, 0},
|
||||
{
|
||||
"-32768", "%d", 0x8000, 0},
|
||||
{
|
||||
"32767", "%d", 0x7fff, 0},
|
||||
{
|
||||
"-32767", "%d", 0x8001, 0},
|
||||
{
|
||||
"8000", "%x", 0x8000, 0},
|
||||
{
|
||||
" 1", "%4x", 1, 0},
|
||||
{
|
||||
"0001", "%04x", 1, 0},
|
||||
{
|
||||
"1 ", "%-4x", 1, 0},
|
||||
{
|
||||
"1000", "%-04x", 1, 0},
|
||||
{
|
||||
"1", "%ld", 1, 0},
|
||||
{
|
||||
"-1", "%ld", -1, -1},
|
||||
{
|
||||
"65535", "%ld", -1, 0},
|
||||
{
|
||||
"65535", "%u", -1, 0},
|
||||
{
|
||||
"8000", "%lx", 0x8000, 0},
|
||||
{
|
||||
"80000000", "%lx", 0, 0x8000},
|
||||
{
|
||||
" 1", "%4lx", 1, 0},
|
||||
{
|
||||
"0001", "%04lx", 1, 0},
|
||||
{
|
||||
"1 ", "%-4lx", 1, 0},
|
||||
{
|
||||
"1000", "%-04lx", 1, 0},
|
||||
{
|
||||
"-2147483648", "%ld", 0, 0x8000},
|
||||
{
|
||||
"2147483648", "%lu", 0, 0x8000},
|
||||
{
|
||||
"2147483649", "%lu", 1, 0x8000},
|
||||
{
|
||||
"-2147483647", "%ld", 1, 0x8000},
|
||||
{
|
||||
"32767", "%ld", 0x7fff, 0},
|
||||
{
|
||||
"ptr 1234:5678", "ptr %p", 0x5678, 0x1234}, 0};
|
||||
|
||||
{ "1", "%ld", 1, 0},
|
||||
{ "-1", "%ld", -1,-1},
|
||||
{ "65535", "%ld", -1,0},
|
||||
{ "65535", "%u", -1,0},
|
||||
{"8000", "%lx", 0x8000, 0},
|
||||
{"80000000", "%lx", 0,0x8000},
|
||||
{" 1", "%4lx", 1, 0},
|
||||
{"0001", "%04lx", 1, 0},
|
||||
{"1 ", "%-4lx", 1, 0},
|
||||
{"1000", "%-04lx", 1, 0},
|
||||
|
||||
{ "-2147483648", "%ld", 0,0x8000},
|
||||
{ "2147483648", "%lu", 0,0x8000},
|
||||
{ "2147483649", "%lu", 1,0x8000},
|
||||
{ "-2147483647", "%ld", 1,0x8000},
|
||||
{ "32767", "%ld", 0x7fff,0},
|
||||
|
||||
{ "ptr 1234:5678", "ptr %p", 0x5678,0x1234},
|
||||
|
||||
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
test(char *should, char *format, unsigned lowint, unsigned highint)
|
||||
{
|
||||
char b[100];
|
||||
|
||||
sprintf(b, format, lowint,highint);
|
||||
|
||||
printf("'%s' = '%s'\n", should, b);
|
||||
|
||||
if (strcmp(b,should)) { printf("\nhit the ANYKEY\n"); getch(); }
|
||||
}
|
||||
char b[100];
|
||||
|
||||
sprintf(b, format, lowint, highint);
|
||||
|
||||
printf("'%s' = '%s'\n", should, b);
|
||||
|
||||
if (strcmp(b, should))
|
||||
{
|
||||
printf("\nhit the ANYKEY\n");
|
||||
getch();
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
int i;
|
||||
printf("hello world\n");
|
||||
|
||||
for (i = 0; testarray[i].should; i++)
|
||||
{
|
||||
test(testarray[i].should,testarray[i].format, testarray[i].lowint, testarray[i].highint);
|
||||
}
|
||||
int i;
|
||||
printf("hello world\n");
|
||||
|
||||
for (i = 0; testarray[i].should; i++)
|
||||
{
|
||||
test(testarray[i].should, testarray[i].format, testarray[i].lowint,
|
||||
testarray[i].highint);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -517,4 +528,3 @@ main()
|
||||
* Rev 1.0 02 Jul 1995 8:05:10 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
152
kernel/proto.h
152
kernel/proto.h
@ -28,15 +28,15 @@
|
||||
|
||||
#ifdef MAIN
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *Proto_hRcsId = "$Id$";
|
||||
static BYTE *Proto_hRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* blockio.c */
|
||||
ULONG getblkno(struct buffer FAR *);
|
||||
VOID setblkno(struct buffer FAR *, ULONG);
|
||||
struct buffer FAR *getblock (ULONG blkno, COUNT dsk);
|
||||
struct buffer FAR *getblock(ULONG blkno, COUNT dsk);
|
||||
struct buffer FAR *getblockOver(ULONG blkno, COUNT dsk);
|
||||
VOID setinvld(REG COUNT dsk);
|
||||
BOOL flush_buffers(REG COUNT dsk);
|
||||
@ -45,7 +45,8 @@ BOOL flush(void);
|
||||
BOOL fill(REG struct buffer FAR * bp, ULONG blkno, COUNT dsk);
|
||||
BOOL DeleteBlockInBufferCache(ULONG blknolow, ULONG blknohigh, COUNT dsk);
|
||||
/* *** Changed on 9/4/00 BER */
|
||||
UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, COUNT mode);
|
||||
UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
|
||||
COUNT mode);
|
||||
/* *** End of change */
|
||||
|
||||
/* chario.c */
|
||||
@ -66,19 +67,20 @@ sft FAR *get_sft(UCOUNT);
|
||||
|
||||
/* dosfns.c */
|
||||
#ifdef WITHFAT32
|
||||
struct dpb FAR *GetDriveDPB(UBYTE drive, COUNT *rc);
|
||||
struct dpb FAR *GetDriveDPB(UBYTE drive, COUNT * rc);
|
||||
#endif
|
||||
BYTE FAR *get_root(BYTE FAR *);
|
||||
BOOL fnmatch(BYTE FAR *, BYTE FAR *, COUNT, COUNT);
|
||||
BOOL check_break(void);
|
||||
UCOUNT GenericReadSft(sft far *sftp, UCOUNT n, BYTE FAR * bp, COUNT FAR * err,
|
||||
BOOL force_binary);
|
||||
COUNT SftSeek(sft FAR *sftp, LONG new_pos, COUNT mode);
|
||||
UCOUNT GenericReadSft(sft far * sftp, UCOUNT n, BYTE FAR * bp,
|
||||
COUNT FAR * err, BOOL force_binary);
|
||||
COUNT SftSeek(sft FAR * sftp, LONG new_pos, COUNT mode);
|
||||
/* COUNT DosRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err); */
|
||||
#define GenericRead(hndl, n, bp, err, t) GenericReadSft(get_sft(hndl), n, bp, err, t)
|
||||
#define DosRead(hndl, n, bp, err) GenericRead(hndl, n, bp, err, FALSE)
|
||||
#define DosReadSft(sftp, n, bp, err) GenericReadSft(sftp, n, bp, err, FALSE)
|
||||
UCOUNT DosWriteSft(sft FAR *sftp, UCOUNT n, BYTE FAR * bp, COUNT FAR * err);
|
||||
UCOUNT DosWriteSft(sft FAR * sftp, UCOUNT n, BYTE FAR * bp,
|
||||
COUNT FAR * err);
|
||||
#define DosWrite(hndl, n, bp, err) DosWriteSft(get_sft(hndl), n, bp, err)
|
||||
COUNT DosSeek(COUNT hndl, LONG new_pos, COUNT mode, ULONG * set_pos);
|
||||
COUNT DosCreat(BYTE FAR * fname, COUNT attrib);
|
||||
@ -90,8 +92,9 @@ COUNT DosOpen(BYTE FAR * fname, COUNT mode);
|
||||
COUNT DosOpenSft(BYTE * fname, COUNT mode);
|
||||
COUNT DosClose(COUNT hndl);
|
||||
COUNT DosCloseSft(WORD sft_idx);
|
||||
BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc, UCOUNT FAR * bps, UCOUNT FAR * nc);
|
||||
COUNT DosGetExtFree(BYTE FAR *DriveString, struct xfreespace FAR *xfsp);
|
||||
BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc,
|
||||
UCOUNT FAR * bps, UCOUNT FAR * nc);
|
||||
COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp);
|
||||
COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s);
|
||||
COUNT DosChangeDir(BYTE FAR * s);
|
||||
COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name);
|
||||
@ -102,12 +105,12 @@ COUNT DosSetFtimeSft(WORD sft_idx, date dp, time tp);
|
||||
COUNT DosGetFattr(BYTE FAR * name);
|
||||
COUNT DosSetFattr(BYTE FAR * name, UWORD attrp);
|
||||
UBYTE DosSelectDrv(UBYTE drv);
|
||||
COUNT DosDelete(BYTE FAR *path);
|
||||
COUNT DosDelete(BYTE FAR * path);
|
||||
COUNT DosRename(BYTE FAR * path1, BYTE FAR * path2);
|
||||
COUNT DosRenameTrue(BYTE * path1, BYTE * path2);
|
||||
COUNT DosMkdir(BYTE FAR * dir);
|
||||
COUNT DosRmdir(BYTE FAR * dir);
|
||||
struct dhdr FAR * IsDevice(BYTE FAR * FileName);
|
||||
struct dhdr FAR *IsDevice(BYTE FAR * FileName);
|
||||
BOOL IsShareInstalled(void);
|
||||
COUNT DosLockUnlock(COUNT hndl, LONG pos, LONG len, COUNT unlock);
|
||||
sft FAR *idx_to_sft(COUNT SftIndex);
|
||||
@ -140,11 +143,11 @@ BOOL dir_write(REG f_node_ptr fnp);
|
||||
VOID dir_close(REG f_node_ptr fnp);
|
||||
COUNT dos_findfirst(UCOUNT attr, BYTE * name);
|
||||
COUNT dos_findnext(void);
|
||||
void ConvertName83ToNameSZ(BYTE FAR *destSZ, BYTE FAR *srcFCBName);
|
||||
int FileName83Length(BYTE *filename83);
|
||||
void ConvertName83ToNameSZ(BYTE FAR * destSZ, BYTE FAR * srcFCBName);
|
||||
int FileName83Length(BYTE * filename83);
|
||||
|
||||
/* fatfs.c */
|
||||
ULONG clus2phys(CLUSTER cl_no, struct dpb FAR *dpbp);
|
||||
ULONG clus2phys(CLUSTER cl_no, struct dpb FAR * dpbp);
|
||||
COUNT dos_open(BYTE * path, COUNT flag);
|
||||
BOOL fcmp(BYTE * s1, BYTE * s2, COUNT n);
|
||||
BOOL fcmp_wild(BYTE FAR * s1, BYTE FAR * s2, COUNT n);
|
||||
@ -169,7 +172,7 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err);
|
||||
COUNT dos_read(COUNT fd, VOID FAR * buffer, UCOUNT count);
|
||||
COUNT dos_write(COUNT fd, VOID FAR * buffer, UCOUNT count);
|
||||
LONG dos_lseek(COUNT fd, LONG foffset, COUNT origin);
|
||||
CLUSTER dos_free(struct dpb FAR *dpbp);
|
||||
CLUSTER dos_free(struct dpb FAR * dpbp);
|
||||
|
||||
VOID trim_path(BYTE FAR * s);
|
||||
|
||||
@ -180,27 +183,31 @@ VOID release_f_node(f_node_ptr fnp);
|
||||
VOID dos_setdta(BYTE FAR * newdta);
|
||||
COUNT dos_getfattr(BYTE * name);
|
||||
COUNT dos_setfattr(BYTE * name, UWORD attrp);
|
||||
COUNT media_check(REG struct dpb FAR *dpbp);
|
||||
COUNT media_check(REG struct dpb FAR * dpbp);
|
||||
f_node_ptr xlt_fd(COUNT fd);
|
||||
COUNT xlt_fnp(f_node_ptr fnp);
|
||||
struct dhdr FAR *select_unit(COUNT drive);
|
||||
#ifdef WITHFAT32
|
||||
VOID bpb_to_dpb(bpb FAR *bpbp, REG struct dpb FAR * dpbp, BOOL extended);
|
||||
VOID bpb_to_dpb(bpb FAR * bpbp, REG struct dpb FAR * dpbp, BOOL extended);
|
||||
#else
|
||||
VOID bpb_to_dpb(bpb FAR *bpbp, REG struct dpb FAR * dpbp);
|
||||
VOID bpb_to_dpb(bpb FAR * bpbp, REG struct dpb FAR * dpbp);
|
||||
#endif
|
||||
|
||||
/* fattab.c */
|
||||
void read_fsinfo(struct dpb FAR *dpbp);
|
||||
void write_fsinfo(struct dpb FAR *dpbp);
|
||||
UCOUNT link_fat(struct dpb FAR *dpbp, CLUSTER Cluster1, REG CLUSTER Cluster2);
|
||||
UCOUNT link_fat32(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2);
|
||||
UCOUNT link_fat16(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2);
|
||||
UCOUNT link_fat12(struct dpb FAR *dpbp, CLUSTER Cluster1, CLUSTER Cluster2);
|
||||
CLUSTER next_cluster(struct dpb FAR *dpbp, REG CLUSTER ClusterNum);
|
||||
CLUSTER next_cl32(struct dpb FAR *dpbp, REG CLUSTER ClusterNum);
|
||||
CLUSTER next_cl16(struct dpb FAR *dpbp, REG CLUSTER ClusterNum);
|
||||
CLUSTER next_cl12(struct dpb FAR *dpbp, REG CLUSTER ClusterNum);
|
||||
void read_fsinfo(struct dpb FAR * dpbp);
|
||||
void write_fsinfo(struct dpb FAR * dpbp);
|
||||
UCOUNT link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
REG CLUSTER Cluster2);
|
||||
UCOUNT link_fat32(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
CLUSTER Cluster2);
|
||||
UCOUNT link_fat16(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
CLUSTER Cluster2);
|
||||
UCOUNT link_fat12(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
CLUSTER Cluster2);
|
||||
CLUSTER next_cluster(struct dpb FAR * dpbp, REG CLUSTER ClusterNum);
|
||||
CLUSTER next_cl32(struct dpb FAR * dpbp, REG CLUSTER ClusterNum);
|
||||
CLUSTER next_cl16(struct dpb FAR * dpbp, REG CLUSTER ClusterNum);
|
||||
CLUSTER next_cl12(struct dpb FAR * dpbp, REG CLUSTER ClusterNum);
|
||||
|
||||
/* fcbfns.c */
|
||||
VOID DosOutputString(BYTE FAR * s);
|
||||
@ -209,21 +216,25 @@ int DosCharInput(VOID);
|
||||
VOID DosDirectConsoleIO(iregs FAR * r);
|
||||
VOID DosCharOutput(COUNT c);
|
||||
VOID DosDisplayOutput(COUNT c);
|
||||
VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps, UCOUNT FAR * nc, BYTE FAR ** mdp);
|
||||
VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
|
||||
UCOUNT FAR * nc, BYTE FAR ** mdp);
|
||||
WORD FcbParseFname(int wTestMode, BYTE FAR ** lpFileName, fcb FAR * lpFcb);
|
||||
BYTE FAR *ParseSkipWh(BYTE FAR * lpFileName);
|
||||
BOOL TestCmnSeps(BYTE FAR * lpFileName);
|
||||
BOOL TestFieldSeps(BYTE FAR * lpFileName);
|
||||
BYTE FAR *GetNameField(BYTE FAR * lpFileName, BYTE FAR * lpDestField, COUNT nFieldSize, BOOL * pbWildCard);
|
||||
BYTE FAR *GetNameField(BYTE FAR * lpFileName, BYTE FAR * lpDestField,
|
||||
COUNT nFieldSize, BOOL * pbWildCard);
|
||||
BOOL FcbRead(xfcb FAR * lpXfcb, COUNT * nErrorCode);
|
||||
BOOL FcbWrite(xfcb FAR * lpXfcb, COUNT * nErrorCode);
|
||||
BOOL FcbGetFileSize(xfcb FAR * lpXfcb);
|
||||
BOOL FcbSetRandom(xfcb FAR * lpXfcb);
|
||||
BOOL FcbCalcRec(xfcb FAR * lpXfcb);
|
||||
BOOL FcbRandomBlockRead(xfcb FAR * lpXfcb, COUNT nRecords, COUNT * nErrorCode);
|
||||
BOOL FcbRandomBlockWrite(xfcb FAR * lpXfcb, COUNT nRecords, COUNT * nErrorCode);
|
||||
BOOL FcbRandomBlockRead(xfcb FAR * lpXfcb, COUNT nRecords,
|
||||
COUNT * nErrorCode);
|
||||
BOOL FcbRandomBlockWrite(xfcb FAR * lpXfcb, COUNT nRecords,
|
||||
COUNT * nErrorCode);
|
||||
BOOL FcbRandomIO(xfcb FAR * lpXfcb, COUNT * nErrorCode,
|
||||
BOOL (*FcbFunc)(xfcb FAR *, COUNT *));
|
||||
BOOL(*FcbFunc) (xfcb FAR *, COUNT *));
|
||||
BOOL FcbCreate(xfcb FAR * lpXfcb);
|
||||
void FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
|
||||
BOOL FcbOpen(xfcb FAR * lpXfcb);
|
||||
@ -242,7 +253,8 @@ seg far2para(VOID FAR * p);
|
||||
seg long2para(ULONG size);
|
||||
VOID FAR *add_far(VOID FAR * fp, ULONG off);
|
||||
VOID FAR *adjust_far(VOID FAR * fp);
|
||||
COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para, UWORD FAR * asize);
|
||||
COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para,
|
||||
UWORD FAR * asize);
|
||||
COUNT DosMemLargest(UWORD FAR * size);
|
||||
COUNT DosMemFree(UWORD para);
|
||||
COUNT DosMemChange(UWORD para, UWORD size, UWORD * maxSize);
|
||||
@ -258,7 +270,7 @@ VOID strcpy(REG BYTE * d, REG BYTE * s);
|
||||
VOID ASMCFUNC fmemcpy(REG VOID FAR * d, REG VOID FAR * s, REG COUNT n);
|
||||
VOID ASMCFUNC fstrcpy(REG BYTE FAR * d, REG BYTE FAR * s);
|
||||
VOID ASMCFUNC fstrcpy(REG BYTE FAR * d, REG BYTE FAR * s);
|
||||
void ASMCFUNC memcpy(REG void * d, REG VOID * s, REG COUNT n);
|
||||
void ASMCFUNC memcpy(REG void *d, REG VOID * s, REG COUNT n);
|
||||
void ASMCFUNC fmemset(REG VOID FAR * s, REG int ch, REG COUNT n);
|
||||
void ASMCFUNC memset(REG VOID * s, REG int ch, REG COUNT n);
|
||||
|
||||
@ -280,27 +292,27 @@ BYTE DosYesNo(unsigned char ch);
|
||||
VOID DosUpMem(VOID FAR * str, unsigned len);
|
||||
#endif
|
||||
unsigned char ASMCFUNC DosUpChar(unsigned char ch);
|
||||
VOID DosUpString(char FAR *str);
|
||||
VOID DosUpFMem(VOID FAR *str, unsigned len);
|
||||
VOID DosUpString(char FAR * str);
|
||||
VOID DosUpFMem(VOID FAR * str, unsigned len);
|
||||
unsigned char DosUpFChar(unsigned char ch);
|
||||
VOID DosUpFString(char FAR *str);
|
||||
COUNT DosGetData(int subfct, UWORD cp, UWORD cntry
|
||||
, UWORD bufsize, VOID FAR * buf);
|
||||
VOID DosUpFString(char FAR * str);
|
||||
COUNT DosGetData(int subfct, UWORD cp, UWORD cntry, UWORD bufsize,
|
||||
VOID FAR * buf);
|
||||
#ifndef DosGetCountryInformation
|
||||
COUNT DosGetCountryInformation(UWORD cntry, VOID FAR *buf);
|
||||
COUNT DosGetCountryInformation(UWORD cntry, VOID FAR * buf);
|
||||
#endif
|
||||
#ifndef DosSetCountry
|
||||
COUNT DosSetCountry(UWORD cntry);
|
||||
#endif
|
||||
COUNT DosGetCodepage(UWORD FAR* actCP, UWORD FAR* sysCP);
|
||||
COUNT DosGetCodepage(UWORD FAR * actCP, UWORD FAR * sysCP);
|
||||
COUNT DosSetCodepage(UWORD actCP, UWORD sysCP);
|
||||
UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS);
|
||||
|
||||
/* prf.c */
|
||||
VOID put_console(COUNT c);
|
||||
WORD printf(CONST BYTE * fmt,...);
|
||||
WORD printf(CONST BYTE * fmt, ...);
|
||||
WORD sprintf(BYTE * buff, CONST BYTE * fmt, ...);
|
||||
VOID hexd(char *title,VOID FAR *p,COUNT numBytes);
|
||||
VOID hexd(char *title, VOID FAR * p, COUNT numBytes);
|
||||
|
||||
/* strings.c */
|
||||
COUNT ASMCFUNC strlen(REG BYTE * s);
|
||||
@ -318,7 +330,7 @@ void fsncopy(REG BYTE FAR * s, REG BYTE FAR * d, COUNT l);
|
||||
void ASMCFUNC fstrncpy(REG BYTE FAR * d, REG BYTE FAR * s, COUNT l);
|
||||
#define fsncopy(s,d,l) fstrncpy(d,s,l)
|
||||
|
||||
BYTE * ASMCFUNC strchr(BYTE * s, BYTE c);
|
||||
BYTE *ASMCFUNC strchr(BYTE * s, BYTE c);
|
||||
|
||||
/* sysclk.c */
|
||||
WORD FAR ASMCFUNC clk_driver(rqptr rp);
|
||||
@ -341,18 +353,19 @@ WORD con_driver(rqptr rp);
|
||||
VOID break_handler(void);
|
||||
|
||||
/* systime.c */
|
||||
VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp, BYTE FAR * hdp);
|
||||
VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp,
|
||||
BYTE FAR * hdp);
|
||||
COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd);
|
||||
VOID DosGetDate(BYTE FAR * wdp, BYTE FAR * mp, BYTE FAR * mdp, COUNT FAR * yp);
|
||||
VOID DosGetDate(BYTE FAR * wdp, BYTE FAR * mp, BYTE FAR * mdp,
|
||||
COUNT FAR * yp);
|
||||
COUNT DosSetDate(UWORD Month, UWORD DayOfMonth, UWORD Year);
|
||||
|
||||
UWORD *is_leap_year_monthdays(UWORD year);
|
||||
UWORD *is_leap_year_monthdays(UWORD year);
|
||||
UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth);
|
||||
|
||||
|
||||
|
||||
/* task.c */
|
||||
COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg, char far * pathname);
|
||||
COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg,
|
||||
char far * pathname);
|
||||
VOID new_psp(psp FAR * p, int psize);
|
||||
VOID return_user(void);
|
||||
COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp);
|
||||
@ -366,8 +379,10 @@ COUNT get_verify_drive(char FAR * src);
|
||||
COUNT ASMCFUNC truename(char FAR * src, char FAR * dest, COUNT t);
|
||||
|
||||
/* network.c */
|
||||
COUNT ASMCFUNC remote_doredirect(UWORD b, UCOUNT n, UWORD d, VOID FAR * s, UWORD i, VOID FAR * data);
|
||||
COUNT ASMCFUNC remote_printset(UWORD b, UCOUNT n, UWORD d, VOID FAR * s, UWORD i, VOID FAR * data);
|
||||
COUNT ASMCFUNC remote_doredirect(UWORD b, UCOUNT n, UWORD d, VOID FAR * s,
|
||||
UWORD i, VOID FAR * data);
|
||||
COUNT ASMCFUNC remote_printset(UWORD b, UCOUNT n, UWORD d, VOID FAR * s,
|
||||
UWORD i, VOID FAR * data);
|
||||
COUNT ASMCFUNC remote_rename(VOID);
|
||||
COUNT ASMCFUNC remote_delete(VOID);
|
||||
COUNT ASMCFUNC remote_chdir(VOID);
|
||||
@ -376,18 +391,18 @@ COUNT ASMCFUNC remote_rmdir(VOID);
|
||||
COUNT ASMCFUNC remote_close_all(VOID);
|
||||
COUNT ASMCFUNC remote_process_end(VOID);
|
||||
COUNT ASMCFUNC remote_flushall(VOID);
|
||||
COUNT ASMCFUNC remote_findfirst(VOID FAR *s);
|
||||
COUNT ASMCFUNC remote_findnext(VOID FAR *s);
|
||||
COUNT ASMCFUNC remote_findfirst(VOID FAR * s);
|
||||
COUNT ASMCFUNC remote_findnext(VOID FAR * s);
|
||||
COUNT ASMCFUNC remote_getfattr(VOID);
|
||||
COUNT ASMCFUNC remote_getfree(VOID FAR *s, VOID *d);
|
||||
COUNT ASMCFUNC remote_open(sft FAR *s, COUNT mode);
|
||||
LONG ASMCFUNC remote_lseek(sft FAR *s, LONG new_pos);
|
||||
UCOUNT ASMCFUNC remote_read(sft FAR *s, UCOUNT n, COUNT * err);
|
||||
UCOUNT ASMCFUNC remote_write(sft FAR *s, UCOUNT n, COUNT * err);
|
||||
COUNT ASMCFUNC remote_creat(sft FAR *s, COUNT attr);
|
||||
COUNT ASMCFUNC remote_getfree(VOID FAR * s, VOID * d);
|
||||
COUNT ASMCFUNC remote_open(sft FAR * s, COUNT mode);
|
||||
LONG ASMCFUNC remote_lseek(sft FAR * s, LONG new_pos);
|
||||
UCOUNT ASMCFUNC remote_read(sft FAR * s, UCOUNT n, COUNT * err);
|
||||
UCOUNT ASMCFUNC remote_write(sft FAR * s, UCOUNT n, COUNT * err);
|
||||
COUNT ASMCFUNC remote_creat(sft FAR * s, COUNT attr);
|
||||
COUNT ASMCFUNC remote_setfattr(COUNT attr);
|
||||
COUNT ASMCFUNC remote_printredir(UCOUNT dx, UCOUNT ax);
|
||||
COUNT ASMCFUNC remote_close(sft FAR *s);
|
||||
COUNT ASMCFUNC remote_close(sft FAR * s);
|
||||
COUNT ASMCFUNC QRemote_Fn(char FAR * s, char FAR * d);
|
||||
|
||||
UWORD get_machine_name(BYTE FAR * netname);
|
||||
@ -399,7 +414,6 @@ VOID ASMCFUNC exec_user(iregs FAR * irp);
|
||||
/* detect.c */
|
||||
unsigned long FAR is_dosemu(void);
|
||||
|
||||
|
||||
/* new by TE */
|
||||
|
||||
/*
|
||||
@ -413,10 +427,10 @@ unsigned long FAR is_dosemu(void);
|
||||
#define ASSERT_CONST(x) { typedef struct { char _xx[x ? 1 : -1]; } xx ; }
|
||||
|
||||
#if defined(WATCOM) && 0
|
||||
ULONG FAR ASMCFUNC MULULUS(ULONG mul1, UWORD mul2); /* MULtiply ULong by UShort */
|
||||
ULONG FAR ASMCFUNC MULULUL(ULONG mul1, ULONG mul2); /* MULtiply ULong by ULong */
|
||||
ULONG FAR ASMCFUNC DIVULUS(ULONG mul1, UWORD mul2); /* DIVide ULong by UShort */
|
||||
ULONG FAR ASMCFUNC DIVMODULUS(ULONG mul1, UWORD mul2,UWORD *rem); /* DIVide ULong by UShort */
|
||||
ULONG FAR ASMCFUNC MULULUS(ULONG mul1, UWORD mul2); /* MULtiply ULong by UShort */
|
||||
ULONG FAR ASMCFUNC MULULUL(ULONG mul1, ULONG mul2); /* MULtiply ULong by ULong */
|
||||
ULONG FAR ASMCFUNC DIVULUS(ULONG mul1, UWORD mul2); /* DIVide ULong by UShort */
|
||||
ULONG FAR ASMCFUNC DIVMODULUS(ULONG mul1, UWORD mul2, UWORD * rem); /* DIVide ULong by UShort */
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -29,7 +29,8 @@
|
||||
#include "portab.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *stringsRcsId = "$Id$";
|
||||
static BYTE *stringsRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#ifndef I86
|
||||
@ -187,4 +188,3 @@ BYTE *strchr(BYTE * s, BYTE c)
|
||||
* Rev 1.0 02 Jul 1995 8:33:46 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
106
kernel/sysclk.c
106
kernel/sysclk.c
@ -30,7 +30,8 @@
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId = "$Id$";
|
||||
static BYTE *RcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#ifdef PROTO
|
||||
@ -54,8 +55,7 @@ VOID DayToBcd();
|
||||
/* */
|
||||
/* WARNING - THIS DRIVER IS NON-PORTABLE!!!! */
|
||||
/* */
|
||||
extern UWORD days[2][13]; /* this is defined by SYSTIME.C */
|
||||
|
||||
extern UWORD days[2][13]; /* this is defined by SYSTIME.C */
|
||||
|
||||
static struct ClockRecord clk;
|
||||
|
||||
@ -82,42 +82,35 @@ static COUNT BcdToByte(COUNT x)
|
||||
|
||||
WORD FAR ASMCFUNC clk_driver(rqptr rp)
|
||||
{
|
||||
COUNT
|
||||
c;
|
||||
COUNT c;
|
||||
UWORD *pdays;
|
||||
BYTE bcd_days[4],
|
||||
bcd_minutes,
|
||||
bcd_hours,
|
||||
bcd_seconds;
|
||||
BYTE bcd_days[4], bcd_minutes, bcd_hours, bcd_seconds;
|
||||
ULONG Ticks;
|
||||
UWORD Month,
|
||||
Day,
|
||||
Year;
|
||||
|
||||
|
||||
|
||||
UWORD Month, Day, Year;
|
||||
|
||||
switch (rp->r_command)
|
||||
{
|
||||
case C_INIT:
|
||||
/* If AT clock exists, copy AT clock time to system clock */
|
||||
if (!ReadATClock(bcd_days, &bcd_hours, &bcd_minutes, &bcd_seconds))
|
||||
{
|
||||
DaysSinceEpoch = DaysFromYearMonthDay(
|
||||
100 * BcdToByte(bcd_days[3]) + BcdToByte(bcd_days[2]),
|
||||
BcdToByte(bcd_days[1]),
|
||||
BcdToByte(bcd_days[0]) );
|
||||
DaysSinceEpoch =
|
||||
DaysFromYearMonthDay(100 * BcdToByte(bcd_days[3]) +
|
||||
BcdToByte(bcd_days[2]),
|
||||
BcdToByte(bcd_days[1]),
|
||||
BcdToByte(bcd_days[0]));
|
||||
|
||||
/*
|
||||
* This is a rather tricky calculation. The number of timer ticks per
|
||||
* second is not exactly 18.2, but rather 0x1800b0 / 86400 = 19663 / 1080
|
||||
* (the timer interrupt updates the midnight flag when the tick count
|
||||
* reaches 0x1800b0). Fortunately, 86400 * 19663 = 1698883200 < ULONG_MAX,
|
||||
* so we can simply multiply the number of seconds by 19663 without
|
||||
* worrying about overflow. :) -- ror4
|
||||
*/
|
||||
/*
|
||||
* This is a rather tricky calculation. The number of timer ticks per
|
||||
* second is not exactly 18.2, but rather 0x1800b0 / 86400 = 19663 / 1080
|
||||
* (the timer interrupt updates the midnight flag when the tick count
|
||||
* reaches 0x1800b0). Fortunately, 86400 * 19663 = 1698883200 < ULONG_MAX,
|
||||
* so we can simply multiply the number of seconds by 19663 without
|
||||
* worrying about overflow. :) -- ror4
|
||||
*/
|
||||
Ticks = (3600ul * BcdToByte(bcd_hours) +
|
||||
60ul * BcdToByte(bcd_minutes) +
|
||||
BcdToByte(bcd_seconds)) * 19663ul / 1080ul;
|
||||
60ul * BcdToByte(bcd_minutes) +
|
||||
BcdToByte(bcd_seconds)) * 19663ul / 1080ul;
|
||||
WritePCClock(Ticks);
|
||||
}
|
||||
rp->r_endaddr = device_end();
|
||||
@ -126,8 +119,7 @@ WORD FAR ASMCFUNC clk_driver(rqptr rp)
|
||||
|
||||
case C_INPUT:
|
||||
{
|
||||
ULONG remainder,
|
||||
hs;
|
||||
ULONG remainder, hs;
|
||||
if (ReadPCClock(&Ticks))
|
||||
++DaysSinceEpoch;
|
||||
clk.clkDays = DaysSinceEpoch;
|
||||
@ -138,7 +130,7 @@ WORD FAR ASMCFUNC clk_driver(rqptr rp)
|
||||
* (100 x 86400) / 0x1800b0 = 108000 / 19663. -- ror4
|
||||
*/
|
||||
hs = 0;
|
||||
#if 0
|
||||
#if 0
|
||||
if (Ticks >= 64 * 19663ul)
|
||||
{
|
||||
hs += 64 * 108000ul;
|
||||
@ -175,14 +167,14 @@ WORD FAR ASMCFUNC clk_driver(rqptr rp)
|
||||
Ticks -= 19663ul;
|
||||
}
|
||||
#else
|
||||
{
|
||||
UWORD q1 = Ticks/19663ul;
|
||||
{
|
||||
UWORD q1 = Ticks / 19663ul;
|
||||
|
||||
Ticks -= q1*19663ul;
|
||||
hs = q1*108000ul;
|
||||
}
|
||||
|
||||
#endif
|
||||
Ticks -= q1 * 19663ul;
|
||||
hs = q1 * 108000ul;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Now Ticks < 19663, so Ticks * 108000 < 2123604000 < ULONG_MAX.
|
||||
* *phew* -- ror4
|
||||
@ -195,12 +187,13 @@ WORD FAR ASMCFUNC clk_driver(rqptr rp)
|
||||
clk.clkSeconds = remainder / 100ul;
|
||||
clk.clkHundredths = remainder % 100ul;
|
||||
}
|
||||
|
||||
fmemcpy(rp->r_trans, &clk, min(sizeof(struct ClockRecord),rp->r_count ));
|
||||
|
||||
fmemcpy(rp->r_trans, &clk,
|
||||
min(sizeof(struct ClockRecord), rp->r_count));
|
||||
return S_DONE;
|
||||
|
||||
case C_OUTPUT:
|
||||
rp->r_count = min(rp->r_count,sizeof(struct ClockRecord));
|
||||
rp->r_count = min(rp->r_count, sizeof(struct ClockRecord));
|
||||
fmemcpy(&clk, rp->r_trans, rp->r_count);
|
||||
|
||||
/* Set PC Clock first */
|
||||
@ -209,10 +202,9 @@ WORD FAR ASMCFUNC clk_driver(rqptr rp)
|
||||
ULONG hs;
|
||||
hs = 360000ul * clk.clkHours +
|
||||
6000ul * clk.clkMinutes +
|
||||
100ul * clk.clkSeconds +
|
||||
clk.clkHundredths;
|
||||
100ul * clk.clkSeconds + clk.clkHundredths;
|
||||
Ticks = 0;
|
||||
#if 0
|
||||
#if 0
|
||||
if (hs >= 64 * 108000ul)
|
||||
{
|
||||
Ticks += 64 * 19663ul;
|
||||
@ -248,15 +240,15 @@ WORD FAR ASMCFUNC clk_driver(rqptr rp)
|
||||
Ticks += 19663ul;
|
||||
hs -= 108000ul;
|
||||
}
|
||||
#else
|
||||
{
|
||||
UWORD q1 = hs/108000ul;
|
||||
#else
|
||||
{
|
||||
UWORD q1 = hs / 108000ul;
|
||||
|
||||
hs -= q1*108000ul;
|
||||
Ticks = q1*19663ul;
|
||||
}
|
||||
|
||||
#endif
|
||||
hs -= q1 * 108000ul;
|
||||
Ticks = q1 * 19663ul;
|
||||
}
|
||||
|
||||
#endif
|
||||
Ticks += hs * 19663ul / 108000ul;
|
||||
}
|
||||
WritePCClock(Ticks);
|
||||
@ -264,7 +256,7 @@ WORD FAR ASMCFUNC clk_driver(rqptr rp)
|
||||
/* Now set AT clock */
|
||||
/* Fix year by looping through each year, subtracting */
|
||||
/* the appropriate number of days for that year. */
|
||||
for (Year = 1980, c = clk.clkDays; ;)
|
||||
for (Year = 1980, c = clk.clkDays;;)
|
||||
{
|
||||
pdays = is_leap_year_monthdays(Year);
|
||||
if (c >= pdays[12])
|
||||
@ -286,8 +278,7 @@ WORD FAR ASMCFUNC clk_driver(rqptr rp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
DayToBcd((BYTE *) bcd_days, &Month, &Day, &Year);
|
||||
bcd_minutes = ByteToBcd(clk.clkMinutes);
|
||||
bcd_hours = ByteToBcd(clk.clkHours);
|
||||
@ -304,7 +295,7 @@ WORD FAR ASMCFUNC clk_driver(rqptr rp)
|
||||
case C_OSTAT:
|
||||
case C_ISTAT:
|
||||
default:
|
||||
return failure(E_FAILURE); /* general failure */
|
||||
return failure(E_FAILURE); /* general failure */
|
||||
}
|
||||
}
|
||||
|
||||
@ -364,4 +355,3 @@ VOID DayToBcd(BYTE * x, UWORD * mon, UWORD * day, UWORD * yr)
|
||||
* Rev 1.0 02 Jul 1995 8:32:30 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
@ -31,7 +31,8 @@
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *syspackRcsId = "$Id$";
|
||||
static BYTE *syspackRcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#ifdef NONNATIVE
|
||||
@ -55,7 +56,8 @@ VOID getbyte(VOID * vp, BYTE * bp)
|
||||
|
||||
VOID fgetword(REG VOID FAR * vp, WORD FAR * wp)
|
||||
{
|
||||
*wp = (((BYTE FAR *) vp)[0] & 0xff) + ((((BYTE FAR *) vp)[1] & 0xff) << 8);
|
||||
*wp =
|
||||
(((BYTE FAR *) vp)[0] & 0xff) + ((((BYTE FAR *) vp)[1] & 0xff) << 8);
|
||||
}
|
||||
|
||||
VOID fgetlong(REG VOID FAR * vp, LONG FAR * lp)
|
||||
|
@ -32,43 +32,43 @@
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId = "$Id$";
|
||||
static BYTE *RcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
UWORD days[2][13] =
|
||||
{
|
||||
UWORD days[2][13] = {
|
||||
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
|
||||
{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
|
||||
};
|
||||
|
||||
extern request
|
||||
ClkReqHdr;
|
||||
|
||||
extern request ClkReqHdr;
|
||||
|
||||
/*
|
||||
return a pointer to an array with the days for that year
|
||||
*/
|
||||
*/
|
||||
|
||||
UWORD *is_leap_year_monthdays(UWORD y)
|
||||
{
|
||||
/* this is correct in a strict mathematical sense
|
||||
return ((y) & 3 ? days[0] : (y) % 100 ? days[1] : (y) % 400 ? days[0] : days[1]); */
|
||||
|
||||
/* this will work until 2200 - long enough for me - and saves 0x1f bytes */
|
||||
|
||||
if ((y & 3) || y == 2100) return days[0];
|
||||
|
||||
return days[1];
|
||||
/* this is correct in a strict mathematical sense
|
||||
return ((y) & 3 ? days[0] : (y) % 100 ? days[1] : (y) % 400 ? days[0] : days[1]); */
|
||||
|
||||
/* this will work until 2200 - long enough for me - and saves 0x1f bytes */
|
||||
|
||||
if ((y & 3) || y == 2100)
|
||||
return days[0];
|
||||
|
||||
return days[1];
|
||||
}
|
||||
|
||||
UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth)
|
||||
{
|
||||
if (Year < 1980) return 0;
|
||||
|
||||
if (Year < 1980)
|
||||
return 0;
|
||||
|
||||
return DayOfMonth - 1
|
||||
+ is_leap_year_monthdays(Year)[Month - 1]
|
||||
+ ((Year - 1980) * 365)
|
||||
+ ((Year - 1980 + 3) / 4);
|
||||
|
||||
+ ((Year - 1980) * 365) + ((Year - 1980 + 3) / 4);
|
||||
|
||||
}
|
||||
|
||||
/* common - call the clock driver */
|
||||
@ -80,14 +80,13 @@ void ExecuteClockDriverRequest(BYTE command)
|
||||
ClkReqHdr.r_trans = (BYTE FAR *) (&ClkRecord);
|
||||
ClkReqHdr.r_status = 0;
|
||||
execrh((request FAR *) & ClkReqHdr, (struct dhdr FAR *)clock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp, BYTE FAR * hdp)
|
||||
VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp,
|
||||
BYTE FAR * hdp)
|
||||
{
|
||||
ExecuteClockDriverRequest(C_INPUT);
|
||||
|
||||
|
||||
if (ClkReqHdr.r_status & S_ERROR)
|
||||
return;
|
||||
|
||||
@ -99,8 +98,9 @@ VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp, BYTE FAR * hdp)
|
||||
|
||||
COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd)
|
||||
{
|
||||
BYTE Month, DayOfMonth, DayOfWeek; COUNT Year;
|
||||
|
||||
BYTE Month, DayOfMonth, DayOfWeek;
|
||||
COUNT Year;
|
||||
|
||||
DosGetDate((BYTE FAR *) & DayOfWeek, (BYTE FAR *) & Month,
|
||||
(BYTE FAR *) & DayOfMonth, (COUNT FAR *) & Year);
|
||||
|
||||
@ -119,21 +119,19 @@ COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd)
|
||||
}
|
||||
|
||||
VOID DosGetDate(wdp, mp, mdp, yp)
|
||||
BYTE FAR *wdp,
|
||||
FAR * mp,
|
||||
FAR * mdp;
|
||||
BYTE FAR *wdp, FAR * mp, FAR * mdp;
|
||||
COUNT FAR *yp;
|
||||
{
|
||||
UWORD c;
|
||||
UWORD *pdays;
|
||||
UWORD Year,Month;
|
||||
UWORD *pdays;
|
||||
UWORD Year, Month;
|
||||
|
||||
ExecuteClockDriverRequest(C_INPUT);
|
||||
|
||||
if (ClkReqHdr.r_status & S_ERROR)
|
||||
return;
|
||||
|
||||
for (Year = 1980, c = ClkRecord.clkDays; ;)
|
||||
for (Year = 1980, c = ClkRecord.clkDays;;)
|
||||
{
|
||||
pdays = is_leap_year_monthdays(Year);
|
||||
if (c >= pdays[12])
|
||||
@ -154,7 +152,7 @@ COUNT FAR *yp;
|
||||
}
|
||||
|
||||
*mp = Month;
|
||||
*mdp = c - pdays[Month-1] + 1;
|
||||
*mdp = c - pdays[Month - 1] + 1;
|
||||
*yp = Year;
|
||||
|
||||
/* Day of week is simple. Take mod 7, add 2 (for Tuesday */
|
||||
@ -164,19 +162,15 @@ COUNT FAR *yp;
|
||||
}
|
||||
|
||||
COUNT DosSetDate(Month, DayOfMonth, Year)
|
||||
UWORD Month,
|
||||
DayOfMonth,
|
||||
Year;
|
||||
UWORD Month, DayOfMonth, Year;
|
||||
{
|
||||
UWORD *pdays;
|
||||
pdays = is_leap_year_monthdays(Year);
|
||||
|
||||
pdays = is_leap_year_monthdays(Year);
|
||||
|
||||
if (Year < 1980 || Year > 2099
|
||||
|| Month < 1 || Month > 12
|
||||
|| DayOfMonth < 1
|
||||
|| DayOfMonth > pdays[Month] - pdays[Month-1])
|
||||
|| DayOfMonth < 1 || DayOfMonth > pdays[Month] - pdays[Month - 1])
|
||||
return DE_INVLDDATA;
|
||||
|
||||
|
||||
DosGetTime((BYTE FAR *) & ClkRecord.clkHours,
|
||||
(BYTE FAR *) & ClkRecord.clkMinutes,
|
||||
|
721
kernel/task.c
721
kernel/task.c
@ -30,7 +30,8 @@
|
||||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId = "$Id$";
|
||||
static BYTE *RcsId =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#define toupper(c) ((c) >= 'a' && (c) <= 'z' ? (c) + ('A' - 'a') : (c))
|
||||
@ -46,11 +47,11 @@ static exe_header header;
|
||||
#define CHUNK 32256
|
||||
#define MAXENV 32768u
|
||||
#define ENV_KEEPFREE 83 /* keep unallocated by environment variables */
|
||||
/* The '65' added to nEnvSize does not cover the additional stuff:
|
||||
+ 2 bytes: number of strings
|
||||
+ 80 bytes: maximum absolute filename
|
||||
+ 1 byte: '\0'
|
||||
-- 1999/04/21 ska */
|
||||
/* The '65' added to nEnvSize does not cover the additional stuff:
|
||||
+ 2 bytes: number of strings
|
||||
+ 80 bytes: maximum absolute filename
|
||||
+ 1 byte: '\0'
|
||||
-- 1999/04/21 ska */
|
||||
|
||||
#ifndef PROTO
|
||||
COUNT ChildEnv(exec_blk FAR *, UWORD *, char far *);
|
||||
@ -88,7 +89,8 @@ LONG DosGetFsize(COUNT hndl)
|
||||
return dos_getfsize(s->sft_status);
|
||||
}
|
||||
|
||||
COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg, char far * pathname)
|
||||
COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg,
|
||||
char far * pathname)
|
||||
{
|
||||
BYTE FAR *pSrc;
|
||||
BYTE FAR *pDest;
|
||||
@ -101,14 +103,12 @@ COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg, char far * pathname)
|
||||
/* copy parent's environment if exec.env_seg == 0 */
|
||||
|
||||
pSrc = exp->exec.env_seg ?
|
||||
MK_FP(exp->exec.env_seg, 0) :
|
||||
MK_FP(ppsp->ps_environ, 0);
|
||||
MK_FP(exp->exec.env_seg, 0) : MK_FP(ppsp->ps_environ, 0);
|
||||
|
||||
#if 0
|
||||
/* Every process requires an environment because of argv[0]
|
||||
-- 1999/04/21 ska */
|
||||
*/
|
||||
if (!pSrc) /* no environment to copy */
|
||||
*/if (!pSrc) /* no environment to copy */
|
||||
{
|
||||
*pChildEnvSeg = 0;
|
||||
return SUCCESS;
|
||||
@ -120,15 +120,15 @@ COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg, char far * pathname)
|
||||
-- 1999/04/21 ska */
|
||||
if (pSrc)
|
||||
{ /* if no environment is available, one byte is required */
|
||||
|
||||
for (nEnvSize = 0; ; nEnvSize++)
|
||||
|
||||
for (nEnvSize = 0;; nEnvSize++)
|
||||
{
|
||||
/* Test env size and abort if greater than max */
|
||||
if (nEnvSize >= MAXENV - ENV_KEEPFREE)
|
||||
return DE_INVLDENV;
|
||||
|
||||
if (*(UWORD FAR *)(pSrc+nEnvSize) == 0)
|
||||
break;
|
||||
/* Test env size and abort if greater than max */
|
||||
if (nEnvSize >= MAXENV - ENV_KEEPFREE)
|
||||
return DE_INVLDENV;
|
||||
|
||||
if (*(UWORD FAR *) (pSrc + nEnvSize) == 0)
|
||||
break;
|
||||
}
|
||||
nEnvSize += 2; /* account for trailing \0\0 */
|
||||
}
|
||||
@ -136,7 +136,7 @@ COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg, char far * pathname)
|
||||
/* allocate enough space for env + path */
|
||||
if ((RetCode = DosMemAlloc(long2para(nEnvSize + ENV_KEEPFREE),
|
||||
mem_access_mode, (seg FAR *) pChildEnvSeg,
|
||||
NULL /*(UWORD FAR *) MaxEnvSize ska */ )) < 0)
|
||||
NULL /*(UWORD FAR *) MaxEnvSize ska */ )) < 0)
|
||||
return RetCode;
|
||||
pDest = MK_FP(*pChildEnvSeg + 1, 0);
|
||||
|
||||
@ -152,12 +152,13 @@ COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg, char far * pathname)
|
||||
else
|
||||
*pDest++ = '\0'; /* create an empty environment */
|
||||
|
||||
/* initialize 'extra strings' count */
|
||||
/* initialize 'extra strings' count */
|
||||
*((UWORD FAR *) pDest) = 1;
|
||||
pDest += sizeof(UWORD)/sizeof(BYTE);
|
||||
pDest += sizeof(UWORD) / sizeof(BYTE);
|
||||
|
||||
/* copy complete pathname */
|
||||
if ((RetCode = truename(pathname, pDest, TRUE)) != SUCCESS) {
|
||||
if ((RetCode = truename(pathname, pDest, TRUE)) != SUCCESS)
|
||||
{
|
||||
return RetCode;
|
||||
}
|
||||
|
||||
@ -172,7 +173,7 @@ COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg, char far * pathname)
|
||||
/* The following code is 8086 dependant */
|
||||
VOID new_psp(psp FAR * p, int psize)
|
||||
{
|
||||
REG COUNT i;
|
||||
REG COUNT i;
|
||||
psp FAR *q = MK_FP(cu_psp, 0);
|
||||
|
||||
/* Clear out new psp first */
|
||||
@ -225,7 +226,7 @@ VOID new_psp(psp FAR * p, int psize)
|
||||
p->ps_filetab = p->ps_files;
|
||||
|
||||
/* clone the file table */
|
||||
if (p!=q)
|
||||
if (p != q)
|
||||
{
|
||||
REG COUNT i;
|
||||
|
||||
@ -250,7 +251,7 @@ VOID new_psp(psp FAR * p, int psize)
|
||||
RootPsp = FP_SEG(p);
|
||||
}
|
||||
|
||||
STATIC UWORD patchPSP(UWORD pspseg, UWORD envseg, exec_blk FAR *exb,
|
||||
STATIC UWORD patchPSP(UWORD pspseg, UWORD envseg, exec_blk FAR * exb,
|
||||
BYTE FAR * fnam)
|
||||
{
|
||||
psp FAR *psp;
|
||||
@ -302,29 +303,33 @@ set_name:
|
||||
pspmcb->m_name[i] = '\0';
|
||||
|
||||
/* return value: AX value to be passed based on FCB values */
|
||||
return ((psp->ps_fcb1.fcb_drive<lastdrive &&
|
||||
CDSp->cds_table[psp->ps_fcb1.fcb_drive].cdsFlags & CDSVALID) ? 0 : 0xff) +
|
||||
((psp->ps_fcb2.fcb_drive<lastdrive &&
|
||||
CDSp->cds_table[psp->ps_fcb2.fcb_drive].cdsFlags & CDSVALID) ? 0 : 0xff) * 0x100;
|
||||
return ((psp->ps_fcb1.fcb_drive < lastdrive &&
|
||||
CDSp->cds_table[psp->ps_fcb1.fcb_drive].
|
||||
cdsFlags & CDSVALID) ? 0 : 0xff) + ((psp->ps_fcb2.fcb_drive <
|
||||
lastdrive
|
||||
&& CDSp->cds_table[psp->
|
||||
ps_fcb2.
|
||||
fcb_drive].
|
||||
cdsFlags & CDSVALID) ? 0 :
|
||||
0xff) * 0x100;
|
||||
}
|
||||
|
||||
COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
{
|
||||
COUNT rc
|
||||
/* err */
|
||||
/*,env_size*/;
|
||||
/* err */
|
||||
/*,env_size */ ;
|
||||
COUNT nread;
|
||||
UWORD mem;
|
||||
UWORD env,
|
||||
asize;
|
||||
UWORD env, asize;
|
||||
BYTE FAR *sp;
|
||||
psp FAR *p;
|
||||
psp FAR *q = MK_FP(cu_psp, 0);
|
||||
iregs FAR *irp;
|
||||
LONG com_size;
|
||||
|
||||
int ModeLoadHigh = mode & 0x80;
|
||||
UBYTE UMBstate = uppermem_link;
|
||||
int ModeLoadHigh = mode & 0x80;
|
||||
UBYTE UMBstate = uppermem_link;
|
||||
|
||||
mode &= 0x7f;
|
||||
|
||||
@ -335,9 +340,9 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* COMFILES will always be loaded in largest area. is that true TE*/
|
||||
|
||||
|
||||
/* COMFILES will always be loaded in largest area. is that true TE */
|
||||
|
||||
/* Now find out how many paragraphs are available */
|
||||
if ((rc = DosMemLargest((seg FAR *) & asize)) != SUCCESS)
|
||||
{
|
||||
@ -345,48 +350,49 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
return rc;
|
||||
}
|
||||
com_size = asize;
|
||||
|
||||
if ( ModeLoadHigh )
|
||||
{
|
||||
DosUmbLink(1); /* link in UMB's */
|
||||
}
|
||||
|
||||
/* Allocate our memory and pass back any errors */
|
||||
if ((rc = DosMemAlloc((seg) com_size, mem_access_mode, (seg FAR *) & mem
|
||||
,(UWORD FAR *) & asize)) < 0)
|
||||
|
||||
if (ModeLoadHigh)
|
||||
{
|
||||
if (rc == DE_NOMEM)
|
||||
DosUmbLink(1); /* link in UMB's */
|
||||
}
|
||||
|
||||
/* Allocate our memory and pass back any errors */
|
||||
if ((rc =
|
||||
DosMemAlloc((seg) com_size, mem_access_mode, (seg FAR *) & mem,
|
||||
(UWORD FAR *) & asize)) < 0)
|
||||
{
|
||||
if (rc == DE_NOMEM)
|
||||
{
|
||||
if ((rc =
|
||||
DosMemAlloc(0, LARGEST, (seg FAR *) & mem,
|
||||
(UWORD FAR *) & asize)) < 0)
|
||||
{
|
||||
if ((rc = DosMemAlloc(0, LARGEST, (seg FAR *) & mem
|
||||
,(UWORD FAR *) & asize)) < 0)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
/* This should never happen, but ... */
|
||||
if (asize < com_size)
|
||||
{
|
||||
DosMemFree(mem);
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
else
|
||||
/* This should never happen, but ... */
|
||||
if (asize < com_size)
|
||||
{
|
||||
DosMemFree(env); /* env may be 0 */
|
||||
return rc;
|
||||
DosMemFree(mem);
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DosMemFree(env); /* env may be 0 */
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
++mem;
|
||||
}
|
||||
else
|
||||
mem = exp->load.load_seg;
|
||||
|
||||
if ( ModeLoadHigh )
|
||||
{
|
||||
DosUmbLink(UMBstate); /* restore link state */
|
||||
}
|
||||
|
||||
|
||||
if (ModeLoadHigh)
|
||||
{
|
||||
DosUmbLink(UMBstate); /* restore link state */
|
||||
}
|
||||
|
||||
/* Now load the executable */
|
||||
/* If file not found - error */
|
||||
@ -401,20 +407,19 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
if (mode == OVERLAY) /* memory already allocated */
|
||||
sp = MK_FP(mem, 0);
|
||||
else
|
||||
{ /* test the filesize against the allocated memory */
|
||||
|
||||
{ /* test the filesize against the allocated memory */
|
||||
|
||||
sp = MK_FP(mem, sizeof(psp));
|
||||
|
||||
/* This is a potential problem, what to do with .COM files larger than
|
||||
the allocated memory?
|
||||
MS DOS always only loads the very first 64KB - sizeof(psp) bytes.
|
||||
-- 1999/04/21 ska */
|
||||
|
||||
/* BUG !! in case of LH, memory may be smaller then 64K TE*/
|
||||
|
||||
|
||||
if (com_size > ((LONG)asize << 4)) /* less memory than the .COM file has */
|
||||
com_size = (LONG)asize << 4;
|
||||
|
||||
/* BUG !! in case of LH, memory may be smaller then 64K TE */
|
||||
|
||||
if (com_size > ((LONG) asize << 4)) /* less memory than the .COM file has */
|
||||
com_size = (LONG) asize << 4;
|
||||
}
|
||||
do
|
||||
{
|
||||
@ -433,7 +438,7 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
setvec(0x22, (VOID(INRPT FAR *) (VOID)) MK_FP(user_r->CS, user_r->IP));
|
||||
new_psp(p, mem + asize);
|
||||
|
||||
asize = patchPSP(mem - 1, env, exp, namep); /* asize=fcbcode for ax */
|
||||
asize = patchPSP(mem - 1, env, exp, namep); /* asize=fcbcode for ax */
|
||||
|
||||
/* Transfer control to the executable */
|
||||
p->ps_parent = cu_psp;
|
||||
@ -447,14 +452,13 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
{
|
||||
case LOADNGO:
|
||||
{
|
||||
/* BUG !!
|
||||
this works only, if COMSIZE >= 64K
|
||||
in case of LH, this is not necessarily true
|
||||
*/
|
||||
|
||||
|
||||
/* BUG !!
|
||||
this works only, if COMSIZE >= 64K
|
||||
in case of LH, this is not necessarily true
|
||||
*/
|
||||
|
||||
*((UWORD FAR *) MK_FP(mem, 0xfffe)) = (UWORD) 0;
|
||||
|
||||
|
||||
/* build the user area on the stack */
|
||||
irp = MK_FP(mem, (0xfffe - sizeof(iregs)));
|
||||
|
||||
@ -462,13 +466,8 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
irp->ES = irp->DS = mem;
|
||||
irp->CS = mem;
|
||||
irp->IP = 0x100;
|
||||
irp->AX = asize; /* fcbcode */
|
||||
irp->BX =
|
||||
irp->CX =
|
||||
irp->DX =
|
||||
irp->SI =
|
||||
irp->DI =
|
||||
irp->BP = 0;
|
||||
irp->AX = asize; /* fcbcode */
|
||||
irp->BX = irp->CX = irp->DX = irp->SI = irp->DI = irp->BP = 0;
|
||||
irp->FLAGS = 0x200;
|
||||
|
||||
if (InDOS)
|
||||
@ -476,12 +475,12 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
exec_user(irp);
|
||||
|
||||
/* We should never be here
|
||||
fatal("KERNEL RETURNED!!!"); */
|
||||
fatal("KERNEL RETURNED!!!"); */
|
||||
break;
|
||||
}
|
||||
case LOAD:
|
||||
exp->exec.stack = MK_FP(mem, 0xfffe);
|
||||
*((UWORD FAR *)exp->exec.stack) = asize;
|
||||
*((UWORD FAR *) exp->exec.stack) = asize;
|
||||
exp->exec.start_addr = MK_FP(mem, 0x100);
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -491,8 +490,7 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
|
||||
VOID return_user(void)
|
||||
{
|
||||
psp FAR *p,
|
||||
FAR * q;
|
||||
psp FAR *p, FAR * q;
|
||||
REG COUNT i;
|
||||
iregs FAR *irp;
|
||||
/* long j;*/
|
||||
@ -506,8 +504,8 @@ VOID return_user(void)
|
||||
setvec(0x24, p->ps_isv24);
|
||||
|
||||
/* And free all process memory if not a TSR return */
|
||||
remote_process_end(); /* might be a good idea to do that after closing
|
||||
but doesn't help NET either TE */
|
||||
remote_process_end(); /* might be a good idea to do that after closing
|
||||
but doesn't help NET either TE */
|
||||
if (!tsr)
|
||||
{
|
||||
remote_close_all();
|
||||
@ -518,7 +516,6 @@ VOID return_user(void)
|
||||
FcbCloseAll();
|
||||
FreeProcessMem(cu_psp);
|
||||
}
|
||||
|
||||
|
||||
cu_psp = p->ps_parent;
|
||||
q = MK_FP(cu_psp, 0);
|
||||
@ -536,20 +533,16 @@ VOID return_user(void)
|
||||
|
||||
COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
{
|
||||
COUNT rc;
|
||||
/*err, */
|
||||
/*env_size,*/
|
||||
|
||||
UWORD mem,
|
||||
env,
|
||||
asize,
|
||||
start_seg;
|
||||
COUNT rc;
|
||||
/*err, */
|
||||
/*env_size, */
|
||||
|
||||
int ModeLoadHigh = mode & 0x80;
|
||||
UWORD mem, env, asize, start_seg;
|
||||
|
||||
int ModeLoadHigh = mode & 0x80;
|
||||
UBYTE UMBstate = uppermem_link;
|
||||
|
||||
mode &= 0x7f;
|
||||
|
||||
|
||||
/* Clone the environement and create a memory arena */
|
||||
if (mode != OVERLAY)
|
||||
@ -559,126 +552,123 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
}
|
||||
else
|
||||
mem = exp->load.load_seg;
|
||||
|
||||
|
||||
{
|
||||
ULONG image_size;
|
||||
ULONG image_offset;
|
||||
LONG exe_size;
|
||||
mcb FAR *mp;
|
||||
|
||||
ULONG image_size;
|
||||
ULONG image_offset;
|
||||
LONG exe_size;
|
||||
mcb FAR *mp;
|
||||
|
||||
/* compute image offset from the header */
|
||||
image_offset = (ULONG)header.exHeaderSize * 16;
|
||||
/* compute image offset from the header */
|
||||
image_offset = (ULONG) header.exHeaderSize * 16;
|
||||
|
||||
/* compute image size by removing the offset from the */
|
||||
/* number pages scaled to bytes plus the remainder and */
|
||||
/* the psp */
|
||||
/* First scale the size */
|
||||
image_size = (ULONG)header.exPages * 512;
|
||||
/* remove the offset */
|
||||
image_size -= image_offset;
|
||||
/* compute image size by removing the offset from the */
|
||||
/* number pages scaled to bytes plus the remainder and */
|
||||
/* the psp */
|
||||
/* First scale the size */
|
||||
image_size = (ULONG) header.exPages * 512;
|
||||
/* remove the offset */
|
||||
image_size -= image_offset;
|
||||
|
||||
/* and finally add in the psp size */
|
||||
if (mode != OVERLAY)
|
||||
image_size += sizeof(psp); /*TE 03/20/01*/
|
||||
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
if ( ModeLoadHigh )
|
||||
/* and finally add in the psp size */
|
||||
if (mode != OVERLAY)
|
||||
image_size += sizeof(psp); /*TE 03/20/01 */
|
||||
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
DosUmbLink(1); /* link in UMB's */
|
||||
mem_access_mode |= ModeLoadHigh;
|
||||
}
|
||||
|
||||
/* Now find out how many paragraphs are available */
|
||||
if ((rc = DosMemLargest((seg FAR *) & asize)) != SUCCESS)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
if (ModeLoadHigh)
|
||||
{
|
||||
DosUmbLink(1); /* link in UMB's */
|
||||
mem_access_mode |= ModeLoadHigh;
|
||||
}
|
||||
|
||||
exe_size = (LONG) long2para(image_size) + header.exMinAlloc;
|
||||
|
||||
|
||||
/* + long2para((LONG) sizeof(psp)); ?? see above
|
||||
image_size += sizeof(psp) -- 1999/04/21 ska */
|
||||
if (exe_size > asize && (mem_access_mode & 0x80))
|
||||
{
|
||||
/* First try low memory */
|
||||
mem_access_mode &= ~0x80;
|
||||
rc = DosMemLargest((seg FAR *) & asize);
|
||||
mem_access_mode |= 0x80;
|
||||
if (rc != SUCCESS)
|
||||
/* Now find out how many paragraphs are available */
|
||||
if ((rc = DosMemLargest((seg FAR *) & asize)) != SUCCESS)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
if (exe_size > asize)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return DE_NOMEM;
|
||||
}
|
||||
exe_size = (LONG) long2para(image_size) + header.exMaxAlloc;
|
||||
/* + long2para((LONG) sizeof(psp)); ?? -- 1999/04/21 ska */
|
||||
if (exe_size > asize)
|
||||
exe_size = asize;
|
||||
|
||||
/* TE if header.exMinAlloc == header.exMaxAlloc == 0,
|
||||
DOS will allocate the largest possible memory area
|
||||
and load the image as high as possible into it.
|
||||
discovered (and after that found in RBIL), when testing NET */
|
||||
|
||||
if ((header.exMinAlloc | header.exMaxAlloc ) == 0)
|
||||
exe_size = asize;
|
||||
|
||||
|
||||
/* /// Removed closing curly brace. We should not attempt to allocate
|
||||
memory if we are overlaying the current process, because the new
|
||||
process will simply re-use the block we already have allocated.
|
||||
This was causing execl() to fail in applications which use it to
|
||||
overlay (replace) the current exe file with a new one.
|
||||
Jun 11, 2000 - rbc
|
||||
} */
|
||||
|
||||
exe_size = (LONG) long2para(image_size) + header.exMinAlloc;
|
||||
|
||||
/* Allocate our memory and pass back any errors */
|
||||
/* We can still get an error on first fit if the above */
|
||||
/* returned size was a bet fit case */
|
||||
/* ModeLoadHigh = 80 = try high, then low */
|
||||
if ((rc = DosMemAlloc((seg) exe_size, mem_access_mode | ModeLoadHigh, (seg FAR *) & mem
|
||||
,(UWORD FAR *) & asize)) < 0)
|
||||
{
|
||||
if (rc == DE_NOMEM)
|
||||
{
|
||||
if ((rc = DosMemAlloc(0, LARGEST, (seg FAR *) & mem
|
||||
,(UWORD FAR *) & asize)) < 0)
|
||||
/* + long2para((LONG) sizeof(psp)); ?? see above
|
||||
image_size += sizeof(psp) -- 1999/04/21 ska */
|
||||
if (exe_size > asize && (mem_access_mode & 0x80))
|
||||
{
|
||||
/* First try low memory */
|
||||
mem_access_mode &= ~0x80;
|
||||
rc = DosMemLargest((seg FAR *) & asize);
|
||||
mem_access_mode |= 0x80;
|
||||
if (rc != SUCCESS)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
if (exe_size > asize)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
return DE_NOMEM;
|
||||
}
|
||||
/* This should never happen, but ... */
|
||||
if (asize < exe_size)
|
||||
{
|
||||
DosMemFree(mem);
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* with no error, we got exactly what we asked for */
|
||||
asize = exe_size;
|
||||
exe_size = (LONG) long2para(image_size) + header.exMaxAlloc;
|
||||
/* + long2para((LONG) sizeof(psp)); ?? -- 1999/04/21 ska */
|
||||
if (exe_size > asize)
|
||||
exe_size = asize;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("loading '%S' at %04x\n", namep, mem);
|
||||
#endif
|
||||
/* TE if header.exMinAlloc == header.exMaxAlloc == 0,
|
||||
DOS will allocate the largest possible memory area
|
||||
and load the image as high as possible into it.
|
||||
discovered (and after that found in RBIL), when testing NET */
|
||||
|
||||
if ((header.exMinAlloc | header.exMaxAlloc) == 0)
|
||||
exe_size = asize;
|
||||
|
||||
/* /// Removed closing curly brace. We should not attempt to allocate
|
||||
memory if we are overlaying the current process, because the new
|
||||
process will simply re-use the block we already have allocated.
|
||||
This was causing execl() to fail in applications which use it to
|
||||
overlay (replace) the current exe file with a new one.
|
||||
Jun 11, 2000 - rbc
|
||||
} */
|
||||
|
||||
/* Allocate our memory and pass back any errors */
|
||||
/* We can still get an error on first fit if the above */
|
||||
/* returned size was a bet fit case */
|
||||
/* ModeLoadHigh = 80 = try high, then low */
|
||||
if ((rc =
|
||||
DosMemAlloc((seg) exe_size, mem_access_mode | ModeLoadHigh,
|
||||
(seg FAR *) & mem, (UWORD FAR *) & asize)) < 0)
|
||||
{
|
||||
if (rc == DE_NOMEM)
|
||||
{
|
||||
if ((rc =
|
||||
DosMemAlloc(0, LARGEST, (seg FAR *) & mem,
|
||||
(UWORD FAR *) & asize)) < 0)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
/* This should never happen, but ... */
|
||||
if (asize < exe_size)
|
||||
{
|
||||
DosMemFree(mem);
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* with no error, we got exactly what we asked for */
|
||||
asize = exe_size;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("loading '%S' at %04x\n", namep, mem);
|
||||
#endif
|
||||
|
||||
/* /// Added open curly brace and "else" clause. We should not attempt
|
||||
to allocate memory if we are overlaying the current process, because
|
||||
@ -686,114 +676,118 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
This was causing execl() to fail in applications which use it to
|
||||
overlay (replace) the current exe file with a new one.
|
||||
Jun 11, 2000 - rbc */
|
||||
}
|
||||
else
|
||||
asize = exe_size;
|
||||
/* /// End of additions. Jun 11, 2000 - rbc */
|
||||
|
||||
if ( ModeLoadHigh )
|
||||
{
|
||||
mem_access_mode &= ~ModeLoadHigh; /* restore old situation */
|
||||
DosUmbLink(UMBstate); /* restore link state */
|
||||
}
|
||||
|
||||
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
/* memory found large enough - continue processing */
|
||||
mp = MK_FP(mem, 0);
|
||||
++mem;
|
||||
}
|
||||
else
|
||||
mem = exp->load.load_seg;
|
||||
|
||||
/* create the start seg for later computations */
|
||||
if (mode == OVERLAY)
|
||||
start_seg = mem;
|
||||
else
|
||||
{
|
||||
start_seg = mem + long2para((LONG) sizeof(psp));
|
||||
}
|
||||
|
||||
/* Now load the executable */
|
||||
/* If file not found - error */
|
||||
/* NOTE - this is fatal because we lost it in transit */
|
||||
/* from DosExec! */
|
||||
if ((rc = DosOpen(namep, 0)) < 0)
|
||||
{
|
||||
fatal("(DosExeLoader) exe file lost in transit");
|
||||
}
|
||||
/* offset to start of image */
|
||||
if (doslseek(rc, image_offset, 0) != image_offset)
|
||||
{
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
DosMemFree(--mem);
|
||||
DosMemFree(env);
|
||||
}
|
||||
return DE_INVLDDATA;
|
||||
}
|
||||
|
||||
/* read in the image in 32K chunks */
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
exe_size = image_size - sizeof(psp);
|
||||
}
|
||||
else
|
||||
exe_size = image_size;
|
||||
|
||||
if (exe_size > 0)
|
||||
{
|
||||
UCOUNT nBytesRead;
|
||||
BYTE FAR *sp;
|
||||
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
if ((header.exMinAlloc == 0) && (header.exMaxAlloc == 0))
|
||||
{
|
||||
/* then the image should be placed as high as possible */
|
||||
start_seg = start_seg + mp->m_size - (image_size + 15) / 16;
|
||||
}
|
||||
}
|
||||
|
||||
sp = MK_FP(start_seg, 0x0);
|
||||
|
||||
do
|
||||
{
|
||||
nBytesRead = DosRead((COUNT) rc, (COUNT) (exe_size < CHUNK ? exe_size : CHUNK), (VOID FAR *) sp, &UnusedRetVal);
|
||||
sp = add_far((VOID FAR *) sp, (ULONG) nBytesRead);
|
||||
exe_size -= nBytesRead;
|
||||
}
|
||||
while (nBytesRead && exe_size > 0);
|
||||
}
|
||||
}
|
||||
|
||||
{ /* relocate the image for new segment */
|
||||
COUNT i;
|
||||
UWORD reloc[2];
|
||||
seg FAR *spot;
|
||||
|
||||
doslseek(rc, (LONG) header.exRelocTable, 0);
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
{
|
||||
if (DosRead(rc, sizeof(reloc), (VOID FAR *) & reloc[0], &UnusedRetVal) != sizeof(reloc))
|
||||
{
|
||||
return DE_INVLDDATA;
|
||||
}
|
||||
if (mode == OVERLAY)
|
||||
{
|
||||
spot = MK_FP(reloc[1] + mem, reloc[0]);
|
||||
*spot += exp->load.reloc;
|
||||
}
|
||||
else
|
||||
asize = exe_size;
|
||||
/* /// End of additions. Jun 11, 2000 - rbc */
|
||||
|
||||
if (ModeLoadHigh)
|
||||
{
|
||||
/* spot = MK_FP(reloc[1] + mem + 0x10, reloc[0]); */
|
||||
spot = MK_FP(reloc[1] + start_seg, reloc[0]);
|
||||
*spot += start_seg;
|
||||
mem_access_mode &= ~ModeLoadHigh; /* restore old situation */
|
||||
DosUmbLink(UMBstate); /* restore link state */
|
||||
}
|
||||
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
/* memory found large enough - continue processing */
|
||||
mp = MK_FP(mem, 0);
|
||||
++mem;
|
||||
}
|
||||
else
|
||||
mem = exp->load.load_seg;
|
||||
|
||||
/* create the start seg for later computations */
|
||||
if (mode == OVERLAY)
|
||||
start_seg = mem;
|
||||
else
|
||||
{
|
||||
start_seg = mem + long2para((LONG) sizeof(psp));
|
||||
}
|
||||
|
||||
/* Now load the executable */
|
||||
/* If file not found - error */
|
||||
/* NOTE - this is fatal because we lost it in transit */
|
||||
/* from DosExec! */
|
||||
if ((rc = DosOpen(namep, 0)) < 0)
|
||||
{
|
||||
fatal("(DosExeLoader) exe file lost in transit");
|
||||
}
|
||||
/* offset to start of image */
|
||||
if (doslseek(rc, image_offset, 0) != image_offset)
|
||||
{
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
DosMemFree(--mem);
|
||||
DosMemFree(env);
|
||||
}
|
||||
return DE_INVLDDATA;
|
||||
}
|
||||
|
||||
/* read in the image in 32K chunks */
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
exe_size = image_size - sizeof(psp);
|
||||
}
|
||||
else
|
||||
exe_size = image_size;
|
||||
|
||||
if (exe_size > 0)
|
||||
{
|
||||
UCOUNT nBytesRead;
|
||||
BYTE FAR *sp;
|
||||
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
if ((header.exMinAlloc == 0) && (header.exMaxAlloc == 0))
|
||||
{
|
||||
/* then the image should be placed as high as possible */
|
||||
start_seg = start_seg + mp->m_size - (image_size + 15) / 16;
|
||||
}
|
||||
}
|
||||
|
||||
sp = MK_FP(start_seg, 0x0);
|
||||
|
||||
do
|
||||
{
|
||||
nBytesRead =
|
||||
DosRead((COUNT) rc,
|
||||
(COUNT) (exe_size < CHUNK ? exe_size : CHUNK),
|
||||
(VOID FAR *) sp, &UnusedRetVal);
|
||||
sp = add_far((VOID FAR *) sp, (ULONG) nBytesRead);
|
||||
exe_size -= nBytesRead;
|
||||
}
|
||||
while (nBytesRead && exe_size > 0);
|
||||
}
|
||||
}
|
||||
|
||||
{ /* relocate the image for new segment */
|
||||
COUNT i;
|
||||
UWORD reloc[2];
|
||||
seg FAR *spot;
|
||||
|
||||
doslseek(rc, (LONG) header.exRelocTable, 0);
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
{
|
||||
if (DosRead
|
||||
(rc, sizeof(reloc), (VOID FAR *) & reloc[0],
|
||||
&UnusedRetVal) != sizeof(reloc))
|
||||
{
|
||||
return DE_INVLDDATA;
|
||||
}
|
||||
if (mode == OVERLAY)
|
||||
{
|
||||
spot = MK_FP(reloc[1] + mem, reloc[0]);
|
||||
*spot += exp->load.reloc;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* spot = MK_FP(reloc[1] + mem + 0x10, reloc[0]); */
|
||||
spot = MK_FP(reloc[1] + start_seg, reloc[0]);
|
||||
*spot += start_seg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* and finally close the file */
|
||||
DosClose(rc);
|
||||
|
||||
@ -801,64 +795,61 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
if (mode == OVERLAY)
|
||||
return SUCCESS;
|
||||
|
||||
|
||||
{
|
||||
psp FAR *p;
|
||||
psp FAR *q = MK_FP(cu_psp, 0);
|
||||
psp FAR *p;
|
||||
psp FAR *q = MK_FP(cu_psp, 0);
|
||||
|
||||
/* point to the PSP so we can build it */
|
||||
p = MK_FP(mem, 0);
|
||||
setvec(0x22, (VOID(INRPT FAR *) (VOID)) MK_FP(user_r->CS, user_r->IP));
|
||||
new_psp(p, mem + asize);
|
||||
/* point to the PSP so we can build it */
|
||||
p = MK_FP(mem, 0);
|
||||
setvec(0x22, (VOID(INRPT FAR *) (VOID)) MK_FP(user_r->CS, user_r->IP));
|
||||
new_psp(p, mem + asize);
|
||||
|
||||
asize = patchPSP(mem - 1, env, exp, namep); /* asize = fcbcode */
|
||||
asize = patchPSP(mem - 1, env, exp, namep); /* asize = fcbcode */
|
||||
|
||||
/* Transfer control to the executable */
|
||||
p->ps_parent = cu_psp;
|
||||
p->ps_prevpsp = (BYTE FAR *) MK_FP(cu_psp, 0);
|
||||
q->ps_stack = (BYTE FAR *) user_r;
|
||||
user_r->FLAGS &= ~FLG_CARRY;
|
||||
/* Transfer control to the executable */
|
||||
p->ps_parent = cu_psp;
|
||||
p->ps_prevpsp = (BYTE FAR *) MK_FP(cu_psp, 0);
|
||||
q->ps_stack = (BYTE FAR *) user_r;
|
||||
user_r->FLAGS &= ~FLG_CARRY;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case LOADNGO:
|
||||
switch (mode)
|
||||
{
|
||||
/* build the user area on the stack */
|
||||
iregs FAR *irp = MK_FP(header.exInitSS + start_seg,
|
||||
((header.exInitSP - sizeof(iregs)) & 0xffff));
|
||||
case LOADNGO:
|
||||
{
|
||||
/* build the user area on the stack */
|
||||
iregs FAR *irp = MK_FP(header.exInitSS + start_seg,
|
||||
((header.exInitSP -
|
||||
sizeof(iregs)) & 0xffff));
|
||||
|
||||
/* start allocating REGs */
|
||||
/* Note: must match es & ds memory segment */
|
||||
irp->ES = irp->DS = mem;
|
||||
irp->CS = header.exInitCS + start_seg;
|
||||
irp->IP = header.exInitIP;
|
||||
irp->AX = asize; /* asize = fcbcode */
|
||||
irp->BX =
|
||||
irp->CX =
|
||||
irp->DX =
|
||||
irp->SI =
|
||||
irp->DI =
|
||||
irp->BP = 0;
|
||||
irp->FLAGS = 0x200;
|
||||
/* start allocating REGs */
|
||||
/* Note: must match es & ds memory segment */
|
||||
irp->ES = irp->DS = mem;
|
||||
irp->CS = header.exInitCS + start_seg;
|
||||
irp->IP = header.exInitIP;
|
||||
irp->AX = asize; /* asize = fcbcode */
|
||||
irp->BX = irp->CX = irp->DX = irp->SI = irp->DI = irp->BP = 0;
|
||||
irp->FLAGS = 0x200;
|
||||
|
||||
cu_psp = mem;
|
||||
dta = p->ps_dta;
|
||||
cu_psp = mem;
|
||||
dta = p->ps_dta;
|
||||
|
||||
if (InDOS)
|
||||
--InDOS;
|
||||
exec_user(irp);
|
||||
/* We should never be here
|
||||
fatal("KERNEL RETURNED!!!"); */
|
||||
break;
|
||||
if (InDOS)
|
||||
--InDOS;
|
||||
exec_user(irp);
|
||||
/* We should never be here
|
||||
fatal("KERNEL RETURNED!!!"); */
|
||||
break;
|
||||
}
|
||||
|
||||
case LOAD:
|
||||
cu_psp = mem;
|
||||
exp->exec.stack =
|
||||
MK_FP(header.exInitSS + start_seg, header.exInitSP);
|
||||
*((UWORD FAR *) exp->exec.stack) = asize; /* fcbcode */
|
||||
exp->exec.start_addr =
|
||||
MK_FP(header.exInitCS + start_seg, header.exInitIP);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
case LOAD:
|
||||
cu_psp = mem;
|
||||
exp->exec.stack = MK_FP(header.exInitSS + start_seg, header.exInitSP);
|
||||
*((UWORD FAR *) exp->exec.stack) = asize; /* fcbcode */
|
||||
exp->exec.start_addr = MK_FP(header.exInitCS + start_seg, header.exInitIP);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
return DE_INVLDFMT;
|
||||
}
|
||||
@ -885,7 +876,6 @@ COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp)
|
||||
return DE_FILENOTFND;
|
||||
}
|
||||
|
||||
|
||||
if (DosRead(rc, sizeof(exe_header), (VOID FAR *) & header, &UnusedRetVal)
|
||||
!= sizeof(exe_header))
|
||||
{
|
||||
@ -995,4 +985,3 @@ COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp)
|
||||
* Rev 1.0 02 Jul 1995 8:34:06 patv
|
||||
* Initial revision.
|
||||
*/
|
||||
|
||||
|
@ -8,7 +8,8 @@ int main(int argc, char **argv)
|
||||
|
||||
if (argc < 4)
|
||||
{
|
||||
fprintf(stderr, "Usage: bin2c <output bin file> <output h file> <array name>\n");
|
||||
fprintf(stderr,
|
||||
"Usage: bin2c <output bin file> <output h file> <array name>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
379
sys/fdkrncfg.c
379
sys/fdkrncfg.c
@ -15,11 +15,9 @@
|
||||
|
||||
/* This source compiled & tested with Borland C/C++ 3.1 + TC 2.01*/
|
||||
|
||||
|
||||
char VERSION[] = "v1.00";
|
||||
char PROGRAM[] = "SYS CONFIG";
|
||||
char KERNEL[] = "KERNEL.SYS";
|
||||
|
||||
char KERNEL[] = "KERNEL.SYS";
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -30,8 +28,7 @@ char KERNEL[] = "KERNEL.SYS";
|
||||
#define FAR far
|
||||
#include "kconfig.h"
|
||||
|
||||
KernelConfig cfg = {0};
|
||||
|
||||
KernelConfig cfg = { 0 };
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef signed char sbyte;
|
||||
@ -40,45 +37,39 @@ typedef signed short sword;
|
||||
typedef unsigned long dword;
|
||||
typedef signed long sdword;
|
||||
|
||||
|
||||
/* These structures need to be byte packed, if your compiler
|
||||
does not do this by default, add the appropriate command,
|
||||
such as #pragma pack(1) here, protected with #ifdefs of course.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* Displays command line syntax */
|
||||
void showUsage(void)
|
||||
{
|
||||
printf("Usage: \n"
|
||||
" %s \n"
|
||||
" %s [/help | /?]\n"
|
||||
" %s [ [drive:][path]%s] [option=value ...] \n",
|
||||
PROGRAM, PROGRAM, PROGRAM, KERNEL);
|
||||
" %s \n"
|
||||
" %s [/help | /?]\n"
|
||||
" %s [ [drive:][path]%s] [option=value ...] \n",
|
||||
PROGRAM, PROGRAM, PROGRAM, KERNEL);
|
||||
printf("\n");
|
||||
printf(" If no options are given, the current values are shown.\n");
|
||||
printf(" /help or /? displays this usage information.\n"
|
||||
" [drive:][path]KERNEL.SYS specifies the kernel file to\n"
|
||||
" modify, if not given defaults to %s\n",
|
||||
KERNEL);
|
||||
" [drive:][path]KERNEL.SYS specifies the kernel file to\n"
|
||||
" modify, if not given defaults to %s\n", KERNEL);
|
||||
printf("\n");
|
||||
printf(" option=value ... specifies one or more options and the values\n"
|
||||
" to set each to. If an option is given multiple times,\n"
|
||||
" the value set will be the rightmost one.\n");
|
||||
printf
|
||||
(" option=value ... specifies one or more options and the values\n"
|
||||
" to set each to. If an option is given multiple times,\n"
|
||||
" the value set will be the rightmost one.\n");
|
||||
printf(" Current Options are: DLASORT=0|1, SHOWDRIVEASSIGNMENT=0|1\n"
|
||||
" SKIPCONFIGSECONDS=#, FORCELBA=0|1\n"
|
||||
" GLOBALENABLELBASUPPORT=0|1\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* simply reads in current configuration values, exiting program
|
||||
with an error message and error code unable to, otherwise
|
||||
cfg & kfile are valid on return.
|
||||
*/
|
||||
|
||||
|
||||
/* Reads in the current kernel configuration settings,
|
||||
return 0 on success, nonzero on error. If there was
|
||||
an actual error the return value is positive, if there
|
||||
@ -92,35 +83,34 @@ void showUsage(void)
|
||||
not point to allocated memory on entry, as that memory
|
||||
will not be used, and will likely not be freed as a result).
|
||||
*/
|
||||
int readConfigSettings(int kfile, char *kfilename, KernelConfig *cfg)
|
||||
int readConfigSettings(int kfile, char *kfilename, KernelConfig * cfg)
|
||||
{
|
||||
int ch;
|
||||
int configBlkFound;
|
||||
word cfgSize;
|
||||
|
||||
|
||||
/* Seek to start of kernel file */
|
||||
if (lseek(kfile, 2, SEEK_SET) != 2)
|
||||
printf("can't seek to offset 2\n"),exit(1);
|
||||
if (lseek(kfile, 2, SEEK_SET) != 2)
|
||||
printf("can't seek to offset 2\n"), exit(1);
|
||||
|
||||
if (read(kfile,cfg,sizeof(KernelConfig)) != sizeof(KernelConfig))
|
||||
printf("can't read %u bytes\n",sizeof(KernelConfig)),exit(1);
|
||||
if (read(kfile, cfg, sizeof(KernelConfig)) != sizeof(KernelConfig))
|
||||
printf("can't read %u bytes\n", sizeof(KernelConfig)), exit(1);
|
||||
|
||||
if (memcmp(cfg->CONFIG, "CONFIG", 6) != 0)
|
||||
{
|
||||
printf("Error: no CONFIG section found in kernel file <%s>\n", kfilename);
|
||||
printf("Only FreeDOS kernels after 2025 contain a CONFIG section!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (memcmp(cfg->CONFIG, "CONFIG", 6) != 0)
|
||||
{
|
||||
printf("Error: no CONFIG section found in kernel file <%s>\n",
|
||||
kfilename);
|
||||
printf("Only FreeDOS kernels after 2025 contain a CONFIG section!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Writes config values out to file.
|
||||
Returns 0 on success, nonzero on error.
|
||||
*/
|
||||
int writeConfigSettings(int kfile, KernelConfig *cfg)
|
||||
int writeConfigSettings(int kfile, KernelConfig * cfg)
|
||||
{
|
||||
|
||||
/* Seek to CONFIG section at start of options of kernel file */
|
||||
@ -135,53 +125,59 @@ int writeConfigSettings(int kfile, KernelConfig *cfg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Displays kernel configuration information */
|
||||
void displayConfigSettings(KernelConfig *cfg)
|
||||
void displayConfigSettings(KernelConfig * cfg)
|
||||
{
|
||||
/* print known options and current value - only if available */
|
||||
|
||||
if (cfg->ConfigSize >= 1)
|
||||
{
|
||||
printf("DLASORT=0x%02X Sort disks by drive order: *0=no, 1=yes\n",
|
||||
cfg->DLASortByDriveNo);
|
||||
printf
|
||||
("DLASORT=0x%02X Sort disks by drive order: *0=no, 1=yes\n",
|
||||
cfg->DLASortByDriveNo);
|
||||
}
|
||||
|
||||
if (cfg->ConfigSize >= 2)
|
||||
{
|
||||
printf("SHOWDRIVEASSIGNMENT=0x%02X Show how drives assigned: *1=yes 0=no\n",
|
||||
cfg->InitDiskShowDriveAssignment);
|
||||
printf
|
||||
("SHOWDRIVEASSIGNMENT=0x%02X Show how drives assigned: *1=yes 0=no\n",
|
||||
cfg->InitDiskShowDriveAssignment);
|
||||
}
|
||||
|
||||
if (cfg->ConfigSize >= 3)
|
||||
{
|
||||
printf("SKIPCONFIGSECONDS=%-3d time to wait for F5/F8 : *2 sec (skip < 0)\n",
|
||||
cfg->SkipConfigSeconds);
|
||||
printf
|
||||
("SKIPCONFIGSECONDS=%-3d time to wait for F5/F8 : *2 sec (skip < 0)\n",
|
||||
cfg->SkipConfigSeconds);
|
||||
}
|
||||
|
||||
if (cfg->ConfigSize >= 4)
|
||||
{
|
||||
printf("FORCELBA=0x%02X Always use LBA if possible: *0=no, 1=yes\n",
|
||||
cfg->ForceLBA);
|
||||
printf
|
||||
("FORCELBA=0x%02X Always use LBA if possible: *0=no, 1=yes\n",
|
||||
cfg->ForceLBA);
|
||||
}
|
||||
|
||||
if (cfg->ConfigSize >= 5)
|
||||
{
|
||||
printf("GLOBALENABLELBASUPPORT=0x%02X Enable LBA support: *1=yes, 0=no\n",
|
||||
cfg->GlobalEnableLBAsupport);
|
||||
printf
|
||||
("GLOBALENABLELBASUPPORT=0x%02X Enable LBA support: *1=yes, 0=no\n",
|
||||
cfg->GlobalEnableLBAsupport);
|
||||
}
|
||||
|
||||
#if 0 /* we assume that SYS is as current as the kernel */
|
||||
#if 0 /* we assume that SYS is as current as the kernel */
|
||||
|
||||
/* Print value any options added that are unknown as hex dump */
|
||||
if (cfg->configHdr.configSize > sizeof(ConfigData))
|
||||
{
|
||||
printf("Additional options are available, they are not currently\n"
|
||||
"supported by this tool. The current extra values are (in Hex):\n");
|
||||
for (i = 0; i < (cfg->configSize-sizeof(ConfigData)); i++)
|
||||
"supported by this tool. The current extra values are (in Hex):\n");
|
||||
for (i = 0; i < (cfg->configSize - sizeof(ConfigData)); i++)
|
||||
{
|
||||
if ((i%32) == 0) printf("\n");
|
||||
else if ((i%4) == 0) printf(" ");
|
||||
if ((i % 32) == 0)
|
||||
printf("\n");
|
||||
else if ((i % 4) == 0)
|
||||
printf(" ");
|
||||
printf("%02X", (unsigned int)cfg->extra[i]);
|
||||
}
|
||||
printf("\n");
|
||||
@ -190,8 +186,6 @@ void displayConfigSettings(KernelConfig *cfg)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Note: The setXXXOption functions will set the config option of
|
||||
type XXX to the value given. It will display a warning, but
|
||||
allow probably invalid values to be used (cause I believe in
|
||||
@ -205,7 +199,8 @@ void displayConfigSettings(KernelConfig *cfg)
|
||||
/* Sets the given location to an unsigned byte value if different,
|
||||
displays warning if values exceeds max
|
||||
*/
|
||||
void setByteOption(byte *option, char *value, word max, int *updated, char *name)
|
||||
void setByteOption(byte * option, char *value, word max, int *updated,
|
||||
char *name)
|
||||
{
|
||||
unsigned long optionValue;
|
||||
|
||||
@ -215,17 +210,17 @@ void setByteOption(byte *option, char *value, word max, int *updated, char *name
|
||||
if (optionValue > 255)
|
||||
{
|
||||
printf("Warning: Option %s: Value <0x%02lX> will be truncated!\n",
|
||||
name, optionValue);
|
||||
name, optionValue);
|
||||
}
|
||||
if ((byte)optionValue > max)
|
||||
if ((byte) optionValue > max)
|
||||
{
|
||||
printf("Warning: Option %s: Value <0x%02X> may be invalid!\n",
|
||||
name, (unsigned int)((byte)optionValue));
|
||||
name, (unsigned int)((byte) optionValue));
|
||||
}
|
||||
/* Don't bother updating if same value */
|
||||
if ((byte)optionValue != *option)
|
||||
if ((byte) optionValue != *option)
|
||||
{
|
||||
*option = (byte)optionValue;
|
||||
*option = (byte) optionValue;
|
||||
*updated = 1;
|
||||
}
|
||||
}
|
||||
@ -233,36 +228,38 @@ void setByteOption(byte *option, char *value, word max, int *updated, char *name
|
||||
/* Sets the given location to a signed byte value if different,
|
||||
displays warning if values exceeds max or is less than min
|
||||
*/
|
||||
void setSByteOption(sbyte *option, char *value, sword min, sword max, int *updated, char *name)
|
||||
void setSByteOption(sbyte * option, char *value, sword min, sword max,
|
||||
int *updated, char *name)
|
||||
{
|
||||
signed long optionValue;
|
||||
|
||||
/* optionValue = atoi(value); Use strtol instead of atoi/atol as it detects base */
|
||||
optionValue = strtol(value, NULL, 0);
|
||||
|
||||
if ( (optionValue < -128) || (optionValue > 127) )
|
||||
if ((optionValue < -128) || (optionValue > 127))
|
||||
{
|
||||
printf("Warning: Option %s: Value <0x%02lX> will be truncated!\n",
|
||||
name, optionValue);
|
||||
name, optionValue);
|
||||
}
|
||||
if ( ((sbyte)optionValue > max) || ((sbyte)optionValue < min) )
|
||||
if (((sbyte) optionValue > max) || ((sbyte) optionValue < min))
|
||||
{
|
||||
printf("Warning: Option %s: Value <0x%02X> may be invalid!\n",
|
||||
name, (signed int)((byte)optionValue));
|
||||
name, (signed int)((byte) optionValue));
|
||||
}
|
||||
/* Don't bother updating if same value */
|
||||
if ((sbyte)optionValue != *option)
|
||||
if ((sbyte) optionValue != *option)
|
||||
{
|
||||
*option = (sbyte)optionValue;
|
||||
*option = (sbyte) optionValue;
|
||||
*updated = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* disable until there are (un)signed word configuration values */
|
||||
#if 0 /* disable until there are (un)signed word configuration values */
|
||||
/* Sets the given location to an unsigned word value if different,
|
||||
displays warning if values exceeds max
|
||||
*/
|
||||
void setWordOption(word *option, char *value, dword max, int *updated, char *name)
|
||||
void setWordOption(word * option, char *value, dword max, int *updated,
|
||||
char *name)
|
||||
{
|
||||
unsigned long optionValue;
|
||||
|
||||
@ -272,17 +269,17 @@ void setWordOption(word *option, char *value, dword max, int *updated, char *nam
|
||||
if (optionValue > 65535)
|
||||
{
|
||||
printf("Warning: Option %s: Value <0x%02lX> will be truncated!\n",
|
||||
name, optionValue);
|
||||
name, optionValue);
|
||||
}
|
||||
if ((word)optionValue > max)
|
||||
if ((word) optionValue > max)
|
||||
{
|
||||
printf("Warning: Option %s: Value <0x%02X> may be invalid!\n",
|
||||
name, (unsigned int)optionValue);
|
||||
name, (unsigned int)optionValue);
|
||||
}
|
||||
/* Don't bother updating if same value */
|
||||
if ((word)optionValue != *option)
|
||||
if ((word) optionValue != *option)
|
||||
{
|
||||
*option = (word)optionValue;
|
||||
*option = (word) optionValue;
|
||||
*updated = 1;
|
||||
}
|
||||
}
|
||||
@ -290,174 +287,166 @@ void setWordOption(word *option, char *value, dword max, int *updated, char *nam
|
||||
/* Sets the given location to a signed byte value if different,
|
||||
displays warning if values exceeds max or is less than min
|
||||
*/
|
||||
void setSWordOption(sword *option, char *value, sdword min, sdword max, int *updated, char *name)
|
||||
void setSWordOption(sword * option, char *value, sdword min, sdword max,
|
||||
int *updated, char *name)
|
||||
{
|
||||
signed long optionValue;
|
||||
|
||||
/* optionValue = atol(value); Use strtol instead of atoi/atol as it allows 0xFF and 255 */
|
||||
optionValue = strtol(value, NULL, 0);
|
||||
|
||||
if ( (optionValue < -32768) || (optionValue > 32767) )
|
||||
if ((optionValue < -32768) || (optionValue > 32767))
|
||||
{
|
||||
printf("Warning: Option %s: Value <0x%02lX> will be truncated!\n",
|
||||
name, optionValue);
|
||||
name, optionValue);
|
||||
}
|
||||
|
||||
if ( ((sword)optionValue > max) || ((sword)optionValue < min) )
|
||||
if (((sword) optionValue > max) || ((sword) optionValue < min))
|
||||
{
|
||||
printf("Warning: Option %s: Value <0x%02X> may be invalid!\n",
|
||||
name, (signed int)optionValue);
|
||||
name, (signed int)optionValue);
|
||||
}
|
||||
/* Don't bother updating if same value */
|
||||
if ((sword)optionValue != *option)
|
||||
if ((sword) optionValue != *option)
|
||||
{
|
||||
*option = (sword)optionValue;
|
||||
*option = (sword) optionValue;
|
||||
*updated = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Main, processes command line options and calls above
|
||||
functions as required.
|
||||
*/
|
||||
int FDKrnConfigMain(int argc,char **argv)
|
||||
int FDKrnConfigMain(int argc, char **argv)
|
||||
{
|
||||
char *kfilename = KERNEL;
|
||||
char *kfilename = KERNEL;
|
||||
int kfile;
|
||||
int updates = 0; /* flag used to indicate if we need to update kernel */
|
||||
int argstart,i;
|
||||
int updates = 0; /* flag used to indicate if we need to update kernel */
|
||||
int argstart, i;
|
||||
char *cptr;
|
||||
char *argptr;
|
||||
|
||||
printf("FreeDOS Kernel Configuration %s\n", VERSION);
|
||||
|
||||
|
||||
/* 1st go through and just process arguments (help/filename/etc) */
|
||||
for (i = 2; i < argc; i++)
|
||||
for (i = 2; i < argc; i++)
|
||||
{
|
||||
argptr = argv[i];
|
||||
|
||||
/* is it an argument or an option specifier */
|
||||
if (argptr[0] == '-' || argptr[0] == '/')
|
||||
{
|
||||
argptr = argv[i];
|
||||
|
||||
/* is it an argument or an option specifier */
|
||||
if (argptr[0] == '-' || argptr[0] == '/')
|
||||
{
|
||||
switch(argptr[1])
|
||||
{
|
||||
case 'H':
|
||||
case 'h':
|
||||
case '?':
|
||||
showUsage();
|
||||
exit(0);
|
||||
|
||||
default:
|
||||
printf("Invalid argument found <%s>.\nUse %s /help for usage.\n",
|
||||
argptr, PROGRAM);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
argstart = 2;
|
||||
switch (argptr[1])
|
||||
{
|
||||
case 'H':
|
||||
case 'h':
|
||||
case '?':
|
||||
showUsage();
|
||||
exit(0);
|
||||
|
||||
argptr = argv[argstart];
|
||||
default:
|
||||
printf("Invalid argument found <%s>.\nUse %s /help for usage.\n",
|
||||
argptr, PROGRAM);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* No arguments is acceptable, just displays current settings using default kernel file */
|
||||
if (argptr == 0)
|
||||
{
|
||||
showUsage();
|
||||
exit(1);
|
||||
}
|
||||
argstart = 2;
|
||||
|
||||
argptr = argv[argstart];
|
||||
|
||||
#if 0 /* No arguments is acceptable, just displays current settings using default kernel file */
|
||||
if (argptr == 0)
|
||||
{
|
||||
showUsage();
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* the first argument may be the kernel name */
|
||||
if ( (argstart < argc) && (strchr(argptr, '=') == NULL) )
|
||||
{
|
||||
kfilename = argptr;
|
||||
argstart++;
|
||||
}
|
||||
/* the first argument may be the kernel name */
|
||||
if ((argstart < argc) && (strchr(argptr, '=') == NULL))
|
||||
{
|
||||
kfilename = argptr;
|
||||
argstart++;
|
||||
}
|
||||
|
||||
kfile = open(kfilename, O_RDWR | O_BINARY);
|
||||
|
||||
kfile = open(kfilename, O_RDWR | O_BINARY);
|
||||
if (kfile < 0)
|
||||
printf("Error: unable to open kernel file <%s>\n", kfilename), exit(1);
|
||||
|
||||
if (kfile < 0)
|
||||
printf("Error: unable to open kernel file <%s>\n", kfilename),exit(1);
|
||||
/* now that we know the filename (default or given) get config info */
|
||||
readConfigSettings(kfile, kfilename, &cfg);
|
||||
|
||||
for (i = argstart; i < argc; i++)
|
||||
{
|
||||
argptr = argv[i];
|
||||
|
||||
/* now that we know the filename (default or given) get config info */
|
||||
readConfigSettings(kfile, kfilename, &cfg);
|
||||
if ((cptr = strchr(argptr, '=')) == NULL)
|
||||
goto illegal_arg;
|
||||
|
||||
for (i = argstart; i < argc; i++)
|
||||
{
|
||||
argptr = argv[i];
|
||||
/* split argptr into 2 pieces and make cptr point to 2nd one */
|
||||
*cptr = '\0';
|
||||
cptr++;
|
||||
|
||||
if ((cptr = strchr(argptr,'=')) == NULL)
|
||||
goto illegal_arg;
|
||||
|
||||
/* split argptr into 2 pieces and make cptr point to 2nd one */
|
||||
*cptr = '\0';
|
||||
cptr++;
|
||||
|
||||
/* allow 3 valid characters */
|
||||
if (memicmp(argptr, "DLASORT",3) == 0)
|
||||
{
|
||||
setByteOption(&(cfg.DLASortByDriveNo),
|
||||
cptr, 1, &updates, "DLASORT");
|
||||
}
|
||||
else if (memicmp(argptr, "SHOWDRIVEASSIGNMENT",3) == 0)
|
||||
{
|
||||
setByteOption(&(cfg.InitDiskShowDriveAssignment),
|
||||
cptr, 1, &updates, "SHOWDRIVEASSIGNMENT");
|
||||
}
|
||||
else if (memicmp(argptr, "SKIPCONFIGSECONDS",3) == 0)
|
||||
{
|
||||
setSByteOption(&(cfg.SkipConfigSeconds),
|
||||
cptr, -128, 127, &updates, "SKIPCONFIGSECONDS");
|
||||
}
|
||||
else if (memicmp(argptr, "FORCELBA",3) == 0)
|
||||
{
|
||||
setByteOption(&(cfg.ForceLBA),
|
||||
cptr, 1, &updates, "FORCELBA");
|
||||
}
|
||||
else if (memicmp(argptr, "GLOBALENABLELBASUPPORT",3) == 0)
|
||||
{
|
||||
setByteOption(&(cfg.GlobalEnableLBAsupport),
|
||||
cptr, 1, &updates, "GLOBALENABLELBASUPPORT");
|
||||
}
|
||||
else
|
||||
{
|
||||
illegal_arg:
|
||||
printf("Unknown option found <%s>.\nUse %s /help for usage.\n",
|
||||
argptr, PROGRAM);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* write out new config values if modified */
|
||||
if (updates)
|
||||
/* allow 3 valid characters */
|
||||
if (memicmp(argptr, "DLASORT", 3) == 0)
|
||||
{
|
||||
/* update it */
|
||||
if (writeConfigSettings(kfile, &cfg))
|
||||
{
|
||||
printf("Error: Unable to write configuration changes to kernel!\n");
|
||||
printf(" <%s>\n", kfilename);
|
||||
close(kfile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* display new settings */
|
||||
printf("\nUpdated Kernel settings.\n");
|
||||
setByteOption(&(cfg.DLASortByDriveNo), cptr, 1, &updates, "DLASORT");
|
||||
}
|
||||
else if (memicmp(argptr, "SHOWDRIVEASSIGNMENT", 3) == 0)
|
||||
{
|
||||
setByteOption(&(cfg.InitDiskShowDriveAssignment),
|
||||
cptr, 1, &updates, "SHOWDRIVEASSIGNMENT");
|
||||
}
|
||||
else if (memicmp(argptr, "SKIPCONFIGSECONDS", 3) == 0)
|
||||
{
|
||||
setSByteOption(&(cfg.SkipConfigSeconds),
|
||||
cptr, -128, 127, &updates, "SKIPCONFIGSECONDS");
|
||||
}
|
||||
else if (memicmp(argptr, "FORCELBA", 3) == 0)
|
||||
{
|
||||
setByteOption(&(cfg.ForceLBA), cptr, 1, &updates, "FORCELBA");
|
||||
}
|
||||
else if (memicmp(argptr, "GLOBALENABLELBASUPPORT", 3) == 0)
|
||||
{
|
||||
setByteOption(&(cfg.GlobalEnableLBAsupport),
|
||||
cptr, 1, &updates, "GLOBALENABLELBASUPPORT");
|
||||
}
|
||||
else
|
||||
printf("\nCurrent Kernel settings.\n");
|
||||
{
|
||||
illegal_arg:
|
||||
printf("Unknown option found <%s>.\nUse %s /help for usage.\n",
|
||||
argptr, PROGRAM);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* write out new config values if modified */
|
||||
if (updates)
|
||||
{
|
||||
/* update it */
|
||||
if (writeConfigSettings(kfile, &cfg))
|
||||
{
|
||||
printf("Error: Unable to write configuration changes to kernel!\n");
|
||||
printf(" <%s>\n", kfilename);
|
||||
close(kfile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* display new settings */
|
||||
printf("\nUpdated Kernel settings.\n");
|
||||
}
|
||||
else
|
||||
printf("\nCurrent Kernel settings.\n");
|
||||
|
||||
/* display current settings */
|
||||
displayConfigSettings(&cfg);
|
||||
displayConfigSettings(&cfg);
|
||||
|
||||
/* and done */
|
||||
close(kfile);
|
||||
/* and done */
|
||||
close(kfile);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
493
sys/sys.c
493
sys/sys.c
@ -46,9 +46,9 @@
|
||||
#include <dos.h>
|
||||
#include <ctype.h>
|
||||
#ifdef __TURBOC__
|
||||
#include <mem.h>
|
||||
#include <mem.h>
|
||||
#else
|
||||
#include <memory.h>
|
||||
#include <memory.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
/*#include <dir.h> */
|
||||
@ -69,16 +69,14 @@ BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file);
|
||||
COUNT DiskRead(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
|
||||
COUNT DiskWrite(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
|
||||
|
||||
|
||||
#define SEC_SIZE 512
|
||||
#define COPY_SIZE 32768u
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(1)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
struct bootsectortype
|
||||
{
|
||||
struct bootsectortype {
|
||||
UBYTE bsJump[3];
|
||||
char OemName[8];
|
||||
UWORD bsBytesPerSec;
|
||||
@ -106,8 +104,7 @@ struct bootsectortype
|
||||
ULONG sysDataStart; /* first data sector */
|
||||
};
|
||||
|
||||
struct bootsectortype32
|
||||
{
|
||||
struct bootsectortype32 {
|
||||
UBYTE bsJump[3];
|
||||
char OemName[8];
|
||||
UWORD bsBytesPerSec;
|
||||
@ -134,7 +131,7 @@ struct bootsectortype32
|
||||
UBYTE bsReserved3;
|
||||
UBYTE bsExtendedSignature;
|
||||
ULONG bsSerialNumber;
|
||||
char bsVolumeLabel[11];
|
||||
char bsVolumeLabel[11];
|
||||
char bsFileSystemID[8];
|
||||
ULONG sysFatStart;
|
||||
ULONG sysDataStart;
|
||||
@ -144,19 +141,17 @@ struct bootsectortype32
|
||||
|
||||
UBYTE newboot[SEC_SIZE], oldboot[SEC_SIZE];
|
||||
|
||||
|
||||
#define SBOFFSET 11
|
||||
#define SBSIZE (sizeof(struct bootsectortype) - SBOFFSET)
|
||||
#define SBSIZE32 (sizeof(struct bootsectortype32) - SBOFFSET)
|
||||
|
||||
/* essentially - verify alignment on byte boundaries at compile time */
|
||||
struct VerifyBootSectorSize
|
||||
{
|
||||
char failure1[sizeof(struct bootsectortype) == 78 ? 1 : -1];
|
||||
char failure2[sizeof(struct bootsectortype) == 78 ? 1 : 0];
|
||||
struct VerifyBootSectorSize {
|
||||
char failure1[sizeof(struct bootsectortype) == 78 ? 1 : -1];
|
||||
char failure2[sizeof(struct bootsectortype) == 78 ? 1 : 0];
|
||||
};
|
||||
|
||||
int FDKrnConfigMain(int argc,char **argv);
|
||||
int FDKrnConfigMain(int argc, char **argv);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@ -169,26 +164,26 @@ int main(int argc, char **argv)
|
||||
WORD slen;
|
||||
|
||||
printf("FreeDOS System Installer " SYS_VERSION "\n\n");
|
||||
|
||||
if (argc > 1 && memicmp(argv[1],"CONFIG",6) == 0)
|
||||
{
|
||||
exit(FDKrnConfigMain(argc,argv));
|
||||
}
|
||||
|
||||
if (argc > 1 && memicmp(argv[1], "CONFIG", 6) == 0)
|
||||
{
|
||||
exit(FDKrnConfigMain(argc, argv));
|
||||
}
|
||||
|
||||
srcPath[0] = '\0';
|
||||
if (argc > 1 && argv[1][1] == ':' && argv[1][2] == '\0')
|
||||
drivearg = 1;
|
||||
|
||||
|
||||
if (argc > 2 && argv[2][1] == ':' && argv[2][2] == '\0')
|
||||
{
|
||||
drivearg = 2;
|
||||
strncpy(srcPath, argv[1], MAXPATH-12);
|
||||
strncpy(srcPath, argv[1], MAXPATH - 12);
|
||||
/* leave room for COMMAND.COM\0 */
|
||||
srcPath[MAXPATH-13] = '\0';
|
||||
srcPath[MAXPATH - 13] = '\0';
|
||||
/* make sure srcPath + "file" is a valid path */
|
||||
slen = strlen(srcPath);
|
||||
if ( (srcPath[slen-1] != ':') &&
|
||||
((srcPath[slen-1] != '\\') || (srcPath[slen-1] != '/')) )
|
||||
if ((srcPath[slen - 1] != ':') &&
|
||||
((srcPath[slen - 1] != '\\') || (srcPath[slen - 1] != '/')))
|
||||
{
|
||||
srcPath[slen] = '\\';
|
||||
slen++;
|
||||
@ -199,48 +194,52 @@ int main(int argc, char **argv)
|
||||
if (drivearg == 0)
|
||||
{
|
||||
printf("Usage: %s [source] drive: [bootsect [BOTH]]\n", pgm);
|
||||
printf(" source = A:,B:,C:\\KERNEL\\BIN\\,etc., or current directory if not given\n");
|
||||
printf
|
||||
(" source = A:,B:,C:\\KERNEL\\BIN\\,etc., or current directory if not given\n");
|
||||
printf(" drive = A,B,etc.\n");
|
||||
printf(" bootsect = name of 512-byte boot sector file image for drive:\n");
|
||||
printf
|
||||
(" bootsect = name of 512-byte boot sector file image for drive:\n");
|
||||
printf(" to write to instead of real boot sector\n");
|
||||
printf(" BOTH : write to both the real boot sector and the image file\n");
|
||||
printf("%s CONFIG /help\n",pgm);
|
||||
printf
|
||||
(" BOTH : write to both the real boot sector and the image file\n");
|
||||
printf("%s CONFIG /help\n", pgm);
|
||||
exit(1);
|
||||
}
|
||||
drive = toupper(argv[drivearg][0]) - 'A';
|
||||
|
||||
if (drive < 0 || drive >= 26)
|
||||
{
|
||||
printf( "%s: drive %c must be A:..Z:\n", pgm,*argv[(argc == 3 ? 2 : 1)]);
|
||||
printf("%s: drive %c must be A:..Z:\n", pgm,
|
||||
*argv[(argc == 3 ? 2 : 1)]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Get source drive */
|
||||
if ((strlen(srcPath) > 1) && (srcPath[1] == ':')) /* src specifies drive */
|
||||
/* Get source drive */
|
||||
if ((strlen(srcPath) > 1) && (srcPath[1] == ':')) /* src specifies drive */
|
||||
srcDrive = toupper(*srcPath) - 'A';
|
||||
else /* src doesn't specify drive, so assume current drive */
|
||||
{
|
||||
else /* src doesn't specify drive, so assume current drive */
|
||||
{
|
||||
#ifdef __TURBOC__
|
||||
srcDrive = getdisk();
|
||||
#else
|
||||
#else
|
||||
_dos_getdrive(&srcDrive);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Don't try root if src==dst drive or source path given */
|
||||
if ( (drive == srcDrive) || (*srcPath && ((srcPath[1] != ':') || ((srcPath[1] == ':') && srcPath[2]))) )
|
||||
if ((drive == srcDrive)
|
||||
|| (*srcPath
|
||||
&& ((srcPath[1] != ':') || ((srcPath[1] == ':') && srcPath[2]))))
|
||||
*rootPath = '\0';
|
||||
else
|
||||
sprintf(rootPath, "%c:\\", 'A' + srcDrive);
|
||||
|
||||
|
||||
if (!check_space(drive, oldboot))
|
||||
{
|
||||
printf("%s: Not enough space to transfer system files\n", pgm);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
printf("\nCopying KERNEL.SYS...\n");
|
||||
if (!copy(drive, srcPath, rootPath, "kernel.sys"))
|
||||
{
|
||||
@ -255,13 +254,14 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (argc > drivearg+1)
|
||||
bsFile = argv[drivearg+1];
|
||||
|
||||
if (argc > drivearg + 1)
|
||||
bsFile = argv[drivearg + 1];
|
||||
|
||||
printf("\nWriting boot sector...\n");
|
||||
put_boot(drive, bsFile,
|
||||
(argc > drivearg+2) && memicmp(argv[drivearg+2], "BOTH", 4) == 0);
|
||||
|
||||
(argc > drivearg + 2)
|
||||
&& memicmp(argv[drivearg + 2], "BOTH", 4) == 0);
|
||||
|
||||
printf("\nSystem transferred.\n");
|
||||
return 0;
|
||||
}
|
||||
@ -269,78 +269,77 @@ int main(int argc, char **argv)
|
||||
#ifdef DDEBUG
|
||||
VOID dump_sector(unsigned char far * sec)
|
||||
{
|
||||
COUNT x, y;
|
||||
char c;
|
||||
COUNT x, y;
|
||||
char c;
|
||||
|
||||
for (x = 0; x < 32; x++)
|
||||
for (x = 0; x < 32; x++)
|
||||
{
|
||||
printf("%03X ", x * 16);
|
||||
for (y = 0; y < 16; y++)
|
||||
{
|
||||
printf("%03X ", x * 16);
|
||||
for (y = 0; y < 16; y++)
|
||||
{
|
||||
printf("%02X ", sec[x * 16 + y]);
|
||||
}
|
||||
for (y = 0; y < 16; y++)
|
||||
{
|
||||
c = oldboot[x * 16 + y];
|
||||
if (isprint(c))
|
||||
printf( "%c", c);
|
||||
else
|
||||
printf( ".");
|
||||
}
|
||||
printf( "\n");
|
||||
}
|
||||
printf("%02X ", sec[x * 16 + y]);
|
||||
}
|
||||
for (y = 0; y < 16; y++)
|
||||
{
|
||||
c = oldboot[x * 16 + y];
|
||||
if (isprint(c))
|
||||
printf("%c", c);
|
||||
else
|
||||
printf(".");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf( "\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
TC absRead not functional on MSDOS 6.2, large disks
|
||||
MSDOS requires int25, CX=ffff for drives > 32MB
|
||||
*/
|
||||
|
||||
int MyAbsReadWrite(int DosDrive, int count, ULONG sector, void *buffer, unsigned intno)
|
||||
int MyAbsReadWrite(int DosDrive, int count, ULONG sector, void *buffer,
|
||||
unsigned intno)
|
||||
{
|
||||
struct {
|
||||
unsigned long sectorNumber;
|
||||
unsigned short count;
|
||||
void far *address;
|
||||
} diskReadPacket;
|
||||
int retval;
|
||||
union REGS regs;
|
||||
struct {
|
||||
unsigned long sectorNumber;
|
||||
unsigned short count;
|
||||
void far *address;
|
||||
} diskReadPacket;
|
||||
int retval;
|
||||
union REGS regs;
|
||||
|
||||
diskReadPacket.sectorNumber = sector;
|
||||
diskReadPacket.count = count;
|
||||
diskReadPacket.address = buffer;
|
||||
|
||||
diskReadPacket.sectorNumber = sector;
|
||||
diskReadPacket.count = count;
|
||||
diskReadPacket.address = buffer;
|
||||
regs.h.al = (BYTE) DosDrive;
|
||||
regs.x.bx = (short)&diskReadPacket;
|
||||
regs.x.cx = 0xffff;
|
||||
|
||||
regs.h.al = (BYTE)DosDrive;
|
||||
if (intno != 0x25 && intno != 0x26)
|
||||
return 0xff;
|
||||
|
||||
int86(intno, ®s, ®s);
|
||||
|
||||
#ifdef WITHFAT32
|
||||
if (regs.x.cflag)
|
||||
{
|
||||
regs.x.ax = 0x7305;
|
||||
regs.h.dl = DosDrive + 1;
|
||||
regs.x.bx = (short)&diskReadPacket;
|
||||
regs.x.cx = 0xffff;
|
||||
|
||||
if (intno != 0x25 && intno != 0x26) return 0xff;
|
||||
|
||||
int86(intno,®s,®s);
|
||||
|
||||
#ifdef WITHFAT32
|
||||
if (regs.x.cflag)
|
||||
{
|
||||
regs.x.ax = 0x7305;
|
||||
regs.h.dl = DosDrive + 1;
|
||||
regs.x.bx = (short)&diskReadPacket;
|
||||
regs.x.cx = 0xffff;
|
||||
regs.x.si = intno - 0x25;
|
||||
int86(0x21, ®s, ®s);
|
||||
}
|
||||
regs.x.si = intno - 0x25;
|
||||
int86(0x21, ®s, ®s);
|
||||
}
|
||||
#endif
|
||||
|
||||
return regs.x.cflag ? 0xff : 0;
|
||||
}
|
||||
return regs.x.cflag ? 0xff : 0;
|
||||
}
|
||||
|
||||
|
||||
VOID put_boot(COUNT drive, BYTE *bsFile, BOOL both)
|
||||
VOID put_boot(COUNT drive, BYTE * bsFile, BOOL both)
|
||||
{
|
||||
COUNT i, z;
|
||||
WORD head, track, sector, ret;
|
||||
@ -355,25 +354,23 @@ VOID put_boot(COUNT drive, BYTE *bsFile, BOOL both)
|
||||
struct SREGS sregs;
|
||||
char drivename[] = "A:\\";
|
||||
unsigned char x[0x40];
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Reading old bootsector from drive %c:\n",drive+'A');
|
||||
#endif
|
||||
printf("Reading old bootsector from drive %c:\n", drive + 'A');
|
||||
#endif
|
||||
|
||||
if (MyAbsReadWrite(drive, 1, 0, oldboot,0x25) != 0)
|
||||
{
|
||||
printf("can't read old boot sector for drive %c:\n", drive +'A');
|
||||
if (MyAbsReadWrite(drive, 1, 0, oldboot, 0x25) != 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;
|
||||
bs = (struct bootsectortype *)&oldboot;
|
||||
if ((bs->bsFileSysType[4] == '6') && (bs->bsBootSignature == 0x29))
|
||||
{
|
||||
fs = 16;
|
||||
@ -388,78 +385,81 @@ VOID put_boot(COUNT drive, BYTE *bsFile, BOOL both)
|
||||
FS detection method to GetFreeDiskSpace().
|
||||
this should work, as the disk was writeable, so GetFreeDiskSpace should work.
|
||||
*/
|
||||
|
||||
regs.h.ah = 0x36; /* get drive free space */
|
||||
regs.h.dl = drive+1; /* 1 = 'A',... */
|
||||
int86(0x21,®s,®s);
|
||||
|
||||
if (regs.x.ax == 0xffff)
|
||||
{
|
||||
printf("can't get free disk space for %c:\n", drive+'A');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (regs.x.dx <= 0xff6)
|
||||
{
|
||||
if (fs != 12) printf("warning : new detection overrides old detection\a\n");
|
||||
fs = 12;
|
||||
}
|
||||
else {
|
||||
|
||||
if (fs != 16) printf("warning : new detection overrides old detection\a\n");
|
||||
fs = 16;
|
||||
regs.h.ah = 0x36; /* get drive free space */
|
||||
regs.h.dl = drive + 1; /* 1 = 'A',... */
|
||||
int86(0x21, ®s, ®s);
|
||||
|
||||
/* fs = 16/32.
|
||||
we don't want to crash a FAT32 drive
|
||||
*/
|
||||
if (regs.x.ax == 0xffff)
|
||||
{
|
||||
printf("can't get free disk space for %c:\n", drive + 'A');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
segread(&sregs);
|
||||
sregs.es = sregs.ds;
|
||||
|
||||
regs.x.ax = 0x7303; /* get extended drive free space */
|
||||
|
||||
drivename[0] = 'A' + drive;
|
||||
regs.x.dx = (unsigned)&drivename;
|
||||
regs.x.di = (unsigned)&x;
|
||||
regs.x.cx = sizeof(x);
|
||||
|
||||
int86x(0x21,®s,®s,&sregs);
|
||||
|
||||
if (regs.x.cflag) /* error --> no Win98 --> no FAT32 */
|
||||
{
|
||||
printf("get extended drive space not supported --> no FAT32\n");
|
||||
}
|
||||
else {
|
||||
if (*(unsigned long *)(x+0x2c) /* total number of clusters */
|
||||
> (unsigned)65526l)
|
||||
{
|
||||
fs = 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (regs.x.dx <= 0xff6)
|
||||
{
|
||||
if (fs != 12)
|
||||
printf("warning : new detection overrides old detection\a\n");
|
||||
fs = 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (fs != 16)
|
||||
printf("warning : new detection overrides old detection\a\n");
|
||||
fs = 16;
|
||||
|
||||
if (fs == 16)
|
||||
{
|
||||
memcpy(newboot, b_fat16, SEC_SIZE); /* copy FAT16 boot sector */
|
||||
printf("FAT type: FAT16\n");
|
||||
}
|
||||
else if (fs == 12)
|
||||
{
|
||||
memcpy(newboot, b_fat12, SEC_SIZE); /* copy FAT12 boot sector */
|
||||
printf("FAT type: FAT12\n");
|
||||
}
|
||||
/* fs = 16/32.
|
||||
we don't want to crash a FAT32 drive
|
||||
*/
|
||||
|
||||
segread(&sregs);
|
||||
sregs.es = sregs.ds;
|
||||
|
||||
regs.x.ax = 0x7303; /* get extended drive free space */
|
||||
|
||||
drivename[0] = 'A' + drive;
|
||||
regs.x.dx = (unsigned)&drivename;
|
||||
regs.x.di = (unsigned)&x;
|
||||
regs.x.cx = sizeof(x);
|
||||
|
||||
int86x(0x21, ®s, ®s, &sregs);
|
||||
|
||||
if (regs.x.cflag) /* error --> no Win98 --> no FAT32 */
|
||||
{
|
||||
printf("get extended drive space not supported --> no FAT32\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("FAT type: FAT32\n");
|
||||
{
|
||||
if (*(unsigned long *)(x + 0x2c) /* total number of clusters */
|
||||
> (unsigned)65526l)
|
||||
{
|
||||
fs = 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fs == 16)
|
||||
{
|
||||
memcpy(newboot, b_fat16, SEC_SIZE); /* copy FAT16 boot sector */
|
||||
printf("FAT type: FAT16\n");
|
||||
}
|
||||
else if (fs == 12)
|
||||
{
|
||||
memcpy(newboot, b_fat12, SEC_SIZE); /* copy FAT12 boot sector */
|
||||
printf("FAT type: FAT12\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("FAT type: FAT32\n");
|
||||
#ifdef WITHFAT32
|
||||
memcpy(newboot, b_fat32, SEC_SIZE); /* copy FAT32 boot sector */
|
||||
memcpy(newboot, b_fat32, SEC_SIZE); /* copy FAT32 boot sector */
|
||||
#else
|
||||
printf("SYS hasn't been compiled with FAT32 support.");
|
||||
printf("Consider using -DWITHFAT32 option.\n");
|
||||
exit(1);
|
||||
printf("SYS hasn't been compiled with FAT32 support.");
|
||||
printf("Consider using -DWITHFAT32 option.\n");
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy disk parameter from old sector to new sector */
|
||||
#ifdef WITHFAT32
|
||||
@ -469,31 +469,32 @@ VOID put_boot(COUNT drive, BYTE *bsFile, BOOL both)
|
||||
#endif
|
||||
memcpy(&newboot[SBOFFSET], &oldboot[SBOFFSET], SBSIZE);
|
||||
|
||||
bs = (struct bootsectortype *) & newboot;
|
||||
|
||||
memcpy(bs->OemName, "FreeDOS ",8);
|
||||
bs = (struct bootsectortype *)&newboot;
|
||||
|
||||
memcpy(bs->OemName, "FreeDOS ", 8);
|
||||
|
||||
#ifdef WITHFAT32
|
||||
if (fs == 32)
|
||||
{
|
||||
bs32 = (struct bootsectortype32 *) & newboot;
|
||||
|
||||
temp = bs32->bsHiddenSecs + bs32->bsResSectors;
|
||||
bs32->sysFatStart = temp;
|
||||
|
||||
bs32->sysDataStart = temp + bs32->bsBigFatSize * bs32->bsFATs;
|
||||
bs32->sysFatSecMask = bs32->bsBytesPerSec / 4 - 1;
|
||||
|
||||
temp = bs32->sysFatSecMask + 1;
|
||||
for (bs32->sysFatSecShift = 0; temp != 1; bs32->sysFatSecShift++, temp >>= 1);
|
||||
}
|
||||
{
|
||||
bs32 = (struct bootsectortype32 *)&newboot;
|
||||
|
||||
temp = bs32->bsHiddenSecs + bs32->bsResSectors;
|
||||
bs32->sysFatStart = temp;
|
||||
|
||||
bs32->sysDataStart = temp + bs32->bsBigFatSize * bs32->bsFATs;
|
||||
bs32->sysFatSecMask = bs32->bsBytesPerSec / 4 - 1;
|
||||
|
||||
temp = bs32->sysFatSecMask + 1;
|
||||
for (bs32->sysFatSecShift = 0; temp != 1;
|
||||
bs32->sysFatSecShift++, temp >>= 1) ;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (fs == 32)
|
||||
{
|
||||
printf( "FAT starts at sector %lx = (%lx + %x)\n", bs32->sysFatStart,
|
||||
bs32->bsHiddenSecs, bs32->bsResSectors);
|
||||
printf("DATA starts at sector %lx\n", bs32->sysDataStart);
|
||||
}
|
||||
{
|
||||
printf("FAT starts at sector %lx = (%lx + %x)\n", bs32->sysFatStart,
|
||||
bs32->bsHiddenSecs, bs32->bsResSectors);
|
||||
printf("DATA starts at sector %lx\n", bs32->sysDataStart);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
#endif
|
||||
@ -502,39 +503,39 @@ VOID put_boot(COUNT drive, BYTE *bsFile, BOOL both)
|
||||
/* 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));
|
||||
*((UWORD *) (bs->unused)) =
|
||||
*((UWORD *) (((struct bootsectortype *)&b_fat16)->unused));
|
||||
/* end of HACK */
|
||||
/* root directory sectors */
|
||||
/* root directory sectors */
|
||||
|
||||
bs->sysRootDirSecs = bs->bsRootDirEnts / 16;
|
||||
|
||||
/* sector FAT starts on */
|
||||
/* sector FAT starts on */
|
||||
temp = bs->bsHiddenSecs + bs->bsResSectors;
|
||||
bs->sysFatStart = temp;
|
||||
|
||||
/* sector root directory starts on */
|
||||
|
||||
/* sector root directory starts on */
|
||||
temp = temp + bs->bsFATsecs * bs->bsFATs;
|
||||
bs->sysRootDirStart = temp;
|
||||
|
||||
/* sector data starts on */
|
||||
|
||||
/* sector data starts on */
|
||||
temp = temp + bs->sysRootDirSecs;
|
||||
bs->sysDataStart = temp;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
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("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);
|
||||
bs->sysRootDirStart, bs->bsFATsecs, bs->bsFATs);
|
||||
printf("DATA starts at sector %lu = (PREVIOUS + %u)\n", bs->sysDataStart,
|
||||
bs->sysRootDirSecs);
|
||||
bs->sysRootDirSecs);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DDEBUG
|
||||
printf("\nNew Boot Sector:\n");
|
||||
dump_sector(newboot);
|
||||
@ -542,30 +543,32 @@ VOID put_boot(COUNT drive, BYTE *bsFile, BOOL both)
|
||||
|
||||
if ((bsFile == NULL) || both)
|
||||
{
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("writing new bootsector to drive %c:\n",drive+'A');
|
||||
#endif
|
||||
|
||||
if (MyAbsReadWrite(drive, 1, 0, newboot,0x26) != 0)
|
||||
#ifdef DEBUG
|
||||
printf("writing new bootsector to drive %c:\n", drive + 'A');
|
||||
#endif
|
||||
|
||||
if (MyAbsReadWrite(drive, 1, 0, newboot, 0x26) != 0)
|
||||
{
|
||||
printf("Can't write new boot sector to drive %c:\n", drive +'A');
|
||||
printf("Can't write new boot sector to drive %c:\n", drive + 'A');
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (bsFile != NULL)
|
||||
{
|
||||
int fd;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("writing new bootsector to file %s\n", bsFile);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* write newboot to bsFile */
|
||||
if ((fd = open(bsFile, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,S_IREAD|S_IWRITE)) < 0)
|
||||
if ((fd =
|
||||
open(bsFile, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,
|
||||
S_IREAD | S_IWRITE)) < 0)
|
||||
{
|
||||
printf( " %s: can't create\"%s\"\nDOS errnum %d", pgm, bsFile, errno);
|
||||
printf(" %s: can't create\"%s\"\nDOS errnum %d", pgm, bsFile, errno);
|
||||
exit(1);
|
||||
}
|
||||
if (write(fd, newboot, SEC_SIZE) != SEC_SIZE)
|
||||
@ -579,15 +582,13 @@ VOID put_boot(COUNT drive, BYTE *bsFile, BOOL both)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL check_space(COUNT drive, BYTE * BlkBuffer)
|
||||
{
|
||||
/* this should check, if on destination is enough space
|
||||
to hold command.com+ kernel.sys */
|
||||
|
||||
UNREFERENCED_PARAMETER(drive);
|
||||
UNREFERENCED_PARAMETER(BlkBuffer);
|
||||
|
||||
/* this should check, if on destination is enough space
|
||||
to hold command.com+ kernel.sys */
|
||||
|
||||
UNREFERENCED_PARAMETER(drive);
|
||||
UNREFERENCED_PARAMETER(BlkBuffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -602,13 +603,13 @@ BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file)
|
||||
int fdin, fdout;
|
||||
ULONG copied = 0;
|
||||
struct stat fstatbuf;
|
||||
|
||||
|
||||
sprintf(dest, "%c:\\%s", 'A' + drive, file);
|
||||
sprintf(source, "%s%s", srcPath, file);
|
||||
|
||||
if (stat(source, &fstatbuf))
|
||||
{
|
||||
printf( "%s: \"%s\" not found\n", pgm, source);
|
||||
printf("%s: \"%s\" not found\n", pgm, source);
|
||||
|
||||
if ((rootPath != NULL) && (*rootPath) /* && (errno == ENOENT) */ )
|
||||
{
|
||||
@ -616,38 +617,40 @@ BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file)
|
||||
printf("%s: Trying \"%s\"\n", pgm, source);
|
||||
if (stat(source, &fstatbuf))
|
||||
{
|
||||
printf( "%s: \"%s\" not found\n", pgm, source);
|
||||
printf("%s: \"%s\" not found\n", pgm, source);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((fdin = open(source, O_RDONLY|O_BINARY)) < 0)
|
||||
|
||||
if ((fdin = open(source, O_RDONLY | O_BINARY)) < 0)
|
||||
{
|
||||
printf( "%s: failed to open \"%s\"\n", pgm, source);
|
||||
printf("%s: failed to open \"%s\"\n", pgm, source);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((fdout = open(dest, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,S_IREAD|S_IWRITE)) < 0)
|
||||
if ((fdout =
|
||||
open(dest, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,
|
||||
S_IREAD | S_IWRITE)) < 0)
|
||||
{
|
||||
printf( " %s: can't create\"%s\"\nDOS errnum %d", pgm, dest, errno);
|
||||
printf(" %s: can't create\"%s\"\nDOS errnum %d", pgm, dest, errno);
|
||||
close(fdin);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while ((ret = read(fdin, copybuffer,COPY_SIZE)) > 0)
|
||||
while ((ret = read(fdin, copybuffer, COPY_SIZE)) > 0)
|
||||
{
|
||||
if (write(fdout, copybuffer, ret) != ret)
|
||||
{
|
||||
if (write(fdout, copybuffer, ret) != ret)
|
||||
{
|
||||
printf("Can't write %u bytes to %s\n", ret, dest);
|
||||
close(fdout);
|
||||
unlink(dest);
|
||||
break;
|
||||
}
|
||||
copied += ret;
|
||||
}
|
||||
printf("Can't write %u bytes to %s\n", ret, dest);
|
||||
close(fdout);
|
||||
unlink(dest);
|
||||
break;
|
||||
}
|
||||
copied += ret;
|
||||
}
|
||||
|
||||
#ifdef __TURBOC__
|
||||
{
|
||||
@ -655,24 +658,23 @@ BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file)
|
||||
getftime(fdin, &ftime);
|
||||
setftime(fdout, &ftime);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
close(fdin);
|
||||
close(fdout);
|
||||
|
||||
|
||||
#ifdef _MSV_VER
|
||||
{
|
||||
#include <utime.h>
|
||||
struct utimbuf utimb;
|
||||
#include <utime.h>
|
||||
struct utimbuf utimb;
|
||||
|
||||
utimb.actime = /* access time */
|
||||
utimb.modtime = fstatbuf.st_mtime; /* modification time */
|
||||
utime(dest,&utimb);
|
||||
utimb.actime = /* access time */
|
||||
utimb.modtime = fstatbuf.st_mtime; /* modification time */
|
||||
utime(dest, &utimb);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
printf("%lu Bytes transferred", copied);
|
||||
|
||||
return TRUE;
|
||||
@ -755,4 +757,3 @@ BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file)
|
||||
* it create a .COM file.
|
||||
*
|
||||
*/
|
||||
|
||||
|
294
utils/patchobj.c
294
utils/patchobj.c
@ -16,200 +16,188 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1==1)
|
||||
#define FALSE (0==1)
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1==1)
|
||||
#define FALSE (0==1)
|
||||
#endif
|
||||
|
||||
struct {
|
||||
char *sin,*sout;
|
||||
} repl[100];
|
||||
char *sin, *sout;
|
||||
} repl[100];
|
||||
int repl_count;
|
||||
|
||||
|
||||
void quit(char *s,...)
|
||||
void quit(char *s, ...)
|
||||
{
|
||||
vprintf(s,(void*)((char *)&s+sizeof(s)));
|
||||
exit(1);
|
||||
vprintf(s, (void *)((char *)&s + sizeof(s)));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void define_replace(char *sin)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (repl_count >= 99)
|
||||
quit("too many replacements");
|
||||
|
||||
if ((s = strchr(sin, '=')) == NULL)
|
||||
quit("illegal replacement <%s>, missing '='", sin);
|
||||
char *s;
|
||||
|
||||
*s = 0;
|
||||
repl[repl_count].sin = sin;
|
||||
repl[repl_count].sout = s+1;
|
||||
|
||||
repl_count++;
|
||||
if (repl_count >= 99)
|
||||
quit("too many replacements");
|
||||
|
||||
if ((s = strchr(sin, '=')) == NULL)
|
||||
quit("illegal replacement <%s>, missing '='", sin);
|
||||
|
||||
*s = 0;
|
||||
repl[repl_count].sin = sin;
|
||||
repl[repl_count].sout = s + 1;
|
||||
|
||||
repl_count++;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *argptr;
|
||||
int argloop;
|
||||
int cont;
|
||||
int file = 0;
|
||||
FILE *fd,*fdo;
|
||||
char *inname=0,*outname= "~patchob.tmp";
|
||||
char *argptr;
|
||||
int argloop;
|
||||
int cont;
|
||||
int file = 0;
|
||||
FILE *fd, *fdo;
|
||||
char *inname = 0, *outname = "~patchob.tmp";
|
||||
|
||||
int use_temp_file = TRUE;
|
||||
int use_temp_file = TRUE;
|
||||
|
||||
argc--,argv++;
|
||||
argc--, argv++;
|
||||
|
||||
for (; argc != 0; argc--,argv++)
|
||||
{
|
||||
argptr = *argv;
|
||||
|
||||
if (*argptr != '-' && *argptr != '-')
|
||||
{
|
||||
if (inname == 0) { inname = argptr; continue;}
|
||||
define_replace(argptr);
|
||||
continue;
|
||||
}
|
||||
switch (toupper(argptr[1]))
|
||||
{
|
||||
case 'O':
|
||||
outname = argptr+2;
|
||||
use_temp_file = FALSE;
|
||||
break;
|
||||
default:
|
||||
quit("illegal argument <%s>\n",argptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; argc != 0; argc--, argv++)
|
||||
{
|
||||
argptr = *argv;
|
||||
|
||||
|
||||
if (*argptr != '-' && *argptr != '-')
|
||||
{
|
||||
if (inname == 0)
|
||||
{
|
||||
inname = argptr;
|
||||
continue;
|
||||
}
|
||||
define_replace(argptr);
|
||||
continue;
|
||||
}
|
||||
switch (toupper(argptr[1]))
|
||||
{
|
||||
case 'O':
|
||||
outname = argptr + 2;
|
||||
use_temp_file = FALSE;
|
||||
break;
|
||||
default:
|
||||
quit("illegal argument <%s>\n", argptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (inname == 0)
|
||||
quit("Inputfile must be specified\n");
|
||||
if (inname == 0)
|
||||
quit("Inputfile must be specified\n");
|
||||
|
||||
if (repl_count == 0)
|
||||
quit("no replacements defined");
|
||||
if (repl_count == 0)
|
||||
quit("no replacements defined");
|
||||
|
||||
if ((fd = fopen(inname, "rb")) == NULL) /* open for READ/WRITE */
|
||||
quit("can't read %s\n", inname);
|
||||
|
||||
if ((fd = fopen(inname,"rb")) == NULL) /* open for READ/WRITE */
|
||||
quit("can't read %s\n",inname);
|
||||
if ((fdo = fopen(outname, "wb")) == NULL) /* open for READ/WRITE */
|
||||
quit("can't write %s\n", outname);
|
||||
|
||||
if ((fdo = fopen(outname,"wb")) == NULL) /* open for READ/WRITE */
|
||||
quit("can't write %s\n",outname);
|
||||
go_records(fd, fdo);
|
||||
|
||||
go_records(fd,fdo);
|
||||
fclose(fd);
|
||||
fclose(fdo);
|
||||
if (use_temp_file)
|
||||
{
|
||||
unlink(inname);
|
||||
rename(outname, inname);
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
fclose(fdo);
|
||||
if (use_temp_file)
|
||||
{
|
||||
unlink(inname);
|
||||
rename(outname,inname);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
fputs(
|
||||
"DELSYM V1.0 5'95by tom ehlert, SIG Aachen\n"
|
||||
" delete symbolic info in object files\n"
|
||||
"usage:\n"
|
||||
" DELSYM infile [outfile]\n"
|
||||
,stderr);
|
||||
exit(1);
|
||||
fputs("DELSYM V1.0 5'95by tom ehlert, SIG Aachen\n"
|
||||
" delete symbolic info in object files\n"
|
||||
"usage:\n" " DELSYM infile [outfile]\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct record
|
||||
{
|
||||
unsigned char rectyp;
|
||||
unsigned datalen;
|
||||
unsigned char buffer[0x2000];
|
||||
} Record,Outrecord;
|
||||
struct record {
|
||||
unsigned char rectyp;
|
||||
unsigned datalen;
|
||||
unsigned char buffer[0x2000];
|
||||
} Record, Outrecord;
|
||||
|
||||
go_records(FILE * fdin, FILE * fdo)
|
||||
{
|
||||
unsigned char stringlen;
|
||||
unsigned char *string, *s;
|
||||
int i, j;
|
||||
unsigned char chksum;
|
||||
|
||||
go_records(FILE *fdin,FILE *fdo)
|
||||
{
|
||||
unsigned char stringlen;
|
||||
unsigned char *string,*s;
|
||||
int i,j;
|
||||
unsigned char chksum;
|
||||
do
|
||||
{
|
||||
if (fread(&Record, 1, 3, fdin) != 3)
|
||||
{ /* read type and reclen */
|
||||
/* printf("end of fdin read\n"); */
|
||||
break;
|
||||
}
|
||||
if (Record.datalen > sizeof(Record.buffer))
|
||||
quit("record to large : length %u Bytes \n", Record.datalen);
|
||||
|
||||
do {
|
||||
if (fread(&Record,1,3,fdin) != 3) { /* read type and reclen*/
|
||||
/* printf("end of fdin read\n"); */
|
||||
break;
|
||||
}
|
||||
if (Record.datalen > sizeof(Record.buffer))
|
||||
quit ("record to large : length %u Bytes \n",Record.datalen);
|
||||
if (fread(Record.buffer, 1, Record.datalen, fdin) != Record.datalen)
|
||||
{
|
||||
printf("invalid record format\n");
|
||||
quit("can't continue\n");
|
||||
}
|
||||
|
||||
if (fread(Record.buffer,1,Record.datalen,fdin) != Record.datalen)
|
||||
{
|
||||
printf("invalid record format\n");
|
||||
quit ("can't continue\n");
|
||||
}
|
||||
if (Record.rectyp != 0x96) /* we are only interested in LNAMES */
|
||||
{
|
||||
fwrite(&Record, 1, 3 + Record.datalen, fdo);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (Record.rectyp != 0x96) /* we are only interested in LNAMES */
|
||||
{
|
||||
fwrite(&Record,1,3+Record.datalen,fdo);
|
||||
continue;
|
||||
}
|
||||
Outrecord.rectyp = 0x96;
|
||||
Outrecord.datalen = 0;
|
||||
|
||||
Outrecord.rectyp = 0x96;
|
||||
Outrecord.datalen= 0;
|
||||
for (i = 0; i < Record.datalen - 1;)
|
||||
{
|
||||
stringlen = Record.buffer[i];
|
||||
i++;
|
||||
|
||||
string = &Record.buffer[i];
|
||||
i += stringlen;
|
||||
|
||||
|
||||
|
||||
if (i > Record.datalen)
|
||||
quit("invalid lnames record");
|
||||
|
||||
|
||||
for (i = 0; i < Record.datalen-1; )
|
||||
{
|
||||
stringlen = Record.buffer[i];
|
||||
i++;
|
||||
|
||||
string = &Record.buffer[i];
|
||||
i += stringlen;
|
||||
|
||||
|
||||
if (i > Record.datalen)
|
||||
quit("invalid lnames record");
|
||||
|
||||
|
||||
for (j = 0; j < repl_count; j++)
|
||||
if (memcmp(string,repl[j].sin,stringlen) == 0
|
||||
&& strlen(repl[j].sin) == stringlen)
|
||||
{
|
||||
string = repl[j].sout;
|
||||
stringlen = strlen(repl[j].sout);
|
||||
}
|
||||
Outrecord.buffer[Outrecord.datalen] = stringlen;
|
||||
Outrecord.datalen++;
|
||||
memcpy(Outrecord.buffer+Outrecord.datalen,string,stringlen);
|
||||
Outrecord.datalen += stringlen;
|
||||
}
|
||||
for (j = 0; j < repl_count; j++)
|
||||
if (memcmp(string, repl[j].sin, stringlen) == 0
|
||||
&& strlen(repl[j].sin) == stringlen)
|
||||
{
|
||||
string = repl[j].sout;
|
||||
stringlen = strlen(repl[j].sout);
|
||||
}
|
||||
Outrecord.buffer[Outrecord.datalen] = stringlen;
|
||||
Outrecord.datalen++;
|
||||
memcpy(Outrecord.buffer + Outrecord.datalen, string, stringlen);
|
||||
Outrecord.datalen += stringlen;
|
||||
}
|
||||
|
||||
chksum = 0;
|
||||
for (s = (unsigned char *)&Outrecord; s < &Outrecord.buffer[Outrecord.datalen]; s++)
|
||||
chksum += *s;
|
||||
|
||||
Outrecord.buffer[Outrecord.datalen] = ~chksum;
|
||||
Outrecord.datalen++;
|
||||
|
||||
/* printf("^sum = %02x - %02x\n",chksum,~chksum); */
|
||||
|
||||
|
||||
fwrite(&Outrecord,1,3+Outrecord.datalen,fdo);
|
||||
|
||||
} while (Record.rectyp != 0x00 /*ENDFIL*/);
|
||||
chksum = 0;
|
||||
for (s = (unsigned char *)&Outrecord;
|
||||
s < &Outrecord.buffer[Outrecord.datalen]; s++)
|
||||
chksum += *s;
|
||||
|
||||
printf("\n");
|
||||
Outrecord.buffer[Outrecord.datalen] = ~chksum;
|
||||
Outrecord.datalen++;
|
||||
|
||||
/* printf("^sum = %02x - %02x\n",chksum,~chksum); */
|
||||
|
||||
fwrite(&Outrecord, 1, 3 + Outrecord.datalen, fdo);
|
||||
|
||||
}
|
||||
while (Record.rectyp != 0x00 /*ENDFIL*/);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
205
utils/relocinf.c
205
utils/relocinf.c
@ -18,23 +18,19 @@
|
||||
**
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
*/
|
||||
|
||||
* /
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
typedef unsigned short UWORD;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned long ULONG;
|
||||
#ifndef _MSC_VER
|
||||
#define const
|
||||
#define __cdecl cdecl
|
||||
#define const
|
||||
#define __cdecl cdecl
|
||||
#endif
|
||||
|
||||
/* from EXE.H */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
UWORD exSignature;
|
||||
UWORD exExtraBytes;
|
||||
UWORD exPages;
|
||||
@ -49,115 +45,118 @@ typedef struct
|
||||
UWORD exInitCS;
|
||||
UWORD exRelocTable;
|
||||
UWORD exOverlay;
|
||||
}
|
||||
exe_header;
|
||||
} exe_header;
|
||||
|
||||
#define MAGIC 0x5a4d
|
||||
|
||||
struct relocEntry{
|
||||
UWORD off;
|
||||
UWORD seg;
|
||||
UWORD refseg;
|
||||
};
|
||||
struct relocEntry {
|
||||
UWORD off;
|
||||
UWORD seg;
|
||||
UWORD refseg;
|
||||
};
|
||||
|
||||
int __cdecl compReloc(const void *p1, const void *p2)
|
||||
{
|
||||
struct relocEntry *r1 = (struct relocEntry*)p1;
|
||||
struct relocEntry *r2 = (struct relocEntry*)p2;
|
||||
|
||||
if (r1->refseg > r2->refseg) return 1;
|
||||
if (r1->refseg < r2->refseg) return -1;
|
||||
|
||||
if (r1->seg > r2->seg) return 1;
|
||||
if (r1->seg < r2->seg) return -1;
|
||||
|
||||
if (r1->off > r2->off) return 1;
|
||||
if (r1->off < r2->off) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
main(int argc,char *argv[])
|
||||
{
|
||||
FILE *fdin;
|
||||
exe_header header;
|
||||
struct relocEntry *reloc;
|
||||
struct relocEntry *r1 = (struct relocEntry *)p1;
|
||||
struct relocEntry *r2 = (struct relocEntry *)p2;
|
||||
|
||||
int i;
|
||||
ULONG image_offset;
|
||||
|
||||
|
||||
if (argc < 2 || (fdin = fopen(argv[1],"rb")) == NULL)
|
||||
{
|
||||
printf("can't open %s\n",argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
if (r1->refseg > r2->refseg)
|
||||
return 1;
|
||||
if (r1->refseg < r2->refseg)
|
||||
return -1;
|
||||
|
||||
if (fread(&header, sizeof(header),1,fdin) != 1 ||
|
||||
header.exSignature != MAGIC)
|
||||
{
|
||||
printf("%s is no EXE file\n");
|
||||
exit(1);
|
||||
}
|
||||
if (r1->seg > r2->seg)
|
||||
return 1;
|
||||
if (r1->seg < r2->seg)
|
||||
return -1;
|
||||
|
||||
printf("%u relocation entries found\n", header.exRelocItems);
|
||||
|
||||
if (header.exRelocItems > 0x8000/sizeof(*reloc))
|
||||
{
|
||||
printf("too many relocation entries \n");
|
||||
exit(1);
|
||||
}
|
||||
if (r1->off > r2->off)
|
||||
return 1;
|
||||
if (r1->off < r2->off)
|
||||
return -1;
|
||||
|
||||
if ((reloc = malloc(header.exRelocItems*sizeof(*reloc))) == NULL)
|
||||
{
|
||||
printf("can't alloc memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fseek(fdin, header.exRelocTable, 0))
|
||||
{
|
||||
printf("can't seek\n");
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
if (fread(reloc+i, 4,1,fdin) != 1)
|
||||
{
|
||||
printf("can't read reloc info\n");
|
||||
exit(1);
|
||||
}
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
FILE *fdin;
|
||||
exe_header header;
|
||||
struct relocEntry *reloc;
|
||||
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
{
|
||||
image_offset = (ULONG)header.exHeaderSize * 16;
|
||||
int i;
|
||||
ULONG image_offset;
|
||||
|
||||
image_offset += ((ULONG)reloc[i].seg << 4) + reloc[i].off;
|
||||
if (argc < 2 || (fdin = fopen(argv[1], "rb")) == NULL)
|
||||
{
|
||||
printf("can't open %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fseek(fdin, image_offset, 0))
|
||||
{
|
||||
printf("can't seek reloc data\n");
|
||||
exit(1);
|
||||
}
|
||||
if (fread(&header, sizeof(header), 1, fdin) != 1 ||
|
||||
header.exSignature != MAGIC)
|
||||
{
|
||||
printf("%s is no EXE file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fread(&reloc[i].refseg, 2,1,fdin) != 1)
|
||||
{
|
||||
printf("can't read rel data for item %d\n",i);
|
||||
exit(1);
|
||||
}
|
||||
/* printf("%04x:%04x -> %04x\n", reloc[i].seg, reloc[i].off, reloc[i].refseg); */
|
||||
}
|
||||
printf("%u relocation entries found\n", header.exRelocItems);
|
||||
|
||||
/* sort reloc entries */
|
||||
if (header.exRelocItems > 0x8000 / sizeof(*reloc))
|
||||
{
|
||||
printf("too many relocation entries \n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
qsort(reloc, header.exRelocItems, sizeof(*reloc), compReloc);
|
||||
if ((reloc = malloc(header.exRelocItems * sizeof(*reloc))) == NULL)
|
||||
{
|
||||
printf("can't alloc memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
printf("# seg:off references data in -->\n");
|
||||
printf("%3d %04x:%04x -> %04x\n", i,reloc[i].seg, reloc[i].off, reloc[i].refseg);
|
||||
}
|
||||
|
||||
}
|
||||
if (fseek(fdin, header.exRelocTable, 0))
|
||||
{
|
||||
printf("can't seek\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
if (fread(reloc + i, 4, 1, fdin) != 1)
|
||||
{
|
||||
printf("can't read reloc info\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
{
|
||||
image_offset = (ULONG) header.exHeaderSize * 16;
|
||||
|
||||
image_offset += ((ULONG) reloc[i].seg << 4) + reloc[i].off;
|
||||
|
||||
if (fseek(fdin, image_offset, 0))
|
||||
{
|
||||
printf("can't seek reloc data\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fread(&reloc[i].refseg, 2, 1, fdin) != 1)
|
||||
{
|
||||
printf("can't read rel data for item %d\n", i);
|
||||
exit(1);
|
||||
}
|
||||
/* printf("%04x:%04x -> %04x\n", reloc[i].seg, reloc[i].off, reloc[i].refseg); */
|
||||
}
|
||||
|
||||
/* sort reloc entries */
|
||||
|
||||
qsort(reloc, header.exRelocItems, sizeof(*reloc), compReloc);
|
||||
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
printf("# seg:off references data in -->\n");
|
||||
printf("%3d %04x:%04x -> %04x\n", i, reloc[i].seg, reloc[i].off,
|
||||
reloc[i].refseg);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user