pm.c
来自「BIOS emulator and interface to Realmode 」· C语言 代码 · 共 865 行 · 第 1/2 页
C
865 行
void PMAPI PM_sleep(ulong milliseconds){ /* We never sleep in a VxD */}int PMAPI PM_getCOMPort(int port){ // TODO: Re-code this to determine real values using the Plug and Play // manager for the OS. switch (port) { case 0: return 0x3F8; case 1: return 0x2F8; } return 0;}int PMAPI PM_getLPTPort(int port){ // TODO: Re-code this to determine real values using the Plug and Play // manager for the OS. switch (port) { case 0: return 0x3BC; case 1: return 0x378; case 2: return 0x278; } return 0;}ulong PMAPI PM_getPhysicalAddr(void *p){ DWORD pte; CopyPageTable(((DWORD)p) >> 12, 1, (PVOID*)&pte, 0); return (pte & ~0xFFF) | (((DWORD)p) & 0xFFF);}void PMAPI _PM_freeMemoryMappings(void){ int i; for (i = 0; i < numMappings; i++) PageFree(maps[i].linear,PR_STATIC);}void * PMAPI PM_mapRealPointer(uint r_seg,uint r_off){ return (void*)MK_PHYS(r_seg,r_off); }void * PMAPI PM_allocRealSeg(uint size,uint *r_seg,uint *r_off){ return NULL; }void PMAPI PM_freeRealSeg(void *mem){ }void PMAPI DPMI_int86(int intno, DPMI_regs *regs){ /* Unsed in VxD's */}/****************************************************************************REMARKS:Load the V86 registers in the client state, and save the original statebefore loading the registers.****************************************************************************/static void LoadV86Registers( CLIENT_STRUCT *saveRegs, RMREGS *in, RMSREGS *sregs){ CLIENT_STRUCT newRegs; Save_Client_State(saveRegs); newRegs = *saveRegs; newRegs.CRS.Client_EAX = in->e.eax; newRegs.CRS.Client_EBX = in->e.ebx; newRegs.CRS.Client_ECX = in->e.ecx; newRegs.CRS.Client_EDX = in->e.edx; newRegs.CRS.Client_ESI = in->e.esi; newRegs.CRS.Client_EDI = in->e.edi; newRegs.CRS.Client_ES = sregs->es; newRegs.CRS.Client_DS = sregs->ds; Restore_Client_State(&newRegs);}/****************************************************************************REMARKS:Read the V86 registers from the client state and restore the original state.****************************************************************************/static void ReadV86Registers( CLIENT_STRUCT *saveRegs, RMREGS *out, RMSREGS *sregs){ CLIENT_STRUCT newRegs; Save_Client_State(&newRegs); out->e.eax = newRegs.CRS.Client_EAX; out->e.ebx = newRegs.CRS.Client_EBX; out->e.ecx = newRegs.CRS.Client_ECX; out->e.edx = newRegs.CRS.Client_EDX; out->e.esi = newRegs.CRS.Client_ESI; out->e.edi = newRegs.CRS.Client_EDI; sregs->es = newRegs.CRS.Client_ES; sregs->ds = newRegs.CRS.Client_DS; Restore_Client_State(saveRegs);}/****************************************************************************REMARKS:Call a V86 real mode function with the specified register valuesloaded before the call. The call returns with a far ret.****************************************************************************/void PMAPI PM_callRealMode( uint seg, uint off, RMREGS *regs, RMSREGS *sregs){ CLIENT_STRUCT saveRegs; TRACE("SDDHELP: Entering PM_callRealMode()\n"); Begin_Nest_V86_Exec(); LoadV86Registers(&saveRegs,regs,sregs); Simulate_Far_Call(seg, off); Resume_Exec(); ReadV86Registers(&saveRegs,regs,sregs); End_Nest_Exec(); TRACE("SDDHELP: Exiting PM_callRealMode()\n");}/****************************************************************************REMARKS:Issue a V86 real mode interrupt with the specified register valuesloaded before the interrupt.****************************************************************************/int PMAPI PM_int86( int intno, RMREGS *in, RMREGS *out){ RMSREGS sregs = {0}; CLIENT_STRUCT saveRegs; ushort oldDisable; TRACE("SDDHELP: Entering PM_int86()\n"); // Disable pass-up to our VxD handler so we directly call BIOS if (disableTSRFlag) { oldDisable = *disableTSRFlag; *disableTSRFlag = 0; } Begin_Nest_V86_Exec(); LoadV86Registers(&saveRegs,in,&sregs); Exec_Int(intno); ReadV86Registers(&saveRegs,out,&sregs); End_Nest_Exec(); // Re-enable pass-up to our VxD handler if previously enabled if (disableTSRFlag) *disableTSRFlag = oldDisable; TRACE("SDDHELP: Exiting PM_int86()\n"); return out->x.ax;}/****************************************************************************REMARKS:Issue a V86 real mode interrupt with the specified register valuesloaded before the interrupt.****************************************************************************/int PMAPI PM_int86x( int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs){ CLIENT_STRUCT saveRegs; ushort oldDisable; TRACE("SDDHELP: Entering PM_int86x()\n"); // Disable pass-up to our VxD handler so we directly call BIOS if (disableTSRFlag) { oldDisable = *disableTSRFlag; *disableTSRFlag = 0; } Begin_Nest_V86_Exec(); LoadV86Registers(&saveRegs,in,sregs); Exec_Int(intno); ReadV86Registers(&saveRegs,out,sregs); End_Nest_Exec(); // Re-enable pass-up to our VxD handler if previously enabled if (disableTSRFlag) *disableTSRFlag = oldDisable; TRACE("SDDHELP: Exiting PM_int86x()\n"); return out->x.ax;}void PMAPI PM_availableMemory(ulong *physical,ulong *total){ *physical = *total = 0; }/****************************************************************************REMARKS:Allocates a block of locked physical memory.****************************************************************************/void * PMAPI PM_allocLockedMem(uint size,ulong *physAddr){ MEMHANDLE hMem; DWORD nPages = (size + 0xFFF) >> 12; void *p; PageAllocate(nPages,PG_SYS,0,0,0,0xFFFFFFFF,physAddr, PAGECONTIG | PAGEFIXED | PAGEUSEALIGN,&hMem,&p); return p;}/****************************************************************************REMARKS:Frees a block of locked physical memory.****************************************************************************/void PMAPI PM_freeLockedMem(void *p,uint size){ if (p) PageFree((ulong)p,0);}/****************************************************************************REMARKS:Lock linear memory so it won't be paged.****************************************************************************/int PMAPI PM_lockDataPages(void *p,uint len){ DWORD pgNum = (ulong)p >> 12; DWORD nPages = (len + (ulong)p - (pgNum << 12) + 0xFFF) >> 12; return LinPageLock(pgNum,nPages,0);}/****************************************************************************REMARKS:Unlock linear memory so it won't be paged.****************************************************************************/int PMAPI PM_unlockDataPages(void *p,uint len){ DWORD pgNum = (ulong)p >> 12; DWORD nPages = (len + (ulong)p - (pgNum << 12) + 0xFFF) >> 12; return LinPageUnLock(pgNum,nPages,0);}/****************************************************************************REMARKS:Lock linear memory so it won't be paged.****************************************************************************/int PMAPI PM_lockCodePages(void (*p)(),uint len){ return PM_lockDataPages((void*)p,len);}/****************************************************************************REMARKS:Unlock linear memory so it won't be paged.****************************************************************************/int PMAPI PM_unlockCodePages(void (*p)(),uint len){ return PM_unlockDataPages((void*)p,len);}/****************************************************************************REMARKS:Real time clock interrupt handler, which calls the user registered C code.****************************************************************************/static BOOL __stdcall RTCInt_Handler( VMHANDLE hVM, IRQHANDLE hIRQ){ static char inside = 0; /* Clear priority interrupt controller and re-enable interrupts so we * dont lock things up for long. */ VPICD_Phys_EOI(hIRQ); /* Clear real-time clock timeout */ _PM_readCMOS(0x0C); /* Now call the C based interrupt handler (but check for mutual * exclusion since we may still be servicing an old interrupt when a * new one comes along; if that happens we ignore the old one). */ if (!inside) { inside = 1; enable(); _PM_rtcHandler(); inside = 0; } return TRUE;}/****************************************************************************REMARKS:Set the real time clock handler (used for software stereo modes).****************************************************************************/ibool PMAPI PM_setRealTimeClockHandler( PM_intHandler ih, int frequency){ struct VPICD_IRQ_Descriptor IRQdesc; /* 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 */ CHECK(ih != NULL); _PM_rtcHandler = ih; IRQdesc.VID_IRQ_Number = 0x8; IRQdesc.VID_Options = 0; IRQdesc.VID_Hw_Int_Proc = (DWORD)VPICD_Thunk_HWInt(RTCInt_Handler, &RTCInt_Thunk); IRQdesc.VID_EOI_Proc = 0; IRQdesc.VID_Virt_Int_Proc = 0; IRQdesc.VID_Mask_Change_Proc= 0; IRQdesc.VID_IRET_Proc = 0; IRQdesc.VID_IRET_Time_Out = 500; if ((RTCIRQHandle = VPICD_Virtualize_IRQ(&IRQdesc)) == 0) return false; /* Program the real time clock default frequency */ PM_setRealTimeClockFrequency(frequency); /* Unmask IRQ8 in the PIC */ VPICD_Physically_Unmask(RTCIRQHandle); return true;}/****************************************************************************REMARKS:Set the real time clock frequency (for stereo modes).****************************************************************************/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,(_PM_oldCMOSRegA & 0xF0) | (i+3)); _PM_writeCMOS(0x0B,(_PM_oldCMOSRegB & 0x0F) | 0x40); }}/****************************************************************************REMARKS:Restore the original real time clock handler.****************************************************************************/void PMAPI PM_restoreRealTimeClockHandler(void){ if (RTCIRQHandle) { /* Restore CMOS registers and mask RTC clock */ _PM_writeCMOS(0x0A,_PM_oldCMOSRegA); _PM_writeCMOS(0x0B,_PM_oldCMOSRegB); /* Restore the interrupt vector */ VPICD_Set_Auto_Masking(RTCIRQHandle); VPICD_Force_Default_Behavior(RTCIRQHandle); RTCIRQHandle = 0; }}/****************************************************************************REMARKS:OS specific shared libraries not supported inside a VxD****************************************************************************/PM_MODULE PMAPI PM_loadLibrary( const char *szDLLName){ (void)szDLLName; return NULL;}/****************************************************************************REMARKS:OS specific shared libraries not supported inside a VxD****************************************************************************/void * PMAPI PM_getProcAddress( PM_MODULE hModule, const char *szProcName){ (void)hModule; (void)szProcName; return NULL;}/****************************************************************************REMARKS:OS specific shared libraries not supported inside a VxD****************************************************************************/void PMAPI PM_freeLibrary( PM_MODULE hModule){ (void)hModule;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?