From eee2182f7bffef7bbb534519fd6cf9cf3d399809 Mon Sep 17 00:00:00 2001 From: William McBrine Date: Fri, 29 Dec 2006 17:08:21 +0000 Subject: [PATCH] Use DPMI simulate real mode interrupt for Watcom 32-bit DOS, as with DJGPP. This allows checking the flags register, which allows use of the BIOS call in PDC_check_bios_key() instead of kbhit(). If it's anything like DJGPP, it may also be more efficient in general. Stolen and modified from Angband, which stole it from DJGPP... hopefully this counts as fair use. --- dos/pdcdos.h | 50 +++++++++++++++++++++++++++++++++++++++++--------- dos/pdckbd.c | 6 +++--- dos/pdcscrn.c | 18 +++++++++++++++++- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/dos/pdcdos.h b/dos/pdcdos.h index 748ad67d..fb6339f7 100644 --- a/dos/pdcdos.h +++ b/dos/pdcdos.h @@ -11,7 +11,7 @@ * See the file maintain.er for details of the current maintainer. * ************************************************************************/ -/* $Id: pdcdos.h,v 1.22 2006/12/16 17:14:54 wmcbrine Exp $ */ +/* $Id: pdcdos.h,v 1.23 2006/12/29 17:08:21 wmcbrine Exp $ */ #include #include @@ -107,25 +107,55 @@ void setdosmemword(int offs, unsigned short w); (*((unsigned short PDC_FAR *) _FAR_POINTER(0,offs)) = (x)) #endif +#if defined(__WATCOMC__) && defined(__386__) + +typedef union +{ + struct + { + unsigned long edi, esi, ebp, res, ebx, edx, ecx, eax; + } d; + + struct + { + unsigned short di, di_hi, si, si_hi, bp, bp_hi, res, res_hi, + bx, bx_hi, dx, dx_hi, cx, cx_hi, ax, ax_hi, flags, + es, ds, fs, gs, ip, cs, sp, ss; + } w; + + struct + { + unsigned char edi[4], esi[4], ebp[4], res[4], + bl, bh, ebx_b2, ebx_b3, dl, dh, edx_b2, edx_b3, + cl, ch, ecx_b2, ecx_b3, al, ah, eax_b2, eax_b3; + } h; +} __dpmi_regs; + +void __dpmi_int(int, __dpmi_regs *); + +#endif + #ifdef __DJGPP__ # include # define PDCREGS __dpmi_regs # define PDCINT(vector, regs) __dpmi_int(vector, ®s) #else -# if defined(__WATCOMC__) && !defined(__386__) -# define PDCREGS union REGPACK -# define PDCINT(vector, regs) intr(vector, ®s) +# ifdef __WATCOMC__ +# ifdef __386__ +# define PDCREGS __dpmi_regs +# define PDCINT(vector, regs) __dpmi_int(vector, ®s) +# else +# define PDCREGS union REGPACK +# define PDCINT(vector, regs) intr(vector, ®s) +# endif # else # define PDCREGS union REGS -# if defined(__WATCOMC__) && defined(__386__) -# define PDCINT(vector, regs) int386(vector, ®s, ®s) -# else -# define PDCINT(vector, regs) int86(vector, ®s, ®s) -# endif +# define PDCINT(vector, regs) int86(vector, ®s, ®s) # endif #endif /* Wide registers in REGS: w or x? */ + #ifdef __WATCOMC__ # define W w #else @@ -133,6 +163,7 @@ void setdosmemword(int offs, unsigned short w); #endif /* Monitor (terminal) type information */ + enum { _NONE, _MDA, _CGA, @@ -143,6 +174,7 @@ enum }; /* Text-mode font size information */ + enum { _FONT8 = 8, diff --git a/dos/pdckbd.c b/dos/pdckbd.c index 4e2b5a84..e72c15e3 100644 --- a/dos/pdckbd.c +++ b/dos/pdckbd.c @@ -15,8 +15,8 @@ # include #endif -/* MS C and Watcom don't return flags from int86() */ -#if defined(MSC) || (defined(__WATCOMC__) && defined(__386__)) +/* MS C doesn't return flags from int86() */ +#ifdef MSC # define USE_KBHIT #endif @@ -26,7 +26,7 @@ #include "pdcdos.h" -RCSID("$Id: pdckbd.c,v 1.73 2006/12/24 06:07:25 wmcbrine Exp $"); +RCSID("$Id: pdckbd.c,v 1.74 2006/12/29 17:08:21 wmcbrine Exp $"); /************************************************************************ * Table for key code translation of function keys in keypad mode * diff --git a/dos/pdcscrn.c b/dos/pdcscrn.c index 4b9d528b..2fe7ee01 100644 --- a/dos/pdcscrn.c +++ b/dos/pdcscrn.c @@ -19,7 +19,7 @@ # include #endif -RCSID("$Id: pdcscrn.c,v 1.73 2006/12/28 09:51:31 wmcbrine Exp $"); +RCSID("$Id: pdcscrn.c,v 1.74 2006/12/29 17:08:21 wmcbrine Exp $"); int pdc_adapter; /* screen type */ int pdc_scrnmode; /* default screen mode */ @@ -758,3 +758,19 @@ int PDC_init_color(short color, short red, short green, short blue) return OK; } + +#if defined(__WATCOMC__) && defined(__386__) + +void __dpmi_int(int vector, __dpmi_regs *rmregs) +{ + union REGPACK regs = {0}; + + regs.w.ax = 0x300; + regs.h.bl = vector; + regs.x.edi = FP_OFF(rmregs); + regs.x.es = FP_SEG(rmregs); + + intr(0x31, ®s); +} + +#endif