diff --git a/filelist b/filelist index 0d4bd1d..33bd657 100644 --- a/filelist +++ b/filelist @@ -108,6 +108,7 @@ */*/kernel/lfnapi.c */*/kernel/ludivmul.inc */*/kernel/main.c +*/*/kernel/memdisk.asm */*/kernel/memmgr.c */*/kernel/misc.c */*/kernel/network.c diff --git a/kernel/config.c b/kernel/config.c index 55fc403..e5cf3bd 100644 --- a/kernel/config.c +++ b/kernel/config.c @@ -599,16 +599,99 @@ STATIC void umb_init(void) } } +/* we require 386, so only supported for 386+ compiled kernels */ +#if defined(MEMDISK_ARGS) +#ifndef I386 +#undef MEMDISK_ARGS +#endif +#endif + +#ifdef MEMDISK_ARGS +struct memdiskinfo { + UWORD bytes; /* Total size of this structure, value >= 26 */ + UBYTE version_minor; /* Memdisk minor version */ + UBYTE version; /* Memdisk major version */ + UDWORD base; /* Pointer to disk data in high memory */ + UDWORD size; /* Size of disk in 512 byte sectors */ + char FAR * cmdline; /* Command line */ + ADDRESS oldint13; /* Old INT 13h */ + ADDRESS oldint15; /* Old INT 15h */ + UWORD olddosmem; /* Amount of DOS memory before Memdisk loaded */ + UBYTE boot_id; /* major >= 3, boot loader ID */ + UBYTE unused; + UWORD DPT_offset; /* >= 3.71, ES based offset to installed DPT, +16 is Old INT 1Eh */ +}; + +/* query_memdisk() based on similar subroutine in Eric Auer's public domain getargs.asm which is based on IFMEMDSK */ +struct memdiskinfo FAR * ASMCFUNC query_memdisk(UBYTE drive); +#endif + + VOID DoConfig(int nPass) { COUNT nFileDesc; BYTE *pLine; BOOL bEof; + + +#ifdef MEMDISK_ARGS + /* check if MEMDISK used for LoL->BootDrive, if so check for special appended arguments */ + struct memdiskinfo FAR *mdsk; + BYTE FAR *mdsk_cfg = NULL; + UBYTE drv = (LoL->BootDrive < 3)?0x0:0x80; /* 1=A,2=B,3=C */ + mdsk = query_memdisk(drv); +#endif + if (nPass==0) + { HaltCpuWhileIdle = 0; /* init to "no HLT while idle" */ +#ifdef MEMDISK_ARGS + if (mdsk != NULL) + { + printf("MEMDISK version %u.%02u (%lu sectors)\n", mdsk->version, mdsk->version_minor, mdsk->size); + DebugPrintf(("MEMDISK args:{%S} bootdrive=[%0Xh]\n", mdsk->cmdline, (unsigned int)drv)); + } +#endif + } + +#ifdef MEMDISK_ARGS + if (mdsk != NULL) + { + /* scan for FD= */ + /* when done mdsk->cmdline points to { character or assume no valid CONFIG options */ + for (mdsk_cfg=mdsk->cmdline; *mdsk_cfg; ++mdsk_cfg) + { + if (*mdsk_cfg != ' ') continue; + ++mdsk_cfg; + if (*mdsk_cfg != 'F') goto goback1; + ++mdsk_cfg; + if (*mdsk_cfg != 'D') goto goback2; + ++mdsk_cfg; + if (*mdsk_cfg != '=') goto goback3; + ++mdsk_cfg; + break; + + goback3: + --mdsk_cfg; + goback2: + --mdsk_cfg; + goback1: + --mdsk_cfg; + } + /* if FD= was not found then flag as no extra CONFIG lines */ + if (!*mdsk_cfg) mdsk_cfg = NULL; + } + else + { + DebugPrintf(("MEMDISK not detected! bootdrive=[%0Xh]\n", (unsigned int)drv)); + } +#endif + + /* Check to see if we have a config.sys file. If not, just */ - /* exit since we don't force the user to have one. */ + /* exit since we don't force the user to have one (but 1st */ + /* also process MEMDISK passed config options if present). */ if ((nFileDesc = open("fdconfig.sys", 0)) >= 0) { DebugPrintf(("Reading FDCONFIG.SYS...\n")); @@ -619,9 +702,17 @@ VOID DoConfig(int nPass) if ((nFileDesc = open("config.sys", 0)) < 0) { DebugPrintf(("CONFIG.SYS not found\n")); - return; +#ifdef MEMDISK_ARGS + if (mdsk_cfg != NULL) + bEof = TRUE; + else +#endif + return; + } + else + { + DebugPrintf(("Reading CONFIG.SYS...\n")); } - DebugPrintf(("Reading CONFIG.SYS...\n")); } /* Have one -- initialize. */ @@ -633,12 +724,22 @@ VOID DoConfig(int nPass) /* do the table lookup and execute the handler for that */ /* function. */ +#ifdef MEMDISK_ARGS + for (; !bEof || (mdsk_cfg != NULL); nCfgLine++) +#else for (; !bEof; nCfgLine++) +#endif { struct table *pEntry; pLineStart = szLine; + +#ifdef MEMDISK_ARGS + if (!bEof) + { +#endif + /* read in a single line, \n or ^Z terminated */ for (pLine = szLine;;) @@ -663,9 +764,47 @@ VOID DoConfig(int nPass) pLine++; } +#ifdef MEMDISK_ARGS + } + else if (mdsk_cfg != NULL) + { + pLine = szLine; + /* copy data to near buffer skipping { and } */ + if (*mdsk_cfg != '{') /* if not at start of line */ + { + mdsk_cfg = NULL; /* no longer need data, so set to NULL to flag done */ + } + else + { + for (pLine = szLine, mdsk_cfg++; *mdsk_cfg; mdsk_cfg++, pLine++) + { + /* copy character to near buffer */ + *pLine = *mdsk_cfg; + + /* ensure we don't copy too much, exceed our buffer size */ + if (pLine >= szLine + sizeof(szLine) - 3) + { + CfgFailure(pLine); + printf("error - line overflow line %d \n", nCfgLine); + break; + } + + /* if end of this simulated line is found, skip over EOL marker then proceed to process line */ + if (*pLine == '}') + { + mdsk_cfg++; + break; + } + } + } + } +#endif + *pLine = 0; pLine = szLine; + DebugPrintf(("CONFIG=[%s]\n", pLine)); + /* Skip leading white space and get verb. */ pLine = scan(pLine, szBuf); diff --git a/kernel/makefile b/kernel/makefile index bce2e5b..935ac8f 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -20,7 +20,7 @@ error.obj OBJS4=break.obj dosfns.obj fatdir.obj fatfs.obj fattab.obj fcbfns.obj \ inthndlr.obj OBJS5=ioctl.obj memmgr.obj task.obj newstuff.obj nls.obj network.obj -OBJS6=prf.obj misc.obj strings.obj syspack.obj lfnapi.obj iasmsupt.obj +OBJS6=prf.obj misc.obj strings.obj syspack.obj lfnapi.obj iasmsupt.obj memdisk.obj OBJS7=main.obj config.obj initoem.obj inithma.obj dyninit.obj iprf.obj \ initdisk.obj initclk.obj OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS6) $(OBJS7) @@ -79,6 +79,7 @@ intr.obj: intr.asm segs.inc $(TARGET).lnk io.obj: io.asm segs.inc $(HDR)stacks.inc $(TARGET).lnk irqstack.obj: irqstack.asm segs.inc $(TARGET).lnk kernel.obj: kernel.asm segs.inc ludivmul.inc $(TARGET).lnk +memdisk.obj: memdisk.asm segs.inc $(TARGET).lnk nls_hc.obj: nls_hc.asm segs.inc $(TARGET).lnk nlssupt.obj: nlssupt.asm segs.inc $(HDR)stacks.inc $(TARGET).lnk printer.obj: printer.asm io.inc $(TARGET).lnk diff --git a/kernel/memdisk.asm b/kernel/memdisk.asm new file mode 100644 index 0000000..1daa8e8 --- /dev/null +++ b/kernel/memdisk.asm @@ -0,0 +1,81 @@ +; File: +; memdisk.asm +; Description: +; Query for memdisk provided config.sys parameters +; +; DOS-C +; Copyright (c) 2011 +; FreeDOS +; 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. +; +; + +%if XCPU == 386 ; requires 386+ registers, until CPU check implemented only allow for 386 builds + +%include "segs.inc" +segment INIT_TEXT + +CPU 386 +;********************************************************************* +; +; query_memdisk() based on similar subroutine in Eric Auer's public domain getargs.asm which is based on IFMEMDSK +; input: drive (in AL) to query if memdisk provided disk +; output: a far * to a memdiskinfo structure as defined by memdisk (see config.c) +; struct memdiskinfo FAR * query_memdisk(UBYTE drive); + global _query_memdisk + _query_memdisk: + ; save registers, assumes enough space on stack & valid stack frame setup, ax & dx return values + push es + push di + push ebx + push ecx + push edx ; we only care about high word + push eax ; we only care about high word + mov dl, al ; drive number (only argument, assumed to be in AL) + mov eax,454d0800h ; magic1 + AH=8 (get geometry) + mov ecx,444d0000h ; magic2 + mov edx,53490000h ; magic3 + + mov ebx,3f4b0000h ; magic4 + int 13h ; BIOS DISK API + shr eax,16 ; ignore AX + shr ebx,16 ; ignore BX + shr ecx,16 ; ignore CX (geometry C/S) + shr edx,16 ; ignore DX (geometry H in DH) + cmp ax,4d21h ; magic5 + jnz nomemdisk + cmp cx,4d45h ; magic6 + jnz nomemdisk + cmp dx,4944h ; magic7 + jnz nomemdisk + cmp bx,4b53h ; magic8 + jnz nomemdisk + jmp cleanup + + nomemdisk: + xor di, di ; return NULL; + mov es, di + + cleanup: + pop eax + pop edx + mov ax, di ; return MK_FP(es, di); + mov dx, es + pop ecx + pop ebx + pop di + pop es + retn + +%endif