📄 pmdos.c
字号:
/****************************************************************************** SciTech OS Portability Manager Library** ========================================================================** The contents of this file are subject to the SciTech MGL Public* License Version 1.0 (the "License"); you may not use this file* except in compliance with the License. You may obtain a copy of* the License at http://www.scitechsoft.com/mgl-license.txt** Software distributed under the License is distributed on an* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or* implied. See the License for the specific language governing* rights and limitations under the License.** The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.** The Initial Developer of the Original Code is SciTech Software, Inc.* All Rights Reserved.** ========================================================================** Language: ANSI C* Environment: 16/32 bit DOS** Description: Implementation for the OS Portability Manager Library, which* contains functions to implement OS specific services in a* generic, cross platform API. Porting the OS Portability* Manager library is the first step to porting any SciTech* products to a new platform.*****************************************************************************/#include "pmapi.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <dos.h>/*--------------------------- Global variables ----------------------------*/#ifndef REALMODEstatic int globalDataStart;#endifPM_criticalHandler _VARAPI _PM_critHandler = NULL;PM_breakHandler _VARAPI _PM_breakHandler = NULL;PM_intHandler _VARAPI _PM_timerHandler = NULL;PM_intHandler _VARAPI _PM_rtcHandler = NULL;PM_intHandler _VARAPI _PM_keyHandler = NULL;PM_key15Handler _VARAPI _PM_key15Handler = NULL;PM_mouseHandler _VARAPI _PM_mouseHandler = NULL;PM_intHandler _VARAPI _PM_int10Handler = NULL;int _VARAPI _PM_mouseMask;uchar * _VARAPI _PM_ctrlCPtr; /* Location of Ctrl-C flag */uchar * _VARAPI _PM_ctrlBPtr; /* Location of Ctrl-Break flag */uchar * _VARAPI _PM_critPtr; /* Location of Critical error Bf*/PMFARPTR _VARAPI _PM_prevTimer = PMNULL; /* Previous timer handler */PMFARPTR _VARAPI _PM_prevRTC = PMNULL; /* Previous RTC handler */PMFARPTR _VARAPI _PM_prevKey = PMNULL; /* Previous key handler */PMFARPTR _VARAPI _PM_prevKey15 = PMNULL; /* Previous key15 handler */PMFARPTR _VARAPI _PM_prevBreak = PMNULL; /* Previous break handler */PMFARPTR _VARAPI _PM_prevCtrlC = PMNULL; /* Previous CtrlC handler */PMFARPTR _VARAPI _PM_prevCritical = PMNULL; /* Previous critical handler */long _VARAPI _PM_prevRealTimer; /* Previous real mode timer */long _VARAPI _PM_prevRealRTC; /* Previous real mode RTC */long _VARAPI _PM_prevRealKey; /* Previous real mode key */long _VARAPI _PM_prevRealKey15; /* Previous real mode key15 */long _VARAPI _PM_prevRealInt10; /* Previous real mode int 10h */static uchar _PM_oldCMOSRegA; /* CMOS register A contents */static uchar _PM_oldCMOSRegB; /* CMOS register B contents */static uchar _PM_oldRTCPIC2; /* Mask value for RTC IRQ8 *//* Structure to maintain information about hardware interrupt handlers, * include a copy of the hardware IRQ assembler thunk (one for each * hooked interrupt handler). */typedef struct { uchar IRQ; uchar IRQVect; uchar prevPIC; uchar prevPIC2; PMFARPTR prevHandler; long prevRealhandler; uchar thunk[1]; /* IRQ assembler thunk follows ... */ } _PM_IRQHandle;/*----------------------------- Implementation ----------------------------*//* Globals for locking interrupt handlers in _pmdos.asm */#ifndef REALMODEextern int _VARAPI _PM_pmdosDataStart;extern int _VARAPI _PM_pmdosDataEnd;extern int _VARAPI _PM_DMADataStart;extern int _VARAPI _PM_DMADataEnd;void _ASMAPI _PM_pmdosCodeStart(void);void _ASMAPI _PM_pmdosCodeEnd(void);void _ASMAPI _PM_DMACodeStart(void);void _ASMAPI _PM_DMACodeEnd(void);#endif/* Protected mode interrupt handlers, also called by PM callbacks below */void _ASMAPI _PM_timerISR(void);void _ASMAPI _PM_rtcISR(void);void _ASMAPI _PM_irqISRTemplate(void);void _ASMAPI _PM_irqISRTemplateEnd(void);void _ASMAPI _PM_keyISR(void);void _ASMAPI _PM_key15ISR(void);void _ASMAPI _PM_breakISR(void);void _ASMAPI _PM_ctrlCISR(void);void _ASMAPI _PM_criticalISR(void);void _ASMAPI _PM_mouseISR(void);void _ASMAPI _PM_int10PMCB(void);/* Protected mode DPMI callback handlers */void _ASMAPI _PM_mousePMCB(void);/* Routine to install a mouse handler function */void _ASMAPI _PM_setMouseHandler(int mask);/* Routine to allocate DPMI real mode callback routines */ibool _ASMAPI _DPMI_allocateCallback(void (_ASMAPI *pmcode)(),void *rmregs,long *RMCB);void _ASMAPI _DPMI_freeCallback(long RMCB);/* DPMI helper functions in PMLITE.C */ulong PMAPI DPMI_mapPhysicalToLinear(ulong physAddr,ulong limit);int PMAPI DPMI_setSelectorBase(ushort sel,ulong linAddr);ulong PMAPI DPMI_getSelectorBase(ushort sel);int PMAPI DPMI_setSelectorLimit(ushort sel,ulong limit);uint PMAPI DPMI_createSelector(ulong base,ulong limit);void PMAPI DPMI_freeSelector(uint sel);int PMAPI DPMI_lockLinearPages(ulong linear,ulong len);int PMAPI DPMI_unlockLinearPages(ulong linear,ulong len);/* Functions to read and write CMOS registers */uchar PMAPI _PM_readCMOS(int index);void PMAPI _PM_writeCMOS(int index,uchar value);/*-------------------------------------------------------------------------*//* Generic routines common to all environments *//*-------------------------------------------------------------------------*/void PMAPI PM_resetMouseDriver(int hardReset){ RMREGS regs; PM_mouseHandler oldHandler = _PM_mouseHandler; PM_restoreMouseHandler(); regs.x.ax = hardReset ? 0 : 33; PM_int86(0x33, ®s, ®s); if (oldHandler) PM_setMouseHandler(_PM_mouseMask, oldHandler);}void PMAPI PM_setRealTimeClockFrequency(int frequency){ static short convert[] = { 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, -1, }; int i; /* First clear any pending RTC timeout if not cleared */ _PM_readCMOS(0x0C); if (frequency == 0) { /* Disable RTC timout */ _PM_writeCMOS(0x0A,_PM_oldCMOSRegA); _PM_writeCMOS(0x0B,_PM_oldCMOSRegB & 0x0F); } else { /* Convert frequency value to RTC clock indexes */ for (i = 0; convert[i] != -1; i++) { if (convert[i] == frequency) break; } /* Set RTC timout value and enable timeout */ _PM_writeCMOS(0x0A,0x20 | (i+3)); _PM_writeCMOS(0x0B,(_PM_oldCMOSRegB & 0x0F) | 0x40); }}#ifndef REALMODEstatic void PMAPI lockPMHandlers(void){ static int locked = 0; int stat; PM_lockHandle lh; /* Unused in DOS */ /* Lock all of the code and data used by our protected mode interrupt * handling routines, so that it will continue to work correctly * under real mode. */ if (!locked) { PM_saveDS(); stat = !PM_lockDataPages(&globalDataStart-2048,4096,&lh); stat |= !PM_lockDataPages(&_PM_pmdosDataStart,(int)&_PM_pmdosDataEnd - (int)&_PM_pmdosDataStart,&lh); stat |= !PM_lockCodePages((__codePtr)_PM_pmdosCodeStart,(int)_PM_pmdosCodeEnd-(int)_PM_pmdosCodeStart,&lh); stat |= !PM_lockDataPages(&_PM_DMADataStart,(int)&_PM_DMADataEnd - (int)&_PM_DMADataStart,&lh); stat |= !PM_lockCodePages((__codePtr)_PM_DMACodeStart,(int)_PM_DMACodeEnd-(int)_PM_DMACodeStart,&lh); if (stat) { printf("Page locking services failed - interrupt handling not safe!\n"); exit(1); } locked = 1; }}#endif/*-------------------------------------------------------------------------*//* DOS Real Mode support. *//*-------------------------------------------------------------------------*/#ifdef REALMODE#ifndef MK_FP#define MK_FP(s,o) ( (void far *)( ((ulong)(s) << 16) + \ (ulong)(o) ))#endifint PMAPI PM_setMouseHandler(int mask, PM_mouseHandler mh){ PM_saveDS(); _PM_mouseHandler = mh; _PM_setMouseHandler(_PM_mouseMask = mask); return 1;}void PMAPI PM_restoreMouseHandler(void){ union REGS regs; if (_PM_mouseHandler) { regs.x.ax = 33; int86(0x33, ®s, ®s); _PM_mouseHandler = NULL; }}void PMAPI PM_setTimerHandler(PM_intHandler th){ _PM_getRMvect(0x8, (long*)&_PM_prevTimer); _PM_timerHandler = th; _PM_setRMvect(0x8, (long)_PM_timerISR);}void PMAPI PM_restoreTimerHandler(void){ if (_PM_timerHandler) { _PM_setRMvect(0x8, (long)_PM_prevTimer); _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 */ _PM_getRMvect(0x70, (long*)&_PM_prevRTC); _PM_rtcHandler = th; _PM_setRMvect(0x70, (long)_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 */ _PM_setRMvect(0x70, (long)_PM_prevRTC); _PM_rtcHandler = NULL; }}void PMAPI PM_setKeyHandler(PM_intHandler kh){ _PM_getRMvect(0x9, (long*)&_PM_prevKey); _PM_keyHandler = kh; _PM_setRMvect(0x9, (long)_PM_keyISR);}void PMAPI PM_restoreKeyHandler(void){ if (_PM_keyHandler) { _PM_setRMvect(0x9, (long)_PM_prevKey); _PM_keyHandler = NULL; }}void PMAPI PM_setKey15Handler(PM_key15Handler kh){ _PM_getRMvect(0x15, (long*)&_PM_prevKey15); _PM_key15Handler = kh; _PM_setRMvect(0x15, (long)_PM_key15ISR);}void PMAPI PM_restoreKey15Handler(void){ if (_PM_key15Handler) { _PM_setRMvect(0x15, (long)_PM_prevKey15); _PM_key15Handler = NULL; }}void PMAPI PM_installAltBreakHandler(PM_breakHandler bh){ static int ctrlCFlag,ctrlBFlag; _PM_ctrlCPtr = (uchar*)&ctrlCFlag; _PM_ctrlBPtr = (uchar*)&ctrlBFlag; _PM_getRMvect(0x1B, (long*)&_PM_prevBreak); _PM_getRMvect(0x23, (long*)&_PM_prevCtrlC); _PM_breakHandler = bh; _PM_setRMvect(0x1B, (long)_PM_breakISR); _PM_setRMvect(0x23, (long)_PM_ctrlCISR);}void PMAPI PM_installBreakHandler(void){ PM_installAltBreakHandler(NULL);}void PMAPI PM_restoreBreakHandler(void){ if (_PM_prevBreak) { _PM_setRMvect(0x1B, (long)_PM_prevBreak); _PM_setRMvect(0x23, (long)_PM_prevCtrlC); _PM_prevBreak = NULL; _PM_breakHandler = NULL; }}void PMAPI PM_installAltCriticalHandler(PM_criticalHandler ch){ static short critBuf[2]; _PM_critPtr = (uchar*)critBuf; _PM_getRMvect(0x24, (long*)&_PM_prevCritical); _PM_critHandler = ch; _PM_setRMvect(0x24, (long)_PM_criticalISR);}void PMAPI PM_installCriticalHandler(void){ PM_installAltCriticalHandler(NULL);}void PMAPI PM_restoreCriticalHandler(void){ if (_PM_prevCritical) { _PM_setRMvect(0x24, (long)_PM_prevCritical); _PM_prevCritical = NULL; _PM_critHandler = NULL; }}int PMAPI PM_lockDataPages(void *p,uint len,PM_lockHandle *lh){ p = p; len = len; /* Do nothing for real mode */ return 1;}int PMAPI PM_unlockDataPages(void *p,uint len,PM_lockHandle *lh){ p = p; len = len; /* Do nothing for real mode */ return 1;}int PMAPI PM_lockCodePages(void (*p)(),uint len,PM_lockHandle *lh){ p = p; len = len; /* Do nothing for real mode */ 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, ®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_freeRealSeg(mousePtr); _PM_mouseHandler = NULL; }}void PMAPI PM_getPMvect(int intno, PMFARPTR *isr){ FARPTR ph;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -