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, &regs, &regs, &sregs);
    return 1;
}

void PMAPI PM_restoreMouseHandler(void)
{
    RMREGS  regs;

    if (_PM_mouseHandler) {
	regs.x.ax = 33;
	PM_int86(0x33, &regs, &regs);
	_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, &regs, &regs, &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, &regs, &regs, &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, &regs, &regs, &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, &regs, &regs, &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,&regs,&regs);
    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,&regs,&regs);
}

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,&regs,&regs);
}
#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,&regs,&regs,&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,&regs,&regs,&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,&regs,&regs,&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, &regs, &regs);
	_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,&regs,&regs);
    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 + -
显示快捷键?