⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pm.c

📁 BIOS emulator and interface to Realmode X86 Emulator Library Can emulate a PCI Graphic Controller V
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************					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 "drvlib/os/os.h"#include "ztimerc.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <dos.h>#include <conio.h>#ifdef DJGPP#include <unistd.h>#include <sys/nearptr.h>#else#include <direct.h>#endif#ifdef	__BORLANDC__#pragma	warn -par#endif/*--------------------------- Global variables ----------------------------*/typedef struct {	int		oldMode;	int     old50Lines;	} DOS_stateBuf;#define	MAX_RM_BLOCKS	10static struct {	void	*p;	uint	tag;	} rmBlocks[MAX_RM_BLOCKS];static uint	VESABuf_len = 1024;		/* Length of the VESABuf buffer		*/static void *VESABuf_ptr = NULL;	/* Near pointer to VESABuf          */static uint VESABuf_rseg;   		/* Real mode segment of VESABuf     */static uint	VESABuf_roff;			/* Real mode offset of VESABuf      */static void (PMAPIP fatalErrorCleanup)(void) = NULL;ushort _VARAPI _PM_savedDS = 0;#ifdef	DOS4GWstatic ulong	PDB = 0,*pPDB = NULL;#endif/*----------------------------- Implementation ----------------------------*/void 	MTRR_init(void);ulong 	_ASMAPI _PM_getPDB(void);void PMAPI PM_init(void){#ifndef	REALMODE	MTRR_init();#endif}ibool PMAPI PM_haveBIOSAccess(void){ return true; }long PMAPI PM_getOSType(void){ return _OS_DOS; }int PMAPI PM_getModeType(void){#if	defined(REALMODE)	return PM_realMode;#elif defined(PM286)	return PM_286;#elif defined(PM386)	return PM_386;#endif}void PMAPI PM_backslash(char *s){	uint pos = strlen(s);	if (s[pos-1] != '\\') {		s[pos] = '\\';		s[pos+1] = '\0';		}}void PMAPI PM_setFatalErrorCleanup(	void (PMAPIP cleanup)(void)){	fatalErrorCleanup = cleanup;}void PMAPI PM_fatalError(const char *msg){	if (fatalErrorCleanup)		fatalErrorCleanup();	fprintf(stderr,"%s\n", msg);	exit(1);}static void ExitVBEBuf(void){	if (VESABuf_ptr)		PM_freeRealSeg(VESABuf_ptr);	VESABuf_ptr = 0;}void * PMAPI PM_getVESABuf(uint *len,uint *rseg,uint *roff){	if (!VESABuf_ptr) {		/* Allocate a global buffer for communicating with the VESA VBE */		if ((VESABuf_ptr = PM_allocRealSeg(VESABuf_len, &VESABuf_rseg, &VESABuf_roff)) == NULL)			return NULL;		atexit(ExitVBEBuf);		}	*len = VESABuf_len;	*rseg = VESABuf_rseg;	*roff = VESABuf_roff;	return VESABuf_ptr;}int PMAPI PM_int386(int intno, PMREGS *in, PMREGS *out){	PMSREGS	sregs;	PM_segread(&sregs);	return PM_int386x(intno,in,out,&sregs);}/* Routines to set and get the real mode interrupt vectors, by making * direct real mode calls to DOS and bypassing the DOS extenders API. * This is the safest way to handle this, as some servers try to be * smart about changing real mode vectors. */void PMAPI _PM_getRMvect(int intno, long *realisr){	RMREGS	regs;	RMSREGS	sregs;	PM_saveDS();	regs.h.ah = 0x35;	regs.h.al = intno;	PM_int86x(0x21, &regs, &regs, &sregs);	*realisr = ((long)sregs.es << 16) | regs.x.bx;}void PMAPI _PM_setRMvect(int intno, long realisr){	RMREGS	regs;	RMSREGS	sregs;	PM_saveDS();	regs.h.ah = 0x25;	regs.h.al = intno;	sregs.ds = (int)(realisr >> 16);	regs.x.dx = (int)(realisr & 0xFFFF);	PM_int86x(0x21, &regs, &regs, &sregs);}void PMAPI _PM_addRealModeBlock(void *mem,uint tag){	int i;	for (i = 0; i < MAX_RM_BLOCKS; i++) {		if (rmBlocks[i].p == NULL) {			rmBlocks[i].p = mem;			rmBlocks[i].tag = tag;			return;			}		}	PM_fatalError("To many real mode memory block allocations!");}uint PMAPI _PM_findRealModeBlock(void *mem){	int i;	for (i = 0; i < MAX_RM_BLOCKS; i++) {		if (rmBlocks[i].p == mem)			return rmBlocks[i].tag;		}	PM_fatalError("Could not find prior real mode memory block allocation!");	return 0;}const char * PMAPI PM_getCurrentPath(void){	static char cwd[256];	return getcwd(cwd,sizeof(cwd));}char PMAPI PM_getBootDrive(void){ return 'C'; }const char * PMAPI PM_getVBEAFPath(void){ return "c:\\"; }const char * PMAPI PM_getNucleusPath(void){	static char	path[256];	char 		*env;	if ((env = getenv("NUCLEUS_PATH")) != NULL)		return env;	if ((env = getenv("WINBOOTDIR")) != NULL) {		strcpy(path,env);		strcat(path,"\\system\\nucleus");		return path;		}	return "c:\\nucleus";}const char * PMAPI PM_getNucleusConfigPath(void){	static char path[256];	strcpy(path,PM_getNucleusPath());	PM_backslash(path);	strcat(path,"config");	return path;}const char * PMAPI PM_getUniqueID(void){ return "DOS"; }const char * PMAPI PM_getMachineName(void){ return "DOS"; }int PMAPI PM_kbhit(void){	return kbhit();}int PMAPI PM_getch(void){	return getch();}PM_HWND	PMAPI PM_openConsole(PM_HWND hwndUser,int device,int xRes,int yRes,int bpp,ibool fullScreen){	/* Not used for DOS */	(void)hwndUser;	(void)device;	(void)xRes;	(void)yRes;	(void)bpp;	(void)fullScreen;	return 0;}int PMAPI PM_getConsoleStateSize(void){	return sizeof(DOS_stateBuf);}void PMAPI PM_saveConsoleState(void *stateBuf,PM_HWND hwndConsole){	RMREGS  		regs;	DOS_stateBuf	*sb = stateBuf;	/* Save the old video mode state */	regs.h.ah = 0x0F;	PM_int86(0x10,&regs,&regs);	sb->oldMode = regs.h.al & 0x7F;	sb->old50Lines = false;	if (sb->oldMode == 0x3) {		regs.x.ax = 0x1130;		regs.x.bx = 0;		regs.x.dx = 0;		PM_int86(0x10,&regs,&regs);		sb->old50Lines = (regs.h.dl == 42 || regs.h.dl == 49);		}	(void)hwndConsole;}void PMAPI PM_changeResolution(PM_HWND hwndConsole,int xRes,int yRes,int bpp){	/* Not used for DOS */	(void)hwndConsole;	(void)xRes;	(void)yRes;	(void)bpp;}void PMAPI PM_setSuspendAppCallback(int (_ASMAPIP saveState)(int flags)){	/* Not used for DOS */	(void)saveState;}void PMAPI PM_restoreConsoleState(const void *stateBuf,PM_HWND hwndConsole){	RMREGS  			regs;	const DOS_stateBuf	*sb = stateBuf;	/* Retore 50 line mode if set */	if (sb->old50Lines) {		regs.x.ax = 0x1112;		regs.x.bx = 0;		PM_int86(0x10,&regs,&regs);		}	(void)hwndConsole;}void PMAPI PM_closeConsole(PM_HWND hwndConsole){	/* Not used for DOS */	(void)hwndConsole;}void PMAPI PM_setOSCursorLocation(int x,int y){	uchar *_biosPtr = PM_getBIOSPointer();	PM_setByte(_biosPtr+0x50,x);	PM_setByte(_biosPtr+0x51,y);}void PMAPI PM_setOSScreenWidth(int width,int height){	uchar *_biosPtr = PM_getBIOSPointer();	PM_setWord(_biosPtr+0x4A,width);	PM_setWord(_biosPtr+0x4C,width*2);	PM_setByte(_biosPtr+0x84,height-1);	if (height > 25) {		PM_setWord(_biosPtr+0x60,0x0607);		PM_setByte(_biosPtr+0x85,0x08);		}	else {		PM_setWord(_biosPtr+0x60,0x0D0E);		PM_setByte(_biosPtr+0x85,0x016);		}}void * PMAPI PM_mallocShared(long size){	return malloc(size);}int PMAPI PM_mapShared(void *ptr){	(void)ptr;	return 0;}void PMAPI PM_freeShared(void *ptr){	free(ptr);}#define	GetRMVect(intno,isr)	*(isr) = ((ulong*)rmZeroPtr)[intno]#define	SetRMVect(intno,isr)	((ulong*)rmZeroPtr)[intno] = (isr)ibool PMAPI PM_doBIOSPOST(	ushort axVal,	ulong BIOSPhysAddr,	void *mappedBIOS,	ulong BIOSLen){	static int		firstTime = true;	static uchar	*rmZeroPtr;	long			Current10,Current6D,Current42;	RMREGS			regs;	RMSREGS			sregs;	/* Create a zero memory mapping for us to use */	if (firstTime) {		rmZeroPtr = PM_mapPhysicalAddr(0,0x7FFF,true);		firstTime = false;		}	/* Remap the secondary BIOS to 0xC0000 physical */	if (BIOSPhysAddr != 0xC0000L || BIOSLen > 32768) {		/* DOS cannot virtually remap the BIOS, so we can only work if all		 * the secondary controllers are identical, and we then use the		 * BIOS on the first controller for all the remaining controllers.		 *		 * For OS'es that do virtual memory, and remapping of 0xC0000		 * physical (perhaps a copy on write mapping) should be all that		 * is needed.		 */		return false;		}	/* Save current handlers of int 10h and 6Dh */	GetRMVect(0x10,&Current10);	GetRMVect(0x6D,&Current6D);	/* POST the secondary BIOS */	GetRMVect(0x42,&Current42);	SetRMVect(0x10,Current42);	/* Restore int 10h to STD-BIOS */	regs.x.ax = axVal;	PM_callRealMode(0xC000,0x0003,&regs,&sregs);	/* Restore current handlers */	SetRMVect(0x10,Current10);	SetRMVect(0x6D,Current6D);	/* Second the primary BIOS mappin 1:1 for 0xC0000 physical */	if (BIOSPhysAddr != 0xC0000L) {		/* DOS does not support this */		(void)mappedBIOS;		}	return true;}void PMAPI PM_sleep(ulong milliseconds){	ulong			microseconds = milliseconds * 1000L;	LZTimerObject	tm;	LZTimerOnExt(&tm);	while (LZTimerLapExt(&tm) < microseconds)		;	LZTimerOffExt(&tm);}int PMAPI PM_getCOMPort(int port){	switch (port) {		case 0:	return 0x3F8;		case 1:	return 0x2F8;		}	return 0;}int PMAPI PM_getLPTPort(int port){	switch (port) {		case 0:	return 0x3BC;		case 1: return 0x378;		case 2:	return 0x278;		}	return 0;}PM_MODULE PMAPI PM_loadLibrary(	const char *szDLLName){	(void)szDLLName;	return NULL;}void * PMAPI PM_getProcAddress(	PM_MODULE hModule,	const char *szProcName){

⌨️ 快捷键说明

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