📄 main.c
字号:
/****************************************************************/
/* */
/* main.c */
/* DOS-C */
/* */
/* Main Kernel Functions */
/* */
/* Copyright (c) 1995, 1996 */
/* 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, Inc., */
/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */
/****************************************************************/
#include "portab.h"
#include "init-mod.h"
#include "dyndata.h"
#ifdef VERSION_STRINGS
static BYTE *mainRcsId =
"$Id: main.c,v 1.81 2004/05/23 22:04:42 bartoldeman Exp $";
#endif
static char copyright[] =
"(C) Copyright 1995-2004 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"
"either version 2, or (at your option) any later version.\n";
struct _KernelConfig InitKernelConfig BSS_INIT({0});
STATIC VOID InitIO(void);
STATIC VOID update_dcb(struct dhdr FAR *);
STATIC VOID init_kernel(VOID);
STATIC VOID signon(VOID);
STATIC VOID kernel(VOID);
STATIC VOID FsConfig(VOID);
STATIC VOID InitPrinters(VOID);
STATIC VOID InitSerialPorts(VOID);
STATIC void CheckContinueBootFromHarddisk(void);
STATIC void setup_int_vectors(void);
#ifdef _MSC_VER
BYTE _acrtused = 0;
__segment DosDataSeg = 0; /* serves for all references to the DOS DATA segment
necessary for MSC+our funny linking model
*/
__segment DosTextSeg = 0;
#endif
struct lol FAR *LoL = &DATASTART;
VOID ASMCFUNC FreeDOSmain(void)
{
unsigned char drv;
unsigned char FAR *p;
#ifdef _MSC_VER
extern FAR prn_dev;
DosDataSeg = (__segment) & DATASTART;
DosTextSeg = (__segment) & prn_dev;
#endif
/* clear the Init BSS area (what normally the RTL does */
memset(_ib_start, 0, _ib_end - _ib_start);
/* if the kernel has been UPX'ed,
CONFIG info is stored at 50:e2 ..fc
and the bootdrive (passed from BIOS)
at 50:e0
*/
drv = LoL->BootDrive + 1;
p = MK_FP(0, 0x5e0);
if (fmemcmp(p+2,"CONFIG",6) == 0) /* UPX */
{
fmemcpy(&InitKernelConfig, p+2, sizeof(InitKernelConfig));
drv = *p + 1;
*(DWORD FAR *)(p+2) = 0;
}
else
{
*p = drv - 1;
fmemcpy(&InitKernelConfig, &LowKernelConfig, sizeof(InitKernelConfig));
}
if (drv >= 0x80)
drv = 3; /* C: */
LoL->BootDrive = drv;
setup_int_vectors();
CheckContinueBootFromHarddisk();
signon();
init_kernel();
#ifdef DEBUG
/* Non-portable message kludge alert! */
printf("KERNEL: Boot drive = %c\n", 'A' + LoL->BootDrive - 1);
#endif
DoInstall();
kernel();
}
/*
InitializeAllBPBs()
or MakeNortonDiskEditorHappy()
it has been determined, that FDOS's BPB tables are initialized,
only when used (like DIR H:).
at least one known utility (norton DE) seems to access them directly.
ok, so we access for all drives, that the stuff gets build
*/
void InitializeAllBPBs(VOID)
{
static char filename[] = "A:-@JUNK@-.TMP";
int drive, fileno;
for (drive = 'C'; drive < 'A' + LoL->nblkdev; drive++)
{
filename[0] = drive;
if ((fileno = open(filename, O_RDONLY)) >= 0)
close(fileno);
}
}
STATIC void PSPInit(void)
{
psp far *p = MK_FP(DOS_PSP, 0);
/* Clear out new psp first */
fmemset(p, 0, sizeof(psp));
/* initialize all entries and exits */
/* CP/M-like exit point */
p->ps_exit = 0x20cd;
/* CP/M-like entry point - call far to special entry */
p->ps_farcall = 0x9a;
p->ps_reentry = MK_FP(0, 0x30 * 4);
/* unix style call - 0xcd 0x21 0xcb (int 21, retf) */
p->ps_unix[0] = 0xcd;
p->ps_unix[1] = 0x21;
p->ps_unix[2] = 0xcb;
/* Now for parent-child relationships */
/* parent psp segment */
p->ps_parent = FP_SEG(p);
/* previous psp pointer */
p->ps_prevpsp = MK_FP(0xffff,0xffff);
/* Environment and memory useage parameters */
/* memory size in paragraphs */
/* p->ps_size = 0; clear from above */
/* environment paragraph */
p->ps_environ = DOS_PSP + 8;
/* terminate address */
p->ps_isv22 = getvec(0x22);
/* break address */
p->ps_isv23 = getvec(0x23);
/* critical error address */
p->ps_isv24 = getvec(0x24);
/* user stack pointer - int 21 */
/* p->ps_stack = NULL; clear from above */
/* File System parameters */
/* maximum open files */
p->ps_maxfiles = 20;
fmemset(p->ps_files, 0xff, 20);
/* open file table pointer */
p->ps_filetab = p->ps_files;
/* first command line argument */
/* p->ps_fcb1.fcb_drive = 0; already set */
fmemset(p->ps_fcb1.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE);
/* second command line argument */
/* p->ps_fcb2.fcb_drive = 0; already set */
fmemset(p->ps_fcb2.fcb_fname, ' ', FNAME_SIZE + FEXT_SIZE);
/* local command line */
/* p->ps_cmd.ctCount = 0; command tail, already set */
p->ps_cmd.ctBuffer[0] = 0xd; /* command tail */
}
#ifndef __WATCOMC__
/* for WATCOMC we can use the ones in task.c */
intvec getvec(unsigned char intno)
{
intvec iv;
disable();
iv = *(intvec FAR *)MK_FP(0,4 * (intno));
enable();
return iv;
}
void setvec(unsigned char intno, intvec vector)
{
disable();
*(intvec FAR *)MK_FP(0,4 * intno) = vector;
enable();
}
#endif
STATIC void setup_int_vectors(void)
{
static struct vec
{
unsigned char intno;
size_t handleroff;
} vectors[] =
{
/* all of these are in the DOS DS */
{ 0x0, FP_OFF(int0_handler) }, /* zero divide */
{ 0x1, FP_OFF(empty_handler) }, /* single step */
{ 0x3, FP_OFF(empty_handler) }, /* debug breakpoint */
{ 0x6, FP_OFF(int6_handler) }, /* invalid opcode */
{ 0x20, FP_OFF(int20_handler) },
{ 0x21, FP_OFF(int21_handler) },
{ 0x22, FP_OFF(int22_handler) },
{ 0x24, FP_OFF(int24_handler) },
{ 0x25, FP_OFF(low_int25_handler) },
{ 0x26, FP_OFF(low_int26_handler) },
{ 0x27, FP_OFF(int27_handler) },
{ 0x28, FP_OFF(int28_handler) },
{ 0x2a, FP_OFF(int2a_handler) },
{ 0x2f, FP_OFF(int2f_handler) }
};
struct vec *pvec;
int i;
for (i = 0x23; i <= 0x3f; i++)
setvec(i, empty_handler);
for (pvec = vectors; pvec < vectors + (sizeof vectors/sizeof *pvec); pvec++)
setvec(pvec->intno, (intvec)MK_FP(FP_SEG(empty_handler), pvec->handleroff));
pokeb(0, 0x30 * 4, 0xea);
pokel(0, 0x30 * 4 + 1, (ULONG)cpm_entry);
/* these two are in the device driver area LOWTEXT (0x70) */
setvec(0x1b, got_cbreak);
setvec(0x29, int29_handler); /* required for printf! */
}
STATIC void init_kernel(void)
{
COUNT i;
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();
/* move kernel to high conventional RAM, just below the init code */
#ifdef __WATCOMC__
lpTop = MK_FP(_CS, 0);
#else
lpTop = MK_FP(_CS - (FP_OFF(_HMATextEnd) + 15) / 16, 0);
#endif
MoveKernel(FP_SEG(lpTop));
lpTop = MK_FP(FP_SEG(lpTop) - 0xfff, 0xfff0);
/* Initialize IO subsystem */
InitIO();
InitPrinters();
InitSerialPorts();
init_PSPSet(DOS_PSP);
set_DTA(MK_FP(DOS_PSP, 0x80));
PSPInit();
Init_clk_driver();
/* Do first initialization of system variable buffers so that */
/* we can read config.sys later. */
LoL->lastdrive = Config.cfgLastdrive;
/* init_device((struct dhdr FAR *)&blk_dev, NULL, 0, &ram_top); */
blk_dev.dh_name[0] = dsk_init();
PreConfig();
/* Number of units */
if (blk_dev.dh_name[0] > 0)
update_dcb(&blk_dev);
/* Now config the temporary file system */
FsConfig();
/* Now process CONFIG.SYS */
DoConfig(0);
DoConfig(1);
/* initialize near data and MCBs */
PreConfig2();
/* and process CONFIG.SYS one last time for device drivers */
DoConfig(2);
/* Close all (device) files */
for (i = 0; i < 20; i++)
close(i);
/* and do final buffer allocation. */
PostConfig();
/* Init the file system one more time */
FsConfig();
configDone();
InitializeAllBPBs();
}
STATIC VOID FsConfig(VOID)
{
struct dpb FAR *dpb = LoL->DPBp;
int i;
/* Initialize the current directory structures */
for (i = 0; i < LoL->lastdrive; i++)
{
struct cds FAR *pcds_table = &LoL->CDSp[i];
fmemcpy(pcds_table->cdsCurrentPath, "A:\\\0", 4);
pcds_table->cdsCurrentPath[0] += i;
if (i < LoL->nblkdev && (ULONG) dpb != 0xffffffffl)
{
pcds_table->cdsDpb = dpb;
pcds_table->cdsFlags = CDSPHYSDRV;
dpb = dpb->dpb_next;
}
else
{
pcds_table->cdsFlags = 0;
}
pcds_table->cdsStrtClst = 0xffff;
pcds_table->cdsParam = 0xffff;
pcds_table->cdsStoreUData = 0xffff;
pcds_table->cdsJoinOffset = 2;
}
/* Log-in the default drive. */
init_setdrive(LoL->BootDrive - 1);
/* The system file tables need special handling and are "hand */
/* built. Included is the stdin, stdout, stdaux and stdprn. */
/* a little bit of shuffling is necessary for compatibility */
/* sft_idx=0 is /dev/aux */
open("AUX", O_RDWR);
/* handle 1, sft_idx=1 is /dev/con (stdout) */
open("CON", O_RDWR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -