kernel 2026b changes

git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@382 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2002-05-08 22:49:35 +00:00
parent bbbd0ce42f
commit 2098578b1b
33 changed files with 636 additions and 954 deletions

View File

@ -206,7 +206,7 @@ cont: mov ds, ax
mov [drive], dl ; BIOS passes drive number in DL mov [drive], dl ; BIOS passes drive number in DL
call print call print
db "Loading FreeDOS...",13,10,"ROOT",0 db "Loading FreeDOS ",0
%ifdef CALCPARAMS %ifdef CALCPARAMS
GETDRIVEPARMS GETDRIVEPARMS
@ -370,7 +370,7 @@ boot_error: call print
int 0x19 ; reboot the machine int 0x19 ; reboot the machine
boot_success: call print boot_success: call print
db " GO!",13,10,0 db " GO! ",0
mov bl, [drive] mov bl, [drive]
jmp word LOADSEG:0 jmp word LOADSEG:0

View File

@ -99,7 +99,7 @@ cont: mov ds, ax
mov [drive], dl ; BIOS passes drive number in DL mov [drive], dl ; BIOS passes drive number in DL
call print call print
db "Loading FreeDOS...",13,10,0 db "Loading FreeDOS ",0
; FINDFILE: Searches for the file in the root directory. ; FINDFILE: Searches for the file in the root directory.
; ;

View File

@ -40,10 +40,6 @@ segment HMA_TEXT
_ReadPCClock: _ReadPCClock:
xor ah,ah xor ah,ah
int 1ah int 1ah
mov bx,sp
mov bx,[bx+2]
mov [bx],dx
mov [bx+2],cx
extern _DaysSinceEpoch ; ; update days if necessary extern _DaysSinceEpoch ; ; update days if necessary
mov ah,0 mov ah,0
@ -51,6 +47,9 @@ _ReadPCClock:
add word [_DaysSinceEpoch ],ax ; *some* BIOS's accumulate several days add word [_DaysSinceEpoch ],ax ; *some* BIOS's accumulate several days
adc word [_DaysSinceEpoch+2],0 ; adc word [_DaysSinceEpoch+2],0 ;
mov ax,dx ; set return value
mov dx,cx
ret ret
; Log: rdpcclk.asm,v ; Log: rdpcclk.asm,v

View File

@ -4,7 +4,7 @@
@if \%COMPILER% == \TURBOCPP set MAKE=%TP1_BASE%\bin\make @if \%COMPILER% == \TURBOCPP set MAKE=%TP1_BASE%\bin\make
@if \%COMPILER% == \TC3 set MAKE=%TC3_BASE%\bin\make @if \%COMPILER% == \TC3 set MAKE=%TC3_BASE%\bin\make
@if \%COMPILER% == \BC5 set MAKE=%BC5_BASE%\bin\make @if \%COMPILER% == \BC5 set MAKE=%BC5_BASE%\bin\make
@if \%COMPILER% == \WATCOM set MAKE=%WATCOM%\binw\wmake /ms @if \%COMPILER% == \WATCOM set MAKE=wmake /ms
@if \%COMPILER% == \MSCL8 set MAKE=%MS_BASE%\nmake /nologo @if \%COMPILER% == \MSCL8 set MAKE=%MS_BASE%\bin\nmake /nologo
:make_set :make_set

View File

@ -58,7 +58,7 @@ struct buffer {
LONG _b_huge_blkno; /* DOS-C: actual block number if >= 0xffff */ LONG _b_huge_blkno; /* DOS-C: actual block number if >= 0xffff */
} _b; } _b;
#endif #endif
BYTE b_buffer[BUFFERSIZE]; /* 512 byte sectors for now */ UBYTE b_buffer[BUFFERSIZE]; /* 512 byte sectors for now */
}; };
#define b_dpbp _b._b_dpbp #define b_dpbp _b._b_dpbp

View File

