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 + -
显示快捷键?