From faaff5006a3586640b9752010ca47cc949e31f14 Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Sun, 15 Jun 2003 19:26:49 +0000 Subject: [PATCH] + Changes Eric Auer * add sanity check to initdisk.c for (driveParam->chs.Sector == 0) + some display tweaks * add ANYDOS, KBDRATE, VIDMODE, MENUCOLOR and EECHO support to the config.sys parser. * distinguish between the builtin DOS version and the settable DOS version. git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@601 6ac86273-5f31-0410-b378-82cca8765d1b --- docs/history.txt | 30 ++++++-- hdr/lol.h | 16 ++-- kernel/config.c | 183 ++++++++++++++++++++++++++++++++++++++++++++-- kernel/globals.h | 4 +- kernel/initdisk.c | 17 +++-- kernel/inthndlr.c | 14 +++- kernel/kernel.asm | 4 + kernel/main.c | 4 +- 8 files changed, 239 insertions(+), 33 deletions(-) diff --git a/docs/history.txt b/docs/history.txt index 1c1b88f..28d29ef 100644 --- a/docs/history.txt +++ b/docs/history.txt @@ -1,10 +1,20 @@ 2003 Jun xx - Build 2030 -------- Bart Oldeman (bart@dosemu.org) + Changes Tom -if user left accidentally floppy or CD in drive, -give him a chance to continue to boot from HD. -disabled by default, enablable by SYS CONFIG - + * if user left accidentally floppy or CD in drive, + give him a chance to continue to boot from HD. + disabled by default, enablable by SYS CONFIG + (BOOTHARDDISKSECONDS) ++ Changes Lixing Yuan + * dosnames.c cleanup, fix for truename if the filename + contains wildcards and a trailing dot. ++ Changes Eric Auer + * add sanity check to initdisk.c for (driveParam->chs.Sector == 0) + + some display tweaks + * add ANYDOS, KBDRATE, VIDMODE, MENUCOLOR and EECHO support to the + config.sys parser. + * distinguish between the builtin DOS version and the settable + DOS version. + Changes Bart * flip some slashes in drivers/*.asm (enables cross-assembly on Linux) @@ -23,9 +33,15 @@ disabled by default, enablable by SYS CONFIG the final allocation takes place. * handle multiple UMBs more correctly (but config.sys can use only one UMB for devicehigh -- /Ln,xxxx is not yet implemented) - * minor size optimizations in chario.c, dosfns.c; - asmsupt.asm: correct fmemchr (all n's) and *memset/*memcpy (n==0) - 185 relocs, 54 not shown + * minor size optimizations in newstuff.c, chario.c, dosfns.c and fcbfns.c. + asmsupt.asm: correct fmemchr (all n's) and *memset/*memcpy + (n==0) + * introduce lol structure for list of lists; avoid lots of + relocations + * avoid more relocations in the asm files by loading ds from + [cs:_DGROUP_] + * Fix problem with attributes with the volume label bit + findnext + * 2003 Mar 14 - Build 2029 -------- Bart Oldeman (bart@dosemu.org) + Changes Tom diff --git a/hdr/lol.h b/hdr/lol.h index eac928e..97f75d7 100644 --- a/hdr/lol.h +++ b/hdr/lol.h @@ -72,11 +72,13 @@ struct lol { unsigned short uppermem_root;/* 66 Start of umb chain (usually 9fff) */ unsigned short last_para; /* 68 para: start scanning during memalloc */ /* FreeDOS specific entries */ - unsigned char os_minor; /* 6a minor DOS version */ - unsigned char os_major; /* 6b major DOS version */ - unsigned char rev_number; /* 6c minor DOS version */ - unsigned char version_flags; /* 6d DOS version flags */ - f_node_ptr f_nodes; /* 6e pointer to the array */ - unsigned short f_nodes_cnt; /* 70 number of allocated f_nodes */ - char *os_release; /* 72 near pointer to os_release string */ + unsigned char os_setver_minor;/*6a settable minor DOS version */ + unsigned char os_setver_major;/*6b settable major DOS version */ + unsigned char os_minor; /* 6c minor DOS version */ + unsigned char os_major; /* 6d major DOS version */ + unsigned char rev_number; /* 6e minor DOS version */ + unsigned char version_flags; /* 6f DOS version flags */ + f_node_ptr f_nodes; /* 70 pointer to the array */ + unsigned short f_nodes_cnt; /* 72 number of allocated f_nodes */ + char *os_release; /* 74 near pointer to os_release string */ }; diff --git a/kernel/config.c b/kernel/config.c index a78f21a..5147af0 100644 --- a/kernel/config.c +++ b/kernel/config.c @@ -144,6 +144,9 @@ STATIC VOID CfgSwitchar(BYTE * pLine); STATIC VOID CfgFailure(BYTE * pLine); STATIC VOID CfgIgnore(BYTE * pLine); STATIC VOID CfgMenu(BYTE * pLine); + +STATIC VOID CfgMenuEsc(BYTE * pLine); + STATIC VOID DoMenu(void); STATIC VOID CfgMenuDefault(BYTE * pLine); STATIC BYTE * skipwh(BYTE * s); @@ -159,6 +162,12 @@ STATIC VOID mumcb_init(UCOUNT seg, UWORD size); STATIC VOID Stacks(BYTE * pLine); STATIC VOID StacksHigh(BYTE * pLine); + +STATIC VOID sysKbdRate(BYTE * pLine); +STATIC VOID sysKbdBuf(BYTE * pLine); +STATIC VOID sysVidMode(BYTE * pLine); +STATIC VOID sysMenuColor(BYTE * pLine); + STATIC VOID SetAnyDos(BYTE * pLine); STATIC VOID Numlock(BYTE * pLine); STATIC BYTE * GetNumArg(BYTE * pLine, COUNT * pnArg); @@ -218,9 +227,13 @@ STATIC struct table commands[] = { {"STACKS", 1, Stacks}, {"STACKSHIGH", 1, StacksHigh}, {"SWITCHAR", 1, CfgSwitchar}, - {"SCREEN", 1, sysScreenMode}, /* JPP */ - {"VERSION", 1, sysVersion}, /* JPP */ - {"ANYDOS", 1, SetAnyDos}, /* tom */ + {"SCREEN", 1, sysScreenMode}, /* JPP */ + {"VERSION", 1, sysVersion}, /* JPP */ + {"ANYDOS", 1, SetAnyDos}, /* tom */ + {"KBDRATE", 1, sysKbdRate}, /* ea */ + {"KBDBUF", 1, sysKbdBuf}, /* ea */ + {"VIDMODE", 1, sysVidMode}, /* ea */ + {"MENUCOLOR", 1, sysMenuColor}, /* ea */ {"DEVICE", 2, Device}, {"DEVICEHIGH", 2, DeviceHigh}, @@ -637,10 +650,10 @@ VOID DoConfig(int pass) continue; } - if (pEntry->func != CfgMenu) + if ((pEntry->func != CfgMenu) && (pEntry->func != CfgMenuEsc)) pLine = skipwh(pLine); - if ('=' != *pLine && pEntry->func != CfgMenu) + if ('=' != *pLine && pEntry->func != CfgMenu && pEntry->func != CfgMenuEsc) CfgFailure(pLine); else /* YES. DO IT */ (*(pEntry->func)) (skipwh(pLine + 1)); @@ -1122,6 +1135,148 @@ STATIC VOID StacksHigh(BYTE * pLine) Config.cfgStacksHigh = 1; } +STATIC VOID sysKbdRate(BYTE * pLine) +{ + COUNT krate = 16; /* default: medium rate */ + COUNT kdelay = 3; /* default: maximum delay */ + + /* Format: KBDRATE = ratecode [, delay] */ + pLine = GetNumArg(pLine, &krate); + + pLine = skipwh(pLine); + + if (*pLine == ',') + GetNumArg(++pLine, &kdelay); + + if (krate < 0 || krate > 31 || kdelay < 0 || kdelay > 3) { + printf("KBDRATE arguments must be 0..31, 0..3 for rate, delay\n"); + CfgFailure(pLine); + return; + } + + /* could check if int 16.9 returns AL and 4 NZ before setting rates */ + +#if defined(__TURBOC__) + _AX = 0x0305; + _BH = kdelay; + _BL = krate; + __int__(0x16); +#elif defined(I86) + asm + { + mov ax, 0x0305; + mov bh, byte ptr kdelay; + mov bl, byte ptr krate; + int 0x16; + } +#endif + + printf("Set keyboard repeat rate=%d (0=fastest, 31=slowest), delay=%d\n", + krate, kdelay); +} + +STATIC VOID sysKbdBuf(BYTE * pLine) +{ + COUNT kbuf1 = 0xb0; /* default - okay if no EDD/... BIOS */ + COUNT kbuf2 = 0xfe; /* default - end of BIOS data */ + WORD FAR *kbufstart = MK_FP(0x40, 0x80); + WORD FAR *kbufend = MK_FP(0x40, 0x82); + WORD FAR *kbufptr1 = MK_FP(0x40, 0x1a); + WORD FAR *kbufptr2 = MK_FP(0x40, 0x1c); + + /* Format: KBDBUF = start [, end] */ + pLine = GetNumArg(pLine, &kbuf1); + + pLine = skipwh(pLine); + + if (*pLine == ',') + GetNumArg(++pLine, &kbuf2); + kbuf1 &= 0xfffe; + kbuf2 &= 0xfffe; + + if ((kbuf1 >= kbuf2) || (kbuf1 < 0xac) || (kbuf2 > 0xfe)) { + printf("KBDBUF start [, end] must be in BIOS data, not %x..%x\n", + kbuf1, kbuf2); + CfgFailure(pLine); + return; + } + + printf("KBDBUF: setting buffer to 0x40:%2x..%2x\n", kbuf1, kbuf2); + /* CLI !? */ + kbufstart[0] = kbufptr1[0] = kbufptr2[0] = kbuf1; + kbufend[0] = kbuf2; + /* STI !? */ +} + +STATIC VOID sysVidMode(BYTE * pLine) +{ + COUNT vmode = 3; /* default: 80x25 */ + + /* Format: VIDMODE = modenumber */ + pLine = GetNumArg(pLine, &vmode); + + if (vmode < 0 || vmode > 0x10c || (vmode < 0x108 && vmode >= 0x100)) { + printf("VIDMODE argument must be 0..0xff or 0x108..0x10c\n"); + /* 0x108..0x10c are normal VESA text modes. */ + /* 0..0xff are all kinds of normal video modes, no sanity checks! */ + CfgFailure(pLine); + return; + } + + if (vmode < 0x100) { +#if defined(__TURBOC__) + _AX = 0x0000 + vmode; /* CLASSIC video mode set */ + __int__(0x10); +#elif defined(I86) + asm + { + mov ah, 0; + mov al, byte ptr vmode + int 0x10; + } +#endif + } else { +#if defined(__TURBOC__) + _AX = 0x4f02; /* VESA video mode set */ + _BX = vmode; + __int__(0x10); /* if AL not 4f now, no VESA. if AH 1 now, failed */ +#elif defined(I86) + asm + { + mov ax, 0x4f02; + mov bx, word ptr vmode + int 0x10; + } +#endif + } + printf("Set video mode to %x (0x1??: VESA 0x0?? normal)\n", vmode); +} + +STATIC VOID sysMenuColor(BYTE * pLine) +{ + COUNT fgcolor = 7; /* default grey */ + COUNT bgcolor = 0; /* default black */ + + /* Format: MENUCOLOR = foreground [, background] */ + pLine = GetNumArg(pLine, &fgcolor); + + pLine = skipwh(pLine); + + if (*pLine == ',') + GetNumArg(++pLine, &bgcolor); + + if (fgcolor < 0 || fgcolor > 15 || bgcolor < 0 || bgcolor > 15) { + printf("MENUCOLOR fgcolor [, bgcolor] have 0..15 limit\n"); + CfgFailure(pLine); + return; + } + + printf("Not yet used: foreground=%d background=%d\n", fgcolor, bgcolor); + /* *** TODO: Either print ANSI sequence or make int 29h *** */ + /* *** use colored int 10.02/09 (not 0e)...??? or only *** */ + /* *** use int 10.2/3/8/9 loop to recolor current text *** */ +} + STATIC VOID InitPgmHigh(BYTE * pLine) { InitPgm(pLine); @@ -1470,6 +1625,7 @@ STATIC BOOL isnum(BYTE * pLine) } /* JPP - changed so will accept hex number. */ +/* ea - changed to accept hex digits in hex numbers */ STATIC BYTE * GetNumber(REG BYTE * pszString, REG COUNT * pnNum) { BYTE Base = 10; @@ -1482,15 +1638,20 @@ STATIC BYTE * GetNumber(REG BYTE * pszString, REG COUNT * pnNum) Sign = TRUE; } - while (isnum(pszString) || toupper(*pszString) == 'X') + while ( isnum(pszString) || toupper(*pszString) == 'X' || + ( Base==16 && (toupper(*pszString)<='F') && (toupper(*pszString)>='A') ) ) { if (toupper(*pszString) == 'X') { Base = 16; pszString++; } - else + else if (isnum(pszString)) { *pnNum = *pnNum * Base + (*pszString++ - '0'); + } + else { + *pnNum = *pnNum * Base + (10 + toupper(*pszString++) - 'A'); + } } if (Sign) *pnNum = -*pnNum; @@ -1692,6 +1853,14 @@ STATIC VOID CfgMenu(BYTE * pLine) printf("%s\n",pLine); } +STATIC VOID CfgMenuEsc(BYTE * pLine) +{ + BYTE * check; + for (check = pLine; check[0]; check++) + if (check[0] == '$') check[0] = 27; /* translate $ to ESC */ + printf("%s\n",pLine); +} + STATIC VOID DoMenu(void) { if (Menus == 0) diff --git a/kernel/globals.h b/kernel/globals.h index b67a8c5..1aee906 100644 --- a/kernel/globals.h +++ b/kernel/globals.h @@ -178,7 +178,9 @@ extern struct ClockRecord /* */ /* Global variables */ /* */ -extern BYTE os_major, /* major version number */ +extern BYTE os_setver_major, /* editable major version number */ + os_setver_minor, /* editable minor version number */ + os_major, /* major version number */ os_minor, /* minor version number */ rev_number, /* minor version number */ version_flags; /* minor version number */ diff --git a/kernel/initdisk.c b/kernel/initdisk.c index 534101e..f8d71d9 100644 --- a/kernel/initdisk.c +++ b/kernel/initdisk.c @@ -367,6 +367,7 @@ void init_LBA_to_CHS(struct CHS *chs, ULONG LBA_address, void printCHS(char *title, struct CHS *chs) { printf("%s", title); + /* has no fixed size for head/sect: is often 1/1 in our context */ printf("%4u-%u-%u", chs->Cylinder, chs->Head, chs->Sector); } @@ -621,13 +622,13 @@ void DosDefinePartition(struct DriveParamS *driveParam, printf("\r%c: HD%d", 'A' + nUnits, (driveParam->driveno & 0x7f) + 1); if (extendedPartNo) - printf(" Ext:%d", extendedPartNo); + printf(", Ext[%2d]", extendedPartNo); else - printf(" Pri:%d", PrimaryNum + 1); + printf(", Pri[%2d]", PrimaryNum + 1); - printCHS(" CHS= ", &chs); + printCHS(", CHS= ", &chs); - printf(" start = %5luMB,size =%5lu", + printf(", start=%6lu MB, size=%6lu MB", StartSector / 2048, pEntry->NumSect / 2048); printf("\n"); @@ -704,7 +705,7 @@ int LBA_Get_Drive_Parameters(int drive, struct DriveParamS *driveParam) lba_bios_parameters.sectors > 0xffff || lba_bios_parameters.totalSectHigh != 0) { - printf("Drive is too large to handle, using only 1'st 8 GB\n" + printf("Drive is too large to handle, using only 1st 8 GB\n" " drive %02x heads %lu sectors %lu , total=0x%lx-%08lx\n", drive, (ULONG) lba_bios_parameters.heads, @@ -740,6 +741,12 @@ StandardBios: /* old way to get parameters */ driveParam->chs.Head = (regs.d.x >> 8) + 1; driveParam->chs.Sector = (regs.c.x & 0x3f); driveParam->chs.Cylinder = (regs.c.x >> 8) | ((regs.c.x & 0xc0) << 2); + + if (driveParam->chs.Sector == 0) { + /* happens e.g. with Bochs 1.x if no harddisk defined */ + driveParam->chs.Sector = 63; /* avoid division by zero...! */ + printf("BIOS reported 0 sectors/track, assuming 63!\n"); + } if (!driveParam->LBA_supported) { diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index 1239974..865c043 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -95,7 +95,7 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp) irp->DL = BootDrive; break; - /* Get DOS-C version */ + /* Get (real) DOS-C version */ case 0x06: irp->BL = os_major; irp->BH = os_minor; @@ -110,6 +110,12 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp) irp->AL = 0xff; break; + /* set FreeDOS returned version for int 21.30 from BX */ + case 0xfc: /* 0xfc ... 0xff are FreeDOS extensions */ + os_setver_major = irp->BL; + os_setver_minor = irp->BH; + break; + /* Toggle DOS-C rdwrblock trace dump */ case 0xfd: #ifdef DEBUG @@ -708,10 +714,10 @@ dispatch: lr.BX = FP_OFF(dta); break; - /* Get DOS Version */ + /* Get (editable) DOS Version */ case 0x30: - lr.AL = os_major; - lr.AH = os_minor; + lr.AL = os_setver_major; + lr.AH = os_setver_minor; lr.BH = OEM_ID; lr.CH = REVISION_MAJOR; /* JPP */ lr.CL = REVISION_MINOR; diff --git a/kernel/kernel.asm b/kernel/kernel.asm index 1d49d85..0755dc6 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -335,6 +335,10 @@ _uppermem_root dw 0ffffh ; 0066 dmd_upper_root (usually 9fff) _last_para dw 0 ; 0068 para of last mem search SysVarEnd: ;; FreeDOS specific entries + global _os_setver_minor +_os_setver_minor db 0 + global _os_setver_major +_os_setver_major db 5 global _os_minor _os_minor db 0 global _os_major diff --git a/kernel/main.c b/kernel/main.c index 16ab805..82c6fc1 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -204,8 +204,8 @@ STATIC void init_kernel(void) { COUNT i; - LoL->os_major = MAJOR_RELEASE; - LoL->os_minor = MINOR_RELEASE; + LoL->os_setver_major = LoL->os_major = MAJOR_RELEASE; + LoL->os_setver_minor = LoL->os_minor = MINOR_RELEASE; /* Init oem hook - returns memory size in KB */ ram_top = init_oem();