mirror of https://github.com/FDOS/kernel.git
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:
parent
bbbd0ce42f
commit
2098578b1b
|
@ -206,7 +206,7 @@ cont: mov ds, ax
|
|||
mov [drive], dl ; BIOS passes drive number in DL
|
||||
|
||||
call print
|
||||
db "Loading FreeDOS...",13,10,"ROOT",0
|
||||
db "Loading FreeDOS ",0
|
||||
|
||||
%ifdef CALCPARAMS
|
||||
GETDRIVEPARMS
|
||||
|
@ -370,7 +370,7 @@ boot_error: call print
|
|||
int 0x19 ; reboot the machine
|
||||
|
||||
boot_success: call print
|
||||
db " GO!",13,10,0
|
||||
db " GO! ",0
|
||||
mov bl, [drive]
|
||||
jmp word LOADSEG:0
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ cont: mov ds, ax
|
|||
mov [drive], dl ; BIOS passes drive number in DL
|
||||
|
||||
call print
|
||||
db "Loading FreeDOS...",13,10,0
|
||||
db "Loading FreeDOS ",0
|
||||
|
||||
; FINDFILE: Searches for the file in the root directory.
|
||||
;
|
||||
|
|
|
@ -40,10 +40,6 @@ segment HMA_TEXT
|
|||
_ReadPCClock:
|
||||
xor ah,ah
|
||||
int 1ah
|
||||
mov bx,sp
|
||||
mov bx,[bx+2]
|
||||
mov [bx],dx
|
||||
mov [bx+2],cx
|
||||
extern _DaysSinceEpoch ; ; update days if necessary
|
||||
|
||||
mov ah,0
|
||||
|
@ -51,6 +47,9 @@ _ReadPCClock:
|
|||
add word [_DaysSinceEpoch ],ax ; *some* BIOS's accumulate several days
|
||||
adc word [_DaysSinceEpoch+2],0 ;
|
||||
|
||||
mov ax,dx ; set return value
|
||||
mov dx,cx
|
||||
|
||||
ret
|
||||
|
||||
; Log: rdpcclk.asm,v
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
@if \%COMPILER% == \TURBOCPP set MAKE=%TP1_BASE%\bin\make
|
||||
@if \%COMPILER% == \TC3 set MAKE=%TC3_BASE%\bin\make
|
||||
@if \%COMPILER% == \BC5 set MAKE=%BC5_BASE%\bin\make
|
||||
@if \%COMPILER% == \WATCOM set MAKE=%WATCOM%\binw\wmake /ms
|
||||
@if \%COMPILER% == \MSCL8 set MAKE=%MS_BASE%\nmake /nologo
|
||||
@if \%COMPILER% == \WATCOM set MAKE=wmake /ms
|
||||
@if \%COMPILER% == \MSCL8 set MAKE=%MS_BASE%\bin\nmake /nologo
|
||||
|
||||
:make_set
|
||||
|
|
|
@ -58,7 +58,7 @@ struct buffer {
|
|||
LONG _b_huge_blkno; /* DOS-C: actual block number if >= 0xffff */
|
||||
} _b;
|
||||
#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
|
||||
|
|
|
@ -80,12 +80,12 @@ typedef struct {
|
|||
UBYTE FAR *ps_filetab; /* 34 open file table pointer */
|
||||
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 */
|
||||
BYTE ps_fill3[9];
|
||||
BYTE ps_fill2[16]; /* 40 */
|
||||
UBYTE ps_unix[3]; /* 50 unix style call - 0xcd 0x21 0xcb */
|
||||
BYTE ps_fill3[9]; /* 53 */
|
||||
union {
|
||||
struct {
|
||||
fcb _ps_fcb1; /* first command line argument */
|
||||
fcb _ps_fcb1; /* 5c first command line argument */
|
||||
} _u1;
|
||||
struct {
|
||||
BYTE fill4[16];
|
||||
|
|
|
@ -49,6 +49,6 @@ static BYTE *date_hRcsId =
|
|||
#define REVISION_MINOR 1
|
||||
#define REVISION_SEQ 26
|
||||
#define BUILD "2026"
|
||||
#define SUB_BUILD "a"
|
||||
#define KERNEL_VERSION_STRING "1.1.26a" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */
|
||||
#define KERNEL_BUILD_STRING "2026a" /*#BUILD SUB_BUILD */
|
||||
#define SUB_BUILD "b"
|
||||
#define KERNEL_VERSION_STRING "1.1.26b" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */
|
||||
#define KERNEL_BUILD_STRING "2026b" /*#BUILD SUB_BUILD */
|
||||
|
|
|
@ -128,8 +128,8 @@ BYTE askThisSingleCommand = FALSE; /* ?device= device?= */
|
|||
BYTE DontAskThisSingleCommand = FALSE; /* !files= */
|
||||
|
||||
COUNT MenuTimeout = -1;
|
||||
BYTE MenuSelected = 0;
|
||||
BYTE MenuLine = 0;
|
||||
BYTE MenuSelected = 0;
|
||||
UCOUNT MenuLine = 0;
|
||||
UCOUNT Menus = 0;
|
||||
|
||||
STATIC VOID zumcb_init(UCOUNT seg, UWORD size);
|
||||
|
@ -633,7 +633,7 @@ VOID DoConfig(int pass)
|
|||
|
||||
}
|
||||
close(nFileDesc);
|
||||
|
||||
|
||||
if (nPass == 0)
|
||||
{
|
||||
DoMenu();
|
||||
|
@ -703,20 +703,15 @@ STATIC BOOL SkipLine(char *pLine)
|
|||
{
|
||||
short key;
|
||||
|
||||
static char initialized = FALSE;
|
||||
|
||||
if (!initialized)
|
||||
if (InitKernelConfig.SkipConfigSeconds >= 0)
|
||||
{
|
||||
|
||||
initialized = TRUE;
|
||||
|
||||
if (InitKernelConfig.SkipConfigSeconds < 0)
|
||||
return FALSE;
|
||||
|
||||
if (InitKernelConfig.SkipConfigSeconds > 0)
|
||||
printf("Press F8 to trace or F5 to skip CONFIG.SYS/AUTOEXEC.BAT");
|
||||
|
||||
key = GetBiosKey(InitKernelConfig.SkipConfigSeconds); /* wait 2 seconds */
|
||||
|
||||
InitKernelConfig.SkipConfigSeconds = -1;
|
||||
|
||||
if (key == 0x3f00) /* F5 */
|
||||
{
|
||||
|
@ -737,10 +732,10 @@ STATIC BOOL SkipLine(char *pLine)
|
|||
return TRUE;
|
||||
|
||||
/* 1?device=CDROM.SYS */
|
||||
/* 2?device=OAKROM.SYS */
|
||||
/* 3?device=EMM386.EXE NOEMS */
|
||||
if (MenuLine != 0 &&
|
||||
MenuSelected != MenuLine)
|
||||
/* 12?device=OAKROM.SYS */
|
||||
/* 123?device=EMM386.EXE NOEMS */
|
||||
if ( MenuLine != 0 &&
|
||||
(MenuLine & (1 << MenuSelected)) == 0)
|
||||
return TRUE;
|
||||
|
||||
if (DontAskThisSingleCommand) /* !files=30 */
|
||||
|
@ -924,7 +919,7 @@ STATIC VOID Dosmem(BYTE * pLine)
|
|||
for (pTmp = szBuf; *pTmp != '\0'; pTmp++)
|
||||
*pTmp = toupper(*pTmp);
|
||||
|
||||
printf("DOS called with %s\n", szBuf);
|
||||
/* printf("DOS called with %s\n", szBuf); */
|
||||
|
||||
for (pTmp = szBuf;;)
|
||||
{
|
||||
|
@ -1295,14 +1290,22 @@ STATIC BYTE * scan(BYTE * s, BYTE * d)
|
|||
|
||||
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];
|
||||
Menus |= 1 << (MenuLine - '0');
|
||||
s = skipwh(s+2);
|
||||
unsigned numbers = 0;
|
||||
for ( ; isnum(s); s++)
|
||||
numbers |= 1 << (*s -'0');
|
||||
|
||||
if (*s == '?')
|
||||
{
|
||||
MenuLine = numbers;
|
||||
Menus |= numbers;
|
||||
s = skipwh(s+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* !dos=high,umb ?? */
|
||||
if (*s == '!')
|
||||
|
@ -1613,7 +1616,9 @@ STATIC VOID CfgMenu(BYTE * pLine)
|
|||
STATIC VOID DoMenu(void)
|
||||
{
|
||||
if (Menus == 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
InitKernelConfig.SkipConfigSeconds = -1;
|
||||
|
||||
Menus |= 1 << 0; /* '0' Menu always allowed */
|
||||
|
||||
|
@ -1667,7 +1672,7 @@ STATIC VOID DoMenu(void)
|
|||
if (key >= '0' && key <= '9')
|
||||
if (Menus & (1 << (key - '0')))
|
||||
{
|
||||
MenuSelected = key; break;
|
||||
MenuSelected = key - '0'; break;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
@ -1688,7 +1693,7 @@ STATIC VOID CfgMenuDefault(BYTE * pLine)
|
|||
|
||||
/* Format: STACKS = stacks [, stackSize] */
|
||||
pLine = GetNumArg(pLine, &num);
|
||||
MenuSelected = '0' + num;
|
||||
MenuSelected = num;
|
||||
pLine = skipwh(pLine);
|
||||
|
||||
if (*pLine == ',')
|
||||
|
|
|
@ -269,8 +269,6 @@ UCOUNT GenericReadSft(sft FAR * s, UCOUNT n, BYTE FAR * bp,
|
|||
else
|
||||
/* a block read */
|
||||
{
|
||||
COUNT rc;
|
||||
|
||||
/* /// Added for SHARE - Ron Cemer */
|
||||
if (IsShareInstalled())
|
||||
{
|
||||
|
@ -290,9 +288,9 @@ UCOUNT GenericReadSft(sft FAR * s, UCOUNT n, BYTE FAR * bp,
|
|||
}
|
||||
/* /// End of additions for SHARE - Ron Cemer */
|
||||
|
||||
ReadCount = readblock(s->sft_status, bp, n, &rc);
|
||||
*err = rc;
|
||||
return (rc == SUCCESS ? ReadCount : 0);
|
||||
ReadCount = rwblock(s->sft_status, bp, n, XFR_READ);
|
||||
*err = SUCCESS;
|
||||
return ReadCount;
|
||||
}
|
||||
*err = SUCCESS;
|
||||
return 0;
|
||||
|
@ -445,8 +443,6 @@ UCOUNT DosWriteSft(sft FAR * s, UCOUNT n, const BYTE FAR * bp, COUNT FAR * err)
|
|||
else
|
||||
/* a block write */
|
||||
{
|
||||
COUNT rc;
|
||||
|
||||
/* /// Added for SHARE - Ron Cemer */
|
||||
if (IsShareInstalled())
|
||||
{
|
||||
|
@ -466,20 +462,10 @@ UCOUNT DosWriteSft(sft FAR * s, UCOUNT n, const BYTE FAR * bp, COUNT FAR * err)
|
|||
}
|
||||
/* /// 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);
|
||||
/* if (rc < SUCCESS) */
|
||||
if (rc == DE_ACCESS || /* -5 Access denied */
|
||||
rc == DE_INVLDHNDL) /* -6 Invalid handle */
|
||||
{
|
||||
*err = rc;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*err = SUCCESS;
|
||||
return WriteCount;
|
||||
}
|
||||
*err = SUCCESS;
|
||||
return WriteCount;
|
||||
}
|
||||
*err = SUCCESS;
|
||||
return 0;
|
||||
|
@ -1041,20 +1027,26 @@ BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc,
|
|||
|
||||
if (cdsp->cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
if (*nc == 0xffff)
|
||||
{
|
||||
/* Undoc DOS says, its not supported for
|
||||
network drives. so it's probably OK */
|
||||
/*printf("FatGetDrvData not yet supported over network drives\n"); */
|
||||
if (remote_getfree(cdsp, rg) != SUCCESS)
|
||||
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];
|
||||
*nc = (COUNT) rg[1];
|
||||
*bps = (COUNT) rg[2];
|
||||
*navc = (COUNT) rg[3];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1187,6 +1179,15 @@ COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s)
|
|||
|
||||
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 = ¤t_ldt->cdsCurrentPath[current_ldt->cdsJoinOffset];
|
||||
if (*cp == '\0')
|
||||
s[0] = '\0';
|
||||
|
@ -1361,6 +1362,7 @@ COUNT DosFindNext(void)
|
|||
fmemset(dta, 0, sizeof(dmatch));
|
||||
p = dta;
|
||||
dta = (BYTE FAR *) TempBuffer;
|
||||
current_ldt = &CDSp->cds_table[((dmatch *) TempBuffer)->dm_drive];
|
||||
rc = (((dmatch *) TempBuffer)->dm_drive & 0x80) ?
|
||||
remote_findnext((VOID FAR *) current_ldt) : dos_findnext();
|
||||
|
||||
|
|
29
kernel/dsk.c
29
kernel/dsk.c
|
@ -114,14 +114,12 @@ ULONG dsk_lasttime = 0;
|
|||
|
||||
STATIC VOID tmark(ddt *pddt)
|
||||
{
|
||||
ReadPCClock(&pddt->ddt_fh.ddt_lasttime);
|
||||
pddt->ddt_fh.ddt_lasttime = ReadPCClock();
|
||||
}
|
||||
|
||||
STATIC BOOL tdelay(ddt *pddt, ULONG ticks)
|
||||
{
|
||||
ULONG now;
|
||||
ReadPCClock(&now);
|
||||
return now - pddt->ddt_fh.ddt_lasttime >= ticks;
|
||||
return ReadPCClock() - pddt->ddt_fh.ddt_lasttime >= ticks;
|
||||
}
|
||||
|
||||
#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,
|
||||
blk_Media, blk_noerr, blk_nondr, blk_error;
|
||||
|
||||
STATIC WORD getbpb(ddt * pddt);
|
||||
#ifdef PROTO
|
||||
STATIC WORD dskerr(COUNT);
|
||||
#else
|
||||
|
@ -278,6 +277,16 @@ STATIC WORD mediachk(rqptr rp, ddt * pddt)
|
|||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -395,8 +404,7 @@ STATIC WORD getbpb(ddt * pddt)
|
|||
if (ret != 0)
|
||||
return (dskerr(ret));
|
||||
|
||||
getword(&((((BYTE *) & DiskTransferBuffer[BT_BPB]))[0]),
|
||||
&pbpbarray->bpb_nbyte);
|
||||
pbpbarray->bpb_nbyte = getword(&DiskTransferBuffer[BT_BPB]);
|
||||
|
||||
if (DiskTransferBuffer[0x1fe] != 0x55
|
||||
|| DiskTransferBuffer[0x1ff] != 0xaa || pbpbarray->bpb_nbyte != 512)
|
||||
|
@ -426,23 +434,20 @@ STATIC WORD getbpb(ddt * pddt)
|
|||
if (pbpbarray->bpb_nfsect != 0)
|
||||
{
|
||||
/* FAT16/FAT12 boot sector */
|
||||
getlong(&((((BYTE *) & DiskTransferBuffer[0x27])[0])),
|
||||
&pddt->ddt_serialno);
|
||||
pddt->ddt_serialno = getlong(&DiskTransferBuffer[0x27]);
|
||||
memcpy(pddt->ddt_volume, &DiskTransferBuffer[0x2B], 11);
|
||||
memcpy(pddt->ddt_fstype, &DiskTransferBuffer[0x36], 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FAT32 boot sector */
|
||||
getlong(&((((BYTE *) & DiskTransferBuffer[0x43])[0])),
|
||||
&pddt->ddt_serialno);
|
||||
pddt->ddt_serialno = getlong(&DiskTransferBuffer[0x43]);
|
||||
memcpy(pddt->ddt_volume, &DiskTransferBuffer[0x47], 11);
|
||||
memcpy(pddt->ddt_fstype, &DiskTransferBuffer[0x52], 8);
|
||||
pbpbarray->bpb_ndirent = 512;
|
||||
}
|
||||
#else
|
||||
getlong(&((((BYTE *) & DiskTransferBuffer[0x27])[0])),
|
||||
&pddt->ddt_serialno);
|
||||
pddt->ddt_serialno = getlong(&DiskTransferBuffer[0x27]);
|
||||
memcpy(pddt->ddt_volume, &DiskTransferBuffer[0x2B], 11);
|
||||
memcpy(pddt->ddt_fstype, &DiskTransferBuffer[0x36], 8);
|
||||
#endif
|
||||
|
|
655
kernel/fatfs.c
655
kernel/fatfs.c
|
@ -163,7 +163,6 @@ COUNT dos_close(COUNT fd)
|
|||
|
||||
if (fnp->f_flags.f_dmod)
|
||||
{
|
||||
fnp->f_dir.dir_attrib |= D_ARCHIVE;
|
||||
if (fnp->f_flags.f_ddate == FALSE)
|
||||
{
|
||||
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)
|
||||
{
|
||||
BOOL found = FALSE;
|
||||
|
||||
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)
|
||||
&& fcmp(fext, (BYTE *) fnp->f_dir.dir_ext, FEXT_SIZE)
|
||||
&& (fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE | attr)) == 0)
|
||||
{
|
||||
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)
|
||||
&& (fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE | attr)) == 0)
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Description.
|
||||
|
@ -836,7 +827,6 @@ STATIC BOOL find_free(f_node_ptr fnp)
|
|||
/* */
|
||||
date dos_getdate()
|
||||
{
|
||||
#ifndef NOTIME
|
||||
BYTE WeekDay, Month, MonthDay;
|
||||
COUNT Year;
|
||||
date Date;
|
||||
|
@ -848,12 +838,6 @@ date dos_getdate()
|
|||
(BYTE FAR *) & MonthDay, (COUNT FAR *) & Year);
|
||||
Date = DT_ENCODE(Month, MonthDay, Year - EPOCH_YEAR);
|
||||
return Date;
|
||||
|
||||
#else
|
||||
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/* */
|
||||
|
@ -861,7 +845,6 @@ date dos_getdate()
|
|||
/* */
|
||||
time dos_gettime()
|
||||
{
|
||||
#ifndef NOTIME
|
||||
BYTE Hour, Minute, Second, Hundredth;
|
||||
|
||||
/* First - get the system time set by either the user */
|
||||
|
@ -870,9 +853,6 @@ time dos_gettime()
|
|||
(BYTE FAR *) & Minute,
|
||||
(BYTE FAR *) & Second, (BYTE FAR *) & Hundredth);
|
||||
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 (!first_fat(fnp))
|
||||
{
|
||||
dir_close(fnp);
|
||||
return DE_HNDLDSKFULL;
|
||||
}
|
||||
}
|
||||
|
@ -1453,300 +1432,6 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode)
|
|||
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 */
|
||||
/* Proper OS's write zeros in between, but DOS just adds */
|
||||
/* garbage sectors, and lets the caller do the zero filling */
|
||||
|
@ -1827,24 +1512,90 @@ STATIC COUNT dos_extend(f_node_ptr fnp)
|
|||
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;
|
||||
struct buffer FAR *bp;
|
||||
REG struct buffer FAR *bp;
|
||||
UCOUNT xfr_cnt = 0;
|
||||
UCOUNT ret_cnt = 0;
|
||||
UWORD secsize;
|
||||
UCOUNT to_xfer = count;
|
||||
ULONG currentblock;
|
||||
|
||||
#ifdef DEBUG
|
||||
#if 0 /*DSK_DEBUG*/
|
||||
if (bDumpRdWrParms)
|
||||
{
|
||||
printf("writeblock: fd %02d buffer %04x:%04x count %d\n",
|
||||
fd, (COUNT) FP_SEG(buffer), (COUNT) FP_OFF(buffer), count);
|
||||
printf("rwblock: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);
|
||||
|
@ -1854,25 +1605,19 @@ UCOUNT writeblock(COUNT fd, const VOID FAR * buffer, UCOUNT count, COUNT * err)
|
|||
/* 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 have a valid mode for this fnode */
|
||||
if (fnp->f_mode != WRONLY && fnp->f_mode != RDWR)
|
||||
if (mode==XFR_WRITE)
|
||||
{
|
||||
*err = DE_INVLDACC;
|
||||
return 0;
|
||||
fnp->f_dir.dir_attrib |= D_ARCHIVE;
|
||||
fnp->f_flags.f_dmod = TRUE; /* mark file as modified */
|
||||
fnp->f_flags.f_ddate = FALSE; /* set date not valid any more */
|
||||
|
||||
if (dos_extend(fnp) != SUCCESS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
fnp->f_flags.f_dmod = TRUE; /* mark file as modified */
|
||||
fnp->f_flags.f_ddate = FALSE; /* set date not valid any more */
|
||||
|
||||
/* extend file from fnp->f_highwater to fnp->f_offset */
|
||||
*err = dos_extend(fnp);
|
||||
if (*err != SUCCESS)
|
||||
return 0;
|
||||
|
||||
|
||||
/* 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 */
|
||||
/* read with a count of zero is a nop). */
|
||||
|
@ -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 */
|
||||
/* Now done in dos_extend BO */
|
||||
/* remove all the following allocated clusters in shrink_file */
|
||||
fnp->f_highwater = fnp->f_offset;
|
||||
shrink_file(fnp);
|
||||
if (mode == XFR_WRITE)
|
||||
{
|
||||
fnp->f_highwater = fnp->f_offset;
|
||||
shrink_file(fnp);
|
||||
}
|
||||
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. */
|
||||
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 */
|
||||
/* done by updating the fnode's cluster, block (sector) and */
|
||||
/* byte offset so that read or write becomes a simple data move */
|
||||
/* 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) */
|
||||
/* 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 blockio block buffering scheme to simplify the */
|
||||
/* task. */
|
||||
else
|
||||
{
|
||||
#ifdef DISPLAY_GETBLOCK
|
||||
printf("writeblock: ");
|
||||
printf("rwblock: ");
|
||||
#endif
|
||||
if (map_cluster(fnp, XFR_WRITE) != SUCCESS)
|
||||
{
|
||||
*err = DE_HNDLDSKFULL;
|
||||
return ret_cnt;
|
||||
}
|
||||
if (map_cluster(fnp, mode) != SUCCESS)
|
||||
{
|
||||
return ret_cnt;
|
||||
}
|
||||
if (mode == XFR_WRITE)
|
||||
{
|
||||
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_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
|
||||
printf("write %d links; dir offset %ld, cluster %d\n",
|
||||
fnp->f_count, fnp->f_diroff, fnp->f_cluster);
|
||||
printf("r/w %d links; dir offset %ld, cluster %d, mode %x\n",
|
||||
fnp->f_count, fnp->f_diroff, fnp->f_cluster, mode);
|
||||
#endif
|
||||
|
||||
/* /// Moved xfr_cnt calculation from below so we can
|
||||
use it to help decide how to get the block:
|
||||
read-modify-write using getblock() if we are only
|
||||
going to write part of the block, or
|
||||
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 */
|
||||
/* /// BUG!!! Added conditional to only use getbuf() if we're going
|
||||
to write the entire block, which is faster because it does
|
||||
not first read the block from disk. However, if we are
|
||||
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))
|
||||
/* 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 (rwblock)\n");
|
||||
#endif
|
||||
if (bp == NULL) /* (struct buffer *)0 --> DS:0 !! */
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2016,32 +1788,51 @@ UCOUNT writeblock(COUNT fd, const VOID FAR * buffer, UCOUNT count, COUNT * err)
|
|||
/* requested transfer size, whichever is smaller. */
|
||||
/* Then compare to what is left, since we can transfer */
|
||||
/* 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);
|
||||
*/
|
||||
fmemcpy(&bp->b_buffer[fnp->f_boff], buffer, xfr_cnt);
|
||||
bp->b_flag |= BFR_DIRTY | BFR_VALID;
|
||||
if (!fnp->f_flags.f_ddir && mode == XFR_READ)
|
||||
xfr_cnt = (UWORD) min(xfr_cnt, fnp->f_highwater - fnp->f_offset);
|
||||
|
||||
if (xfr_cnt == sizeof(bp->b_buffer)) /* probably not used later */
|
||||
/* 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);
|
||||
bp->b_flag |= BFR_DIRTY | BFR_VALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
fmemcpy(buffer, &bp->b_buffer[fnp->f_boff], xfr_cnt);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* update pointers and counters */
|
||||
fnp->f_offset += xfr_cnt;
|
||||
|
||||
update_pointers:
|
||||
ret_cnt += xfr_cnt;
|
||||
to_xfer -= xfr_cnt;
|
||||
fnp->f_offset += xfr_cnt;
|
||||
buffer = add_far((VOID FAR *) buffer, (ULONG) xfr_cnt);
|
||||
if (fnp->f_offset > fnp->f_highwater)
|
||||
if (mode == XFR_WRITE)
|
||||
{
|
||||
fnp->f_highwater = fnp->f_offset;
|
||||
fnp->f_dir.dir_size = fnp->f_highwater;
|
||||
if (fnp->f_offset > fnp->f_highwater)
|
||||
{
|
||||
fnp->f_highwater = fnp->f_offset;
|
||||
fnp->f_dir.dir_size = fnp->f_highwater;
|
||||
}
|
||||
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
|
||||
}
|
||||
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
|
||||
}
|
||||
*err = SUCCESS;
|
||||
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)
|
||||
{
|
||||
BYTE status;
|
||||
|
||||
/* First test if anyone has changed the removable media */
|
||||
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:
|
||||
/* It was definitely not changed, so ignore it */
|
||||
|
@ -2392,10 +2186,15 @@ COUNT media_check(REG struct dpb FAR * dpbp)
|
|||
}
|
||||
}
|
||||
#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
|
||||
bpb_to_dpb(MediaReqHdr.r_bpptr, dpbp);
|
||||
#endif
|
||||
/* need to change to root directory if changed */
|
||||
if (status == M_CHANGED)
|
||||
CDSp->cds_table[dpbp->dpb_unit].cdsCurrentPath[3] = '\0';
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,21 +34,9 @@ static BYTE *RcsId =
|
|||
"$Id$";
|
||||
#endif
|
||||
|
||||
#ifdef PROTO
|
||||
UCOUNT link_fat12(struct dpb FAR *, CLUSTER, CLUSTER);
|
||||
UCOUNT link_fat16(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
|
||||
STATIC unsigned link_fat12(struct dpb FAR *, unsigned, unsigned);
|
||||
STATIC unsigned link_fat16(struct dpb FAR *, unsigned, unsigned);
|
||||
STATIC unsigned link_fat32(struct dpb FAR *, CLUSTER, CLUSTER);
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
|
@ -158,15 +146,15 @@ void write_fsinfo(struct dpb FAR * dpbp)
|
|||
/* 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)
|
||||
{
|
||||
UCOUNT res;
|
||||
unsigned res;
|
||||
|
||||
if (ISFAT12(dpbp))
|
||||
res = link_fat12(dpbp, Cluster1, Cluster2);
|
||||
res = link_fat12(dpbp, (unsigned)Cluster1, (unsigned)Cluster2);
|
||||
else if (ISFAT16(dpbp))
|
||||
res = link_fat16(dpbp, Cluster1, Cluster2);
|
||||
res = link_fat16(dpbp, (unsigned)Cluster1, (unsigned)Cluster2);
|
||||
#ifdef WITHFAT32
|
||||
else if (ISFAT32(dpbp))
|
||||
res = link_fat32(dpbp, Cluster1, Cluster2);
|
||||
|
@ -212,10 +200,10 @@ UCOUNT link_fat(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
|||
}
|
||||
|
||||
#ifdef WITHFAT32
|
||||
UCOUNT link_fat32(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
STATIC unsigned link_fat32(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
CLUSTER Cluster2)
|
||||
{
|
||||
UCOUNT idx;
|
||||
unsigned idx;
|
||||
struct buffer FAR *bp;
|
||||
|
||||
/* 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 */
|
||||
/* 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;
|
||||
|
||||
/* Return successful. */
|
||||
|
@ -240,10 +228,10 @@ UCOUNT link_fat32(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
|||
|
||||
#endif
|
||||
|
||||
STATIC UCOUNT link_fat16(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
CLUSTER Cluster2)
|
||||
STATIC unsigned link_fat16(struct dpb FAR * dpbp, unsigned Cluster1,
|
||||
unsigned Cluster2)
|
||||
{
|
||||
UCOUNT idx;
|
||||
unsigned idx;
|
||||
struct buffer FAR *bp;
|
||||
|
||||
/* 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 */
|
||||
/* 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 */
|
||||
/* 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;
|
||||
|
||||
/* Return successful. */
|
||||
|
@ -266,11 +254,11 @@ STATIC UCOUNT link_fat16(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
STATIC UCOUNT link_fat12(struct dpb FAR * dpbp, CLUSTER Cluster1,
|
||||
CLUSTER Cluster2)
|
||||
STATIC unsigned link_fat12(struct dpb FAR * dpbp, unsigned Cluster1,
|
||||
unsigned Cluster2)
|
||||
{
|
||||
REG UBYTE FAR *fbp0, FAR * fbp1;
|
||||
UCOUNT idx;
|
||||
unsigned idx;
|
||||
struct buffer FAR *bp, FAR * bp1;
|
||||
|
||||
/* 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 */
|
||||
/* 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 */
|
||||
/* it does, get the next block and use both to form the */
|
||||
/* the FAT word. Otherwise, just point to the next */
|
||||
/* block. */
|
||||
fbp0 = &bp->b_buffer[idx];
|
||||
fbp1 = fbp0 + 1;
|
||||
|
||||
if (idx >= dpbp->dpb_secsize - 1)
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/* Now pack the value in */
|
||||
|
@ -338,16 +326,15 @@ CLUSTER next_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
|
|||
{
|
||||
union {
|
||||
UBYTE bytes[2];
|
||||
UCOUNT word;
|
||||
unsigned word;
|
||||
} clusterbuff;
|
||||
|
||||
UCOUNT idx;
|
||||
unsigned 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 = ((((unsigned)ClusterNum << 1) + (unsigned)ClusterNum) >> 1) %
|
||||
dpbp->dpb_secsize;
|
||||
|
||||
clusterbuff.bytes[0] = bp->b_buffer[idx];
|
||||
|
||||
|
@ -395,26 +382,13 @@ CLUSTER next_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
|
|||
{
|
||||
UWORD res;
|
||||
|
||||
#ifndef I86
|
||||
UCOUNT idx;
|
||||
|
||||
/* form an index so that we can read the block as a */
|
||||
/* 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)
|
||||
return LONG_LAST_CLUSTER;
|
||||
if (res == BAD16)
|
||||
|
@ -427,11 +401,8 @@ CLUSTER next_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
|
|||
{
|
||||
UDWORD res;
|
||||
|
||||
res =
|
||||
*(UDWORD FAR *) & (bp->
|
||||
b_buffer[(UCOUNT)
|
||||
((ClusterNum * SIZEOF_CLST32) %
|
||||
dpbp->dpb_secsize)]);
|
||||
res = fgetlong(&bp->b_buffer[((unsigned)ClusterNum * SIZEOF_CLST32) %
|
||||
dpbp->dpb_secsize]);
|
||||
if (res > LONG_BAD)
|
||||
return LONG_LAST_CLUSTER;
|
||||
|
||||
|
|
|
@ -62,13 +62,27 @@ static dmatch Dmatch;
|
|||
VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
|
||||
UCOUNT FAR * nc, BYTE FAR ** mdp)
|
||||
{
|
||||
static BYTE mdb;
|
||||
UCOUNT navc;
|
||||
|
||||
/* get the data available from dpb */
|
||||
*nc = 0xffff; /* pass 0xffff to skip free count */
|
||||
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 */
|
||||
*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
|
||||
|
|
|
@ -399,7 +399,10 @@ VOID ASMCFUNC FAR CharMapSrvc(VOID);
|
|||
VOID ASMCFUNC FAR set_stack(VOID);
|
||||
VOID ASMCFUNC FAR restore_stack(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);
|
||||
COUNT ASMCFUNC kb_data(VOID);
|
||||
COUNT ASMCFUNC kb_input(VOID);
|
||||
|
@ -427,25 +430,25 @@ COUNT con();
|
|||
/* special word packing prototypes */
|
||||
/* */
|
||||
#ifdef NATIVE
|
||||
#define getlong(vp, lp) (*(LONG *)(lp)=*(LONG *)(vp))
|
||||
#define getword(vp, wp) (*(WORD *)(wp)=*(WORD *)(vp))
|
||||
#define getbyte(vp, bp) (*(BYTE *)(bp)=*(BYTE *)(vp))
|
||||
#define fgetlong(vp, lp) (*(LONG FAR *)(lp)=*(LONG FAR *)(vp))
|
||||
#define fgetword(vp, wp) (*(WORD FAR *)(wp)=*(WORD FAR *)(vp))
|
||||
#define fgetbyte(vp, bp) (*(BYTE FAR *)(bp)=*(BYTE FAR *)(vp))
|
||||
#define fputlong(lp, vp) (*(LONG FAR *)(vp)=*(LONG FAR *)(lp))
|
||||
#define fputword(wp, vp) (*(WORD FAR *)(vp)=*(WORD FAR *)(wp))
|
||||
#define fputbyte(bp, vp) (*(BYTE FAR *)(vp)=*(BYTE FAR *)(bp))
|
||||
#define getlong(vp) (*(UDWORD *)(vp))
|
||||
#define getword(vp) (*(UWORD *)(vp))
|
||||
#define getbyte(vp) (*(UBYTE *)(vp))
|
||||
#define fgetlong(vp) (*(UDWORD FAR *)(vp))
|
||||
#define fgetword(vp) (*(UWORD FAR *)(vp))
|
||||
#define fgetbyte(vp) (*(UBYTE FAR *)(vp))
|
||||
#define fputlong(vp, l) (*(UDWORD FAR *)(vp)=l)
|
||||
#define fputword(vp, w) (*(UWORD FAR *)(vp)=w)
|
||||
#define fputbyte(vp, b) (*(UBYTE FAR *)(vp)=b)
|
||||
#else
|
||||
#ifdef PROTO
|
||||
VOID getword(VOID *, WORD *);
|
||||
VOID getbyte(VOID *, BYTE *);
|
||||
VOID fgetlong(VOID FAR *, LONG FAR *);
|
||||
VOID fgetword(VOID FAR *, WORD FAR *);
|
||||
VOID fgetbyte(VOID FAR *, BYTE FAR *);
|
||||
VOID fputlong(LONG FAR *, VOID FAR *);
|
||||
VOID fputword(WORD FAR *, VOID FAR *);
|
||||
VOID fputbyte(BYTE FAR *, VOID FAR *);
|
||||
WORD getword(VOID *);
|
||||
BYTE getbyte(VOID *);
|
||||
LONG fgetlong(VOID FAR *);
|
||||
WORD fgetword(VOID FAR *);
|
||||
BYTE fgetbyte(VOID FAR *);
|
||||
VOID fputlong(VOID FAR *, UDWORD);
|
||||
VOID fputword(VOID FAR *, UWORD);
|
||||
VOID fputbyte(VOID FAR *, UBYTE);
|
||||
#else
|
||||
VOID getword();
|
||||
VOID getbyte();
|
||||
|
|
|
@ -42,6 +42,9 @@ extern COUNT DOSFAR nUnits;
|
|||
|
||||
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
|
||||
* Initial revision.
|
||||
|
@ -611,7 +614,7 @@ void DosDefinePartition(struct DriveParamS *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)
|
||||
printf(" Ext:%d", extendedPartNo);
|
||||
|
@ -1237,6 +1240,14 @@ void ReadAllPartitionTables(void)
|
|||
ddt FAR *pddt;
|
||||
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 */
|
||||
for (Unit = 0; Unit < nUnits; Unit++)
|
||||
{
|
||||
|
@ -1339,7 +1350,7 @@ void ReadAllPartitionTables(void)
|
|||
/* disk initialization: returns number of units */
|
||||
COUNT dsk_init()
|
||||
{
|
||||
printf(" - InitDisk\n");
|
||||
printf(" - InitDisk");
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@ static BYTE *RcsId =
|
|||
|
||||
UWORD init_oem(void)
|
||||
{
|
||||
UWORD top_k;
|
||||
UWORD top_k = 0;
|
||||
|
||||
#ifndef __TURBOC__
|
||||
asm
|
||||
|
|
|
@ -58,6 +58,10 @@ struct HugeSectorBlock {
|
|||
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 */
|
||||
/* variables needed for the rest of the handler. */
|
||||
/* this here works on the users stack !! and only very few functions
|
||||
|
@ -1325,7 +1329,6 @@ dispatch:
|
|||
/* UNDOCUMENTED: Double byte and korean tables */
|
||||
case 0x63:
|
||||
{
|
||||
static char *dbcsTable = "\0\0\0\0";
|
||||
r->DS = FP_SEG(dbcsTable);
|
||||
r->SI = FP_OFF(dbcsTable);
|
||||
#if 0
|
||||
|
|
|
@ -230,7 +230,9 @@ _nul_intr:
|
|||
pop es
|
||||
retf
|
||||
|
||||
|
||||
; floppy parameter table
|
||||
global _int1e_table
|
||||
_int1e_table: times 0eh db 0
|
||||
|
||||
;************************************************************
|
||||
; KERNEL FIXED DATA AREA
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "init-dat.h"
|
||||
|
||||
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"
|
||||
"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"
|
||||
|
@ -174,13 +174,13 @@ VOID ASMCFUNC FreeDOSmain(void)
|
|||
/* clear the Init BSS area (what normally the RTL does */
|
||||
memset(_ib_start, 0, _ib_end - _ib_start);
|
||||
|
||||
signon();
|
||||
init_kernel();
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Non-portable message kludge alert! */
|
||||
printf("KERNEL: Boot drive = %c\n", 'A' + BootDrive - 1);
|
||||
#endif
|
||||
signon();
|
||||
kernel();
|
||||
}
|
||||
|
||||
|
@ -361,9 +361,9 @@ STATIC VOID FsConfig(VOID)
|
|||
|
||||
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__)
|
||||
printf(" - TURBOC");
|
||||
|
@ -393,6 +393,7 @@ STATIC void kernel()
|
|||
int rc;
|
||||
|
||||
extern char MenuSelected;
|
||||
extern unsigned Menus;
|
||||
|
||||
BYTE master_env[32];
|
||||
char *masterenv_ptr = master_env;
|
||||
|
@ -405,9 +406,9 @@ STATIC void kernel()
|
|||
masterenv_ptr += sprintf(masterenv_ptr, "PATH=.");
|
||||
|
||||
/* 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;
|
||||
|
@ -463,8 +464,8 @@ STATIC void kernel()
|
|||
}
|
||||
|
||||
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
|
||||
printf("Process 0 starting: %s\n\n", Config.cfgInit);
|
||||
#endif
|
||||
|
|
|
@ -168,43 +168,43 @@ HEADERS=\
|
|||
# XXX: I generated these using `gcc -MM' and `sed', so they may not be
|
||||
# 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
|
||||
|
|
|
@ -286,8 +286,13 @@ stopIt: /* reached from FIRST_FIT on match */
|
|||
*/
|
||||
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 */
|
||||
p = ((mem_access_mode & (FIRST_FIT_UO | FIRST_FIT_U)) && uppermem_link
|
||||
&& 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
|
||||
block was found at all or a zero-length block only.
|
||||
Both is considered as a failure */
|
||||
return *size ? SUCCESS : DE_NOMEM;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -393,6 +393,7 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
|
|||
char c, *bufend = buf + (sizeof(buf) - 1);
|
||||
int gotAnyWildcards = 0;
|
||||
int seglen, copylen, state;
|
||||
int error = DE_PATHNOTFND;
|
||||
while ((*src) && (bufp < bufend))
|
||||
{
|
||||
/* Skip duplicated slashes. */
|
||||
|
@ -404,7 +405,12 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
|
|||
for (seglen = 0;; seglen++)
|
||||
{
|
||||
c = src[seglen];
|
||||
if ((c == '\0') || (c == '/') || (c == '\\'))
|
||||
if (c == '\0')
|
||||
{
|
||||
error = DE_FILENOTFND;
|
||||
break;
|
||||
}
|
||||
else if ((c == '/') || (c == '\\'))
|
||||
break;
|
||||
}
|
||||
if (seglen > 0)
|
||||
|
@ -426,7 +432,7 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
|
|||
else
|
||||
{
|
||||
/* .. in root dir illegal */
|
||||
return DE_PATHNOTFND;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -434,7 +440,7 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
|
|||
/* New segment. If any wildcards in previous
|
||||
segment(s), this is an invalid path. */
|
||||
if (gotAnyWildcards || src[0] == '.')
|
||||
return DE_PATHNOTFND;
|
||||
return error;
|
||||
/* Append current path segment to result. */
|
||||
*(bufp++) = '\\';
|
||||
if (bufp >= bufend)
|
||||
|
@ -456,8 +462,6 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
|
|||
break;
|
||||
copylen++;
|
||||
}
|
||||
copylen = 0;
|
||||
state = 1; /* Go wait for dot */
|
||||
break;
|
||||
}
|
||||
if (c == '.')
|
||||
|
@ -465,26 +469,17 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
|
|||
if (src[i + 1] != '.' && i + 1 < seglen)
|
||||
*(bufp++) = '.';
|
||||
copylen = 0;
|
||||
state = 2; /* Copy extension next */
|
||||
state = 1; /* Copy extension next */
|
||||
break;
|
||||
}
|
||||
*(bufp++) = c;
|
||||
copylen++;
|
||||
if (copylen >= FNAME_SIZE)
|
||||
if (copylen < FNAME_SIZE)
|
||||
{
|
||||
copylen = 0;
|
||||
state = 1; /* Go wait for dot */
|
||||
*(bufp++) = c;
|
||||
copylen++;
|
||||
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 */
|
||||
case 1: /* Copying extension */
|
||||
if (c == '*')
|
||||
{
|
||||
while (copylen < FEXT_SIZE)
|
||||
|
@ -494,20 +489,13 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
|
|||
break;
|
||||
copylen++;
|
||||
}
|
||||
i = seglen; /* Done with segment */
|
||||
break;
|
||||
}
|
||||
if (c == '.')
|
||||
return error;
|
||||
if (copylen < FEXT_SIZE)
|
||||
{
|
||||
i = seglen; /* Done with segment */
|
||||
break;
|
||||
}
|
||||
*(bufp++) = c;
|
||||
copylen++;
|
||||
if (copylen >= FEXT_SIZE)
|
||||
{
|
||||
i = seglen; /* Done with segment */
|
||||
break;
|
||||
*(bufp++) = c;
|
||||
copylen++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
21
kernel/prf.c
21
kernel/prf.c
|
@ -366,15 +366,20 @@ COUNT do_printf(CONST BYTE * fmt, BYTE ** arg)
|
|||
|
||||
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("|");
|
||||
int loop, start = 0;
|
||||
printf("%s", title);
|
||||
if (numBytes > 16)
|
||||
printf("\n");
|
||||
|
||||
for (loop = 0; loop < numBytes; loop++)
|
||||
printf("%c", p[loop] < 0x20 ? '.' : p[loop]);
|
||||
printf("\n");
|
||||
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("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
|
|
@ -177,7 +177,7 @@ _spawn_int23:
|
|||
;; complete the jump to INT-23 via RETF and restore 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
|
||||
;; on the stack
|
||||
retf
|
||||
|
|
|
@ -158,8 +158,7 @@ BOOL dos_setfsize(COUNT fd, LONG size);
|
|||
COUNT dos_mkdir(BYTE * dir);
|
||||
BOOL last_link(f_node_ptr fnp);
|
||||
COUNT map_cluster(REG f_node_ptr fnp, COUNT mode);
|
||||
UCOUNT readblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err);
|
||||
UCOUNT writeblock(COUNT fd, const VOID FAR * buffer, UCOUNT count, COUNT * err);
|
||||
UCOUNT rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode);
|
||||
COUNT dos_read(COUNT fd, 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);
|
||||
|
@ -184,16 +183,7 @@ 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);
|
||||
|
|
315
kernel/sysclk.c
315
kernel/sysclk.c
|
@ -30,61 +30,37 @@
|
|||
#include "globals.h"
|
||||
|
||||
#ifdef VERSION_STRINGS
|
||||
static BYTE *RcsId =
|
||||
static char *RcsId =
|
||||
"$Id$";
|
||||
#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!!!! */
|
||||
/* */
|
||||
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;
|
||||
typedef UDWORD ticks_t;
|
||||
|
||||
BOOL ASMCFUNC ReadATClock(BYTE *, BYTE *, BYTE *, BYTE *);
|
||||
|
||||
STATIC COUNT BcdToByte(COUNT x)
|
||||
STATIC int ByteToBcd(int 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)
|
||||
{
|
||||
COUNT c;
|
||||
const UWORD *pdays;
|
||||
BYTE bcd_days[4], bcd_minutes, bcd_hours, bcd_seconds;
|
||||
ULONG Ticks;
|
||||
UWORD Month, Day, Year;
|
||||
|
||||
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 (!ReadATClock(bcd_days, &bcd_hours, &bcd_minutes, &bcd_seconds))
|
||||
{
|
||||
ticks_t seconds;
|
||||
|
||||
DaysSinceEpoch =
|
||||
DaysFromYearMonthDay(100 * BcdToByte(bcd_days[3]) +
|
||||
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
|
||||
* 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
|
||||
* second is not exactly 18.2, but rather 1193180 / 65536
|
||||
* where 1193180 = 0x1234dc
|
||||
* The timer interrupt updates the midnight flag when the tick count
|
||||
* reaches 0x1800b0 -- ror4.
|
||||
*/
|
||||
Ticks = (3600ul * BcdToByte(bcd_hours) +
|
||||
60ul * BcdToByte(bcd_minutes) +
|
||||
BcdToByte(bcd_seconds)) * 19663ul / 1080ul;
|
||||
WritePCClock(Ticks);
|
||||
|
||||
seconds =
|
||||
60 * (ticks_t)(60 * BcdToByte(bcd_hours) + BcdToByte(bcd_minutes)) +
|
||||
BcdToByte(bcd_seconds);
|
||||
WritePCClock(seconds * 0x12 + ((seconds * 0x34dc) >> 16));
|
||||
}
|
||||
/* rp->r_endaddr = device_end(); not needed - bart */
|
||||
rp->r_nunits = 0;
|
||||
|
@ -117,170 +95,86 @@ WORD ASMCFUNC FAR clk_driver(rqptr rp)
|
|||
|
||||
case C_INPUT:
|
||||
{
|
||||
ULONG remainder, hs;
|
||||
ReadPCClock(&Ticks);
|
||||
struct ClockRecord clk;
|
||||
int tmp;
|
||||
ticks_t ticks;
|
||||
|
||||
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;
|
||||
|
||||
/* The scaling factor is now
|
||||
6553600/1193180 = 327680/59659 = 65536*5/59659 */
|
||||
|
||||
ticks = 5 * ReadPCClock();
|
||||
ticks = ((ticks / 59659u) << 16) + ((ticks % 59659u) << 16) / 59659u;
|
||||
|
||||
tmp = (int)(ticks / 6000);
|
||||
clk.clkHours = tmp / 60;
|
||||
clk.clkMinutes = tmp % 60;
|
||||
|
||||
Ticks -= q1 * 19663ul;
|
||||
hs = q1 * 108000ul;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Now Ticks < 19663, so Ticks * 108000 < 2123604000 < ULONG_MAX.
|
||||
* *phew* -- ror4
|
||||
*/
|
||||
hs += Ticks * 108000ul / 19663ul;
|
||||
clk.clkHours = hs / 360000ul;
|
||||
remainder = hs % 360000ul;
|
||||
clk.clkMinutes = remainder / 6000ul;
|
||||
remainder %= 6000ul;
|
||||
clk.clkSeconds = remainder / 100ul;
|
||||
clk.clkHundredths = remainder % 100ul;
|
||||
}
|
||||
|
||||
fmemcpy(rp->r_trans, &clk,
|
||||
min(sizeof(struct ClockRecord), rp->r_count));
|
||||
tmp = (int)(ticks % 6000);
|
||||
clk.clkSeconds = tmp / 100;
|
||||
clk.clkHundredths = tmp % 100;
|
||||
|
||||
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));
|
||||
fmemcpy(&clk, rp->r_trans, rp->r_count);
|
||||
|
||||
/* Set PC Clock first */
|
||||
DaysSinceEpoch = clk.clkDays;
|
||||
{
|
||||
ULONG hs;
|
||||
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;
|
||||
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));
|
||||
fmemcpy(&clk, rp->r_trans, rp->r_count);
|
||||
|
||||
hs -= q1 * 108000ul;
|
||||
Ticks = q1 * 19663ul;
|
||||
/* Set PC Clock first */
|
||||
DaysSinceEpoch = clk.clkDays;
|
||||
hs = 6000 * (ticks_t)(60 * clk.clkHours + clk.clkMinutes) +
|
||||
(ticks_t)(100 * clk.clkSeconds + clk.clkHundredths);
|
||||
|
||||
/* The scaling factor is now
|
||||
1193180/6553600 = 59659/327680 = 59659/65536/5 */
|
||||
|
||||
Ticks = ((hs >> 16) * 59659u + (((hs & 0xffff) * 59659u) >> 16)) / 5;
|
||||
|
||||
WritePCClock(Ticks);
|
||||
|
||||
/* 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;;)
|
||||
{
|
||||
pdays = is_leap_year_monthdays(Year);
|
||||
if (c >= pdays[12])
|
||||
{
|
||||
++Year;
|
||||
c -= pdays[12];
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* c contains the days left and count the number of */
|
||||
/* days for that year. Use this to index the table. */
|
||||
for (Month = 1; Month < 13; ++Month)
|
||||
{
|
||||
if (pdays[Month] > c)
|
||||
{
|
||||
Day = c - pdays[Month - 1] + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Ticks += hs * 19663ul / 108000ul;
|
||||
DayToBcd(bcd_days, Month, Day, Year);
|
||||
bcd_minutes = ByteToBcd(clk.clkMinutes);
|
||||
bcd_hours = ByteToBcd(clk.clkHours);
|
||||
bcd_seconds = ByteToBcd(clk.clkSeconds);
|
||||
WriteATClock(bcd_days, bcd_hours, bcd_minutes, bcd_seconds);
|
||||
}
|
||||
WritePCClock(Ticks);
|
||||
|
||||
/* 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;;)
|
||||
{
|
||||
pdays = is_leap_year_monthdays(Year);
|
||||
if (c >= pdays[12])
|
||||
{
|
||||
++Year;
|
||||
c -= pdays[12];
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* c contains the days left and count the number of */
|
||||
/* days for that year. Use this to index the table. */
|
||||
for (Month = 1; Month < 13; ++Month)
|
||||
{
|
||||
if (pdays[Month] > c)
|
||||
{
|
||||
Day = c - pdays[Month - 1] + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DayToBcd((BYTE *) bcd_days, &Month, &Day, &Year);
|
||||
bcd_minutes = ByteToBcd(clk.clkMinutes);
|
||||
bcd_hours = ByteToBcd(clk.clkHours);
|
||||
bcd_seconds = ByteToBcd(clk.clkSeconds);
|
||||
WriteATClock(bcd_days, bcd_hours, bcd_minutes, bcd_seconds);
|
||||
return S_DONE;
|
||||
|
||||
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"
|
||||
*
|
||||
|
|
|
@ -36,90 +36,89 @@ static BYTE *syspackRcsId =
|
|||
#endif
|
||||
|
||||
#ifdef NONNATIVE
|
||||
VOID getlong(REG VOID * vp, LONG * lp)
|
||||
UDWORD getlong(REG VOID * vp)
|
||||
{
|
||||
*lp = (((BYTE *) vp)[0] & 0xff) +
|
||||
((((BYTE *) vp)[1] & 0xff) << 8) +
|
||||
((((BYTE *) vp)[2] & 0xff) << 16) +
|
||||
((((BYTE *) vp)[3] & 0xff) << 24);
|
||||
return (((UBYTE *) vp)[0] & 0xff) +
|
||||
((((UBYTE *) vp)[1] & 0xff) << 8) +
|
||||
((((UBYTE *) vp)[2] & 0xff) << 16) +
|
||||
((((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 =
|
||||
(((BYTE FAR *) vp)[0] & 0xff) + ((((BYTE FAR *) vp)[1] & 0xff) << 8);
|
||||
return (((UBYTE FAR *) vp)[0] & 0xff) + ((((UBYTE 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) +
|
||||
((((BYTE *) vp)[1] & 0xff) << 8) +
|
||||
((((BYTE *) vp)[2] & 0xff) << 16) +
|
||||
((((BYTE *) vp)[3] & 0xff) << 24);
|
||||
return (((UBYTE *) vp)[0] & 0xff) +
|
||||
((((UBYTE *) vp)[1] & 0xff) << 8) +
|
||||
((((UBYTE *) vp)[2] & 0xff) << 16) +
|
||||
((((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[1] = (*lp >> 8) & 0xff;
|
||||
bp[2] = (*lp >> 16) & 0xff;
|
||||
bp[3] = (*lp >> 24) & 0xff;
|
||||
bp[0] = l & 0xff;
|
||||
bp[1] = (l >> 8) & 0xff;
|
||||
bp[2] = (l >> 16) & 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[1] = (*wp >> 8) & 0xff;
|
||||
bp[0] = w & 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_ext, &vp[DIR_EXT], FEXT_SIZE);
|
||||
fgetbyte(&vp[DIR_ATTRIB], (BYTE FAR *) & dp->dir_attrib);
|
||||
fgetword(&vp[DIR_TIME], (WORD FAR *) & dp->dir_time);
|
||||
fgetword(&vp[DIR_DATE], (WORD FAR *) & dp->dir_date);
|
||||
fgetword(&vp[DIR_START], (WORD FAR *) & dp->dir_start);
|
||||
fgetlong(&vp[DIR_SIZE], (LONG FAR *) & dp->dir_size);
|
||||
dp->dir_attrib = fgetbyte(&vp[DIR_ATTRIB]);
|
||||
dp->dir_time = fgetword(&vp[DIR_TIME]);
|
||||
dp->dir_date = fgetword(&vp[DIR_DATE]);
|
||||
dp->dir_start = fgetword(&vp[DIR_START]);
|
||||
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 BYTE FAR *p;
|
||||
|
||||
fmemcpy(&vp[DIR_NAME], dp->dir_name, FNAME_SIZE);
|
||||
fmemcpy(&vp[DIR_EXT], dp->dir_ext, FEXT_SIZE);
|
||||
fputbyte((BYTE FAR *) & dp->dir_attrib, &vp[DIR_ATTRIB]);
|
||||
fputword((WORD FAR *) & dp->dir_time, &vp[DIR_TIME]);
|
||||
fputword((WORD FAR *) & dp->dir_date, &vp[DIR_DATE]);
|
||||
fputword((WORD FAR *) & dp->dir_start, &vp[DIR_START]);
|
||||
fputlong((LONG FAR *) & dp->dir_size, &vp[DIR_SIZE]);
|
||||
for (i = 0, p = (BYTE FAR *) & vp[DIR_RESERVED]; i < 10; i++)
|
||||
fputbyte(&vp[DIR_ATTRIB], dp->dir_attrib);
|
||||
fputword(&vp[DIR_TIME], dp->dir_time);
|
||||
fputword(&vp[DIR_DATE], dp->dir_date);
|
||||
fputword(&vp[DIR_START], dp->dir_start);
|
||||
fputlong(&vp[DIR_SIZE], dp->dir_size);
|
||||
for (i = 0, p = (UBYTE FAR *) & vp[DIR_RESERVED]; i < 10; i++)
|
||||
*p++ = NULL;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
BYTE Month, DayOfMonth, DayOfWeek;
|
||||
COUNT Year;
|
||||
|
||||
DosGetDate((BYTE FAR *) & DayOfWeek, (BYTE FAR *) & Month,
|
||||
(BYTE FAR *) & DayOfMonth, (COUNT FAR *) & Year);
|
||||
/* for ClkRecord.clkDays */
|
||||
ExecuteClockDriverRequest(C_INPUT);
|
||||
|
||||
ClkRecord.clkHours = h;
|
||||
ClkRecord.clkMinutes = m;
|
||||
ClkRecord.clkSeconds = s;
|
||||
ClkRecord.clkHundredths = hd;
|
||||
|
||||
ClkRecord.clkDays = DaysFromYearMonthDay(Year, Month, DayOfMonth);
|
||||
|
||||
ExecuteClockDriverRequest(C_OUTPUT);
|
||||
|
||||
if (ClkReqHdr.r_status & S_ERROR)
|
||||
|
@ -172,10 +167,7 @@ UWORD Month, DayOfMonth, Year;
|
|||
|| DayOfMonth < 1 || DayOfMonth > pdays[Month] - pdays[Month - 1])
|
||||
return DE_INVLDDATA;
|
||||
|
||||
DosGetTime((BYTE FAR *) & ClkRecord.clkHours,
|
||||
(BYTE FAR *) & ClkRecord.clkMinutes,
|
||||
(BYTE FAR *) & ClkRecord.clkSeconds,
|
||||
(BYTE FAR *) & ClkRecord.clkHundredths);
|
||||
ExecuteClockDriverRequest(C_INPUT);
|
||||
|
||||
ClkRecord.clkDays = DaysFromYearMonthDay(Year, Month, DayOfMonth);
|
||||
|
||||
|
|
|
@ -241,8 +241,10 @@ VOID new_psp(psp FAR * p, int psize)
|
|||
|
||||
/* first command line argument */
|
||||
p->ps_fcb1.fcb_drive = 0;
|
||||
fmemset(p->ps_fcb1.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE);
|
||||
/* second command line argument */
|
||||
p->ps_fcb2.fcb_drive = 0;
|
||||
fmemset(p->ps_fcb2.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE);
|
||||
|
||||
/* local command line */
|
||||
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 */
|
||||
fmemcpy(psp->ps_cmd, exb->exec.cmd_line->ctBuffer, 127);
|
||||
fmemcpy(&psp->ps_fcb1, exb->exec.fcb_1, 16);
|
||||
fmemcpy(&psp->ps_fcb2, exb->exec.fcb_2, 16);
|
||||
if (FP_OFF(exb->exec.fcb_1) != 0xffff)
|
||||
{
|
||||
fmemcpy(&psp->ps_fcb1, exb->exec.fcb_1, 16);
|
||||
fmemcpy(&psp->ps_fcb2, exb->exec.fcb_2, 16);
|
||||
}
|
||||
psp->ps_cmd_count = exb->exec.cmd_line->ctCount;
|
||||
|
||||
/* identify the mcb as this functions' */
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
|
||||
# Use these for WATCOM 11.0c
|
||||
COMPILERPATH=$(WATCOM)
|
||||
COMPILERBIN=$(WATCOM)\binw
|
||||
CC=$(COMPILERBIN)\wcl
|
||||
CC=wcl
|
||||
INCLUDEPATH=$(COMPILERPATH)\H
|
||||
INCLUDE=$(COMPILERPATH)\h
|
||||
EDPATH=$(COMPILERPATH)\EDDAT
|
||||
|
@ -17,12 +16,12 @@ TARGETOPT=-0
|
|||
!endif
|
||||
|
||||
LIBPATH=$(COMPILERPATH)\lib286
|
||||
LIBUTIL=$(COMPILERBIN)\wlib
|
||||
LIBUTIL=wlib
|
||||
LIBPLUS=
|
||||
LIBTERM=
|
||||
|
||||
CFLAGST=-zp=1 -mt -os -s -we -e=3 -w=2
|
||||
CFLAGSC=-zp=1 -mc -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 -wx
|
||||
|
||||
TARGET=KWC
|
||||
|
||||
|
@ -60,7 +59,7 @@ MATH_INSERT= +i4d +i4m
|
|||
# -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
|
||||
CFLAGS=$(ALLCFLAGS) -nt=HMA_TEXT -nc=HMA -g=HGROUP
|
||||
INITPATCH=..\utils\patchobj __U4D=_IU4D __U4M=_IU4M
|
||||
|
|
|
@ -28,6 +28,7 @@ extern int CDECL printf(CONST BYTE * fmt, ...);
|
|||
extern int CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...);
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
unsigned _dos_close(int handle);
|
||||
#define close _dos_close
|
||||
#define SEEK_SET 0
|
||||
int open(const char *pathname, int flags, ...);
|
||||
|
|
|
@ -66,6 +66,7 @@ extern WORD CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...);
|
|||
#ifndef __WATCOMC__
|
||||
#include <io.h>
|
||||
#else
|
||||
int unlink(const char *pathname);
|
||||
/* some non-conforming functions to make the executable smaller */
|
||||
int open(const char *pathname, int flags, ...)
|
||||
{
|
||||
|
@ -819,7 +820,7 @@ BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file)
|
|||
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
|
||||
Changed so if no source given or only source drive (no path)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
|
Loading…
Reference in New Issue