From c07577cbfb5d43462b668f4f27cde63a9a2b9232 Mon Sep 17 00:00:00 2001 From: Tee-Kiah Chia Date: Sat, 7 Dec 2019 21:18:39 +0800 Subject: [PATCH] (Mostly) fix gcc-ia16 code for non-stack-switching int21 funcs. --- kernel/entry.asm | 31 +++++++++++++++++++++++++++---- kernel/inthndlr.c | 20 ++++++++++++++++++-- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/kernel/entry.asm b/kernel/entry.asm index 3d2b175..fa0f5c6 100644 --- a/kernel/entry.asm +++ b/kernel/entry.asm @@ -236,6 +236,10 @@ reloc_call_int20_handler: ; int21_handler(iregs UserRegs) ; reloc_call_int21_handler: + cmp ah,25h + je int21_func25 + cmp ah,35h + je int21_func35 ; ; Create the stack frame for C call. This is done to ; preserve machine state and provide a C structure for @@ -262,12 +266,8 @@ int21_reentry: mov dx,[cs:_DGROUP_] mov ds,dx - cmp ah,25h - je int21_user cmp ah,33h je int21_user - cmp ah,35h - je int21_user cmp ah,50h je int21_user cmp ah,51h @@ -285,6 +285,29 @@ int21_user: pop cx jmp short int21_ret +int21_func25: + push es + push bx + xor bx,bx + mov es,bx + mov bl,al + shl bx,1 + shl bx,1 + mov [es:bx],dx + mov [es:bx+2],ds + pop bx + pop es + iret + +int21_func35: + xor bx,bx + mov es,bx + mov bl,al + shl bx,1 + shl bx,1 + les bx,[es:bx] + iret + ; ; normal entry, use one of our 4 stacks ; diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index 6bbfe81..fb5352f 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -63,16 +63,26 @@ struct HugeSectorBlock { /* variables needed for the rest of the handler. */ /* this here works on the users stack !! and only very few functions are allowed */ + +/* TODO: really, really make sure that this function works properly */ +/* even when SS != DGROUP (some changes to the compiler (!) may be */ +/* necessary). Currently, between Turbo C++, gcc-ia16, & Open Watcom, */ +/* it seems only Watcom has explicit support for calling near-data */ +/* functions with SS != DGROUP. The code for this function happens to */ +/* to compile under gcc-ia16 to correctly-behaving code _for now_. But */ +/* it will be better to be able to guarantee this. -- tkchia 20191207 */ VOID ASMCFUNC int21_syscall(iregs FAR * irp) { Int21AX = irp->AX; switch (irp->AH) { - /* Set Interrupt Vector */ + /* Set Interrupt Vector - now implemented in entry.asm */ +#if 0 case 0x25: setvec(irp->AL, (intvec)MK_FP(irp->DS, irp->DX)); break; +#endif /* DosVars - get/set dos variables */ case 0x33: @@ -140,12 +150,17 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp) /* Get DOS-C release string pointer */ case 0xff: +#ifndef __GNUC__ irp->DX = FP_SEG(os_release); +#else /* TODO: remove this hacky SS != DGROUP workaround --tkchia 20191207 */ + asm volatile("movw %%ds, %0" : "=g" (irp->DX)); +#endif irp->AX = FP_OFF(os_release); } break; - /* Get Interrupt Vector */ + /* Get Interrupt Vector - now implemented in entry.asm */ +#if 0 case 0x35: { intvec p = getvec(irp->AL); @@ -153,6 +168,7 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp) irp->BX = FP_OFF(p); break; } +#endif /* Set PSP */ case 0x50: