From 2f4e2d3a69605a20e9c5ebe3fdbaaafde907010e Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Tue, 16 Sep 2003 12:38:02 +0000 Subject: [PATCH] * add support for the far jmp at "int 30" (0000:00c0) * mirror it for the HMA (ffff:00d0) * put all DOS int handler (and the CPM entry jumped to from int30) jumpers in the "CONST" portion of DGROUP (instead of LGROUP) This helps Turbo C++ 1.01 make with the -S (swap) switch. * adjustments to set the relevant PSP fields in task.c git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@694 6ac86273-5f31-0410-b378-82cca8765d1b --- hdr/portab.h | 4 ++++ hdr/process.h | 5 +++-- kernel/init-mod.h | 1 + kernel/inithma.c | 7 +++++++ kernel/kernel.asm | 16 +++++++++------- kernel/main.c | 2 ++ kernel/task.c | 31 ++++++++++++++++++------------- 7 files changed, 44 insertions(+), 22 deletions(-) diff --git a/hdr/portab.h b/hdr/portab.h index eecd53a..ab72e18 100644 --- a/hdr/portab.h +++ b/hdr/portab.h @@ -226,8 +226,12 @@ typedef signed long LONG; #define pokeb(seg, ofs, b) (*((unsigned char far *)MK_FP(seg,ofs)) = b) #define poke(seg, ofs, w) (*((unsigned far *)MK_FP(seg,ofs)) = w) +#define pokew poke +#define pokel(seg, ofs, l) (*((unsigned long far *)MK_FP(seg,ofs)) = l) #define peekb(seg, ofs) (*((unsigned char far *)MK_FP(seg,ofs))) #define peek(seg, ofs) (*((unsigned far *)MK_FP(seg,ofs))) +#define peekw peek +#define peekl(seg, ofs) (*((unsigned long far *)MK_FP(seg,ofs))) #if defined(__TURBOC__) && (__TURBOC__ > 0x202) #define FP_SEG(fp) ((unsigned)(void _seg *)(void far *)(fp)) diff --git a/hdr/process.h b/hdr/process.h index 44f33cd..2b654d7 100644 --- a/hdr/process.h +++ b/hdr/process.h @@ -62,8 +62,9 @@ typedef struct { #define load ldata._load typedef struct { - UWORD ps_exit; /* 00 CP/M-like exit poimt */ - UWORD ps_size; /* 02 memory size in paragraphs */ + UWORD ps_exit; /* 00 CP/M-like exit point: int 20 */ + UWORD ps_size; /* 02 segment of first byte beyond */ + /* memory allocated to program */ BYTE ps_fill1; /* 04 single char fill */ /* CP/M-like entry point */ diff --git a/kernel/init-mod.h b/kernel/init-mod.h index 1f8d36c..45fb133 100644 --- a/kernel/init-mod.h +++ b/kernel/init-mod.h @@ -183,6 +183,7 @@ VOID ASMCFUNC FAR int28_handler(void); VOID ASMCFUNC FAR int29_handler(void); VOID ASMCFUNC FAR int2a_handler(void); VOID ASMCFUNC FAR int2f_handler(void); +VOID ASMCFUNC FAR cpm_entry(void); /* main.c */ VOID ASMCFUNC FreeDOSmain(void); diff --git a/kernel/inithma.c b/kernel/inithma.c index 5f50b6c..73aef6e 100644 --- a/kernel/inithma.c +++ b/kernel/inithma.c @@ -408,6 +408,13 @@ void MoveKernel(unsigned NewKernelSegment) rp->jmpSegment = NewKernelSegment; } + + if (NewKernelSegment == 0xffff) + { + /* jmp far cpm_entry (copy from 0:c0) */ + pokeb(0xffff, 0x30 * 4 + 0x10, 0xea); + pokel(0xffff, 0x30 * 4 + 0x11, (ULONG)cpm_entry); + } } CurrentKernelSegment = NewKernelSegment; diff --git a/kernel/kernel.asm b/kernel/kernel.asm index 216f542..219760e 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -718,6 +718,10 @@ begin_hma: times 20h db 0 db 0 +; to minimize relocations + global _DGROUP_ +_DGROUP_ dw DGROUP + %ifdef WATCOM ; 32 bit multiplication + division global __U4M @@ -728,6 +732,10 @@ __U4D: LDIVMODU %endif + resb 0xd0 - ($-begin_hma) + ; reserve space for far jump to cp/m routine + resb 5 + ;End of HMA segment segment HMA_TEXT_END global __HMATextEnd @@ -744,7 +752,7 @@ segment _STACK class=STACK stack -segment _LOWTEXT +segment CONST ; dummy interrupt return handlers global _int22_handler @@ -931,7 +939,6 @@ noNeedToDisable: iret -segment _LOWTEXT ; ; Default Int 24h handler -- always returns fail ; so we have not to relocate it (now) @@ -946,11 +953,6 @@ _int24_handler: mov al,FAIL ; this makes some things easier ; -; to minimize relocations -segment HMA_TEXT - global _DGROUP_ -_DGROUP_ dw DGROUP - segment _LOWTEXT global _TEXT_DGROUP _TEXT_DGROUP dw DGROUP diff --git a/kernel/main.c b/kernel/main.c index 7f49307..669f2cc 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -215,6 +215,8 @@ STATIC void init_kernel(void) setvec(0x28, int28_handler); setvec(0x2a, int2a_handler); setvec(0x2f, int2f_handler); + pokeb(0, 0x30 * 4, 0xea); + pokel(0, 0x30 * 4 + 1, (ULONG)cpm_entry); init_PSPSet(DOS_PSP); set_DTA(MK_FP(DOS_PSP, 0x80)); diff --git a/kernel/task.c b/kernel/task.c index 2039203..8581645 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -171,9 +171,9 @@ void new_psp(seg para, int psize) /* CP/M-like exit point */ p->ps_exit = 0x20cd; - /* CP/M-like entry point - jump to special entry */ - p->ps_farcall = 0xea; - p->ps_reentry = cpm_entry; + /* 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; @@ -470,21 +470,26 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) { UWORD fcbcode; - + psp FAR *p; + /* point to the PSP so we can build it */ setvec(0x22, MK_FP(user_r->CS, user_r->IP)); new_psp(mem, mem + asize); - + fcbcode = patchPSP(mem - 1, env, exp, namep); /* set asize to end of segment */ - if (asize < 0x1000) - asize = (asize << 4) - 2; - else - asize = 0xfffe; - /* TODO: worry about PSP+6: - CP/M compatibility--size of first segment for .COM files, - while preserving the far call */ - + if (asize > 0x1000) + asize = 0x1000; + if (asize < 0x11) + return DE_NOMEM; + asize -= 0x11; + /* CP/M compatibility--size of first segment for .COM files + while preserving the far call to 0:00c0 + + copy in HMA at ffff:00d0 */ + p = MK_FP(mem, 0); + p->ps_reentry = MK_FP(0xc - asize, asize << 4); + asize <<= 4; + asize += 0x10e; exp->exec.stack = MK_FP(mem, asize); exp->exec.start_addr = MK_FP(mem, 0x100); *((UWORD FAR *) MK_FP(mem, asize)) = (UWORD) 0;