@ -80,12 +80,12 @@ typedef struct {
UBYTE FAR *ps_filetab; /* 34 open file table pointer */ UBYTE FAR *ps_filetab; /* 34 open file table pointer */
VOID FAR *ps_prevpsp; /* 38 previous psp pointer */ VOID FAR *ps_prevpsp; /* 38 previous psp pointer */
BYTE FAR *ps_dta; /* 3c process dta address */ BYTE FAR *ps_dta; /* 3c process dta address */
BYTE ps_fill2[16]; BYTE ps_fill2[16]; /* 40 */
UBYTE ps_unix[3]; /* unix style call - 0xcd 0x21 0xcb */ UBYTE ps_unix[3]; /* 50 unix style call - 0xcd 0x21 0xcb */
BYTE ps_fill3[9]; BYTE ps_fill3[9]; /* 53 */
union { union {
struct { struct {
fcb _ps_fcb1; /* first command line argument */ fcb _ps_fcb1; /* 5c first command line argument */
} _u1; } _u1;
struct { struct {
BYTE fill4[16]; BYTE fill4[16];

View File

@ -49,6 +49,6 @@ static BYTE *date_hRcsId =
#define REVISION_MINOR 1 #define REVISION_MINOR 1
#define REVISION_SEQ 26 #define REVISION_SEQ 26
#define BUILD "2026" #define BUILD "2026"
#define SUB_BUILD "a" #define SUB_BUILD "b"
#define KERNEL_VERSION_STRING "1.1.26a" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */ #define KERNEL_VERSION_STRING "1.1.26b" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */
#define KERNEL_BUILD_STRING "2026a" /*#BUILD SUB_BUILD */ #define KERNEL_BUILD_STRING "2026b" /*#BUILD SUB_BUILD */

View File

@ -129,7 +129,7 @@ BYTE DontAskThisSingleCommand = FALSE; /* !files= */
COUNT MenuTimeout = -1; COUNT MenuTimeout = -1;
BYTE MenuSelected = 0; BYTE MenuSelected = 0;
BYTE MenuLine = 0; UCOUNT MenuLine = 0;
UCOUNT Menus = 0; UCOUNT Menus = 0;
STATIC VOID zumcb_init(UCOUNT seg, UWORD size); STATIC VOID zumcb_init(UCOUNT seg, UWORD size);
@ -703,21 +703,16 @@ STATIC BOOL SkipLine(char *pLine)
{ {
short key; short key;
static char initialized = FALSE; if (InitKernelConfig.SkipConfigSeconds >= 0)
if (!initialized)
{ {
initialized = TRUE;
if (InitKernelConfig.SkipConfigSeconds < 0)
return FALSE;
if (InitKernelConfig.SkipConfigSeconds > 0) if (InitKernelConfig.SkipConfigSeconds > 0)
printf("Press F8 to trace or F5 to skip CONFIG.SYS/AUTOEXEC.BAT"); printf("Press F8 to trace or F5 to skip CONFIG.SYS/AUTOEXEC.BAT");
key = GetBiosKey(InitKernelConfig.SkipConfigSeconds); /* wait 2 seconds */ key = GetBiosKey(InitKernelConfig.SkipConfigSeconds); /* wait 2 seconds */
InitKernelConfig.SkipConfigSeconds = -1;
if (key == 0x3f00) /* F5 */ if (key == 0x3f00) /* F5 */
{ {
SkipAllConfig = TRUE; SkipAllConfig = TRUE;
@ -737,10 +732,10 @@ STATIC BOOL SkipLine(char *pLine)
return TRUE; return TRUE;
/* 1?device=CDROM.SYS */ /* 1?device=CDROM.SYS */
/* 2?device=OAKROM.SYS */ /* 12?device=OAKROM.SYS */
/* 3?device=EMM386.EXE NOEMS */ /* 123?device=EMM386.EXE NOEMS */
if ( MenuLine != 0 && if ( MenuLine != 0 &&
MenuSelected != MenuLine) (MenuLine & (1 << MenuSelected)) == 0)
return TRUE; return TRUE;
if (DontAskThisSingleCommand) /* !files=30 */ if (DontAskThisSingleCommand) /* !files=30 */
@ -924,7 +919,7 @@ STATIC VOID Dosmem(BYTE * pLine)
for (pTmp = szBuf; *pTmp != '\0'; pTmp++) for (pTmp = szBuf; *pTmp != '\0'; pTmp++)
*pTmp = toupper(*pTmp); *pTmp = toupper(*pTmp);
printf("DOS called with %s\n", szBuf); /* printf("DOS called with %s\n", szBuf); */
for (pTmp = szBuf;;) for (pTmp = szBuf;;)
{ {
@ -1295,14 +1290,22 @@ STATIC BYTE * scan(BYTE * s, BYTE * d)
MenuLine = 0; MenuLine = 0;
/* does the line start with "1?" */ /* does the line start with "123?" */
if (s[1] == '?' && s[0] >= '0' && s[0] <= '9') if (isnum(s))
{ {
MenuLine = s[0]; unsigned numbers = 0;
Menus |= 1 << (MenuLine - '0'); for ( ; isnum(s); s++)
s = skipwh(s+2); numbers |= 1 << (*s -'0');
if (*s == '?')
{
MenuLine = numbers;
Menus |= numbers;
s = skipwh(s+1);
} }
}
/* !dos=high,umb ?? */ /* !dos=high,umb ?? */
if (*s == '!') if (*s == '!')
@ -1615,6 +1618,8 @@ STATIC VOID DoMenu(void)
if (Menus == 0) if (Menus == 0)
return; return;
InitKernelConfig.SkipConfigSeconds = -1;
Menus |= 1 << 0; /* '0' Menu always allowed */ Menus |= 1 << 0; /* '0' Menu always allowed */
printf("\n\n"); printf("\n\n");
@ -1667,7 +1672,7 @@ STATIC VOID DoMenu(void)
if (key >= '0' && key <= '9') if (key >= '0' && key <= '9')
if (Menus & (1 << (key - '0'))) if (Menus & (1 << (key - '0')))
{ {
MenuSelected = key; break; MenuSelected = key - '0'; break;
} }
} }
printf("\n"); printf("\n");
@ -1688,7 +1693,7 @@ STATIC VOID CfgMenuDefault(BYTE * pLine)
/* Format: STACKS = stacks [, stackSize] */ /* Format: STACKS = stacks [, stackSize] */
pLine = GetNumArg(pLine, &num); pLine = GetNumArg(pLine, &num);
MenuSelected = '0' + num; MenuSelected = num;
pLine = skipwh(pLine); pLine = skipwh(pLine);
if (*pLine == ',') if (*pLine == ',')

View File

@ -269,8 +269,6 @@ UCOUNT GenericReadSft(sft FAR * s, UCOUNT n, BYTE FAR * bp,
else else
/* a block read */ /* a block read */
{ {
COUNT rc;
/* /// Added for SHARE - Ron Cemer */ /* /// Added for SHARE - Ron Cemer */
if (IsShareInstalled()) if (IsShareInstalled())
{ {
@ -290,9 +288,9 @@ UCOUNT GenericReadSft(sft FAR * s, UCOUNT n, BYTE FAR * bp,
} }
/* /// End of additions for SHARE - Ron Cemer */ /* /// End of additions for SHARE - Ron Cemer */
ReadCount = readblock(s->sft_status, bp, n, &rc); ReadCount = rwblock(s->sft_status, bp, n, XFR_READ);
*err = rc; *err = SUCCESS;
return (rc == SUCCESS ? ReadCount : 0); return ReadCount;
} }
*err = SUCCESS; *err = SUCCESS;
return 0; return 0;
@ -445,8 +443,6 @@ UCOUNT DosWriteSft(sft FAR * s, UCOUNT n, const BYTE FAR * bp, COUNT FAR * err)
else else
/* a block write */ /* a block write */
{ {
COUNT rc;
/* /// Added for SHARE - Ron Cemer */ /* /// Added for SHARE - Ron Cemer */
if (IsShareInstalled()) if (IsShareInstalled())
{ {
@ -466,21 +462,11 @@ UCOUNT DosWriteSft(sft FAR * s, UCOUNT n, const BYTE FAR * bp, COUNT FAR * err)
} }
/* /// End of additions for SHARE - Ron Cemer */ /* /// End of additions for SHARE - Ron Cemer */
WriteCount = writeblock(s->sft_status, bp, n, &rc); WriteCount = rwblock(s->sft_status, (BYTE FAR *)bp, n, XFR_WRITE);
s->sft_size = dos_getcufsize(s->sft_status); s->sft_size = dos_getcufsize(s->sft_status);
/* if (rc < SUCCESS) */
if (rc == DE_ACCESS || /* -5 Access denied */
rc == DE_INVLDHNDL) /* -6 Invalid handle */
{
*err = rc;
return 0;
}
else
{
*err = SUCCESS; *err = SUCCESS;
return WriteCount; return WriteCount;
} }
}
*err = SUCCESS; *err = SUCCESS;
return 0; return 0;
} }
@ -1041,20 +1027,26 @@ BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc,
if (cdsp->cdsFlags & CDSNETWDRV) if (cdsp->cdsFlags & CDSNETWDRV)
{ {
if (*nc == 0xffff) if (remote_getfree(cdsp, rg) != SUCCESS)
{
/* Undoc DOS says, its not supported for
network drives. so it's probably OK */
/*printf("FatGetDrvData not yet supported over network drives\n"); */
return FALSE; return FALSE;
}
remote_getfree(cdsp, rg); /* for int21/ah=1c:
Undoc DOS says, its not supported for
network drives. so it's probably OK */
/* some programs such as RHIDE want it though and
the redirector can provide all info
- Bart, 2002 Apr 1 */
if (*nc != 0xffff)
{
*navc = (COUNT) rg[3];
rg[0] &= 0xff;
/* zero media ID (high part) */
}
*spc = (COUNT) rg[0]; *spc = (COUNT) rg[0];
*nc = (COUNT) rg[1]; *nc = (COUNT) rg[1];
*bps = (COUNT) rg[2]; *bps = (COUNT) rg[2];
*navc = (COUNT) rg[3];
return TRUE; return TRUE;
} }
@ -1187,6 +1179,15 @@ COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s)
current_ldt = &CDSp->cds_table[drive]; current_ldt = &CDSp->cds_table[drive];
if ((current_ldt->cdsFlags & CDSNETWDRV) == 0)
{
if (current_ldt->cdsDpb == 0)
return DE_INVLDDRV;
if ((media_check(current_ldt->cdsDpb) < 0))
return DE_INVLDDRV;
}
cp = &current_ldt->cdsCurrentPath[current_ldt->cdsJoinOffset]; cp = &current_ldt->cdsCurrentPath[current_ldt->cdsJoinOffset];
if (*cp == '\0') if (*cp == '\0')
s[0] = '\0'; s[0] = '\0';
@ -1361,6 +1362,7 @@ COUNT DosFindNext(void)
fmemset(dta, 0, sizeof(dmatch)); fmemset(dta, 0, sizeof(dmatch));
p = dta; p = dta;
dta = (BYTE FAR *) TempBuffer; dta = (BYTE FAR *) TempBuffer;
current_ldt = &CDSp->cds_table[((dmatch *) TempBuffer)->dm_drive];
rc = (((dmatch *) TempBuffer)->dm_drive & 0x80) ? rc = (((dmatch *) TempBuffer)->dm_drive & 0x80) ?
remote_findnext((VOID FAR *) current_ldt) : dos_findnext(); remote_findnext((VOID FAR *) current_ldt) : dos_findnext();

View File

@ -114,14 +114,12 @@ ULONG dsk_lasttime = 0;
STATIC VOID tmark(ddt *pddt) STATIC VOID tmark(ddt *pddt)
{ {
ReadPCClock(&pddt->ddt_fh.ddt_lasttime); pddt->ddt_fh.ddt_lasttime = ReadPCClock();
} }
STATIC BOOL tdelay(ddt *pddt, ULONG ticks) STATIC BOOL tdelay(ddt *pddt, ULONG ticks)
{ {
ULONG now; return ReadPCClock() - pddt->ddt_fh.ddt_lasttime >= ticks;
ReadPCClock(&now);
return now - pddt->ddt_fh.ddt_lasttime >= ticks;
} }
#define N_PART 4 /* number of partitions per #define N_PART 4 /* number of partitions per
@ -141,6 +139,7 @@ STATIC dsk_proc _dsk_init, mediachk, bldbpb, blockio, IoctlQueblk,
Genblkdev, Getlogdev, Setlogdev, blk_Open, blk_Close, Genblkdev, Getlogdev, Setlogdev, blk_Open, blk_Close,
blk_Media, blk_noerr, blk_nondr, blk_error; blk_Media, blk_noerr, blk_nondr, blk_error;
STATIC WORD getbpb(ddt * pddt);
#ifdef PROTO #ifdef PROTO
STATIC WORD dskerr(COUNT); STATIC WORD dskerr(COUNT);
#else #else
@ -278,6 +277,16 @@ STATIC WORD mediachk(rqptr rp, ddt * pddt)
else else
{ {
rp->r_mcretcode = diskchange(pddt); rp->r_mcretcode = diskchange(pddt);
if (rp->r_mcretcode == M_DONT_KNOW)
{
/* don't know but can check serial number ... */
ULONG serialno = pddt->ddt_serialno;
COUNT result = getbpb(pddt);
if (result != 0)
return (result);
if (serialno != pddt->ddt_serialno)
rp->r_mcretcode = M_CHANGED;
}
} }
return S_DONE; return S_DONE;
} }
@ -395,8 +404,7 @@ STATIC WORD getbpb(ddt * pddt)
if (ret != 0) if (ret != 0)
return (dskerr(ret)); return (dskerr(ret));
getword(&((((BYTE *) & DiskTransferBuffer[BT_BPB]))[0]), pbpbarray->bpb_nbyte = getword(&DiskTransferBuffer[BT_BPB]);
&pbpbarray->bpb_nbyte);
if (DiskTransferBuffer[0x1fe] != 0x55 if (DiskTransferBuffer[0x1fe] != 0x55
|| DiskTransferBuffer[0x1ff] != 0xaa || pbpbarray->bpb_nbyte != 512) || DiskTransferBuffer[0x1ff] != 0xaa || pbpbarray->bpb_nbyte != 512)
@ -426,23 +434,20 @@ STATIC WORD getbpb(ddt * pddt)
if (pbpbarray->bpb_nfsect != 0) if (pbpbarray->bpb_nfsect != 0)
{ {
/* FAT16/FAT12 boot sector */ /* FAT16/FAT12 boot sector */
getlong(&((((BYTE *) & DiskTransferBuffer[0x27])[0])), pddt->ddt_serialno = getlong(&DiskTransferBuffer[0x27]);
&pddt->ddt_serialno);
memcpy(pddt->ddt_volume, &DiskTransferBuffer[0x2B], 11); memcpy(pddt->ddt_volume, &DiskTransferBuffer[0x2B], 11);
memcpy(pddt->ddt_fstype, &DiskTransferBuffer[0x36], 8); memcpy(pddt->ddt_fstype, &DiskTransferBuffer[0x36], 8);
} }
else else
{ {
/* FAT32 boot sector */ /* FAT32 boot sector */
getlong(&((((BYTE *) & DiskTransferBuffer[0x43])[0])), pddt->ddt_serialno = getlong(&DiskTransferBuffer[0x43]);
&pddt->ddt_serialno);
memcpy(pddt->ddt_volume, &DiskTransferBuffer[0x47], 11); memcpy(pddt->ddt_volume, &DiskTransferBuffer[0x47], 11);
memcpy(pddt->ddt_fstype, &DiskTransferBuffer[0x52], 8); memcpy(pddt->ddt_fstype, &DiskTransferBuffer[0x52], 8);
pbpbarray->bpb_ndirent = 512; pbpbarray->bpb_ndirent = 512;
} }
#else #else
getlong(&((((BYTE *) & DiskTransferBuffer[0x27])[0])), pddt->ddt_serialno = getlong(&DiskTransferBuffer[0x27]);
&pddt->ddt_serialno);
memcpy(pddt->ddt_volume, &DiskTransferBuffer[0x2B], 11); memcpy(pddt->ddt_volume, &DiskTransferBuffer[0x2B], 11);
memcpy(pddt->ddt_fstype, &DiskTransferBuffer[0x36], 8); memcpy(pddt->ddt_fstype, &DiskTransferBuffer[0x36], 8);
#endif #endif

View File

@ -163,7 +163,6 @@ COUNT dos_close(COUNT fd)
if (fnp->f_flags.f_dmod) if (fnp->f_flags.f_dmod)
{ {
fnp->f_dir.dir_attrib |= D_ARCHIVE;
if (fnp->f_flags.f_ddate == FALSE) if (fnp->f_flags.f_ddate == FALSE)
{ {
fnp->f_dir.dir_time = dos_gettime(); fnp->f_dir.dir_time = dos_gettime();
@ -279,25 +278,17 @@ f_node_ptr split_path(BYTE * path, BYTE * fname, BYTE * fext)
STATIC BOOL find_fname(f_node_ptr fnp, BYTE * fname, BYTE * fext, int attr) STATIC BOOL find_fname(f_node_ptr fnp, BYTE * fname, BYTE * fext, int attr)
{ {
BOOL found = FALSE;
while (dir_read(fnp) == 1) while (dir_read(fnp) == 1)
{ {
if (fnp->f_dir.dir_name[0] != '\0') if (fnp->f_dir.dir_name[0] != DELETED
{ && fcmp(fname, (BYTE *) fnp->f_dir.dir_name, FNAME_SIZE)
if (fnp->f_dir.dir_name[0] == DELETED)
continue;
if (fcmp(fname, (BYTE *) fnp->f_dir.dir_name, FNAME_SIZE)
&& fcmp(fext, (BYTE *) fnp->f_dir.dir_ext, FEXT_SIZE) && fcmp(fext, (BYTE *) fnp->f_dir.dir_ext, FEXT_SIZE)
&& (fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE | attr)) == 0) && (fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE | attr)) == 0)
{ {
found = TRUE; return TRUE;
break;
} }
} }
} return FALSE;
return found;
} }
/* Description. /* Description.
@ -836,7 +827,6 @@ STATIC BOOL find_free(f_node_ptr fnp)
/* */ /* */
date dos_getdate() date dos_getdate()
{ {
#ifndef NOTIME
BYTE WeekDay, Month, MonthDay; BYTE WeekDay, Month, MonthDay;
COUNT Year; COUNT Year;
date Date; date Date;
@ -848,12 +838,6 @@ date dos_getdate()
(BYTE FAR *) & MonthDay, (COUNT FAR *) & Year); (BYTE FAR *) & MonthDay, (COUNT FAR *) & Year);
Date = DT_ENCODE(Month, MonthDay, Year - EPOCH_YEAR); Date = DT_ENCODE(Month, MonthDay, Year - EPOCH_YEAR);
return Date; return Date;
#else
return 0;
#endif
} }
/* */ /* */
@ -861,7 +845,6 @@ date dos_getdate()
/* */ /* */
time dos_gettime() time dos_gettime()
{ {
#ifndef NOTIME
BYTE Hour, Minute, Second, Hundredth; BYTE Hour, Minute, Second, Hundredth;
/* First - get the system time set by either the user */ /* First - get the system time set by either the user */
@ -870,9 +853,6 @@ time dos_gettime()
(BYTE FAR *) & Minute, (BYTE FAR *) & Minute,
(BYTE FAR *) & Second, (BYTE FAR *) & Hundredth); (BYTE FAR *) & Second, (BYTE FAR *) & Hundredth);
return TM_ENCODE(Hour, Minute, Second / 2); return TM_ENCODE(Hour, Minute, Second / 2);
#else
return 0;
#endif
} }
/* */ /* */
@ -1391,7 +1371,6 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode)
/* If there are no more free fat entries, then we are full! */ /* If there are no more free fat entries, then we are full! */
if (!first_fat(fnp)) if (!first_fat(fnp))
{ {
dir_close(fnp);
return DE_HNDLDSKFULL; return DE_HNDLDSKFULL;
} }
} }
@ -1453,300 +1432,6 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode)
return SUCCESS; return SUCCESS;
} }
/*
comments read optimization for large reads: read total clusters in one piece
running a program like
while (1) {
read(fd, header, sizeof(header)); // small read
read(fd, buffer, header.size); // where size is large, up to 63K
// with average ~32K
}
FreeDOS 2025 is really slow.
on a P200 with modern 30GB harddisk, doing above for a 14.5 MB file
MSDOS 6.22 clustersize 8K ~2.5 sec (accumulates over clusters, reads for 63 sectors seen),
IBM PCDOS 7.0 8K ~4.3
IBM PCDOS 7.0 16K ~2.8
FreeDOS ke2025 ~17.5
with the read optimization (ke2025a),
clustersize 8K ~6.5 sec
clustersize 16K ~4.2 sec
it was verified with IBM feature tool,
that the drive read ahead cache (says it) is on. still this huge difference ;-)
it's coded pretty conservative to avoid all special cases,
so it shouldn't break anything :-)
possible further optimization:
collect read across clusters (if file is not fragmented).
MSDOS does this (as readcounts up to 63 sectors where seen)
specially important for diskettes, where clustersize is 1 sector
the same should be done for writes as well
the time to compile the complete kernel (on some P200) is
reduced from 67 to 56 seconds - in an otherwise identical configuration.
it's not clear if this improvement shows up elsewhere, but it shouldn't harm either
TE 10/18/01 14:00
collect read across clusters (if file is not fragmented) done.
seems still to work :-))
no large performance gains visible, but should now work _much_
better for the people, that complain about slow floppy access
the
fnp->f_offset +to_xfer < fnp->f_highwater && avoid EOF problems
condition can probably _carefully_ be dropped
TE 10/18/01 19:00
*/
/* Read block from disk */
UCOUNT readblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err)
{
REG f_node_ptr fnp;
REG struct buffer FAR *bp;
UCOUNT xfr_cnt = 0;
UCOUNT ret_cnt = 0;
UWORD secsize;
UCOUNT to_xfer = count;
ULONG currentblock;
#if defined( DEBUG ) && 0
if (bDumpRdWrParms)
{
printf("readblock:fd %02x buffer %04x:%04x count %x\n",
fd, FP_SEG(buffer), FP_OFF(buffer), count);
}
#endif
/* Translate the fd into an fnode pointer, since all internal */
/* operations are achieved through fnodes. */
fnp = xlt_fd(fd);
/* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit */
/* note: an invalid fd is indicated by a 0 return */
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
{
*err = DE_INVLDHNDL;
return 0;
}
/* Test that we are really about to do a data transfer. If the
count is zero, just exit. (Any read with a count of zero is a nop). */
/* NOTE: doing this up front saves a lot of headaches later. */
if (count == 0)
{
*err = SUCCESS;
return 0;
}
/* Another test is to check for a seek past EOF */
/* if (!fnp->f_flags.f_ddir && (fnp->f_offset >= fnp->f_dir.dir_size)) BUG :-< */
if (!fnp->f_flags.f_ddir && (fnp->f_offset >= fnp->f_highwater))
{
*err = SUCCESS;
return 0;
}
/* test that we have a valid mode for this fnode */
if (fnp->f_mode != RDONLY && fnp->f_mode != RDWR)
{
*err = DE_INVLDACC;
return 0;
}
/* The variable secsize will be used later. */
secsize = fnp->f_dpb->dpb_secsize;
/* Adjust the far pointer from user space to supervisor space */
buffer = adjust_far((VOID FAR *) buffer);
/* Do the data transfer. Use block transfer methods so that we */
/* can utilize memory management in future DOS-C versions. */
while (ret_cnt < count)
{
/* Do an EOF test and return whatever was transferred */
/* but only for regular files. */
if (!(fnp->f_flags.f_ddir) && (fnp->f_offset >= fnp->f_highwater))
{
*err = SUCCESS;
return ret_cnt;
}
/* Position the file to the fnode's pointer position. This is */
/* done by updating the fnode's cluster, block (sector) and */
/* byte offset so that read becomes a simple data move */
/* out of the block data buffer. */
/* The more difficult scenario is the (more common) */
/* file offset case. Here, we need to take the fnode's */
/* offset pointer (f_offset) and translate it into a */
/* relative cluster position, cluster block (sector) */
/* offset (f_sector) and byte offset (f_boff). Once we */
/* have this information, we need to translate the */
/* relative cluster position into an absolute cluster */
/* position (f_cluster). This is unfortunate because it */
/* requires a linear search through the file's FAT */
/* entries. It made sense when DOS was originally */
/* designed as a simple floppy disk operating system */
/* where the FAT was contained in core, but now */
/* requires a search through the FAT blocks. */
/* */
/* The algorithm in this function takes advantage of */
/* the blockio block buffering scheme to simplify the */
/* task. */
#ifdef DISPLAY_GETBLOCK
printf("readblock: ");
#endif
if (map_cluster(fnp, XFR_READ) != SUCCESS)
{
*err = DE_SEEK;
dir_close(fnp);
return ret_cnt;
}
/* Compute the block within the cluster and the offset */
/* within the block. */
fnp->f_sector = (fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask;
fnp->f_boff = fnp->f_offset % secsize;
currentblock = clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector;
/* see comments above */
if (!fnp->f_flags.f_ddir && /* don't experiment with directories yet */
fnp->f_boff == 0) /* complete sectors only */
{
static ULONG startoffset;
UCOUNT sectors_to_read, sectors_wanted;
startoffset = fnp->f_offset;
/* avoid EOF problems */
sectors_wanted =
((UCOUNT) min(fnp->f_highwater - fnp->f_offset, to_xfer)) /
secsize;
if (sectors_wanted < 2)
goto normal_read;
sectors_to_read = fnp->f_dpb->dpb_clsmask + 1 - fnp->f_sector;
sectors_to_read = min(sectors_to_read, sectors_wanted);
fnp->f_offset += sectors_to_read * secsize;
while (sectors_to_read < sectors_wanted)
{
if (map_cluster(fnp, XFR_READ) != SUCCESS)
break;
if (clus2phys(fnp->f_cluster, fnp->f_dpb) !=
currentblock + sectors_to_read)
break;
sectors_to_read += fnp->f_dpb->dpb_clsmask + 1;
sectors_to_read = min(sectors_to_read, sectors_wanted);
fnp->f_offset = startoffset + sectors_to_read * secsize;
}
xfr_cnt = sectors_to_read * secsize;
/* avoid caching trouble */
DeleteBlockInBufferCache(currentblock,
currentblock + sectors_to_read - 1,
fnp->f_dpb->dpb_unit);
if (dskxfer(fnp->f_dpb->dpb_unit,
currentblock,
(VOID FAR *) buffer, sectors_to_read, DSKREAD))
{
fnp->f_offset = startoffset;
*err = DE_BLKINVLD;
return ret_cnt;
}
goto update_pointers;
}
/* normal read: just the old, buffer = sector based read */
normal_read:
#ifdef DSK_DEBUG
printf("read %d links; dir offset %ld, cluster %lx\n",
fnp->f_count, fnp->f_diroff, fnp->f_cluster);
#endif
/* Get the block we need from cache */
bp = getblock(currentblock
/*clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector */
, fnp->f_dpb->dpb_unit);
#ifdef DISPLAY_GETBLOCK
printf("DATA (readblock)\n");
#endif
if (bp == NULL) /* (struct buffer *)0 --> DS:0 !! */
{
*err = DE_BLKINVLD;
return ret_cnt;
}
/* transfer a block */
/* Transfer size as either a full block size, or the */
/* requested transfer size, whichever is smaller. */
/* Then compare to what is left, since we can transfer */
/* a maximum of what is left. */
if (fnp->f_flags.f_ddir)
xfr_cnt = min(to_xfer, secsize - fnp->f_boff);
else
xfr_cnt = (UWORD) min(min(to_xfer, secsize - fnp->f_boff),
fnp->f_highwater - fnp->f_offset);
fmemcpy(buffer, &bp->b_buffer[fnp->f_boff], xfr_cnt);
/* complete buffer read ?
probably not reused later
*/
if (xfr_cnt == sizeof(bp->b_buffer) ||
fnp->f_offset + xfr_cnt == fnp->f_highwater)
{
bp->b_flag |= BFR_UNCACHE;
}
/* update pointers and counters */
fnp->f_offset += xfr_cnt;
update_pointers:
ret_cnt += xfr_cnt;
to_xfer -= xfr_cnt;
buffer = add_far((VOID FAR *) buffer, (ULONG) xfr_cnt);
}
*err = SUCCESS;
return ret_cnt;
}
/* extends a file from f_highwater to f_offset */ /* extends a file from f_highwater to f_offset */
/* Proper OS's write zeros in between, but DOS just adds */ /* Proper OS's write zeros in between, but DOS just adds */
/* garbage sectors, and lets the caller do the zero filling */ /* garbage sectors, and lets the caller do the zero filling */
@ -1827,24 +1512,90 @@ STATIC COUNT dos_extend(f_node_ptr fnp)
return SUCCESS; return SUCCESS;
} }
/* Write block to disk */ /*
UCOUNT writeblock(COUNT fd, const VOID FAR * buffer, UCOUNT count, COUNT * err) comments read optimization for large reads: read total clusters in one piece
running a program like
while (1) {
read(fd, header, sizeof(header)); // small read
read(fd, buffer, header.size); // where size is large, up to 63K
// with average ~32K
}
FreeDOS 2025 is really slow.
on a P200 with modern 30GB harddisk, doing above for a 14.5 MB file
MSDOS 6.22 clustersize 8K ~2.5 sec (accumulates over clusters, reads for 63 sectors seen),
IBM PCDOS 7.0 8K ~4.3
IBM PCDOS 7.0 16K ~2.8
FreeDOS ke2025 ~17.5
with the read optimization (ke2025a),
clustersize 8K ~6.5 sec
clustersize 16K ~4.2 sec
it was verified with IBM feature tool,
that the drive read ahead cache (says it) is on. still this huge difference ;-)
it's coded pretty conservative to avoid all special cases,
so it shouldn't break anything :-)
possible further optimization:
collect read across clusters (if file is not fragmented).
MSDOS does this (as readcounts up to 63 sectors where seen)
specially important for diskettes, where clustersize is 1 sector
the same should be done for writes as well
the time to compile the complete kernel (on some P200) is
reduced from 67 to 56 seconds - in an otherwise identical configuration.
it's not clear if this improvement shows up elsewhere, but it shouldn't harm either
TE 10/18/01 14:00
collect read across clusters (if file is not fragmented) done.
seems still to work :-))
no large performance gains visible, but should now work _much_
better for the people, that complain about slow floppy access
the
fnp->f_offset +to_xfer < fnp->f_highwater && avoid EOF problems
condition can probably _carefully_ be dropped
TE 10/18/01 19:00
*/
/* Read/write block from disk */
/* checking for valid access was already done by the functions in
dosfns.c */
UCOUNT rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
{ {
REG f_node_ptr fnp; REG f_node_ptr fnp;
struct buffer FAR *bp; REG struct buffer FAR *bp;
UCOUNT xfr_cnt = 0; UCOUNT xfr_cnt = 0;
UCOUNT ret_cnt = 0; UCOUNT ret_cnt = 0;
UWORD secsize; UWORD secsize;
UCOUNT to_xfer = count; UCOUNT to_xfer = count;
ULONG currentblock;
#ifdef DEBUG #if 0 /*DSK_DEBUG*/
if (bDumpRdWrParms) if (bDumpRdWrParms)
{ {
printf("writeblock: fd %02d buffer %04x:%04x count %d\n", printf("rwblock:fd %02x buffer %04x:%04x count %x\n",
fd, (COUNT) FP_SEG(buffer), (COUNT) FP_OFF(buffer), count); fd, FP_SEG(buffer), FP_OFF(buffer), count);
} }
#endif #endif
/* Translate the fd into an fnode pointer, since all internal */ /* Translate the fd into an fnode pointer, since all internal */
/* operations are achieved through fnodes. */ /* operations are achieved through fnodes. */
fnp = xlt_fd(fd); fnp = xlt_fd(fd);
@ -1854,24 +1605,18 @@ UCOUNT writeblock(COUNT fd, const VOID FAR * buffer, UCOUNT count, COUNT * err)
/* note: an invalid fd is indicated by a 0 return */ /* note: an invalid fd is indicated by a 0 return */
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0) if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
{ {
*err = DE_INVLDHNDL;
return 0; return 0;
} }
/* test that we have a valid mode for this fnode */ if (mode==XFR_WRITE)
if (fnp->f_mode != WRONLY && fnp->f_mode != RDWR)
{ {
*err = DE_INVLDACC; fnp->f_dir.dir_attrib |= D_ARCHIVE;
return 0;
}
fnp->f_flags.f_dmod = TRUE; /* mark file as modified */ fnp->f_flags.f_dmod = TRUE; /* mark file as modified */
fnp->f_flags.f_ddate = FALSE; /* set date not valid any more */ fnp->f_flags.f_ddate = FALSE; /* set date not valid any more */
/* extend file from fnp->f_highwater to fnp->f_offset */ if (dos_extend(fnp) != SUCCESS)
*err = dos_extend(fnp);
if (*err != SUCCESS)
return 0; return 0;
}
/* Test that we are really about to do a data transfer. If the */ /* Test that we are really about to do a data transfer. If the */
/* count is zero and the mode is XFR_READ, just exit. (Any */ /* count is zero and the mode is XFR_READ, just exit. (Any */
@ -1888,8 +1633,11 @@ UCOUNT writeblock(COUNT fd, const VOID FAR * buffer, UCOUNT count, COUNT * err)
/* FAT allocation has to be extended if necessary TE */ /* FAT allocation has to be extended if necessary TE */
/* Now done in dos_extend BO */ /* Now done in dos_extend BO */
/* remove all the following allocated clusters in shrink_file */ /* remove all the following allocated clusters in shrink_file */
if (mode == XFR_WRITE)
{
fnp->f_highwater = fnp->f_offset; fnp->f_highwater = fnp->f_offset;
shrink_file(fnp); shrink_file(fnp);
}
return 0; return 0;
} }
@ -1903,35 +1651,17 @@ UCOUNT writeblock(COUNT fd, const VOID FAR * buffer, UCOUNT count, COUNT * err)
/* can utilize memory management in future DOS-C versions. */ /* can utilize memory management in future DOS-C versions. */
while (ret_cnt < count) while (ret_cnt < count)
{ {
/* Do an EOF test and return whatever was transferred */
/* but only for regular files. */
if (mode == XFR_READ && !(fnp->f_flags.f_ddir) && (fnp->f_offset >= fnp->f_highwater))
{
return ret_cnt;
}
/* Position the file to the fnode's pointer position. This is */ /* Position the file to the fnode's pointer position. This is */
/* done by updating the fnode's cluster, block (sector) and */ /* done by updating the fnode's cluster, block (sector) and */
/* byte offset so that read or write becomes a simple data move */ /* byte offset so that read or write becomes a simple data move */
/* into or out of the block data buffer. */ /* into or out of the block data buffer. */
if (fnp->f_offset == 0l)
{
/* For the write case, a newly created file */
/* will have a start cluster of FREE. If we're */
/* doing a write and this is the first time */
/* through, allocate a new cluster to the file. */
if (checkdstart(fnp->f_dir, FREE))
if (!first_fat(fnp)) /* get a free cluster */
{ /* error means disk full */
dir_close(fnp);
*err = DE_HNDLDSKFULL;
return ret_cnt;
}
/* complete the common operations of */
/* initializing to the starting cluster and */
/* setting all offsets to zero. */
fnp->f_cluster = fnp->f_flags.f_ddir ? fnp->f_dirstart :
getdstart(fnp->f_dir);
fnp->f_cluster_offset = 0l;
fnp->f_back = LONG_LAST_CLUSTER;
fnp->f_sector = 0;
fnp->f_boff = 0;
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
}
/* The more difficult scenario is the (more common) */ /* The more difficult scenario is the (more common) */
/* file offset case. Here, we need to take the fnode's */ /* file offset case. Here, we need to take the fnode's */
@ -1950,16 +1680,15 @@ UCOUNT writeblock(COUNT fd, const VOID FAR * buffer, UCOUNT count, COUNT * err)
/* The algorithm in this function takes advantage of */ /* The algorithm in this function takes advantage of */
/* the blockio block buffering scheme to simplify the */ /* the blockio block buffering scheme to simplify the */
/* task. */ /* task. */
else
{
#ifdef DISPLAY_GETBLOCK #ifdef DISPLAY_GETBLOCK
printf("writeblock: "); printf("rwblock: ");
#endif #endif
if (map_cluster(fnp, XFR_WRITE) != SUCCESS) if (map_cluster(fnp, mode) != SUCCESS)
{ {
*err = DE_HNDLDSKFULL;
return ret_cnt; return ret_cnt;
} }
if (mode == XFR_WRITE)
{
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */ merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
} }
@ -1968,46 +1697,89 @@ UCOUNT writeblock(COUNT fd, const VOID FAR * buffer, UCOUNT count, COUNT * err)
fnp->f_sector = (fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask; fnp->f_sector = (fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask;
fnp->f_boff = fnp->f_offset % secsize; fnp->f_boff = fnp->f_offset % secsize;
currentblock = clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector;
/* see comments above */
if (!fnp->f_flags.f_ddir && /* don't experiment with directories yet */
fnp->f_boff == 0) /* complete sectors only */
{
static ULONG startoffset;
UCOUNT sectors_to_xfer, sectors_wanted;
startoffset = fnp->f_offset;
sectors_wanted = to_xfer;
/* avoid EOF problems */
if (mode == XFR_READ && to_xfer > fnp->f_highwater - fnp->f_offset)
sectors_wanted = (UCOUNT)(fnp->f_highwater - fnp->f_offset);
sectors_wanted /= secsize;
if (sectors_wanted == 0)
goto normal_xfer;
sectors_to_xfer = fnp->f_dpb->dpb_clsmask + 1 - fnp->f_sector;
sectors_to_xfer = min(sectors_to_xfer, sectors_wanted);
fnp->f_offset += sectors_to_xfer * secsize;
while (sectors_to_xfer < sectors_wanted)
{
if (map_cluster(fnp, mode) != SUCCESS)
break;
if (clus2phys(fnp->f_cluster, fnp->f_dpb) !=
currentblock + sectors_to_xfer)
break;
sectors_to_xfer += fnp->f_dpb->dpb_clsmask + 1;
sectors_to_xfer = min(sectors_to_xfer, sectors_wanted);
fnp->f_offset = startoffset + sectors_to_xfer * secsize;
}
xfr_cnt = sectors_to_xfer * secsize;
/* avoid caching trouble */
DeleteBlockInBufferCache(currentblock,
currentblock + sectors_to_xfer - 1,
fnp->f_dpb->dpb_unit);
if (dskxfer(fnp->f_dpb->dpb_unit,
currentblock,
(VOID FAR *) buffer, sectors_to_xfer,
mode == XFR_READ ? DSKREAD : DSKWRITE))
{
fnp->f_offset = startoffset;
return ret_cnt;
}
goto update_pointers;
}
/* normal read: just the old, buffer = sector based read */
normal_xfer:
#ifdef DSK_DEBUG #ifdef DSK_DEBUG
printf("write %d links; dir offset %ld, cluster %d\n", printf("r/w %d links; dir offset %ld, cluster %d, mode %x\n",
fnp->f_count, fnp->f_diroff, fnp->f_cluster); fnp->f_count, fnp->f_diroff, fnp->f_cluster, mode);
#endif #endif
/* /// Moved xfr_cnt calculation from below so we can /* Get the block we need from cache */
use it to help decide how to get the block: bp = getblock(currentblock
read-modify-write using getblock() if we are only /*clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector */
going to write part of the block, or , fnp->f_dpb->dpb_unit);
write using getbuf() if we are going to write
the entire block.
- Ron Cemer */
xfr_cnt = min(to_xfer, secsize - fnp->f_boff);
/* get a buffer to store the block in */ #ifdef DISPLAY_GETBLOCK
/* /// BUG!!! Added conditional to only use getbuf() if we're going printf("DATA (rwblock)\n");
to write the entire block, which is faster because it does #endif
not first read the block from disk. However, if we are if (bp == NULL) /* (struct buffer *)0 --> DS:0 !! */
going to only write part of the block, we MUST use the
getblock() call, which first reads the block from disk.
Without this modification, the kernel was writing garbage
to the file when sequential writes were attempted at less
than the block size. This was causing problems with
piping and redirection in FreeCOM, as well as many other
potential problems.
- Ron Cemer */
if ((fnp->f_boff == 0) && (xfr_cnt == secsize))
{ {
bp = getblockOver(clus2phys(fnp->f_cluster, fnp->f_dpb) +
fnp->f_sector, fnp->f_dpb->dpb_unit);
}
else
{
bp = getblock(clus2phys(fnp->f_cluster, fnp->f_dpb) +
fnp->f_sector, fnp->f_dpb->dpb_unit);
}
if (bp == NULL)
{
*err = DE_BLKINVLD;
return ret_cnt; return ret_cnt;
} }
@ -2016,24 +1788,43 @@ UCOUNT writeblock(COUNT fd, const VOID FAR * buffer, UCOUNT count, COUNT * err)
/* requested transfer size, whichever is smaller. */ /* requested transfer size, whichever is smaller. */
/* Then compare to what is left, since we can transfer */ /* Then compare to what is left, since we can transfer */
/* a maximum of what is left. */ /* a maximum of what is left. */
/* /// Moved xfr_cnt calculation to above getbuf/getblock calls so we can
use it to help decide which one to call.
- Ron Cemer
xfr_cnt = min(to_xfer, secsize - fnp->f_boff); xfr_cnt = min(to_xfer, secsize - fnp->f_boff);
*/ if (!fnp->f_flags.f_ddir && mode == XFR_READ)
xfr_cnt = (UWORD) min(xfr_cnt, fnp->f_highwater - fnp->f_offset);
/* transfer a block */
/* Transfer size as either a full block size, or the */
/* requested transfer size, whichever is smaller. */
/* Then compare to what is left, since we can transfer */
/* a maximum of what is left. */
if (mode == XFR_WRITE)
{
fmemcpy(&bp->b_buffer[fnp->f_boff], buffer, xfr_cnt); fmemcpy(&bp->b_buffer[fnp->f_boff], buffer, xfr_cnt);
bp->b_flag |= BFR_DIRTY | BFR_VALID; bp->b_flag |= BFR_DIRTY | BFR_VALID;
}
else
{
fmemcpy(buffer, &bp->b_buffer[fnp->f_boff], xfr_cnt);
}
if (xfr_cnt == sizeof(bp->b_buffer)) /* probably not used later */ /* complete buffer transferred ?
probably not reused later
*/
if (xfr_cnt == sizeof(bp->b_buffer) ||
(mode == XFR_READ && fnp->f_offset + xfr_cnt == fnp->f_highwater))
{ {
bp->b_flag |= BFR_UNCACHE; bp->b_flag |= BFR_UNCACHE;
} }
/* update pointers and counters */ /* update pointers and counters */
fnp->f_offset += xfr_cnt;
update_pointers:
ret_cnt += xfr_cnt; ret_cnt += xfr_cnt;
to_xfer -= xfr_cnt; to_xfer -= xfr_cnt;
fnp->f_offset += xfr_cnt;
buffer = add_far((VOID FAR *) buffer, (ULONG) xfr_cnt); buffer = add_far((VOID FAR *) buffer, (ULONG) xfr_cnt);
if (mode == XFR_WRITE)
{
if (fnp->f_offset > fnp->f_highwater) if (fnp->f_offset > fnp->f_highwater)
{ {
fnp->f_highwater = fnp->f_offset; fnp->f_highwater = fnp->f_offset;
@ -2041,7 +1832,7 @@ UCOUNT writeblock(COUNT fd, const VOID FAR * buffer, UCOUNT count, COUNT * err)
} }
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */ merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
} }
*err = SUCCESS; }
return ret_cnt; return ret_cnt;
} }
@ -2310,6 +2101,8 @@ VOID bpb_to_dpb(bpb FAR * bpbp, REG struct dpb FAR * dpbp)
COUNT media_check(REG struct dpb FAR * dpbp) COUNT media_check(REG struct dpb FAR * dpbp)
{ {
BYTE status;
/* First test if anyone has changed the removable media */ /* First test if anyone has changed the removable media */
FOREVER FOREVER
{ {
@ -2343,7 +2136,8 @@ COUNT media_check(REG struct dpb FAR * dpbp)
} }
} }
switch (MediaReqHdr.r_mcretcode | dpbp->dpb_flags) status = MediaReqHdr.r_mcretcode | dpbp->dpb_flags;
switch (status)
{ {
case M_NOT_CHANGED: case M_NOT_CHANGED:
/* It was definitely not changed, so ignore it */ /* It was definitely not changed, so ignore it */
@ -2392,10 +2186,15 @@ COUNT media_check(REG struct dpb FAR * dpbp)
} }
} }
#ifdef WITHFAT32 #ifdef WITHFAT32
bpb_to_dpb(MediaReqHdr.r_bpptr, dpbp, TRUE); /* extend dpb only for internal or FAT32 devices */
bpb_to_dpb(MediaReqHdr.r_bpptr, dpbp,
ISFAT32(dpbp) || FP_SEG(dpbp) == FP_SEG(&os_major));
#else #else
bpb_to_dpb(MediaReqHdr.r_bpptr, dpbp); bpb_to_dpb(MediaReqHdr.r_bpptr, dpbp);
#endif #endif
/* need to change to root directory if changed */
if (status == M_CHANGED)
CDSp->cds_table[dpbp->dpb_unit].cdsCurrentPath[3] = '\0';
return SUCCESS; return SUCCESS;
} }
} }

View File

@ -34,21 +34,9 @@ static BYTE *RcsId =
"$Id$"; "$Id$";
#endif #endif
#ifdef PROTO STATIC unsigned link_fat12(struct dpb FAR *, unsigned, unsigned);
UCOUNT link_fat12(struct dpb FAR *, CLUSTER, CLUSTER); STATIC unsigned link_fat16(struct dpb FAR *, unsigned, unsigned);
UCOUNT link_fat16(struct dpb FAR *, CLUSTER, CLUSTER); STATIC unsigned link_fat32(struct dpb FAR *, CLUSTER, CLUSTER);
UCOUNT link_fat32(struct dpb FAR *, CLUSTER, CLUSTER);
CLUSTER next_cl12(struct dpb FAR *, CLUSTER);
CLUSTER next_cl16(struct dpb FAR *, CLUSTER);
CLUSTER next_cl32(struct dpb FAR *, CLUSTER);
#else
UCOUNT link_fat12();
UCOUNT link_fat16();
UCOUNT link_fat32();
CLUSTER next_cl12();
CLUSTER next_cl16();
CLUSTER next_cl32();
#endif
/************************************************************************/ /************************************************************************/
/* */ /* */
@ -158,15 +146,15 @@ void write_fsinfo(struct dpb FAR * dpbp)
/* 12 bytes are compressed to 9 bytes */ /* 12 bytes are compressed to 9 bytes */
/* */ /* */
UCOUNT link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1, unsigned link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
REG CLUSTER Cluster2) REG CLUSTER Cluster2)
{ {
UCOUNT res; unsigned res;
if (ISFAT12(dpbp)) if (ISFAT12(dpbp))
res = link_fat12(dpbp, Cluster1, Cluster2); res = link_fat12(dpbp, (unsigned)Cluster1, (unsigned)Cluster2);
else if (ISFAT16(dpbp)) else if (ISFAT16(dpbp))
res = link_fat16(dpbp, Cluster1, Cluster2); res = link_fat16(dpbp, (unsigned)Cluster1, (unsigned)Cluster2);
#ifdef WITHFAT32 #ifdef WITHFAT32
else if (ISFAT32(dpbp)) else if (ISFAT32(dpbp))
res = link_fat32(dpbp, Cluster1, Cluster2); res = link_fat32(dpbp, Cluster1, Cluster2);
@ -212,10 +200,10 @@ UCOUNT link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
} }
#ifdef WITHFAT32 #ifdef WITHFAT32
UCOUNT link_fat32(struct dpb FAR * dpbp, CLUSTER Cluster1, STATIC unsigned link_fat32(struct dpb FAR * dpbp, CLUSTER Cluster1,
CLUSTER Cluster2) CLUSTER Cluster2)
{ {
UCOUNT idx; unsigned idx;
struct buffer FAR *bp; struct buffer FAR *bp;
/* Get the block that this cluster is in */ /* Get the block that this cluster is in */
@ -230,7 +218,7 @@ UCOUNT link_fat32(struct dpb FAR * dpbp, CLUSTER Cluster1,
/* Finally, put the word into the buffer and mark the */ /* Finally, put the word into the buffer and mark the */
/* buffer as dirty. */ /* buffer as dirty. */
fputlong((DWORD FAR *) & Cluster2, (VOID FAR *) & (bp->b_buffer[idx])); fputlong(&bp->b_buffer[idx], Cluster2);
bp->b_flag |= BFR_DIRTY | BFR_VALID; bp->b_flag |= BFR_DIRTY | BFR_VALID;
/* Return successful. */ /* Return successful. */
@ -240,10 +228,10 @@ UCOUNT link_fat32(struct dpb FAR * dpbp, CLUSTER Cluster1,
#endif #endif
STATIC UCOUNT link_fat16(struct dpb FAR * dpbp, CLUSTER Cluster1, STATIC unsigned link_fat16(struct dpb FAR * dpbp, unsigned Cluster1,
CLUSTER Cluster2) unsigned Cluster2)
{ {
UCOUNT idx; unsigned idx;
struct buffer FAR *bp; struct buffer FAR *bp;
/* Get the block that this cluster is in */ /* Get the block that this cluster is in */
@ -254,11 +242,11 @@ STATIC UCOUNT link_fat16(struct dpb FAR * dpbp, CLUSTER Cluster1,
/* form an index so that we can read the block as a */ /* form an index so that we can read the block as a */
/* byte array */ /* byte array */
idx = (UWORD) ((Cluster1 * SIZEOF_CLST16) % dpbp->dpb_secsize); idx = (Cluster1 * SIZEOF_CLST16) % dpbp->dpb_secsize;
/* Finally, put the word into the buffer and mark the */ /* Finally, put the word into the buffer and mark the */
/* buffer as dirty. */ /* buffer as dirty. */
fputword((WORD FAR *) & Cluster2, (VOID FAR *) & (bp->b_buffer[idx])); fputword(&bp->b_buffer[idx], Cluster2);
bp->b_flag |= BFR_DIRTY | BFR_VALID; bp->b_flag |= BFR_DIRTY | BFR_VALID;
/* Return successful. */ /* Return successful. */
@ -266,11 +254,11 @@ STATIC UCOUNT link_fat16(struct dpb FAR * dpbp, CLUSTER Cluster1,
return SUCCESS; return SUCCESS;
} }
STATIC UCOUNT link_fat12(struct dpb FAR * dpbp, CLUSTER Cluster1, STATIC unsigned link_fat12(struct dpb FAR * dpbp, unsigned Cluster1,
CLUSTER Cluster2) unsigned Cluster2)
{ {
REG UBYTE FAR *fbp0, FAR * fbp1; REG UBYTE FAR *fbp0, FAR * fbp1;
UCOUNT idx; unsigned idx;
struct buffer FAR *bp, FAR * bp1; struct buffer FAR *bp, FAR * bp1;
/* Get the block that this cluster is in */ /* Get the block that this cluster is in */
@ -280,12 +268,15 @@ STATIC UCOUNT link_fat12(struct dpb FAR * dpbp, CLUSTER Cluster1,
/* form an index so that we can read the block as a */ /* form an index so that we can read the block as a */
/* byte array */ /* byte array */
idx = (UCOUNT) (((Cluster1 << 1) + Cluster1) >> 1) % dpbp->dpb_secsize; idx = (unsigned) (((Cluster1 << 1) + Cluster1) >> 1) % dpbp->dpb_secsize;
/* Test to see if the cluster straddles the block. If */ /* Test to see if the cluster straddles the block. If */
/* it does, get the next block and use both to form the */ /* it does, get the next block and use both to form the */
/* the FAT word. Otherwise, just point to the next */ /* the FAT word. Otherwise, just point to the next */
/* block. */ /* block. */
fbp0 = &bp->b_buffer[idx];
fbp1 = fbp0 + 1;
if (idx >= dpbp->dpb_secsize - 1) if (idx >= dpbp->dpb_secsize - 1)
{ {
bp1 = getFATblock(Cluster1 + 1, dpbp); bp1 = getFATblock(Cluster1 + 1, dpbp);
@ -294,11 +285,8 @@ STATIC UCOUNT link_fat12(struct dpb FAR * dpbp, CLUSTER Cluster1,
bp1->b_flag |= BFR_DIRTY | BFR_VALID; bp1->b_flag |= BFR_DIRTY | BFR_VALID;
fbp1 = (UBYTE FAR *) & (bp1->b_buffer[0]); fbp1 = &bp1->b_buffer[0];
} }
else
fbp1 = (UBYTE FAR *) & (bp->b_buffer[idx + 1]);
fbp0 = (UBYTE FAR *) & (bp->b_buffer[idx]);
bp->b_flag |= BFR_DIRTY | BFR_VALID; bp->b_flag |= BFR_DIRTY | BFR_VALID;
/* Now pack the value in */ /* Now pack the value in */
@ -338,16 +326,15 @@ CLUSTER next_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
{ {
union { union {
UBYTE bytes[2]; UBYTE bytes[2];
UCOUNT word; unsigned word;
} clusterbuff; } clusterbuff;
UCOUNT idx; unsigned idx;
/* form an index so that we can read the block as a */ /* form an index so that we can read the block as a */
/* byte array */ /* byte array */
idx = idx = ((((unsigned)ClusterNum << 1) + (unsigned)ClusterNum) >> 1) %
(UCOUNT) (((ClusterNum << 1) + dpbp->dpb_secsize;
ClusterNum) >> 1) % dpbp->dpb_secsize;
clusterbuff.bytes[0] = bp->b_buffer[idx]; clusterbuff.bytes[0] = bp->b_buffer[idx];
@ -395,26 +382,13 @@ CLUSTER next_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
{ {
UWORD res; UWORD res;
#ifndef I86
UCOUNT idx;
/* form an index so that we can read the block as a */ /* form an index so that we can read the block as a */
/* byte array */ /* byte array */
idx = (ClusterNum * SIZEOF_CLST16) % dpbp->dpb_secsize; /* and get the cluster number */
/* Get the cluster number, */ res = fgetword(&bp->b_buffer[((unsigned)ClusterNum * SIZEOF_CLST16) %
dpbp->dpb_secsize]);
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) if (res >= MASK16)
return LONG_LAST_CLUSTER; return LONG_LAST_CLUSTER;
if (res == BAD16) if (res == BAD16)
@ -427,11 +401,8 @@ CLUSTER next_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
{ {
UDWORD res; UDWORD res;
res = res = fgetlong(&bp->b_buffer[((unsigned)ClusterNum * SIZEOF_CLST32) %
*(UDWORD FAR *) & (bp-> dpbp->dpb_secsize]);
b_buffer[(UCOUNT)
((ClusterNum * SIZEOF_CLST32) %
dpbp->dpb_secsize)]);
if (res > LONG_BAD) if (res > LONG_BAD)
return LONG_LAST_CLUSTER; return LONG_LAST_CLUSTER;

View File

@ -62,13 +62,27 @@ static dmatch Dmatch;
VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps, VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
UCOUNT FAR * nc, BYTE FAR ** mdp) UCOUNT FAR * nc, BYTE FAR ** mdp)
{ {
static BYTE mdb;
UCOUNT navc; UCOUNT navc;
/* get the data available from dpb */ /* get the data available from dpb */
*nc = 0xffff; /* pass 0xffff to skip free count */ *nc = 0xffff; /* pass 0xffff to skip free count */
if (DosGetFree((UBYTE) drive, spc, &navc, bps, nc)) if (DosGetFree((UBYTE) drive, spc, &navc, bps, nc))
{
struct cds FAR *cdsp =
&CDSp->cds_table[(drive == 0 ? default_drive : drive - 1)];
/* Point to the media desctriptor for this drive */ /* Point to the media desctriptor for this drive */
*mdp = (BYTE FAR *) & (CDSp->cds_table[drive].cdsDpb->dpb_mdb); if (cdsp->cdsFlags & CDSNETWDRV)
{
mdb = *spc >> 8;
*mdp = &mdb;
*spc &= 0xff;
}
else
{
*mdp = (BYTE FAR *) & (cdsp->cdsDpb->dpb_mdb);
}
}
} }
#define PARSE_SEP_STOP 0x01 #define PARSE_SEP_STOP 0x01

View File

@ -399,7 +399,10 @@ VOID ASMCFUNC FAR CharMapSrvc(VOID);
VOID ASMCFUNC FAR set_stack(VOID); VOID ASMCFUNC FAR set_stack(VOID);
VOID ASMCFUNC FAR restore_stack(VOID); VOID ASMCFUNC FAR restore_stack(VOID);
/*VOID INRPT FAR handle_break(VOID); */ /*VOID INRPT FAR handle_break(VOID); */
VOID ASMCFUNC ReadPCClock(ULONG *); BOOL ASMCFUNC ReadATClock(BYTE *, BYTE *, BYTE *, BYTE *);
ULONG ASMCFUNC ReadPCClock(VOID);
VOID ASMCFUNC WriteATClock(BYTE *, BYTE, BYTE, BYTE);
VOID ASMCFUNC WritePCClock(ULONG);
BYTE FAR * ASMCFUNC device_end(VOID); BYTE FAR * ASMCFUNC device_end(VOID);
COUNT ASMCFUNC kb_data(VOID); COUNT ASMCFUNC kb_data(VOID);
COUNT ASMCFUNC kb_input(VOID); COUNT ASMCFUNC kb_input(VOID);
@ -427,25 +430,25 @@ COUNT con();
/* special word packing prototypes */ /* special word packing prototypes */
/* */ /* */
#ifdef NATIVE #ifdef NATIVE
#define getlong(vp, lp) (*(LONG *)(lp)=*(LONG *)(vp)) #define getlong(vp) (*(UDWORD *)(vp))
#define getword(vp, wp) (*(WORD *)(wp)=*(WORD *)(vp)) #define getword(vp) (*(UWORD *)(vp))
#define getbyte(vp, bp) (*(BYTE *)(bp)=*(BYTE *)(vp)) #define getbyte(vp) (*(UBYTE *)(vp))
#define fgetlong(vp, lp) (*(LONG FAR *)(lp)=*(LONG FAR *)(vp)) #define fgetlong(vp) (*(UDWORD FAR *)(vp))
#define fgetword(vp, wp) (*(WORD FAR *)(wp)=*(WORD FAR *)(vp)) #define fgetword(vp) (*(UWORD FAR *)(vp))
#define fgetbyte(vp, bp) (*(BYTE FAR *)(bp)=*(BYTE FAR *)(vp)) #define fgetbyte(vp) (*(UBYTE FAR *)(vp))
#define fputlong(lp, vp) (*(LONG FAR *)(vp)=*(LONG FAR *)(lp)) #define fputlong(vp, l) (*(UDWORD FAR *)(vp)=l)
#define fputword(wp, vp) (*(WORD FAR *)(vp)=*(WORD FAR *)(wp)) #define fputword(vp, w) (*(UWORD FAR *)(vp)=w)
#define fputbyte(bp, vp) (*(BYTE FAR *)(vp)=*(BYTE FAR *)(bp)) #define fputbyte(vp, b) (*(UBYTE FAR *)(vp)=b)
#else #else
#ifdef PROTO #ifdef PROTO
VOID getword(VOID *, WORD *); WORD getword(VOID *);
VOID getbyte(VOID *, BYTE *); BYTE getbyte(VOID *);
VOID fgetlong(VOID FAR *, LONG FAR *); LONG fgetlong(VOID FAR *);
VOID fgetword(VOID FAR *, WORD FAR *); WORD fgetword(VOID FAR *);
VOID fgetbyte(VOID FAR *, BYTE FAR *); BYTE fgetbyte(VOID FAR *);
VOID fputlong(LONG FAR *, VOID FAR *); VOID fputlong(VOID FAR *, UDWORD);
VOID fputword(WORD FAR *, VOID FAR *); VOID fputword(VOID FAR *, UWORD);
VOID fputbyte(BYTE FAR *, VOID FAR *); VOID fputbyte(VOID FAR *, UBYTE);
#else #else
VOID getword(); VOID getword();
VOID getbyte(); VOID getbyte();

View File

@ -42,6 +42,9 @@ extern COUNT DOSFAR nUnits;
extern UWORD DOSFAR LBA_WRITE_VERIFY; extern UWORD DOSFAR LBA_WRITE_VERIFY;
/* floppy parameter table, at 70:xxxx */
extern unsigned char DOSTEXTFAR int1e_table[0xe];
/* /*
* Rev 1.0 13 May 2001 tom ehlert * Rev 1.0 13 May 2001 tom ehlert
* Initial revision. * Initial revision.
@ -611,7 +614,7 @@ void DosDefinePartition(struct DriveParamS *driveParam,
{ {
LBA_to_CHS(&chs, StartSector, driveParam); LBA_to_CHS(&chs, StartSector, driveParam);
printf("%c: HD%d", 'A' + nUnits, (driveParam->driveno & 0x7f) + 1); printf("\r%c: HD%d", 'A' + nUnits, (driveParam->driveno & 0x7f) + 1);
if (extendedPartNo) if (extendedPartNo)
printf(" Ext:%d", extendedPartNo); printf(" Ext:%d", extendedPartNo);
@ -1237,6 +1240,14 @@ void ReadAllPartitionTables(void)
ddt FAR *pddt; ddt FAR *pddt;
static iregs regs; static iregs regs;
/* quick adjustment of diskette parameter table */
fmemcpy(int1e_table, *(char FAR * FAR *)MK_FP(0, 0x1e*4), sizeof(int1e_table));
/* enforce min. 9 sectors per track */
if (int1e_table[4] < 9)
int1e_table[4] = 9;
/* and adjust int1e */
setvec(0x1e, (intvec)int1e_table);
/* Setup media info and BPBs arrays for floppies */ /* Setup media info and BPBs arrays for floppies */
for (Unit = 0; Unit < nUnits; Unit++) for (Unit = 0; Unit < nUnits; Unit++)
{ {
@ -1339,7 +1350,7 @@ void ReadAllPartitionTables(void)
/* disk initialization: returns number of units */ /* disk initialization: returns number of units */
COUNT dsk_init() COUNT dsk_init()
{ {
printf(" - InitDisk\n"); printf(" - InitDisk");
#ifdef DEBUG #ifdef DEBUG
{ {

View File

@ -37,7 +37,7 @@ static BYTE *RcsId =
UWORD init_oem(void) UWORD init_oem(void)
{ {
UWORD top_k; UWORD top_k = 0;
#ifndef __TURBOC__ #ifndef __TURBOC__
asm asm

View File

@ -58,6 +58,10 @@ struct HugeSectorBlock {
BYTE FAR *buf; BYTE FAR *buf;
}; };
/* must be global/file scope, Turbo C uses the wrong segment for
* function scope */
STATIC const char dbcsTable[] = {0, 0, 0, 0};
/* Normal entry. This minimizes user stack usage by avoiding local */ /* Normal entry. This minimizes user stack usage by avoiding local */
/* variables needed for the rest of the handler. */ /* variables needed for the rest of the handler. */
/* this here works on the users stack !! and only very few functions /* this here works on the users stack !! and only very few functions
@ -1325,7 +1329,6 @@ dispatch:
/* UNDOCUMENTED: Double byte and korean tables */ /* UNDOCUMENTED: Double byte and korean tables */
case 0x63: case 0x63:
{ {
static char *dbcsTable = "\0\0\0\0";
r->DS = FP_SEG(dbcsTable); r->DS = FP_SEG(dbcsTable);
r->SI = FP_OFF(dbcsTable); r->SI = FP_OFF(dbcsTable);
#if 0 #if 0

View File

@ -230,7 +230,9 @@ _nul_intr:
pop es pop es
retf retf
; floppy parameter table
global _int1e_table
_int1e_table: times 0eh db 0
;************************************************************ ;************************************************************
; KERNEL FIXED DATA AREA ; KERNEL FIXED DATA AREA

View File

@ -33,7 +33,7 @@
#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" "(C) Copyright 1995-2002 Pasquale J. Villani and The FreeDOS Project.\n"
"All Rights Reserved. This is free software and comes with ABSOLUTELY NO\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" "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" "GNU General Public License as published by the Free Software Foundation;\n"
@ -174,13 +174,13 @@ VOID ASMCFUNC FreeDOSmain(void)
/* clear the Init BSS area (what normally the RTL does */ /* clear the Init BSS area (what normally the RTL does */
memset(_ib_start, 0, _ib_end - _ib_start); memset(_ib_start, 0, _ib_end - _ib_start);
signon();
init_kernel(); init_kernel();
#ifdef DEBUG #ifdef DEBUG
/* Non-portable message kludge alert! */ /* Non-portable message kludge alert! */
printf("KERNEL: Boot drive = %c\n", 'A' + BootDrive - 1); printf("KERNEL: Boot drive = %c\n", 'A' + BootDrive - 1);
#endif #endif
signon();
kernel(); kernel();
} }
@ -361,9 +361,9 @@ STATIC VOID FsConfig(VOID)
STATIC VOID signon() STATIC VOID signon()
{ {
printf("\n%S", (void FAR *)os_release); printf("\r%S", (void FAR *)os_release);
printf("Kernel compatibility %d.%d", os_major, os_minor); printf("Kernel compatibility %d.%d", MAJOR_RELEASE, MINOR_RELEASE);
#if defined(__TURBOC__) #if defined(__TURBOC__)
printf(" - TURBOC"); printf(" - TURBOC");
@ -393,6 +393,7 @@ STATIC void kernel()
int rc; int rc;
extern char MenuSelected; extern char MenuSelected;
extern unsigned Menus;
BYTE master_env[32]; BYTE master_env[32];
char *masterenv_ptr = master_env; char *masterenv_ptr = master_env;
@ -405,9 +406,9 @@ STATIC void kernel()
masterenv_ptr += sprintf(masterenv_ptr, "PATH=."); masterenv_ptr += sprintf(masterenv_ptr, "PATH=.");
/* export the current selected config menu */ /* export the current selected config menu */
if (MenuSelected) if (Menus)
{ {
masterenv_ptr += sprintf(masterenv_ptr, "CONFIG=%c", MenuSelected); masterenv_ptr += sprintf(masterenv_ptr, "CONFIG=%c", MenuSelected+'0');
} }
exb.exec.env_seg = DOS_PSP + 8; exb.exec.env_seg = DOS_PSP + 8;
@ -463,7 +464,7 @@ STATIC void kernel()
} }
exb.exec.cmd_line = (CommandTail FAR *) & Cmd; exb.exec.cmd_line = (CommandTail FAR *) & Cmd;
exb.exec.fcb_1 = exb.exec.fcb_2 = (fcb FAR *) 0; exb.exec.fcb_1 = exb.exec.fcb_2 = (fcb FAR *) 0xfffffffful;
#ifdef DEBUG #ifdef DEBUG
printf("Process 0 starting: %s\n\n", Config.cfgInit); printf("Process 0 starting: %s\n\n", Config.cfgInit);

View File

@ -168,43 +168,43 @@ HEADERS=\
# XXX: I generated these using `gcc -MM' and `sed', so they may not be # XXX: I generated these using `gcc -MM' and `sed', so they may not be
# completely correct... -- ror4 # completely correct... -- ror4
#blockio.obj: blockio.c $(HEADERS) $(CONFIGURATION) blockio.obj: blockio.c $(HEADERS) $(CONFIGURATION)
#break.obj: break.c $(HEADERS) $(CONFIGURATION) break.obj: break.c $(HEADERS) $(CONFIGURATION)
#chario.obj: chario.c $(HEADERS) $(CONFIGURATION) chario.obj: chario.c $(HEADERS) $(CONFIGURATION)
#dosfns.obj: dosfns.c $(HEADERS) $(CONFIGURATION) dosfns.obj: dosfns.c $(HEADERS) $(CONFIGURATION)
#dosnames.obj: dosnames.c $(HEADERS) $(CONFIGURATION) dosnames.obj: dosnames.c $(HEADERS) $(CONFIGURATION)
#dsk.obj: dsk.c $(HEADERS) $(CONFIGURATION) dsk.obj: dsk.c $(HEADERS) $(CONFIGURATION)
#error.obj: error.c $(HEADERS) $(CONFIGURATION) error.obj: error.c $(HEADERS) $(CONFIGURATION)
#fatdir.obj: fatdir.c $(HEADERS) $(CONFIGURATION) fatdir.obj: fatdir.c $(HEADERS) $(CONFIGURATION)
#fatfs.obj: fatfs.c $(HEADERS) $(CONFIGURATION) fatfs.obj: fatfs.c $(HEADERS) $(CONFIGURATION)
#fattab.obj: fattab.c $(HEADERS) $(CONFIGURATION) fattab.obj: fattab.c $(HEADERS) $(CONFIGURATION)
#fcbfns.obj: fcbfns.c $(HEADERS) $(CONFIGURATION) fcbfns.obj: fcbfns.c $(HEADERS) $(CONFIGURATION)
#inthndlr.obj: inthndlr.c $(HEADERS) $(CONFIGURATION) inthndlr.obj: inthndlr.c $(HEADERS) $(CONFIGURATION)
#ioctl.obj: ioctl.c $(HEADERS) $(CONFIGURATION) ioctl.obj: ioctl.c $(HEADERS) $(CONFIGURATION)
#memmgr.obj: memmgr.c $(HEADERS) $(CONFIGURATION) memmgr.obj: memmgr.c $(HEADERS) $(CONFIGURATION)
#misc.obj: misc.c $(HEADERS) $(CONFIGURATION) misc.obj: misc.c $(HEADERS) $(CONFIGURATION)
#lfnapi.obj: lfnapi.c $(HEADERS) $(CONFIGURATION) lfnapi.obj: lfnapi.c $(HEADERS) $(CONFIGURATION)
#newstuff.obj: newstuff.c $(HEADERS) $(CONFIGURATION) newstuff.obj: newstuff.c $(HEADERS) $(CONFIGURATION)
#network.obj: network.c $(HEADERS) $(CONFIGURATION) network.obj: network.c $(HEADERS) $(CONFIGURATION)
#nls.obj: nls.c $(HEADERS) $(CONFIGURATION) nls.obj: nls.c $(HEADERS) $(CONFIGURATION)
# \ # \
# 001-437.nls # 001-437.nls

View File

@ -286,8 +286,13 @@ stopIt: /* reached from FIRST_FIT on match */
*/ */
COUNT DosMemLargest(UWORD FAR * size) COUNT DosMemLargest(UWORD FAR * size)
{ {
REG mcb FAR *p; seg dummy;
*size = 0;
DosMemAlloc(0xffff, LARGEST, &dummy, size);
return *size ? SUCCESS : DE_NOMEM;
#if 0
REG mcb FAR *p;
/* Initialize */ /* Initialize */
p = ((mem_access_mode & (FIRST_FIT_UO | FIRST_FIT_U)) && uppermem_link p = ((mem_access_mode & (FIRST_FIT_UO | FIRST_FIT_U)) && uppermem_link
&& uppermem_root != 0xffff) ? para2far(uppermem_root) : para2far(first_mcb); && uppermem_root != 0xffff) ? para2far(uppermem_root) : para2far(first_mcb);
@ -320,7 +325,7 @@ COUNT DosMemLargest(UWORD FAR * size)
/* If *size is still zero, aka nothing had changed, either no unused /* If *size is still zero, aka nothing had changed, either no unused
block was found at all or a zero-length block only. block was found at all or a zero-length block only.
Both is considered as a failure */ Both is considered as a failure */
return *size ? SUCCESS : DE_NOMEM; #endif
} }
/* /*

View File

@ -393,6 +393,7 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
char c, *bufend = buf + (sizeof(buf) - 1); char c, *bufend = buf + (sizeof(buf) - 1);
int gotAnyWildcards = 0; int gotAnyWildcards = 0;
int seglen, copylen, state; int seglen, copylen, state;
int error = DE_PATHNOTFND;
while ((*src) && (bufp < bufend)) while ((*src) && (bufp < bufend))
{ {
/* Skip duplicated slashes. */ /* Skip duplicated slashes. */
@ -404,7 +405,12 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
for (seglen = 0;; seglen++) for (seglen = 0;; seglen++)
{ {
c = src[seglen]; c = src[seglen];
if ((c == '\0') || (c == '/') || (c == '\\')) if (c == '\0')
{
error = DE_FILENOTFND;
break;
}
else if ((c == '/') || (c == '\\'))
break; break;
} }
if (seglen > 0) if (seglen > 0)
@ -426,7 +432,7 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
else else
{ {
/* .. in root dir illegal */ /* .. in root dir illegal */
return DE_PATHNOTFND; return error;
} }
} }
else else
@ -434,7 +440,7 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
/* New segment. If any wildcards in previous /* New segment. If any wildcards in previous
segment(s), this is an invalid path. */ segment(s), this is an invalid path. */
if (gotAnyWildcards || src[0] == '.') if (gotAnyWildcards || src[0] == '.')
return DE_PATHNOTFND; return error;
/* Append current path segment to result. */ /* Append current path segment to result. */
*(bufp++) = '\\'; *(bufp++) = '\\';
if (bufp >= bufend) if (bufp >= bufend)
@ -456,8 +462,6 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
break; break;
copylen++; copylen++;
} }
copylen = 0;
state = 1; /* Go wait for dot */
break; break;
} }
if (c == '.') if (c == '.')
@ -465,26 +469,17 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
if (src[i + 1] != '.' && i + 1 < seglen) if (src[i + 1] != '.' && i + 1 < seglen)
*(bufp++) = '.'; *(bufp++) = '.';
copylen = 0; copylen = 0;
state = 2; /* Copy extension next */ state = 1; /* Copy extension next */
break; break;
} }
if (copylen < FNAME_SIZE)
{
*(bufp++) = c; *(bufp++) = c;
copylen++; copylen++;
if (copylen >= FNAME_SIZE)
{
copylen = 0;
state = 1; /* Go wait for dot */
break; break;
} }
break; break;
case 1: /* Looking for dot so we can copy exten */ case 1: /* Copying extension */
if (src[i] == '.' && src[i + 1] != '.' && i + 1 < seglen)
{
*(bufp++) = '.';
state = 2;
}
break;
case 2: /* Copying extension */
if (c == '*') if (c == '*')
{ {
while (copylen < FEXT_SIZE) while (copylen < FEXT_SIZE)
@ -494,20 +489,13 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
break; break;
copylen++; copylen++;
} }
i = seglen; /* Done with segment */
break;
} }
if (c == '.') if (c == '.')
return error;
if (copylen < FEXT_SIZE)
{ {
i = seglen; /* Done with segment */
break;
}
*(bufp++) = c; *(bufp++) = c;
copylen++; copylen++;
if (copylen >= FEXT_SIZE)
{
i = seglen; /* Done with segment */
break;
} }
break; break;
} }

View File

@ -366,16 +366,21 @@ COUNT do_printf(CONST BYTE * fmt, BYTE ** arg)
void hexd(char *title, UBYTE FAR * p, COUNT numBytes) void hexd(char *title, UBYTE FAR * p, COUNT numBytes)
{ {
int loop; int loop, start = 0;
printf("%s%04x|", title, FP_SEG(p)); printf("%s", title);
for (loop = 0; loop < numBytes; loop++) if (numBytes > 16)
printf("%02x ", p[loop]); printf("\n");
printf("|");
for (loop = 0; loop < numBytes; loop++) for (start = 0; start < numBytes; start += 16)
{
printf("%p|", p+start);
for (loop = start; loop < numBytes && loop < start+16;loop++)
printf("%02x ", p[loop]);
for (loop = start; loop < numBytes && loop < start+16;loop++)
printf("%c", p[loop] < 0x20 ? '.' : p[loop]); printf("%c", p[loop] < 0x20 ? '.' : p[loop]);
printf("\n"); printf("\n");
} }
}
#ifdef TEST #ifdef TEST
/* /*

View File

@ -177,7 +177,7 @@ _spawn_int23:
;; complete the jump to INT-23 via RETF and restore BP ;; complete the jump to INT-23 via RETF and restore BP
xchg word [bp-4], bp xchg word [bp-4], bp
stc ;; set default action --> terminate clc ;; set default action --> resume
; invoke the int 23 handler its address has been constructed ; invoke the int 23 handler its address has been constructed
;; on the stack ;; on the stack
retf retf

View File

@ -158,8 +158,7 @@ BOOL dos_setfsize(COUNT fd, LONG size);
COUNT dos_mkdir(BYTE * dir); COUNT dos_mkdir(BYTE * dir);
BOOL last_link(f_node_ptr fnp); BOOL last_link(f_node_ptr fnp);
COUNT map_cluster(REG f_node_ptr fnp, COUNT mode); COUNT map_cluster(REG f_node_ptr fnp, COUNT mode);
UCOUNT readblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err); UCOUNT rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode);
UCOUNT writeblock(COUNT fd, const VOID FAR * buffer, UCOUNT count, COUNT * err);
COUNT dos_read(COUNT fd, VOID FAR * buffer, UCOUNT count); COUNT dos_read(COUNT fd, VOID FAR * buffer, UCOUNT count);
COUNT dos_write(COUNT fd, const VOID FAR * buffer, UCOUNT count); COUNT dos_write(COUNT fd, const VOID FAR * buffer, UCOUNT count);
LONG dos_lseek(COUNT fd, LONG foffset, COUNT origin); LONG dos_lseek(COUNT fd, LONG foffset, COUNT origin);
@ -184,16 +183,7 @@ void read_fsinfo(struct dpb FAR * dpbp);
void write_fsinfo(struct dpb FAR * dpbp); void write_fsinfo(struct dpb FAR * dpbp);
UCOUNT link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1, UCOUNT link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
REG CLUSTER Cluster2); 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_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 */ /* fcbfns.c */
VOID DosOutputString(BYTE FAR * s); VOID DosOutputString(BYTE FAR * s);

View File

@ -30,61 +30,37 @@
#include "globals.h" #include "globals.h"
#ifdef VERSION_STRINGS #ifdef VERSION_STRINGS
static BYTE *RcsId = static char *RcsId =
"$Id$"; "$Id$";
#endif #endif
#ifdef PROTO
VOID ASMCFUNC WriteATClock(BYTE *, BYTE, BYTE, BYTE);
VOID ASMCFUNC WritePCClock(ULONG);
COUNT BcdToByte(COUNT);
COUNT BcdToWord(BYTE *, UWORD *, UWORD *, UWORD *);
COUNT ByteToBcd(COUNT);
VOID DayToBcd(BYTE *, UWORD *, UWORD *, UWORD *);
#else
VOID WriteATClock();
VOID WritePCClock();
COUNT BcdToByte();
COUNT BcdToWord();
COUNT ByteToBcd();
VOID DayToBcd();
#endif
/* */ /* */
/* WARNING - THIS DRIVER IS NON-PORTABLE!!!! */ /* WARNING - THIS DRIVER IS NON-PORTABLE!!!! */
/* */ /* */
extern UWORD days[2][13]; /* this is defined by SYSTIME.C */
static struct ClockRecord clk;
/*
static BYTE bcdDays[4];
static UWORD Month,
Day,
Year;
static BYTE bcdMinutes;
static BYTE bcdHours;
/ ** static BYTE bcdHundredths;* /
static BYTE bcdSeconds;
static ULONG Ticks;
*/
UWORD ASM DaysSinceEpoch = 0; UWORD ASM DaysSinceEpoch = 0;
typedef UDWORD ticks_t;
BOOL ASMCFUNC ReadATClock(BYTE *, BYTE *, BYTE *, BYTE *); STATIC int ByteToBcd(int x)
STATIC COUNT BcdToByte(COUNT x)
{ {
return ((((x) >> 4) & 0xf) * 10 + ((x) & 0xf)); return ((x / 10) << 4) | (x % 10);
}
STATIC int BcdToByte(int x)
{
return ((x >> 4) & 0xf) * 10 + (x & 0xf);
}
STATIC void DayToBcd(BYTE * x, unsigned mon, unsigned day, unsigned yr)
{
x[1] = ByteToBcd(mon);
x[0] = ByteToBcd(day);
x[3] = ByteToBcd(yr / 100);
x[2] = ByteToBcd(yr % 100);
} }
WORD ASMCFUNC FAR clk_driver(rqptr rp) WORD ASMCFUNC FAR clk_driver(rqptr rp)
{ {
COUNT c;
const 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;
switch (rp->r_command) switch (rp->r_command)
{ {
@ -92,6 +68,8 @@ WORD ASMCFUNC FAR clk_driver(rqptr rp)
/* If AT clock exists, copy AT clock time to system clock */ /* If AT clock exists, copy AT clock time to system clock */
if (!ReadATClock(bcd_days, &bcd_hours, &bcd_minutes, &bcd_seconds)) if (!ReadATClock(bcd_days, &bcd_hours, &bcd_minutes, &bcd_seconds))
{ {
ticks_t seconds;
DaysSinceEpoch = DaysSinceEpoch =
DaysFromYearMonthDay(100 * BcdToByte(bcd_days[3]) + DaysFromYearMonthDay(100 * BcdToByte(bcd_days[3]) +
BcdToByte(bcd_days[2]), BcdToByte(bcd_days[2]),
@ -100,16 +78,16 @@ WORD ASMCFUNC FAR clk_driver(rqptr rp)
/* /*
* This is a rather tricky calculation. The number of timer ticks per * This is a rather tricky calculation. The number of timer ticks per
* second is not exactly 18.2, but rather 0x1800b0 / 86400 = 19663 / 1080 * second is not exactly 18.2, but rather 1193180 / 65536
* (the timer interrupt updates the midnight flag when the tick count * where 1193180 = 0x1234dc
* reaches 0x1800b0). Fortunately, 86400 * 19663 = 1698883200 < ULONG_MAX, * The timer interrupt updates the midnight flag when the tick count
* so we can simply multiply the number of seconds by 19663 without * reaches 0x1800b0 -- ror4.
* worrying about overflow. :) -- ror4
*/ */
Ticks = (3600ul * BcdToByte(bcd_hours) +
60ul * BcdToByte(bcd_minutes) + seconds =
BcdToByte(bcd_seconds)) * 19663ul / 1080ul; 60 * (ticks_t)(60 * BcdToByte(bcd_hours) + BcdToByte(bcd_minutes)) +
WritePCClock(Ticks); BcdToByte(bcd_seconds);
WritePCClock(seconds * 0x12 + ((seconds * 0x34dc) >> 16));
} }
/* rp->r_endaddr = device_end(); not needed - bart */ /* rp->r_endaddr = device_end(); not needed - bart */
rp->r_nunits = 0; rp->r_nunits = 0;
@ -117,137 +95,52 @@ WORD ASMCFUNC FAR clk_driver(rqptr rp)
case C_INPUT: case C_INPUT:
{ {
ULONG remainder, hs; struct ClockRecord clk;
ReadPCClock(&Ticks); int tmp;
ticks_t ticks;
clk.clkDays = DaysSinceEpoch; clk.clkDays = DaysSinceEpoch;
/*
* Another tricky calculation (after the one in `main.c'). This time
* we do have a problem with overflow, because we need to extract the
* 1/100s portion too. The scaling factor is now
* (100 x 86400) / 0x1800b0 = 108000 / 19663. -- ror4
*/
hs = 0;
#if 0
if (Ticks >= 64 * 19663ul)
{
hs += 64 * 108000ul;
Ticks -= 64 * 19663ul;
}
if (Ticks >= 32 * 19663ul)
{
hs += 32 * 108000ul;
Ticks -= 32 * 19663ul;
}
if (Ticks >= 16 * 19663ul)
{
hs += 16 * 108000ul;
Ticks -= 16 * 19663ul;
}
if (Ticks >= 8 * 19663ul)
{
hs += 8 * 108000ul;
Ticks -= 8 * 19663ul;
}
if (Ticks >= 4 * 19663ul)
{
hs += 4 * 108000ul;
Ticks -= 4 * 19663ul;
}
if (Ticks >= 2 * 19663ul)
{
hs += 2 * 108000ul;
Ticks -= 2 * 19663ul;
}
if (Ticks >= 19663ul)
{
hs += 108000ul;
Ticks -= 19663ul;
}
#else
{
UWORD q1 = Ticks / 19663ul;
Ticks -= q1 * 19663ul; /* The scaling factor is now
hs = q1 * 108000ul; 6553600/1193180 = 327680/59659 = 65536*5/59659 */
}
#endif ticks = 5 * ReadPCClock();
/* ticks = ((ticks / 59659u) << 16) + ((ticks % 59659u) << 16) / 59659u;
* Now Ticks < 19663, so Ticks * 108000 < 2123604000 < ULONG_MAX.
* *phew* -- ror4 tmp = (int)(ticks / 6000);
*/ clk.clkHours = tmp / 60;
hs += Ticks * 108000ul / 19663ul; clk.clkMinutes = tmp % 60;
clk.clkHours = hs / 360000ul;
remainder = hs % 360000ul; tmp = (int)(ticks % 6000);
clk.clkMinutes = remainder / 6000ul; clk.clkSeconds = tmp / 100;
remainder %= 6000ul; clk.clkHundredths = tmp % 100;
clk.clkSeconds = remainder / 100ul;
clk.clkHundredths = remainder % 100ul;
}
fmemcpy(rp->r_trans, &clk, fmemcpy(rp->r_trans, &clk,
min(sizeof(struct ClockRecord), rp->r_count)); min(sizeof(struct ClockRecord), rp->r_count));
}
return S_DONE; return S_DONE;
case C_OUTPUT: case C_OUTPUT:
{
int c;
const unsigned short *pdays;
unsigned Month, Day, Year;
struct ClockRecord clk;
ticks_t hs, Ticks;
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); fmemcpy(&clk, rp->r_trans, rp->r_count);
/* Set PC Clock first */ /* Set PC Clock first */
DaysSinceEpoch = clk.clkDays; DaysSinceEpoch = clk.clkDays;
{ hs = 6000 * (ticks_t)(60 * clk.clkHours + clk.clkMinutes) +
ULONG hs; (ticks_t)(100 * clk.clkSeconds + clk.clkHundredths);
hs = 360000ul * clk.clkHours +
6000ul * clk.clkMinutes +
100ul * clk.clkSeconds + clk.clkHundredths;
Ticks = 0;
#if 0
if (hs >= 64 * 108000ul)
{
Ticks += 64 * 19663ul;
hs -= 64 * 108000ul;
}
if (hs >= 32 * 108000ul)
{
Ticks += 32 * 19663ul;
hs -= 32 * 108000ul;
}
if (hs >= 16 * 108000ul)
{
Ticks += 16 * 19663ul;
hs -= 16 * 108000ul;
}
if (hs >= 8 * 108000ul)
{
Ticks += 8 * 19663ul;
hs -= 8 * 108000ul;
}
if (hs >= 4 * 108000ul)
{
Ticks += 4 * 19663ul;
hs -= 4 * 108000ul;
}
if (hs >= 2 * 108000ul)
{
Ticks += 2 * 19663ul;
hs -= 2 * 108000ul;
}
if (hs >= 108000ul)
{
Ticks += 19663ul;
hs -= 108000ul;
}
#else
{
UWORD q1 = hs / 108000ul;
hs -= q1 * 108000ul; /* The scaling factor is now
Ticks = q1 * 19663ul; 1193180/6553600 = 59659/327680 = 59659/65536/5 */
}
Ticks = ((hs >> 16) * 59659u + (((hs & 0xffff) * 59659u) >> 16)) / 5;
#endif
Ticks += hs * 19663ul / 108000ul;
}
WritePCClock(Ticks); WritePCClock(Ticks);
/* Now set AT clock */ /* Now set AT clock */
@ -276,11 +169,12 @@ WORD ASMCFUNC FAR clk_driver(rqptr rp)
} }
} }
DayToBcd((BYTE *) bcd_days, &Month, &Day, &Year); DayToBcd(bcd_days, Month, Day, Year);
bcd_minutes = ByteToBcd(clk.clkMinutes); bcd_minutes = ByteToBcd(clk.clkMinutes);
bcd_hours = ByteToBcd(clk.clkHours); bcd_hours = ByteToBcd(clk.clkHours);
bcd_seconds = ByteToBcd(clk.clkSeconds); bcd_seconds = ByteToBcd(clk.clkSeconds);
WriteATClock(bcd_days, bcd_hours, bcd_minutes, bcd_seconds); WriteATClock(bcd_days, bcd_hours, bcd_minutes, bcd_seconds);
}
return S_DONE; return S_DONE;
case C_OFLUSH: case C_OFLUSH:
@ -296,19 +190,6 @@ WORD ASMCFUNC FAR clk_driver(rqptr rp)
} }
} }
COUNT ByteToBcd(COUNT x)
{
return ((x / 10) << 4) | (x % 10);
}
VOID DayToBcd(BYTE * x, UWORD * mon, UWORD * day, UWORD * yr)
{
x[1] = ByteToBcd(*mon);
x[0] = ByteToBcd(*day);
x[3] = ByteToBcd(*yr / 100);
x[2] = ByteToBcd(*yr % 100);
}
/* /*
* Log: sysclk.c,v - for newer entries do "cvs log sysclk.c" * Log: sysclk.c,v - for newer entries do "cvs log sysclk.c"
* *

View File

@ -36,90 +36,89 @@ static BYTE *syspackRcsId =
#endif #endif
#ifdef NONNATIVE #ifdef NONNATIVE
VOID getlong(REG VOID * vp, LONG * lp) UDWORD getlong(REG VOID * vp)
{ {
*lp = (((BYTE *) vp)[0] & 0xff) + return (((UBYTE *) vp)[0] & 0xff) +
((((BYTE *) vp)[1] & 0xff) << 8) + ((((UBYTE *) vp)[1] & 0xff) << 8) +
((((BYTE *) vp)[2] & 0xff) << 16) + ((((UBYTE *) vp)[2] & 0xff) << 16) +
((((BYTE *) vp)[3] & 0xff) << 24); ((((UBYTE *) vp)[3] & 0xff) << 24);
} }
VOID getword(REG VOID * vp, WORD * wp) UWORD getword(REG VOID * vp)
{ {
*wp = (((BYTE *) vp)[0] & 0xff) + ((((BYTE *) vp)[1] & 0xff) << 8); return (((UBYTE *) vp)[0] & 0xff) + ((((UBYTE *) vp)[1] & 0xff) << 8);
} }
VOID getbyte(VOID * vp, BYTE * bp) UBYTE getbyte(VOID * vp)
{ {
*bp = *((BYTE *) vp); return *((BYTE *) vp);
} }
VOID fgetword(REG VOID FAR * vp, WORD FAR * wp) UWORD fgetword(REG VOID FAR * vp)
{ {
*wp = return (((UBYTE FAR *) vp)[0] & 0xff) + ((((UBYTE FAR *) vp)[1] & 0xff) << 8);
(((BYTE FAR *) vp)[0] & 0xff) + ((((BYTE FAR *) vp)[1] & 0xff) << 8);
} }
VOID fgetlong(REG VOID FAR * vp, LONG FAR * lp) UDWORD fgetlong(REG VOID FAR * vp)
{ {
*lp = (((BYTE *) vp)[0] & 0xff) + return (((UBYTE *) vp)[0] & 0xff) +
((((BYTE *) vp)[1] & 0xff) << 8) + ((((UBYTE *) vp)[1] & 0xff) << 8) +
((((BYTE *) vp)[2] & 0xff) << 16) + ((((UBYTE *) vp)[2] & 0xff) << 16) +
((((BYTE *) vp)[3] & 0xff) << 24); ((((UBYTE *) vp)[3] & 0xff) << 24);
} }
VOID fgetbyte(VOID FAR * vp, BYTE FAR * bp) UBYTE fgetbyte(VOID FAR * vp)
{ {
*bp = *((BYTE FAR *) vp); return *((UBYTE FAR *) vp);
} }
VOID fputlong(LONG FAR * lp, VOID FAR * vp) VOID fputlong(VOID FAR * vp, UDWORD l)
{ {
REG BYTE FAR *bp = (BYTE FAR *) vp; REG UBYTE FAR *bp = (UBYTE FAR *) vp;
bp[0] = *lp & 0xff; bp[0] = l & 0xff;
bp[1] = (*lp >> 8) & 0xff; bp[1] = (l >> 8) & 0xff;
bp[2] = (*lp >> 16) & 0xff; bp[2] = (l >> 16) & 0xff;
bp[3] = (*lp >> 24) & 0xff; bp[3] = (l >> 24) & 0xff;
} }
VOID fputword(WORD FAR * wp, VOID FAR * vp) VOID fputword(VOID FAR * vp, UWORD w)
{ {
REG BYTE FAR *bp = (BYTE FAR *) vp; REG UBYTE FAR *bp = (UBYTE FAR *) vp;
bp[0] = *wp & 0xff; bp[0] = w & 0xff;
bp[1] = (*wp >> 8) & 0xff; bp[1] = (w >> 8) & 0xff;
} }
VOID fputbyte(BYTE FAR * bp, VOID FAR * vp) VOID fputbyte(VOID FAR * vp, UBYTE b)
{ {
*(BYTE FAR *) vp = *bp; *(UBYTE FAR *) vp = b;
} }
VOID getdirent(BYTE FAR * vp, struct dirent FAR * dp) VOID getdirent(UBYTE FAR * vp, struct dirent FAR * dp)
{ {
fmemcpy(dp->dir_name, &vp[DIR_NAME], FNAME_SIZE); fmemcpy(dp->dir_name, &vp[DIR_NAME], FNAME_SIZE);
fmemcpy(dp->dir_ext, &vp[DIR_EXT], FEXT_SIZE); fmemcpy(dp->dir_ext, &vp[DIR_EXT], FEXT_SIZE);
fgetbyte(&vp[DIR_ATTRIB], (BYTE FAR *) & dp->dir_attrib); dp->dir_attrib = fgetbyte(&vp[DIR_ATTRIB]);
fgetword(&vp[DIR_TIME], (WORD FAR *) & dp->dir_time); dp->dir_time = fgetword(&vp[DIR_TIME]);
fgetword(&vp[DIR_DATE], (WORD FAR *) & dp->dir_date); dp->dir_date = fgetword(&vp[DIR_DATE]);
fgetword(&vp[DIR_START], (WORD FAR *) & dp->dir_start); dp->dir_start = fgetword(&vp[DIR_START]);
fgetlong(&vp[DIR_SIZE], (LONG FAR *) & dp->dir_size); dp->dir_size = fgetlong(&vp[DIR_SIZE]);
} }
VOID putdirent(struct dirent FAR * dp, BYTE FAR * vp) VOID putdirent(struct dirent FAR * dp, UBYTE FAR * vp)
{ {
REG COUNT i; REG COUNT i;
REG BYTE FAR *p; REG BYTE FAR *p;
fmemcpy(&vp[DIR_NAME], dp->dir_name, FNAME_SIZE); fmemcpy(&vp[DIR_NAME], dp->dir_name, FNAME_SIZE);
fmemcpy(&vp[DIR_EXT], dp->dir_ext, FEXT_SIZE); fmemcpy(&vp[DIR_EXT], dp->dir_ext, FEXT_SIZE);
fputbyte((BYTE FAR *) & dp->dir_attrib, &vp[DIR_ATTRIB]); fputbyte(&vp[DIR_ATTRIB], dp->dir_attrib);
fputword((WORD FAR *) & dp->dir_time, &vp[DIR_TIME]); fputword(&vp[DIR_TIME], dp->dir_time);
fputword((WORD FAR *) & dp->dir_date, &vp[DIR_DATE]); fputword(&vp[DIR_DATE], dp->dir_date);
fputword((WORD FAR *) & dp->dir_start, &vp[DIR_START]); fputword(&vp[DIR_START], dp->dir_start);
fputlong((LONG FAR *) & dp->dir_size, &vp[DIR_SIZE]); fputlong(&vp[DIR_SIZE], dp->dir_size);
for (i = 0, p = (BYTE FAR *) & vp[DIR_RESERVED]; i < 10; i++) for (i = 0, p = (UBYTE FAR *) & vp[DIR_RESERVED]; i < 10; i++)
*p++ = NULL; *p++ = NULL;
} }
#endif #endif

View File

@ -98,19 +98,14 @@ VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp,
COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd) COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd)
{ {
BYTE Month, DayOfMonth, DayOfWeek; /* for ClkRecord.clkDays */
COUNT Year; ExecuteClockDriverRequest(C_INPUT);
DosGetDate((BYTE FAR *) & DayOfWeek, (BYTE FAR *) & Month,
(BYTE FAR *) & DayOfMonth, (COUNT FAR *) & Year);
ClkRecord.clkHours = h; ClkRecord.clkHours = h;
ClkRecord.clkMinutes = m; ClkRecord.clkMinutes = m;
ClkRecord.clkSeconds = s; ClkRecord.clkSeconds = s;
ClkRecord.clkHundredths = hd; ClkRecord.clkHundredths = hd;
ClkRecord.clkDays = DaysFromYearMonthDay(Year, Month, DayOfMonth);
ExecuteClockDriverRequest(C_OUTPUT); ExecuteClockDriverRequest(C_OUTPUT);
if (ClkReqHdr.r_status & S_ERROR) if (ClkReqHdr.r_status & S_ERROR)
@ -172,10 +167,7 @@ UWORD Month, DayOfMonth, Year;
|| DayOfMonth < 1 || DayOfMonth > pdays[Month] - pdays[Month - 1]) || DayOfMonth < 1 || DayOfMonth > pdays[Month] - pdays[Month - 1])
return DE_INVLDDATA; return DE_INVLDDATA;
DosGetTime((BYTE FAR *) & ClkRecord.clkHours, ExecuteClockDriverRequest(C_INPUT);
(BYTE FAR *) & ClkRecord.clkMinutes,
(BYTE FAR *) & ClkRecord.clkSeconds,
(BYTE FAR *) & ClkRecord.clkHundredths);
ClkRecord.clkDays = DaysFromYearMonthDay(Year, Month, DayOfMonth); ClkRecord.clkDays = DaysFromYearMonthDay(Year, Month, DayOfMonth);

View File

@ -241,8 +241,10 @@ VOID new_psp(psp FAR * p, int psize)
/* first command line argument */ /* first command line argument */
p->ps_fcb1.fcb_drive = 0; p->ps_fcb1.fcb_drive = 0;
fmemset(p->ps_fcb1.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE);
/* second command line argument */ /* second command line argument */
p->ps_fcb2.fcb_drive = 0; p->ps_fcb2.fcb_drive = 0;
fmemset(p->ps_fcb2.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE);
/* local command line */ /* local command line */
p->ps_cmd_count = 0; /* command tail */ p->ps_cmd_count = 0; /* command tail */
@ -265,8 +267,11 @@ STATIC UWORD patchPSP(UWORD pspseg, UWORD envseg, exec_blk FAR * exb,
/* complete the psp by adding the command line and FCBs */ /* complete the psp by adding the command line and FCBs */
fmemcpy(psp->ps_cmd, exb->exec.cmd_line->ctBuffer, 127); fmemcpy(psp->ps_cmd, exb->exec.cmd_line->ctBuffer, 127);
if (FP_OFF(exb->exec.fcb_1) != 0xffff)
{
fmemcpy(&psp->ps_fcb1, exb->exec.fcb_1, 16); fmemcpy(&psp->ps_fcb1, exb->exec.fcb_1, 16);
fmemcpy(&psp->ps_fcb2, exb->exec.fcb_2, 16); fmemcpy(&psp->ps_fcb2, exb->exec.fcb_2, 16);
}
psp->ps_cmd_count = exb->exec.cmd_line->ctCount; psp->ps_cmd_count = exb->exec.cmd_line->ctCount;
/* identify the mcb as this functions' */ /* identify the mcb as this functions' */

View File

@ -4,8 +4,7 @@
# Use these for WATCOM 11.0c # Use these for WATCOM 11.0c
COMPILERPATH=$(WATCOM) COMPILERPATH=$(WATCOM)
COMPILERBIN=$(WATCOM)\binw CC=wcl
CC=$(COMPILERBIN)\wcl
INCLUDEPATH=$(COMPILERPATH)\H INCLUDEPATH=$(COMPILERPATH)\H
INCLUDE=$(COMPILERPATH)\h INCLUDE=$(COMPILERPATH)\h
EDPATH=$(COMPILERPATH)\EDDAT EDPATH=$(COMPILERPATH)\EDDAT
@ -17,12 +16,12 @@ TARGETOPT=-0
!endif !endif
LIBPATH=$(COMPILERPATH)\lib286 LIBPATH=$(COMPILERPATH)\lib286
LIBUTIL=$(COMPILERBIN)\wlib LIBUTIL=wlib
LIBPLUS= LIBPLUS=
LIBTERM= LIBTERM=
CFLAGST=-zp=1 -mt -os -s -we -e=3 -w=2 CFLAGST=-zp=1 -mt -os -s -we -e=3 -wx
CFLAGSC=-zp=1 -mc -os -s -we -e=3 -w=2 CFLAGSC=-zp=1 -mc -os -s -we -e=3 -wx
TARGET=KWC TARGET=KWC
@ -60,7 +59,7 @@ MATH_INSERT= +i4d +i4m
# -3 optimization for 386 - given in CONFIG.MAK, not here # -3 optimization for 386 - given in CONFIG.MAK, not here
# #
ALLCFLAGS=-I..\hdr $(TARGETOPT) $(ALLCFLAGS) -zq -os -s -e=5 -j -zl -zp=1 -we ALLCFLAGS=-I..\hdr $(TARGETOPT) $(ALLCFLAGS) -zq -os -s -e=5 -j -zl -zp=1 -wx -we
INITCFLAGS=$(ALLCFLAGS) -nt=INIT_TEXT -nc=INIT -nd=I -g=I_GROUP INITCFLAGS=$(ALLCFLAGS) -nt=INIT_TEXT -nc=INIT -nd=I -g=I_GROUP
CFLAGS=$(ALLCFLAGS) -nt=HMA_TEXT -nc=HMA -g=HGROUP CFLAGS=$(ALLCFLAGS) -nt=HMA_TEXT -nc=HMA -g=HGROUP
INITPATCH=..\utils\patchobj __U4D=_IU4D __U4M=_IU4M INITPATCH=..\utils\patchobj __U4D=_IU4D __U4M=_IU4M

View File

@ -28,6 +28,7 @@ extern int CDECL printf(CONST BYTE * fmt, ...);
extern int CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...); extern int CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...);
#ifdef __WATCOMC__ #ifdef __WATCOMC__
unsigned _dos_close(int handle);
#define close _dos_close #define close _dos_close
#define SEEK_SET 0 #define SEEK_SET 0
int open(const char *pathname, int flags, ...); int open(const char *pathname, int flags, ...);

View File

@ -66,6 +66,7 @@ extern WORD CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...);
#ifndef __WATCOMC__ #ifndef __WATCOMC__
#include <io.h> #include <io.h>
#else #else
int unlink(const char *pathname);
/* some non-conforming functions to make the executable smaller */ /* some non-conforming functions to make the executable smaller */
int open(const char *pathname, int flags, ...) int open(const char *pathname, int flags, ...)
{ {
@ -819,7 +820,7 @@ BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file)
return TRUE; return TRUE;
} }
/* Log: sys.c,v see "cvs log sys.c" for newer entries. /* Log: sys.c,v see "cvs log sys.c" for newer entries. */
/* version 2.2 jeremyd 2001/9/20 /* version 2.2 jeremyd 2001/9/20
Changed so if no source given or only source drive (no path) Changed so if no source given or only source drive (no path)

View File

@ -13,6 +13,7 @@
*****************************************************************************/ *****************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <io.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>