📄 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_STRINGSstatic BYTE *mainRcsId = "$Id: main.c,v 1.84 2006/05/20 21:01:29 mceric Exp $";#endifstatic char copyright[] = "(C) Copyright 1995-2006 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_VERBYTE _acrtused = 0;__segment DosDataSeg = 0; /* serves for all references to the DOS DATA segment necessary for MSC+our funny linking model */__segment DosTextSeg = 0;#endifstruct 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();}#endifSTATIC 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); /* 3 is /dev/aux */ dup2(STDIN, STDAUX); /* 0 is /dev/con (stdin) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -