📄 config.c
字号:
#ifdef DEBUG
printf("Final: \n f_node 0x%p\n", LoL->f_nodes);
/* printf(" FCB table 0x%p\n",LoL->FCBp);*/
printf(" sft table 0x%p\n", LoL->sfthead->sftt_next);
printf(" CDS table 0x%p\n", LoL->CDSp);
printf(" DPB table 0x%p\n", LoL->DPBp);
#endif
if (Config.cfgStacks)
{
VOID FAR *stackBase =
KernelAlloc(Config.cfgStacks * Config.cfgStackSize, 'S',
Config.cfgStacksHigh);
init_stacks(stackBase, Config.cfgStacks, Config.cfgStackSize);
DebugPrintf(("Stacks allocated at %p\n", stackBase));
}
DebugPrintf(("Allocation completed: top at 0x%x\n", base_seg));
}
/* This code must be executed after device drivers has been loaded */
VOID configDone(VOID)
{
if (UmbState == 1)
para2far(base_seg)->m_type = MCB_LAST;
if (HMAState != HMA_DONE)
{
mcb FAR *p;
unsigned short kernel_seg;
unsigned short hma_paras = (HMAFree+0xf)/16;
kernel_seg = allocmem(hma_paras);
p = para2far(kernel_seg - 1);
p->m_name[0] = 'S';
p->m_name[1] = 'C';
p->m_psp = 8;
DebugPrintf(("HMA not available, moving text to %x\n", kernel_seg));
MoveKernel(kernel_seg);
kernel_seg += hma_paras + 1;
DebugPrintf(("kernel is low, start alloc at %x", kernel_seg));
}
/* The standard handles should be reopened here, because
we may have loaded new console or printer drivers in CONFIG.SYS */
}
STATIC seg prev_mcb(seg cur_mcb, seg start)
{
/* determine prev mcb */
seg mcb_prev, mcb_next;
mcb_prev = mcb_next = start;
while (mcb_next < cur_mcb && para2far(mcb_next)->m_type == MCB_NORMAL)
{
mcb_prev = mcb_next;
mcb_next += para2far(mcb_prev)->m_size + 1;
}
return mcb_prev;
}
STATIC void umb_init(void)
{
UCOUNT umb_seg, umb_size;
seg umb_max;
void far *xms_addr;
if ((xms_addr = DetectXMSDriver()) == NULL)
return;
if (UMB_get_largest(xms_addr, &umb_seg, &umb_size))
{
UmbState = 1;
/* reset root */
LoL->uppermem_root = ram_top * 64 - 1;
/* create link mcb (below) */
para2far(base_seg)->m_type = MCB_NORMAL;
para2far(base_seg)->m_size--;
mumcb_init(LoL->uppermem_root, umb_seg - LoL->uppermem_root - 1);
/* setup the real mcb for the devicehigh block */
mcb_init(umb_seg, umb_size - 2, MCB_NORMAL);
umb_base_seg = umb_max = umb_start = umb_seg;
UMB_top = umb_size;
/* there can be more UMB's !
this happens, if memory mapped devces are in between
like UMB memory c800..c8ff, d8ff..efff with device at d000..d7ff
However some of the xxxHIGH commands still only work with
the first UMB.
*/
while (UMB_get_largest(xms_addr, &umb_seg, &umb_size))
{
seg umb_prev, umb_next;
/* setup the real mcb for the devicehigh block */
mcb_init(umb_seg, umb_size - 2, MCB_NORMAL);
/* determine prev and next umbs */
umb_prev = prev_mcb(umb_seg, LoL->uppermem_root);
umb_next = umb_prev + para2far(umb_prev)->m_size + 1;
if (umb_seg < umb_max)
{
if (umb_next - umb_seg - umb_size == 0)
{
/* should the UMB driver return
adjacent memory in several pieces */
umb_size += para2far(umb_next)->m_size + 1;
para2far(umb_seg)->m_size = umb_size;
}
else
{
/* create link mcb (above) */
mumcb_init(umb_seg + umb_size - 1, umb_next - umb_seg - umb_size);
}
}
else /* umb_seg >= umb_max */
{
umb_prev = umb_next;
}
if (umb_seg - umb_prev - 1 == 0)
/* should the UMB driver return
adjacent memory in several pieces */
para2far(prev_mcb(umb_prev, LoL->uppermem_root))->m_size += umb_size;
else
{
/* create link mcb (below) */
mumcb_init(umb_prev, umb_seg - umb_prev - 1);
}
if (umb_seg > umb_max)
umb_max = umb_seg;
}
para2far(umb_max)->m_size++;
para2far(umb_max)->m_type = MCB_LAST;
DebugPrintf(("UMB Allocation completed: start at 0x%x\n", umb_base_seg));
}
}
VOID DoConfig(int nPass)
{
COUNT nFileDesc;
BYTE *pLine;
BOOL bEof;
/* Check to see if we have a config.sys file. If not, just */
/* exit since we don't force the user to have one. */
if ((nFileDesc = open("fdconfig.sys", 0)) >= 0)
{
DebugPrintf(("Reading FDCONFIG.SYS...\n"));
}
else
{
DebugPrintf(("FDCONFIG.SYS not found\n"));
if ((nFileDesc = open("config.sys", 0)) < 0)
{
DebugPrintf(("CONFIG.SYS not found\n"));
return;
}
DebugPrintf(("Reading CONFIG.SYS...\n"));
}
/* Have one -- initialize. */
nCfgLine = 0;
bEof = 0;
pLine = szLine;
/* Read each line into the buffer and then parse the line, */
/* do the table lookup and execute the handler for that */
/* function. */
for (; !bEof; nCfgLine++)
{
struct table *pEntry;
pLineStart = szLine;
/* read in a single line, \n or ^Z terminated */
for (pLine = szLine;;)
{
if (read(nFileDesc, pLine, 1) <= 0)
{
bEof = TRUE;
break;
}
if (pLine >= szLine + sizeof(szLine) - 3)
{
CfgFailure(pLine);
printf("error - line overflow line %d \n", nCfgLine);
break;
}
if (*pLine == '\n' || *pLine == EOF) /* end of line */
break;
if (*pLine != '\r') /* ignore CR */
pLine++;
}
*pLine = 0;
pLine = szLine;
/* Skip leading white space and get verb. */
pLine = scan(pLine, szBuf);
/* If the line was blank, skip it. Otherwise, look up */
/* the verb and execute the appropriate function. */
if (*szBuf == '\0')
continue;
pEntry = LookUp(commands, szBuf);
if (pEntry->pass >= 0 && pEntry->pass != nPass)
continue;
if (nPass == 0) /* pass 0 always executed (rem Menu prompt switches) */
{
pEntry->func(pLine);
continue;
}
else
{
if (SkipLine(pLineStart)) /* F5/F8 processing */
continue;
}
if ((pEntry->func != CfgMenu) && (pEntry->func != CfgMenuEsc))
{
/* compatibility "device foo.sys" */
if (' ' != *pLine && '\t' != *pLine && '=' != *pLine)
{
CfgFailure(pLine);
continue;
}
pLine = skipwh(pLine);
}
if ('=' == *pLine || pEntry->func == CfgMenu || pEntry->func == CfgMenuEsc)
pLine = skipwh(pLine+1);
/* YES. DO IT */
pEntry->func(pLine);
}
close(nFileDesc);
if (nPass == 0)
{
DoMenu();
}
}
STATIC struct table * LookUp(struct table *p, BYTE * token)
{
while (p->entry[0] != '\0' && !strcaseequal(p->entry, token))
++p;
return p;
}
/*
get BIOS key with timeout:
timeout < 0: no timeout
timeout = 0: poll only once
timeout > 0: timeout in seconds
return
0xffff : no key hit
0xHH.. : scancode in upper half
0x..LL : asciicode in lower half
*/
#define GetBiosTime() peekl(0, 0x46c)
UWORD GetBiosKey(int timeout)
{
iregs r;
ULONG startTime = GetBiosTime();
if (timeout >= 0) do
{
r.a.x = 0x0100; /* are there keys available ? */
init_call_intr(0x16, &r);
if ((unsigned)(GetBiosTime() - startTime) >= timeout * 18u)
return 0xffff;
}
while (r.flags & FLG_ZERO);
/* key available or blocking wait (timeout < 0): fetch it */
r.a.x = 0x0000;
init_call_intr(0x16, &r);
return r.a.x;
}
STATIC BOOL SkipLine(char *pLine)
{
short key;
if (InitKernelConfig.SkipConfigSeconds >= 0)
{
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 */
{
SkipAllConfig = TRUE;
}
else if (key == 0x4200) /* F8 */
{
singleStep = TRUE;
}
printf("\r%79s\r", ""); /* clear line */
if (SkipAllConfig)
printf("Skipping CONFIG.SYS/AUTOEXEC.BAT\n");
}
if (SkipAllConfig)
return TRUE;
/* 1?device=CDROM.SYS */
/* 12?device=OAKROM.SYS */
/* 123?device=EMM386.EXE NOEMS */
if ( MenuLine != 0 &&
(MenuLine & (1 << MenuSelected)) == 0)
return TRUE;
if (DontAskThisSingleCommand) /* !files=30 */
return FALSE;
if (!askThisSingleCommand && !singleStep)
return FALSE;
printf("%s[Y,N]?", pLine);
for (;;)
{
key = GetBiosKey(-1);
switch (toupper(key & 0x00ff))
{
case 'N':
case 'n':
printf("N\n");
return TRUE;
case 0x1b: /* don't know where documented
ESCAPE answers all following questions
with YES
*/
singleStep = FALSE; /* and fall through */
case '\r':
case '\n':
case 'Y':
case 'y':
printf("Y\n");
return FALSE;
}
if (key == 0x3f00) /* YES, you may hit F5 here, too */
{
printf("N\n");
SkipAllConfig = TRUE;
return TRUE;
}
}
}
/* JPP - changed so will accept hex number. */
/* ea - changed to accept hex digits in hex numbers */
STATIC char *GetNumArg(char *p, int *num)
{
static char digits[] = "0123456789ABCDEF";
unsigned char base = 10;
int sign = 1;
int n = 0;
/* look for NUMBER */
p = skipwh(p);
if (*p == '-')
{
p++;
sign = -1;
}
else if (!isnum(*p))
{
CfgFailure(p);
return NULL;
}
for( ; *p; p++)
{
char ch = toupper(*p);
if (ch == 'X')
base = 16;
else
{
char *q = strchr(digits, ch);
if (q == NULL)
break;
n = n * base + (q - digits);
}
}
*num = n * sign;
return p;
}
BYTE *GetStringArg(BYTE * pLine, BYTE * pszString)
{
/* look for STRING */
pLine = skipwh(pLine);
/* just return whatever string is there, including null */
return scan(pLine, pszString);
}
STATIC void Config_Buffers(BYTE * pLine)
{
COUNT nBuffers;
/* Get the argument */
if (GetNumArg(pLine, &nBuffers))
Config.cfgBuffers = nBuffers;
}
/**
Set screen mode - rewritten to use init_call_intr() by RE / ICD
*/
STATIC VOID sysScreenMode(BYTE * pLine)
{
iregs r;
COUNT nMode;
COUNT nFunc = 0x11;
/* Get the argument */
if (GetNumArg(pLine, &nMode) == (BYTE *) 0)
return;
if(nMode<0x10)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -