pmdos.c

来自「适合KS8695X」· C语言 代码 · 共 1,638 行 · 第 1/4 页

C
1,638
字号
    return 1;
}

int PMAPI PM_unlockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
{
    p = p;  len = len;      /* Do nothing for real mode */
    return 1;
}

void PMAPI PM_getPMvect(int intno, PMFARPTR *isr)
{
    long t;
    _PM_getRMvect(intno,&t);
    *isr = (void*)t;
}

void PMAPI PM_setPMvect(int intno, PM_intHandler isr)
{
    PM_saveDS();
    _PM_setRMvect(intno,(long)isr);
}

void PMAPI PM_restorePMvect(int intno, PMFARPTR isr)
{
    _PM_setRMvect(intno,(long)isr);
}

#endif

/*-------------------------------------------------------------------------*/
/* Phar Lap TNT DOS Extender support.                                      */
/*-------------------------------------------------------------------------*/

#ifdef TNT

#include <pldos32.h>
#include <pharlap.h>
#include <hw386.h>

static long prevRealBreak;      /* Previous real mode break handler     */
static long prevRealCtrlC;      /* Previous real mode CtrlC handler     */
static long prevRealCritical;   /* Prev real mode critical handler      */
static uchar *mousePtr;

/* The following real mode routine is used to call a 32 bit protected
 * mode FAR function from real mode. We use this for passing up control
 * from the real mode mouse callback to our protected mode code.
 */

static UCHAR realHandler[] = {      /* Real mode code generic handler   */
    0x00,0x00,0x00,0x00,            /* __PM_callProtp                   */
    0x00,0x00,                      /* __PM_protCS                      */
    0x00,0x00,0x00,0x00,            /* __PM_protHandler                 */
    0x66,0x60,                      /*  pushad                          */
    0x1E,                           /*  push    ds                      */
    0x6A,0x00,                      /*  push    0                       */
    0x6A,0x00,                      /*  push    0                       */
    0x2E,0xFF,0x36,0x04,0x00,       /*  push    [cs:__PM_protCS]        */
    0x66,0x2E,0xFF,0x36,0x06,0x00,  /*  push    [cs:__PM_protHandler]   */
    0x2E,0xFF,0x1E,0x00,0x00,       /*  call    [cs:__PM_callProtp]     */
    0x83,0xC4,0x0A,                 /*  add     sp,10                   */
    0x1F,                           /*  pop     ds                      */
    0x66,0x61,                      /*  popad                           */
    0xCB,                           /*  retf                            */
    };

/* The following functions installs the above realmode callback mechanism
 * in real mode memory for calling the protected mode routine.
 */

uchar * installCallback(void (PMAPI *pmCB)(),uint *rseg, uint *roff)
{
    CONFIG_INF  config;
    REALPTR     realBufAdr,callProtp;
    ULONG       bufSize;
    FARPTR      protBufAdr;
    uchar       *p;

    /* Get address of real mode routine to call up to protected mode    */
    _dx_rmlink_get(&callProtp, &realBufAdr, &bufSize, &protBufAdr);
    _dx_config_inf(&config, (UCHAR*)&config);

    /* Fill in the values in the real mode code segment so that it will
     * call the correct routine.
     */
    *((REALPTR*)&realHandler[0]) = callProtp;
    *((USHORT*)&realHandler[4]) = config.c_cs_sel;
    *((ULONG*)&realHandler[6]) = (ULONG)pmCB;

    /* Copy the real mode handler to real mode memory   */
    if ((p = PM_allocRealSeg(sizeof(realHandler),rseg,roff)) == NULL)
	return NULL;
    memcpy(p,realHandler,sizeof(realHandler));

    /* Skip past global variabls in real mode code segment */
    *roff += 0x0A;
    return p;
}

int PMAPI PM_setMouseHandler(int mask, PM_mouseHandler mh)
{
    RMREGS      regs;
    RMSREGS     sregs;
    uint        rseg,roff;

    lockPMHandlers();           /* Ensure our handlers are locked   */

    if ((mousePtr = installCallback(_PM_mouseISR, &rseg, &roff)) == NULL)
	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_freeRealSeg(mousePtr);
	_PM_mouseHandler = NULL;
	}
}

void PMAPI PM_getPMvect(int intno, PMFARPTR *isr)
{
    FARPTR  ph;

    _dx_pmiv_get(intno, &ph);
    isr->sel = FP_SEL(ph);
    isr->off = FP_OFF(ph);
}

void PMAPI PM_setPMvect(int intno, PM_intHandler isr)
{
    CONFIG_INF  config;
    FARPTR      ph;

    PM_saveDS();
    _dx_config_inf(&config, (UCHAR*)&config);
    FP_SET(ph,(uint)isr,config.c_cs_sel);
    _dx_pmiv_set(intno,ph);
}

void PMAPI PM_restorePMvect(int intno, PMFARPTR isr)
{
    FARPTR  ph;

    FP_SET(ph,isr.off,isr.sel);
    _dx_pmiv_set(intno,ph);
}

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)
{
    _PM_setRMvect(intno,realisr);
    PM_restorePMvect(intno,pmisr);
}

static void setISR(int intno, void (PMAPI *isr)())
{
    CONFIG_INF  config;
    FARPTR      ph;

    lockPMHandlers();           /* Ensure our handlers are locked   */

    _dx_config_inf(&config, (UCHAR*)&config);
    FP_SET(ph,(uint)isr,config.c_cs_sel);
    _dx_apmiv_set(intno,ph);
}

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 (_dx_lock_pgsn(p,len) == 0);
}

int PMAPI PM_unlockDataPages(void *p,uint len,PM_lockHandle *lh)
{
    return (_dx_ulock_pgsn(p,len) == 0);
}

int PMAPI PM_lockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
{
    CONFIG_INF  config;
    FARPTR      fp;

    _dx_config_inf(&config, (UCHAR*)&config);
    FP_SET(fp,p,config.c_cs_sel);
    return (_dx_lock_pgs(fp,len) == 0);
}

int PMAPI PM_unlockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
{
    CONFIG_INF  config;
    FARPTR      fp;

    _dx_config_inf(&config, (UCHAR*)&config);
    FP_SET(fp,p,config.c_cs_sel);
    return (_dx_ulock_pgs(fp,len) == 0);
}

#endif

/*-------------------------------------------------------------------------*/
/* Symantec C++ DOSX and FlashTek X-32/X-32VM support                      */
/*-------------------------------------------------------------------------*/

#if defined(DOSX) || defined(X32VM)

#ifdef  X32VM
#include <x32.h>
#endif

static long prevRealBreak;      /* Previous real mode break handler     */
static long prevRealCtrlC;      /* Previous real mode CtrlC handler     */
static long prevRealCritical;   /* Prev real mode critical handler      */

static uint mouseSel = 0,mouseOff;

/* The following real mode routine is used to call a 32 bit protected
 * mode FAR function from real mode. We use this for passing up control
 * from the real mode mouse callback to our protected mode code.
 */

static char realHandler[] = {       /* Real mode code generic handler   */
    0x00,0x00,0x00,0x00,            /* __PM_callProtp                   */
    0x00,0x00,                      /* __PM_protCS                      */
    0x00,0x00,0x00,0x00,            /* __PM_protHandler                 */
    0x1E,                           /*  push    ds                      */
    0x6A,0x00,                      /*  push    0                       */
    0x6A,0x00,                      /*  push    0                       */
    0x2E,0xFF,0x36,0x04,0x00,       /*  push    [cs:__PM_protCS]        */
    0x66,0x2E,0xFF,0x36,0x06,0x00,  /*  push    [cs:__PM_protHandler]   */
    0x2E,0xFF,0x1E,0x00,0x00,       /*  call    [cs:__PM_callProtp]     */
    0x83,0xC4,0x0A,                 /*  add     sp,10                   */
    0x1F,                           /*  pop     ds                      */
    0xCB,                           /*  retf                            */
    };

/* The following functions installs the above realmode callback mechanism
 * in real mode memory for calling the protected mode routine.
 */

int installCallback(void (PMAPI *pmCB)(),uint *psel, uint *poff,
    uint *rseg, uint *roff)
{
    PMREGS          regs;
    PMSREGS         sregs;

    regs.x.ax = 0x250D;
    PM_segread(&sregs);
    PM_int386x(0x21,&regs,&regs,&sregs);    /* Get RM callback address  */

    /* Fill in the values in the real mode code segment so that it will
     * call the correct routine.
     */
    *((ulong*)&realHandler[0]) = regs.e.eax;
    *((ushort*)&realHandler[4]) = sregs.cs;
    *((ulong*)&realHandler[6]) = (ulong)pmCB;

    /* Copy the real mode handler to real mode memory (only allocate the
     * buffer once since we cant dealloate it with X32).
     */
    if (*psel == 0) {
	if (!PM_allocRealSeg(sizeof(realHandler),psel,poff,rseg,roff))
	    return 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?