pmdos.c
来自「适合KS8695X」· C语言 代码 · 共 1,638 行 · 第 1/4 页
C
1,638 行
}
PM_memcpyfn(*psel,*poff,realHandler,sizeof(realHandler));
/* Skip past global variables in real mode code segment */
*roff += 0x0A;
return 1;
}
int PMAPI PM_setMouseHandler(int mask, PM_mouseHandler mh)
{
RMREGS regs;
RMSREGS sregs;
uint rseg,roff;
lockPMHandlers(); /* Ensure our handlers are locked */
if (!installCallback(_PM_mouseISR, &mouseSel, &mouseOff, &rseg, &roff))
return 0;
_PM_mouseHandler = mh;
/* Install the real mode mouse handler */
sregs.es = rseg;
regs.x.dx = roff;
regs.x.cx = _PM_mouseMask = mask;
regs.x.ax = 0xC;
PM_int86x(0x33, ®s, ®s, &sregs);
return 1;
}
void PMAPI PM_restoreMouseHandler(void)
{
RMREGS regs;
if (_PM_mouseHandler) {
regs.x.ax = 33;
PM_int86(0x33, ®s, ®s);
_PM_mouseHandler = NULL;
}
}
void PMAPI PM_getPMvect(int intno, PMFARPTR *isr)
{
PMREGS regs;
PMSREGS sregs;
PM_segread(&sregs);
regs.x.ax = 0x2502; /* Get PM interrupt vector */
regs.x.cx = intno;
PM_int386x(0x21, ®s, ®s, &sregs);
isr->sel = sregs.es;
isr->off = regs.e.ebx;
}
void PMAPI PM_setPMvect(int intno, PM_intHandler isr)
{
PMFARPTR pmisr;
PMSREGS sregs;
PM_saveDS();
PM_segread(&sregs);
pmisr.sel = sregs.cs;
pmisr.off = (uint)isr;
PM_restorePMvect(intno, pmisr);
}
void PMAPI PM_restorePMvect(int intno, PMFARPTR isr)
{
PMREGS regs;
PMSREGS sregs;
PM_segread(&sregs);
regs.x.ax = 0x2505; /* Set PM interrupt vector */
regs.x.cx = intno;
sregs.ds = isr.sel;
regs.e.edx = isr.off;
PM_int386x(0x21, ®s, ®s, &sregs);
}
static void getISR(int intno, PMFARPTR *pmisr, long *realisr)
{
PM_getPMvect(intno,pmisr);
_PM_getRMvect(intno,realisr);
}
static void restoreISR(int intno, PMFARPTR pmisr, long realisr)
{
PMREGS regs;
PMSREGS sregs;
PM_segread(&sregs);
regs.x.ax = 0x2507; /* Set real and PM vectors */
regs.x.cx = intno;
sregs.ds = pmisr.sel;
regs.e.edx = pmisr.off;
regs.e.ebx = realisr;
PM_int386x(0x21, ®s, ®s, &sregs);
}
static void setISR(int intno, void *isr)
{
PMREGS regs;
PMSREGS sregs;
lockPMHandlers(); /* Ensure our handlers are locked */
PM_segread(&sregs);
regs.x.ax = 0x2506; /* Hook real and protected vectors */
regs.x.cx = intno;
sregs.ds = sregs.cs;
regs.e.edx = (uint)isr;
PM_int386x(0x21, ®s, ®s, &sregs);
}
void PMAPI PM_setTimerHandler(PM_intHandler th)
{
getISR(0x8, &_PM_prevTimer, &_PM_prevRealTimer);
_PM_timerHandler = th;
setISR(0x8, _PM_timerISR);
}
void PMAPI PM_restoreTimerHandler(void)
{
if (_PM_timerHandler) {
restoreISR(0x8, _PM_prevTimer, _PM_prevRealTimer);
_PM_timerHandler = NULL;
}
}
ibool PMAPI PM_setRealTimeClockHandler(PM_intHandler th,int frequency)
{
/* Save the old CMOS real time clock values */
_PM_oldCMOSRegA = _PM_readCMOS(0x0A);
_PM_oldCMOSRegB = _PM_readCMOS(0x0B);
/* Set the real time clock interrupt handler */
getISR(0x70, &_PM_prevRTC, &_PM_prevRealRTC);
_PM_rtcHandler = th;
setISR(0x70, _PM_rtcISR);
/* Program the real time clock default frequency */
PM_setRealTimeClockFrequency(frequency);
/* Unmask IRQ8 in the PIC2 */
_PM_oldRTCPIC2 = PM_inpb(0xA1);
PM_outpb(0xA1,_PM_oldRTCPIC2 & 0xFE);
return true;
}
void PMAPI PM_restoreRealTimeClockHandler(void)
{
if (_PM_rtcHandler) {
/* Restore CMOS registers and mask RTC clock */
_PM_writeCMOS(0x0A,_PM_oldCMOSRegA);
_PM_writeCMOS(0x0B,_PM_oldCMOSRegB);
PM_outpb(0xA1,(PM_inpb(0xA1) & 0xFE) | (_PM_oldRTCPIC2 & ~0xFE));
/* Restore the interrupt vector */
restoreISR(0x70, _PM_prevRTC, _PM_prevRealRTC);
_PM_rtcHandler = NULL;
}
}
void PMAPI PM_setKeyHandler(PM_intHandler kh)
{
getISR(0x9, &_PM_prevKey, &_PM_prevRealKey);
_PM_keyHandler = kh;
setISR(0x9, _PM_keyISR);
}
void PMAPI PM_restoreKeyHandler(void)
{
if (_PM_keyHandler) {
restoreISR(0x9, _PM_prevKey, _PM_prevRealKey);
_PM_keyHandler = NULL;
}
}
void PMAPI PM_setKey15Handler(PM_key15Handler kh)
{
getISR(0x15, &_PM_prevKey15, &_PM_prevRealKey15);
_PM_key15Handler = kh;
setISR(0x15, _PM_key15ISR);
}
void PMAPI PM_restoreKey15Handler(void)
{
if (_PM_key15Handler) {
restoreISR(0x15, _PM_prevKey15, _PM_prevRealKey15);
_PM_key15Handler = NULL;
}
}
void PMAPI PM_installAltBreakHandler(PM_breakHandler bh)
{
static int ctrlCFlag,ctrlBFlag;
_PM_ctrlCPtr = (uchar*)&ctrlCFlag;
_PM_ctrlBPtr = (uchar*)&ctrlBFlag;
getISR(0x1B, &_PM_prevBreak, &prevRealBreak);
getISR(0x23, &_PM_prevCtrlC, &prevRealCtrlC);
_PM_breakHandler = bh;
setISR(0x1B, _PM_breakISR);
setISR(0x23, _PM_ctrlCISR);
}
void PMAPI PM_installBreakHandler(void)
{
PM_installAltBreakHandler(NULL);
}
void PMAPI PM_restoreBreakHandler(void)
{
if (_PM_prevBreak.sel) {
restoreISR(0x1B, _PM_prevBreak, prevRealBreak);
restoreISR(0x23, _PM_prevCtrlC, prevRealCtrlC);
_PM_prevBreak.sel = 0;
_PM_breakHandler = NULL;
}
}
void PMAPI PM_installAltCriticalHandler(PM_criticalHandler ch)
{
static short critBuf[2];
_PM_critPtr = (uchar*)critBuf;
getISR(0x24, &_PM_prevCritical, &prevRealCritical);
_PM_critHandler = ch;
setISR(0x24, _PM_criticalISR);
}
void PMAPI PM_installCriticalHandler(void)
{
PM_installAltCriticalHandler(NULL);
}
void PMAPI PM_restoreCriticalHandler(void)
{
if (_PM_prevCritical.sel) {
restoreISR(0x24, _PM_prevCritical, prevRealCritical);
_PM_prevCritical.sel = 0;
_PM_critHandler = NULL;
}
}
int PMAPI PM_lockDataPages(void *p,uint len,PM_lockHandle *lh)
{
return (_x386_memlock(p,len) == 0);
}
int PMAPI PM_unlockDataPages(void *p,uint len,PM_lockHandle *lh)
{
return (_x386_memunlock(p,len) == 0);
}
int PMAPI PM_lockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
{
return (_x386_memlock(p,len) == 0);
}
int PMAPI PM_unlockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
{
return (_x386_memunlock(p,len) == 0);
}
#endif
/*-------------------------------------------------------------------------*/
/* Borland's DPMI32 DOS Power Pack Extender support. */
/*-------------------------------------------------------------------------*/
#ifdef DPMI32
#define GENERIC_DPMI32 /* Use generic 32 bit DPMI routines */
void PMAPI PM_getPMvect(int intno, PMFARPTR *isr)
{
PMREGS regs;
regs.x.ax = 0x204;
regs.h.bl = intno;
PM_int386(0x31,®s,®s);
isr->sel = regs.x.cx;
isr->off = regs.e.edx;
}
void PMAPI PM_setPMvect(int intno, PM_intHandler isr)
{
PMSREGS sregs;
PMREGS regs;
PM_saveDS();
regs.x.ax = 0x205; /* Set protected mode vector */
regs.h.bl = intno;
PM_segread(&sregs);
regs.x.cx = sregs.cs;
regs.e.edx = (uint)isr;
PM_int386(0x31,®s,®s);
}
void PMAPI PM_restorePMvect(int intno, PMFARPTR isr)
{
PMREGS regs;
regs.x.ax = 0x205;
regs.h.bl = intno;
regs.x.cx = isr.sel;
regs.e.edx = isr.off;
PM_int386(0x31,®s,®s);
}
#endif
/*-------------------------------------------------------------------------*/
/* Watcom C/C++ with Rational DOS/4GW support. */
/*-------------------------------------------------------------------------*/
#ifdef DOS4GW
#define GENERIC_DPMI32 /* Use generic 32 bit DPMI routines */
#define MOUSE_SUPPORTED /* DOS4GW directly supports mouse */
/* We use the normal DOS services to save and restore interrupts handlers
* for Watcom C++, because using the direct DPMI functions does not
* appear to work properly. At least if we use the DPMI functions, we
* dont get the auto-passup feature that we need to correctly trap
* real and protected mode interrupts without installing Bi-model
* interrupt handlers.
*/
void PMAPI PM_getPMvect(int intno, PMFARPTR *isr)
{
PMREGS regs;
PMSREGS sregs;
PM_segread(&sregs);
regs.h.ah = 0x35;
regs.h.al = intno;
PM_int386x(0x21,®s,®s,&sregs);
isr->sel = sregs.es;
isr->off = regs.e.ebx;
}
void PMAPI PM_setPMvect(int intno, PM_intHandler isr)
{
PMREGS regs;
PMSREGS sregs;
PM_saveDS();
PM_segread(&sregs);
regs.h.ah = 0x25;
regs.h.al = intno;
sregs.ds = sregs.cs;
regs.e.edx = (uint)isr;
PM_int386x(0x21,®s,®s,&sregs);
}
void PMAPI PM_restorePMvect(int intno, PMFARPTR isr)
{
PMREGS regs;
PMSREGS sregs;
PM_segread(&sregs);
regs.h.ah = 0x25;
regs.h.al = intno;
sregs.ds = isr.sel;
regs.e.edx = isr.off;
PM_int386x(0x21,®s,®s,&sregs);
}
int PMAPI PM_setMouseHandler(int mask, PM_mouseHandler mh)
{
lockPMHandlers(); /* Ensure our handlers are locked */
_PM_mouseHandler = mh;
_PM_setMouseHandler(_PM_mouseMask = mask);
return 1;
}
void PMAPI PM_restoreMouseHandler(void)
{
PMREGS regs;
if (_PM_mouseHandler) {
regs.x.ax = 33;
PM_int386(0x33, ®s, ®s);
_PM_mouseHandler = NULL;
}
}
#endif
/*-------------------------------------------------------------------------*/
/* DJGPP port of GNU C++ support. */
/*-------------------------------------------------------------------------*/
#ifdef DJGPP
#define GENERIC_DPMI32 /* Use generic 32 bit DPMI routines */
void PMAPI PM_getPMvect(int intno, PMFARPTR *isr)
{
PMREGS regs;
regs.x.ax = 0x204;
regs.h.bl = intno;
PM_int386(0x31,®s,®s);
isr->sel = regs.x.cx;
isr->off = regs.e.edx;
}
void PMAPI PM_setPMvect(int intno, PM_intHandler isr)
{
PMSREGS sregs;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?