📄 pm.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: 32 bit SMX embedded systems development.** 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 "event.h"#include "mtrr.h"#include "pm_help.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <dos.h>#include <conio.h>#ifdef __GNUC__#include <unistd.h>#include <sys/nearptr.h>#include <sys/stat.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;static ulong PDB = 0,*pPDB = NULL;static uint VXD_version = -1;/*----------------------------- Implementation ----------------------------*/ulong _ASMAPI _PM_getPDB(void);void _ASMAPI _PM_VxDCall(VXD_regs *regs,uint off,uint sel);/****************************************************************************REMARKS:External function to call the PMHELP helper VxD.****************************************************************************/void PMAPI PM_VxDCall( VXD_regs *regs){}/****************************************************************************RETURNS:BCD coded version number of the VxD, or 0 if not loaded (ie: 0x202 - 2.2)REMARKS:This function gets the version number for the VxD that we have connected to.****************************************************************************/uint PMAPI PMHELP_getVersion(void){ return VXD_version = 0;}void PMAPI PM_init(void){#ifndef REALMODE MTRR_init();#endif}/****************************************************************************PARAMETERS:base - The starting physical base address of the regionsize - The size in bytes of the regiontype - Type to place into the MTRR registerRETURNS:Error code describing the result.REMARKS:Function to enable write combining for the specified region of memory.****************************************************************************/int PMAPI PM_enableWriteCombine( ulong base, ulong size, uint type){#ifndef REALMODE return MTRR_enableWriteCombine(base,size,type);#else return PM_MTRR_NOT_SUPPORTED;#endif}ibool PMAPI PM_haveBIOSAccess(void){ return false; }long PMAPI PM_getOSType(void){ return _OS_SMX; }int PMAPI PM_getModeType(void){ return PM_386; }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 MGLOutput(char *);void PMAPI PM_fatalError(const char *msg){ if (fatalErrorCleanup) fatalErrorCleanup(); MGLOutput(msg);/* No support for fprintf() under smx currently! *//* 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, ®s, ®s, &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, ®s, ®s, &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;}char * PMAPI PM_getCurrentPath( char *path, int maxLen){ return getcwd(path,maxLen);}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; 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 "SMX"; }const char * PMAPI PM_getMachineName(void){ return "SMX"; }int PMAPI PM_kbhit(void){ int hit; event_t evt; hit = EVT_peekNext(&evt,EVT_KEYDOWN | EVT_KEYREPEAT); EVT_flush(~(EVT_KEYDOWN | EVT_KEYREPEAT)); return hit;}int PMAPI PM_getch(void){ event_t evt; EVT_halt(&evt,EVT_KEYDOWN); return EVT_asciiCode(evt.message);}PM_HWND PMAPI PM_openConsole(PM_HWND hwndUser,int device,int xRes,int yRes,int bpp,ibool fullScreen){ /* Not used for SMX */ (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,®s,®s); 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,®s,®s); sb->old50Lines = (regs.h.dl == 42 || regs.h.dl == 49); } (void)hwndConsole;}void PMAPI PM_setSuspendAppCallback(int (_ASMAPIP saveState)(int flags)){ /* Not used for SMX */ (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,®s,®s); } (void)hwndConsole;}void PMAPI PM_closeConsole(PM_HWND hwndConsole){ /* Not used for SMX */ (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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -