📄 pm.c
字号:
(void)height;}/****************************************************************************REMARKS:Set the real time clock handler (used for software stereo modes).****************************************************************************/ibool PMAPI PM_setRealTimeClockHandler( PM_intHandler ih, int frequency){ /* TODO: Implement this! */ (void)ih; (void)frequency; return false;}/****************************************************************************REMARKS:Set the real time clock frequency (for stereo modes).****************************************************************************/void PMAPI PM_setRealTimeClockFrequency( int frequency){ /* TODO: Implement this! */ (void)frequency;}/****************************************************************************REMARKS:Restore the original real time clock handler.****************************************************************************/void PMAPI PM_restoreRealTimeClockHandler(void){ /* TODO: Implement this! */}/****************************************************************************REMARKS:Return the current operating system path or working directory.****************************************************************************/char * PMAPI PM_getCurrentPath( char *path, int maxLen){ return getcwd(path,maxLen);}/****************************************************************************REMARKS:Return the drive letter for the boot drive.****************************************************************************/char PMAPI PM_getBootDrive(void){ ulong boot = 3; DosQuerySysInfo(QSV_BOOT_DRIVE,QSV_BOOT_DRIVE,&boot,sizeof(boot)); return (char)('a' + boot - 1);}/****************************************************************************REMARKS:Return the path to the VBE/AF driver files.****************************************************************************/const char * PMAPI PM_getVBEAFPath(void){ static char path[CCHMAXPATH]; strcpy(path,"x:\\"); path[0] = PM_getBootDrive(); return path;}/****************************************************************************REMARKS:Return the path to the Nucleus driver files.****************************************************************************/const char * PMAPI PM_getNucleusPath(void){ static char path[CCHMAXPATH]; if (getenv("NUCLEUS_PATH") != NULL) return getenv("NUCLEUS_PATH"); strcpy(path,"x:\\os2\\drivers"); path[0] = PM_getBootDrive(); PM_backslash(path); strcat(path,"nucleus"); return path;}/****************************************************************************REMARKS:Return the path to the Nucleus configuration files.****************************************************************************/const char * PMAPI PM_getNucleusConfigPath(void){ static char path[CCHMAXPATH]; strcpy(path,PM_getNucleusPath()); PM_backslash(path); strcat(path,"config"); return path;}/****************************************************************************REMARKS:Return a unique identifier for the machine if possible.****************************************************************************/const char * PMAPI PM_getUniqueID(void){ return PM_getMachineName();}/****************************************************************************REMARKS:Get the name of the machine on the network.****************************************************************************/const char * PMAPI PM_getMachineName(void){ static char name[40],*env; if ((env = getenv("HOSTNAME")) != NULL) { strncpy(name,env,sizeof(name)); name[sizeof(name)-1] = 0; return name; } return "OS2";}/****************************************************************************REMARKS:Return a pointer to the real mode BIOS data area.****************************************************************************/void * PMAPI PM_getBIOSPointer(void){ PM_init(); return lowMem + 0x400;}/****************************************************************************REMARKS:Return a pointer to 0xA0000 physical VGA graphics framebuffer.****************************************************************************/void * PMAPI PM_getA0000Pointer(void){ PM_init(); return lowMem + 0xA0000;}/****************************************************************************REMARKS:Map a physical address to a linear address in the callers process.****************************************************************************/void * PMAPI PM_mapPhysicalAddr( ulong base, ulong limit, ibool isCached){ ulong baseAddr,baseOfs,linear; /* Round the physical address to a 4Kb boundary and the limit to a * 4Kb-1 boundary before passing the values to mmap. If we round the * physical address, then we also add an extra offset into the address * that we return. */ baseOfs = base & 4095; baseAddr = base & ~4095; limit = ((limit+baseOfs+1+4095) & ~4095)-1; parmsIn[0] = baseAddr; parmsIn[1] = limit; parmsIn[2] = isCached; if ((linear = CallSDDHelp(PMHELP_MAPPHYS)) == 0) return NULL; return (void*)(linear + baseOfs);}/****************************************************************************REMARKS:Free a physical address mapping allocated by PM_mapPhysicalAddr.****************************************************************************/void PMAPI PM_freePhysicalAddr( void *ptr, ulong limit){ parmsIn[0] = (ulong)ptr; parmsIn[1] = limit; CallSDDHelp(PMHELP_FREEPHYS);}/****************************************************************************REMARKS:Find the physical address of a linear memory address in current process.****************************************************************************/ulong PMAPI PM_getPhysicalAddr( void *p){ parmsIn[0] = (ulong)p; return CallSDDHelp(PMHELP_GETPHYSICALADDR);}/****************************************************************************REMARKS:Find the physical address of a linear memory address in current process.****************************************************************************/ibool PMAPI PM_getPhysicalAddrRange( void *p, ulong length, ulong *physAddress){ parmsIn[0] = (ulong)p; parmsIn[1] = (ulong)length; parmsIn[2] = (ulong)physAddress; return CallSDDHelp(PMHELP_GETPHYSICALADDRRANGE);}/****************************************************************************REMARKS:Sleep for the specified number of milliseconds.****************************************************************************/void PMAPI PM_sleep( ulong milliseconds){ DosSleep(milliseconds);}/****************************************************************************REMARKS:Return the base I/O port for the specified COM port.****************************************************************************/int PMAPI PM_getCOMPort( int port){ switch (port) { case 0: return 0x3F8; case 1: return 0x2F8; } return 0;}/****************************************************************************REMARKS:Return the base I/O port for the specified LPT port.****************************************************************************/int PMAPI PM_getLPTPort( int port){ switch (port) { case 0: return 0x3BC; case 1: return 0x378; case 2: return 0x278; } return 0;}/****************************************************************************REMARKS:Allocate a block of shared memory. For Win9x we allocate shared memoryas locked, global memory that is accessible from any memory context(including interrupt time context), which allows us to load our importantdata structure and code such that we can access it directly from a ring0 interrupt context.****************************************************************************/void * PMAPI PM_mallocShared( long size){ parmsIn[0] = size; return (void*)CallSDDHelp(PMHELP_MALLOCSHARED);}/****************************************************************************REMARKS:Free a block of shared memory.****************************************************************************/void PMAPI PM_freeShared( void *ptr){ parmsIn[0] = (ulong)ptr; CallSDDHelp(PMHELP_FREESHARED);}/****************************************************************************REMARKS:Map a linear memory address to the calling process address space. Theaddress will have been allocated in another process using thePM_mapPhysicalAddr function.****************************************************************************/void * PMAPI PM_mapToProcess( void *base, ulong limit){ ulong baseAddr,baseOfs; /* Round the physical address to a 4Kb boundary and the limit to a * 4Kb-1 boundary before passing the values to mmap. If we round the * physical address, then we also add an extra offset into the address * that we return. */ baseOfs = (ulong)base & 4095; baseAddr = (ulong)base & ~4095; limit = ((limit+baseOfs+1+4095) & ~4095)-1; parmsIn[0] = (ulong)baseAddr; parmsIn[1] = limit; return (void*)(CallSDDHelp(PMHELP_MAPTOPROCESS)+baseOfs);}/****************************************************************************REMARKS:Map a real mode pointer to a protected mode pointer.****************************************************************************/void * PMAPI PM_mapRealPointer( uint r_seg, uint r_off){ if (r_seg == 0xFFFF) return &RMBuf[r_off]; return lowMem + MK_PHYS(r_seg,r_off);}/****************************************************************************REMARKS:Allocate a block of real mode memory****************************************************************************/void * PMAPI PM_allocRealSeg( uint size, uint *r_seg, uint *r_off){ if (size > sizeof(RMBuf)) return NULL; *r_seg = 0xFFFF; *r_off = 0x0000; return &RMBuf;}/****************************************************************************REMARKS:Free a block of real mode memory.****************************************************************************/void PMAPI PM_freeRealSeg( void *mem){ /* Nothing to do in here */ (void)mem;}#define INDPMI(reg) rmregs.aCRF.reg_##reg = regs->reg#define OUTDPMI(reg) regs->reg = rmregs.aCRF.reg_##reg#define REG_OFFSET(field) (((ULONG)&(((VCRF*)0)->field)) / sizeof(ULONG))/****************************************************************************REMARKS:Issue a real mode interrupt (parameters in DPMI compatible structure)****************************************************************************/void PMAPI DPMI_int86( int intno, DPMI_regs *regs){ INTCRF rmregs; ulong eax = 0; if (!InitInt10()) return; memset(&rmregs, 0, sizeof(rmregs)); rmregs.ulBIOSIntNo = intno; INDPMI(eax); INDPMI(ebx); INDPMI(ecx); INDPMI(edx); INDPMI(esi); INDPMI(edi); rmregs.aCRF.reg_ds = regs->ds; rmregs.aCRF.reg_es = regs->es; if (intno == 0x10) { eax = rmregs.aCRF.reg_eax; switch (eax & 0xFFFF) { case 0x4F00: /* We have to hack the way this function works, due to * some bugs in the IBM mini-VDM BIOS support. Specifically * we need to make the input buffer and output buffer the * 'same' buffer, and that ES:SI points to the output * buffer (ignored by the BIOS). The data will end up * being returned in the input buffer, except for the * first four bytes ('VESA') that will not be returned. */ rmregs.pB[0].bBufferType = INPUT_BUFFER; rmregs.pB[0].bSelCRF = REG_OFFSET(reg_es); rmregs.pB[0].bOffCRF = REG_OFFSET(reg_edi); rmregs.pB[0].pAddress = RMBuf; rmregs.pB[0].ulSize = 4; rmregs.pB[1].bBufferType = OUTPUT_BUFFER; rmregs.pB[1].bSelCRF = REG_OFFSET(reg_es); rmregs.pB[1].bOffCRF = REG_OFFSET(reg_esi); rmregs.pB[1].pAddress = ((PBYTE)RMBuf)+4; rmregs.pB[1].ulSize = 512-4; break; case 0x4F01: rmregs.pB[0].bBufferType = OUTPUT_BUFFER; rmregs.pB[0].bSelCRF = REG_OFFSET(reg_es); rmregs.pB[0].bOffCRF = REG_OFFSET(reg_edi); rmregs.pB[0].pAddress = RMBuf; rmregs.pB[0].ulSize = 256; break; case 0x4F02: rmregs.pB[0].bBufferType = INPUT_BUFFER; rmregs.pB[0].bSelCRF = REG_OFFSET(reg_es); rmregs.pB[0].bOffCRF = REG_OFFSET(reg_edi); rmregs.pB[0].pAddress = RMBuf; rmregs.pB[0].ulSize = 256; break; case 0x4F09:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -