diff --git a/build.bat b/build.bat index e647488..6c353f6 100644 --- a/build.bat +++ b/build.bat @@ -113,7 +113,7 @@ cd ..\kernel %MAKE% production if errorlevel 1 goto abort -cd.. +cd .. :- if you like, put some finalizing commands (like copy to floppy) :- into build2.bat diff --git a/docs/history.txt b/docs/history.txt index df9ea83..d3c2bc1 100644 --- a/docs/history.txt +++ b/docs/history.txt @@ -8,6 +8,8 @@ * cleaned up midnight flag, dates * tmark() and friends are floppy specific and implemented in C instead of ASM (parts by Bart) + * DMA boundary checking gives the right number of sectors if + the start sector is 512-bytes-aligned. + Changes Victor * lfn fixes * FAT32 fixes @@ -36,7 +38,10 @@ recognize FF8-FFF as FAT12 ending (was only FFF) (bug #1021) * avoid using LIB when linking the kernel by echo-ing to a linker resource file. Use a batch file to bypass Borlands Make 2.0 - unwillingness to redirect stdout. + unwillingness to redirect stdout. + * UMB variable clean-up + * use of "const" for constant global variables + * reduced size of Watcom-compiled SYS binary 2001 Nov 18 - Build 2025c -------- Bart Oldeman (bart@dosemu.org) + Changes Bart diff --git a/drivers/devend.asm b/drivers/devend.asm deleted file mode 100644 index 8b12b8c..0000000 --- a/drivers/devend.asm +++ /dev/null @@ -1,70 +0,0 @@ -; -; File: -; devend.asm -; Description: -; get end of device driver primitive -; -; Copyright (c) 1995 -; Pasquale J. Villani -; All Rights Reserved -; -; This file is part of DOS-C. -; -; DOS-C is free software; you can redistribute it and/or -; modify it under the terms of the GNU General Public License -; as published by the Free Software Foundation; either version -; 2, or (at your option) any later version. -; -; DOS-C is distributed in the hope that it will be useful, but -; WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See -; the GNU General Public License for more details. -; -; You should have received a copy of the GNU General Public -; License along with DOS-C; see the file COPYING. If not, -; write to the Free Software Foundation, 675 Mass Ave, -; Cambridge, MA 02139, USA. -; -; $Header$ -; - - %include "..\kernel\segs.inc" - - - extern __bssend:wrt DGROUP - -segment HMA_TEXT - - global _device_end - -_device_end: - mov ax,__bssend - mov dx,DGROUP - ret - -; Log: devend.asm,v -; Revision 1.3 1999/08/10 17:21:08 jprice -; ror4 2011-01 patch -; -; Revision 1.2 1999/03/29 17:08:31 jprice -; ror4 changes -; -; Revision 1.1.1.1 1999/03/29 15:40:22 jprice -; New version without IPL.SYS -; -; Revision 1.2 1999/01/22 04:16:39 jprice -; Formating -; -; Revision 1.1.1.1 1999/01/20 05:51:00 jprice -; Imported sources -; -; -; Rev 1.2 29 Aug 1996 13:07:14 patv -;Bug fixes for v0.91b -; -; Rev 1.1 01 Sep 1995 18:50:34 patv -;Initial GPL release. -; -; Rev 1.0 02 Jul 1995 7:56:50 patv -;Initial revision. -; diff --git a/hdr/portab.h b/hdr/portab.h index 0bcb781..e8d4ea8 100644 --- a/hdr/portab.h +++ b/hdr/portab.h @@ -197,12 +197,12 @@ typedef signed long LONG; #ifdef I86 #ifndef MK_FP #ifdef __WATCOMC__ -#define MK_FP(__s,__o) (((unsigned short)(__s)):>((void __near *)(__o))) +#define MK_FP(seg,ofs) (((UWORD)(seg)):>((VOID *)(ofs))) #else #define MK_FP(seg,ofs) ((VOID far *)(((ULONG)(seg)<<16)|(UWORD)(ofs))) #endif -#define FP_SEG(fp) ((UWORD)((ULONG)(VOID FAR *)(fp)>>16)) -#define FP_OFF(fp) ((UWORD)(fp)) +#define FP_SEG(fp) ((unsigned)(UWORD)((ULONG)(VOID FAR *)(fp)>>16)) +#define FP_OFF(fp) ((unsigned)(UWORD)(fp)) #endif #endif diff --git a/kernel/config.c b/kernel/config.c index 16a2456..f05ccce 100644 --- a/kernel/config.c +++ b/kernel/config.c @@ -84,10 +84,10 @@ extern BYTE DOSFAR ASM VgaSet, DOSFAR _HMATextAvailable, /* first byte of ava DOSFAR ASM switchar, DOSFAR _InitTextStart, /* first available byte of ram */ DOSFAR ReturnAnyDosVersionExpected; -extern UWORD DOSFAR ASM ram_top, /* How much ram in Kbytes */ - - DOSFAR ASM UMB_top, - DOSFAR ASM umb_start, DOSFAR ASM uppermem_root, DOSFAR ASM LoL_nbuffers; +extern UWORD DOSFAR ASM uppermem_root, DOSFAR ASM LoL_nbuffers; + +UWORD umb_start = 0, UMB_top = 0; +UWORD ram_top = 0; /* How much ram in Kbytes */ struct config Config = { NUMBUFF, @@ -446,7 +446,7 @@ VOID configDone(VOID) { /* make last block normal with SC for the devices */ - mumcb_init(uppermem_root, umr_new - uppermem_root - 1); + mumcb_init(umb_start, umr_new - umb_start - 1); zumcb_init(umr_new, (umb_start + UMB_top) - umr_new - 1); upBase += 16; @@ -623,7 +623,7 @@ VOID DoConfig(int pass) umb_start = umb_seg; /* reset root */ - uppermem_root = umb_seg; + uppermem_root = ram_top * 64 - 1; /* setup the real mcb for the devicehigh block */ zumcb_init(umb_seg, UMB_top - 1); upBase += 16; @@ -1408,12 +1408,8 @@ STATIC VOID mcb_init(UCOUNT seg, UWORD size) mcbp->m_type = MCB_LAST; mcbp->m_psp = FREE_PSP; -/* if(UmbState == 1)*/ + mcbp->m_size = (UmbState > 0 ? size - 1 : size); - mcbp->m_size = (size - 1); -/* - mcbp->m_size = size; -*/ for (i = 0; i < 8; i++) mcbp->m_name[i] = '\0'; mem_access_mode = FIRST_FIT; diff --git a/kernel/dosnames.c b/kernel/dosnames.c index eceff6c..3a67d99 100644 --- a/kernel/dosnames.c +++ b/kernel/dosnames.c @@ -37,7 +37,7 @@ static BYTE *dosnamesRcsId = #include "globals.h" -char _DirWildNameChars[] = "*?./\\\"[]:|<>+=;,"; +const char _DirWildNameChars[] = "*?./\\\"[]:|<>+=;,"; #define PathSep(c) ((c)=='/'||(c)=='\\') #define DriveChar(c) (((c)>='A'&&(c)<='Z')||((c)>='a'&&(c)<='z')) diff --git a/kernel/dsk.c b/kernel/dsk.c index dbdc2fa..7ee2816 100644 --- a/kernel/dsk.c +++ b/kernel/dsk.c @@ -151,7 +151,7 @@ STATIC WORD dskerr(); /* the function dispatch table */ /* */ -static dsk_proc (*dispatch[NENTRY]) = +static dsk_proc * const dispatch[NENTRY] = { _dsk_init, /* Initialize */ mediachk, /* Media Check */ @@ -893,18 +893,12 @@ STATIC void LBA_to_CHS(struct CHS *chs, ULONG LBA_address, ddt * pddt) STATIC unsigned DMA_max_transfer(void FAR * buffer, unsigned count) { - UWORD utemp = (((UWORD) FP_SEG(buffer) << 4) + FP_OFF(buffer)); + unsigned dma_off = (UWORD)((FP_SEG(buffer) << 4) + FP_OFF(buffer)); + unsigned sectors_to_dma_boundary = (dma_off == 0 ? + 0xffff / SEC_SIZE : + (UWORD)(-dma_off) / SEC_SIZE); -#define SEC_SHIFT 9 /* = 0x200 = 512 */ - - utemp >>= SEC_SHIFT; - - if (count > (0xffff >> SEC_SHIFT) - utemp) - { - count = (0xffff >> SEC_SHIFT) - utemp; - } - - return count; + return min(count, sectors_to_dma_boundary); } /* @@ -968,12 +962,8 @@ STATIC int LBA_Transfer(ddt * pddt, UWORD mode, VOID FAR * buffer, for (; totaltodo != 0;) { - count = totaltodo; - - count = min(count, 0x7f); - /* avoid overflowing 64K DMA boundary */ - count = DMA_max_transfer(buffer, count); + count = DMA_max_transfer(buffer, totaltodo); if (FP_SEG(buffer) >= 0xa000 || count == 0) { diff --git a/kernel/globals.h b/kernel/globals.h index 54bedec..b780284 100644 --- a/kernel/globals.h +++ b/kernel/globals.h @@ -175,7 +175,6 @@ FAR ASM clk_dev, /* Clock device driver */ FAR ASM prn_dev, /* Generic printer device driver */ FAR ASM aux_dev, /* Generic aux device driver */ FAR ASM blk_dev; /* Block device (Disk) driver */ -extern UWORD ASM ram_top; /* How much ram in Kbytes */ extern COUNT *error_tos, /* error stack */ disk_api_tos, /* API handler stack - disk fns */ char_api_tos; /* API handler stack - char fns */ @@ -233,7 +232,7 @@ GLOBAL BYTE copyright[] = #endif -GLOBAL BYTE os_release[] +GLOBAL const BYTE os_release[] #ifdef MAIN #if 0 = "DOS-C version %d.%d Beta %d [FreeDOS Release] (Build %d).\n" @@ -260,7 +259,7 @@ extern BYTE ASM net_set_count; extern BYTE ASM NetDelay, ASM NetRetry; extern UWORD ASM first_mcb, /* Start of user memory */ - ASM UMB_top, ASM umb_start, ASM uppermem_root; /* Start of umb chain ? */ + ASM uppermem_root; /* Start of umb chain (usually 9fff) */ extern sfttbl FAR * ASM sfthead; /* System File Table head */ extern struct dhdr FAR * ASM clock, /* CLOCK$ device */ diff --git a/kernel/init-mod.h b/kernel/init-mod.h index 1705c53..8312106 100644 --- a/kernel/init-mod.h +++ b/kernel/init-mod.h @@ -161,7 +161,7 @@ VOID ASMCFUNC init_stacks(VOID FAR * stack_base, COUNT nStacks, /* inthndlr.c */ VOID ASMCFUNC FAR int21_entry(iregs UserRegs); VOID ASMCFUNC int21_service(iregs far * r); -VOID CDECL FAR int0_handler(void); +VOID ASMCFUNC FAR int0_handler(void); VOID ASMCFUNC FAR int6_handler(void); VOID ASMCFUNC FAR empty_handler(void); VOID ASMCFUNC FAR got_cbreak(void); /* procsupt.asm */ @@ -184,8 +184,8 @@ BOOL init_device(struct dhdr FAR * dhp, BYTE FAR * cmdLine, VOID init_fatal(BYTE * err_msg); /* prf.c */ -WORD ASMCFUNC init_printf(CONST BYTE * fmt, ...); -WORD ASMCFUNC init_sprintf(BYTE * buff, CONST BYTE * fmt, ...); +WORD CDECL init_printf(CONST BYTE * fmt, ...); +WORD CDECL init_sprintf(BYTE * buff, CONST BYTE * fmt, ...); void MoveKernel(unsigned NewKernelSegment); extern WORD HMAFree; /* first byte in HMA not yet used */ diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index a0f0a73..73744bc 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -1327,11 +1327,9 @@ dispatch: /* UNDOCUMENTED: Double byte and korean tables */ case 0x63: { - static char dbcsTable[4] = { - 0, 0, 0, 0 - }; - r->DS = FP_SEG(&dbcsTable); - r->SI = FP_OFF(&dbcsTable); + static char *dbcsTable = "\0\0\0\0"; + r->DS = FP_SEG(dbcsTable); + r->SI = FP_OFF(dbcsTable); #if 0 /* not really supported, but will pass. */ r->AL = 0x00; /*jpp: according to interrupt list */ diff --git a/kernel/kernel.asm b/kernel/kernel.asm index 082b82e..f46f87c 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -340,12 +340,11 @@ _VgaSet db 0 ; 0060 unknown dw 0 ; 0061 unknown global _uppermem_link _uppermem_link db 0 ; 0063 upper memory link flag - global _UMB_top -_UMB_top dw 0 ; 0064 unknown UMB_top will do for now +_min_pars dw 0 ; 0064 minimum paragraphs of memory + ; required by program being EXECed global _uppermem_root -_uppermem_root dw 0 ; 0066 dmd_upper_root - global _umb_start -_umb_start dw 0 ; 0068 para of last mem search +_uppermem_root dw 0 ; 0066 dmd_upper_root (usually 9fff) +_last_para dw 0 ; 0068 para of last mem search SysVarEnd: ;; The first 5 sft entries appear to have to be at DS:00cc @@ -615,12 +614,6 @@ segment _BSS ;!!intr_dos_seg resw 1 - global _ram_top -_ram_top dw 0 - - - -; ; mark front and end of bss area to clear segment IB_B global __ib_start diff --git a/kernel/main.c b/kernel/main.c index 4a0bc65..88cd488 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -55,7 +55,6 @@ GLOBAL BYTE DOSFAR os_major, /* major version number */ DOSFAR ASM default_drive; /* default drive for dos */ GLOBAL BYTE DOSFAR os_release[]; -/* GLOBAL BYTE DOSFAR copyright[]; */ GLOBAL seg DOSFAR RootPsp; /* Root process -- do not abort */ extern struct dpb FAR *DOSFAR ASM DPBp; /* First drive Parameter Block */ @@ -66,7 +65,6 @@ extern struct dhdr FAR *DOSFAR ASM clock, /* CLOCK$ device extern struct dhdr ASM DOSTEXTFAR con_dev, /* console device drive */ DOSTEXTFAR ASM clk_dev, /* Clock device driver */ DOSTEXTFAR ASM blk_dev; /* Block device (Disk) driver */ -extern UWORD DOSFAR ASM ram_top; /* How much ram in Kbytes */ extern iregs FAR *DOSFAR ASM user_r; /* User registers for int 21h call */ extern BYTE FAR ASM _HMATextEnd[]; @@ -85,6 +83,7 @@ extern BYTE FAR *lpOldTop; extern BYTE FAR *lpTop; extern BYTE FAR *upBase; extern BYTE ASM _ib_start[], ASM _ib_end[], ASM _init_end[]; +extern UWORD ram_top; /* How much ram in Kbytes */ VOID configDone(VOID); STATIC VOID InitIO(void); diff --git a/kernel/memmgr.c b/kernel/memmgr.c index 6edaf5e..ab8b795 100644 --- a/kernel/memmgr.c +++ b/kernel/memmgr.c @@ -568,7 +568,6 @@ VOID DosUmbLink(BYTE n) { REG mcb FAR *p; REG mcb FAR *q; - mcb FAR *end_of_conv_mem = para2far(ram_top * 64 - 1); if (uppermem_root == 0) return; @@ -577,7 +576,7 @@ VOID DosUmbLink(BYTE n) /* like a xor thing! */ if ((uppermem_link == 1) && (n == 0)) { - while (p != end_of_conv_mem) + while (FP_SEG(p) != uppermem_root) { if (mcbFree(p)) joinMCBs(p); @@ -587,7 +586,7 @@ VOID DosUmbLink(BYTE n) p = nxtMCB(p); } - if (q->m_type == MCB_NORMAL) + if (q->m_type == MCB_NORMAL) q->m_type = MCB_LAST; uppermem_link = n; @@ -601,65 +600,13 @@ VOID DosUmbLink(BYTE n) q = nxtMCB(q); } - if (q->m_type == MCB_LAST) - q->m_type = MCB_NORMAL; + q->m_type = MCB_NORMAL; uppermem_link = n; } DUL_exit: return; } -/* - if we arrive here the first time, it's just - before jumping to COMMAND.COM - - so we are done initializing, and can claim the IMIT_DATA segment, - as these data/strings/buffers are no longer in use. - - we carve a free memory block out of it and hope that - it will be useful (maybe for storing environments) - -*/ -#if 0 -BYTE INITDataSegmentClaimed = 1; /* must be enabled by CONFIG.SYS */ -extern BYTE _INIT_DATA_START[], _INIT_DATA_END[]; - -VOID ClaimINITDataSegment() -{ - unsigned ilow, ihigh; - VOID FAR *p; - - if (INITDataSegmentClaimed) - return; - INITDataSegmentClaimed = 1; - - ilow = (unsigned)_INIT_DATA_START; - ilow = (ilow + 0x0f) & ~0x000f; - ihigh = (unsigned)_INIT_DATA_END; - ihigh = ((ihigh + 0x0f) & ~0x000f) - 0x20; - - if (ilow + 0x10 < ihigh) - { - printf("CLAIMING INIT_DATA memory - %u bytes\n", ihigh - ilow); - } - - ((mcb *) ilow)->m_type = MCB_NORMAL; /* 'M' */ - ((mcb *) ilow)->m_psp = FREE_PSP; /* '0' */ - ((mcb *) ilow)->m_size = (ihigh - ilow - 0x10) >> 4; /* '0' */ - - ((mcb *) ihigh)->m_type = MCB_NORMAL; /* 'M' */ - ((mcb *) ihigh)->m_psp = 0x0008; /* system */ - - p = (void FAR *)(void *)ihigh; - - ((mcb *) ihigh)->m_size = first_mcb - 1 - FP_SEG(p) - (FP_OFF(p) >> 4); - - p = (void FAR *)(void *)ilow; - - first_mcb = FP_SEG(p) + (FP_OFF(p) >> 4); - -} -#endif #endif /* diff --git a/kernel/nls_hc.asm b/kernel/nls_hc.asm index c963ee4..c511443 100644 --- a/kernel/nls_hc.asm +++ b/kernel/nls_hc.asm @@ -7,7 +7,7 @@ ;; ==> Reordering tables 1, 2, 4 and 5 %include "segs.inc" -segment _DATA +segment CONST2 GLOBAL _nlsPackageHardcoded _nlsPackageHardcoded: diff --git a/kernel/prf.c b/kernel/prf.c index cef1a4f..aa978fb 100644 --- a/kernel/prf.c +++ b/kernel/prf.c @@ -50,6 +50,7 @@ static char buff[MAX_BUFSIZE]; #define sprintf init_sprintf #define charp init_charp #define hexd init_hexd +#define hexDigits init_hexDigits #endif COUNT ASMCFUNC fstrlen(BYTE FAR * s); /* don't want globals.h, sorry */ @@ -163,9 +164,7 @@ BYTE *ltob(LONG n, BYTE * s, COUNT base) p = q = s; do { /* generate digits in reverse order */ - static char hexDigits[] = "0123456789abcdef"; - - *p++ = hexDigits[(UWORD) (u % base)]; + *p++ = "0123456789abcdef"[(UWORD) (u % base)]; } while ((u /= base) > 0); @@ -277,12 +276,11 @@ COUNT do_printf(CONST BYTE * fmt, BYTE ** arg) case 'p': { UWORD w[2]; - static char pointerFormat[] = "%04x:%04x"; w[1] = *((UWORD *) arg); arg += sizeof(UWORD) / sizeof(BYTE *); w[0] = *((UWORD *) arg); arg += sizeof(UWORD) / sizeof(BYTE *); - do_printf(pointerFormat, (BYTE **) & w); + do_printf("%04x:%04x", (BYTE **) & w); continue; } diff --git a/kernel/proto.h b/kernel/proto.h index ec81fd7..3eb8fa9 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -310,7 +310,7 @@ COUNT ASMCFUNC fstrcmp(REG BYTE FAR * d, REG BYTE FAR * s); COUNT ASMCFUNC fstrncmp(REG BYTE FAR * d, REG BYTE FAR * s, COUNT l); COUNT ASMCFUNC strncmp(REG BYTE * d, REG BYTE * s, COUNT l); void ASMCFUNC fstrncpy(REG BYTE FAR * d, REG BYTE FAR * s, COUNT l); -BYTE * ASMCFUNC strchr(BYTE * s, BYTE c); +BYTE * ASMCFUNC strchr(const BYTE * s, BYTE c); /* sysclk.c */ COUNT BcdToByte(COUNT x); @@ -335,7 +335,7 @@ VOID DosGetDate(BYTE FAR * wdp, BYTE FAR * mp, BYTE FAR * mdp, COUNT FAR * yp); COUNT DosSetDate(UWORD Month, UWORD DayOfMonth, UWORD Year); -UWORD *is_leap_year_monthdays(UWORD year); +const UWORD *is_leap_year_monthdays(UWORD year); UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth); /* task.c */ diff --git a/kernel/sysclk.c b/kernel/sysclk.c index fb6b084..ffc07cc 100644 --- a/kernel/sysclk.c +++ b/kernel/sysclk.c @@ -81,7 +81,7 @@ STATIC COUNT BcdToByte(COUNT x) WORD ASMCFUNC FAR clk_driver(rqptr rp) { COUNT c; - UWORD *pdays; + const UWORD *pdays; BYTE bcd_days[4], bcd_minutes, bcd_hours, bcd_seconds; ULONG Ticks; UWORD Month, Day, Year; diff --git a/kernel/systime.c b/kernel/systime.c index 15a217f..b73281d 100644 --- a/kernel/systime.c +++ b/kernel/systime.c @@ -36,7 +36,7 @@ static BYTE *RcsId = "$Id$"; #endif -UWORD days[2][13] = { +const UWORD days[2][13] = { {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} }; @@ -47,7 +47,7 @@ extern request ASM ClkReqHdr; return a pointer to an array with the days for that year */ -UWORD *is_leap_year_monthdays(UWORD y) +const UWORD *is_leap_year_monthdays(UWORD y) { /* this is correct in a strict mathematical sense return ((y) & 3 ? days[0] : (y) % 100 ? days[1] : (y) % 400 ? days[0] : days[1]); */ @@ -123,7 +123,7 @@ BYTE FAR *wdp, FAR * mp, FAR * mdp; COUNT FAR *yp; { UWORD c; - UWORD *pdays; + const UWORD *pdays; UWORD Year, Month; ExecuteClockDriverRequest(C_INPUT); @@ -164,7 +164,7 @@ COUNT FAR *yp; COUNT DosSetDate(Month, DayOfMonth, Year) UWORD Month, DayOfMonth, Year; { - UWORD *pdays; + const UWORD *pdays; pdays = is_leap_year_monthdays(Year); if (Year < 1980 || Year > 2099 diff --git a/sys/fdkrncfg.c b/sys/fdkrncfg.c index b2d4471..d7541fe 100644 --- a/sys/fdkrncfg.c +++ b/sys/fdkrncfg.c @@ -21,13 +21,30 @@ char KERNEL[] = "KERNEL.SYS"; #include #include -#include #include #include "portab.h" extern WORD CDECL printf(CONST BYTE * fmt, ...); extern WORD CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...); +#ifdef __WATCOMC__ +#define close _dos_close +#define SEEK_SET 0 +int open(const char *pathname, int flags, ...); +int read(int fd, void *buf, unsigned count); +int write(int fd, const void *buf, unsigned count); +int stat(const char *file_name, struct stat *buf); +unsigned long lseek(int fildes, unsigned long offset, int whence); +#pragma aux lseek = \ + "mov ah, 0x42" \ + "int 0x21" \ + parm [bx] [dx cx] [ax] \ + value [dx ax]; + +#else +#include +#endif + #define FAR far #include "kconfig.h" @@ -111,7 +128,6 @@ int readConfigSettings(int kfile, char *kfilename, KernelConfig * cfg) */ int writeConfigSettings(int kfile, KernelConfig * cfg) { - /* Seek to CONFIG section at start of options of kernel file */ if (lseek(kfile, 2, SEEK_SET) != 2) return 1; diff --git a/sys/sys.c b/sys/sys.c index 3480691..fdbc2c6 100644 --- a/sys/sys.c +++ b/sys/sys.c @@ -36,15 +36,13 @@ #define DEBUG /* #define DDEBUG */ -#define SYS_VERSION "v2.3" +#define SYS_VERSION "v2.4" -/* #include */ #include -#include -#include -#include #include #include +#include +#include #ifdef __TURBOC__ #include #else @@ -65,6 +63,48 @@ extern WORD CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...); #include "b_fat32.h" #endif +#ifndef __WATCOMC__ +#include +#else +/* some non-conforming functions to make the executable smaller */ +int open(const char *pathname, int flags, ...) +{ + int handle; + int result = (flags & O_CREAT ? + _dos_creat(pathname, _A_NORMAL, &handle) : + _dos_open(pathname, flags & (O_RDONLY | O_WRONLY | O_RDWR), + &handle)); + + return (result == 0 ? handle : -1); +} + +int read(int fd, void *buf, unsigned count) +{ + unsigned bytes; + int result = _dos_read(fd, buf, count, &bytes); + + return (result == 0 ? bytes : -1); +} + +int write(int fd, const void *buf, unsigned count) +{ + unsigned bytes; + int result = _dos_write(fd, buf, count, &bytes); + + return (result == 0 ? bytes : -1); +} + +#define close _dos_close + +int stat(const char *file_name, struct stat *buf) +{ + struct find_t find_tbuf; + UNREFERENCED_PARAMETER(buf); + + return _dos_findfirst(file_name, _A_NORMAL | _A_HIDDEN | _A_SYSTEM, &find_tbuf); +} +#endif + BYTE pgm[] = "SYS"; void put_boot(COUNT, BYTE *, BOOL); @@ -74,7 +114,7 @@ COUNT DiskRead(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); COUNT DiskWrite(WORD, WORD, WORD, WORD, WORD, BYTE FAR *); #define SEC_SIZE 512 -#define COPY_SIZE 32768u +#define COPY_SIZE 0x7e00 #ifdef _MSC_VER #pragma pack(1) @@ -304,6 +344,66 @@ VOID dump_sector(unsigned char far * sec) MSDOS requires int25, CX=ffff for drives > 32MB */ +#ifdef __WATCOMC__ +unsigned int2526readwrite(int DosDrive, void *diskReadPacket, unsigned intno); +#pragma aux int2526readwrite = \ + "mov cx, 0xffff" \ + "cmp si, 0x26" \ + "je int26" \ + "int 0x25" \ + "jmp short cfltest" \ + "int26:" \ + "int 0x26" \ + "cfltest:" \ + "mov ax, 0" \ + "adc ax, ax" \ + parm [ax] [bx] [si] \ + modify [cx] \ + value [ax]; + +fat32readwrite(int DosDrive, void *diskReadPacket, unsigned intno); +#pragma aux fat32readwrite = \ + "mov ax, 0x7305" \ + "mov cx, 0xffff" \ + "inc dx" \ + "sub si, 0x25" \ + "int 0x21" \ + "mov ax, 0" \ + "adc ax, ax" \ + parm [dx] [bx] [si] \ + modify [cx dx si] \ + value [ax]; + +#else +int2526readwrite(int DosDrive, void *diskReadPacket, unsigned intno) +{ + union REGS regs; + + regs.h.al = (BYTE) DosDrive; + regs.x.bx = (short)&diskReadPacket; + regs.x.cx = 0xffff; + + int86(intno, ®s, ®s); + + return regs.x.cflag; +} + + +fat32readwrite(int DosDrive, void *diskReadPacket, unsigned intno) +{ + union REGS regs; + + regs.x.ax = 0x7305; + regs.h.dl = DosDrive + 1; + regs.x.bx = (short)&diskReadPacket; + regs.x.cx = 0xffff; + regs.x.si = intno - 0x25; + int86(0x21, ®s, ®s); + + return regs.x.cflag; +} +#endif + int MyAbsReadWrite(int DosDrive, int count, ULONG sector, void *buffer, unsigned intno) { @@ -312,36 +412,82 @@ int MyAbsReadWrite(int DosDrive, int count, ULONG sector, void *buffer, unsigned short count; void far *address; } diskReadPacket; - union REGS regs; diskReadPacket.sectorNumber = sector; diskReadPacket.count = count; diskReadPacket.address = buffer; - regs.h.al = (BYTE) DosDrive; - regs.x.bx = (short)&diskReadPacket; - regs.x.cx = 0xffff; - if (intno != 0x25 && intno != 0x26) return 0xff; - int86(intno, ®s, ®s); - -#ifdef WITHFAT32 - if (regs.x.cflag) + if (int2526readwrite(DosDrive, &diskReadPacket, intno)) { - regs.x.ax = 0x7305; - regs.h.dl = DosDrive + 1; - regs.x.bx = (short)&diskReadPacket; - regs.x.cx = 0xffff; - regs.x.si = intno - 0x25; - int86(0x21, ®s, ®s); - } +#ifdef WITHFAT32 + return fat32readwrite(DosDrive, &diskReadPacket, intno); +#else + return 0xff; #endif - - return regs.x.cflag ? 0xff : 0; + } + return 0; } +#ifdef __WATCOMC__ + +unsigned getdrivespace(COUNT drive, unsigned *total_clusters); +#pragma aux getdrivespace = \ + "mov ah, 0x36" \ + "inc dx" \ + "int 0x21" \ + "mov [si], dx" \ + parm [dx] [si] \ + modify [bx cx dx] \ + value [ax]; + +unsigned getextdrivespace(void *drivename, void *buf, unsigned buf_size); +#pragma aux getextdrivespace = \ + "mov ax, 0x7303" \ + "push ds" \ + "pop es" \ + "int 0x21" \ + "mov ax, 0" \ + "adc ax, ax" \ + parm [dx] [di] [cx] \ + modify [es] \ + value [ax]; + +#else + +unsigned getdrivespace(COUNT drive, unsigned *total_clusters) +{ + union REGS regs; + + regs.h.ah = 0x36; /* get drive free space */ + regs.h.dl = drive + 1; /* 1 = 'A',... */ + int86(0x21, ®s, ®s); + *total_clusters = regs.x.dx; + return regs.x.ax; +} + +unsigned getextdrivespace(void *drivename, void *buf, unsigned buf_size) +{ + union REGS regs; + struct SREGS sregs; + + regs.x.ax = 0x7303; /* get extended drive free space */ + + sregs.es = FP_SEG(buf); + regs.x.di = FP_OFF(buf); + sregs.ds = FP_SEG(drivename); + regs.x.dx = FP_OFF(drivename); + + regs.x.cx = buf_size; + + int86x(0x21, ®s, ®s, &sregs); + return regs.x.cflag; +} + +#endif + VOID put_boot(COUNT drive, BYTE * bsFile, BOOL both) { ULONG temp; @@ -350,10 +496,9 @@ VOID put_boot(COUNT drive, BYTE * bsFile, BOOL both) struct bootsectortype32 *bs32; #endif int fs; - union REGS regs; - struct SREGS sregs; char drivename[] = "A:\\"; unsigned char x[0x40]; + unsigned total_clusters; #ifdef DEBUG printf("Reading old bootsector from drive %c:\n", drive + 'A'); @@ -386,17 +531,13 @@ VOID put_boot(COUNT drive, BYTE * bsFile, BOOL both) this should work, as the disk was writeable, so GetFreeDiskSpace should work. */ - regs.h.ah = 0x36; /* get drive free space */ - regs.h.dl = drive + 1; /* 1 = 'A',... */ - int86(0x21, ®s, ®s); - - if (regs.x.ax == 0xffff) + if (getdrivespace(drive, &total_clusters) == 0xffff) { printf("can't get free disk space for %c:\n", drive + 'A'); exit(1); } - if (regs.x.dx <= 0xff6) + if (total_clusters <= 0xff6) { if (fs != 12) printf("warning : new detection overrides old detection\a\n"); @@ -413,19 +554,9 @@ VOID put_boot(COUNT drive, BYTE * bsFile, BOOL both) we don't want to crash a FAT32 drive */ - segread(&sregs); - sregs.es = sregs.ds; - - regs.x.ax = 0x7303; /* get extended drive free space */ - drivename[0] = 'A' + drive; - regs.x.dx = (unsigned)&drivename; - regs.x.di = (unsigned)&x; - regs.x.cx = sizeof(x); - - int86x(0x21, ®s, ®s, &sregs); - - if (regs.x.cflag) /* error --> no Win98 --> no FAT32 */ + if (getextdrivespace(drivename, x, sizeof(x))) + /* error --> no Win98 --> no FAT32 */ { printf("get extended drive space not supported --> no FAT32\n"); }