📄 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 OS/2** 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 "pm_help.h"#include "mtrr.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#define INCL_DOSERRORS#define INCL_DOS#define INCL_SUB#define INCL_VIO#define INCL_KBD#include <os2.h>/*--------------------------- Global variables ----------------------------*//* Public structures used to communicate with VIDEOPMI for implementing * the ability to call the real mode BIOS functions. */typedef struct _VIDEOMODEINFO { ULONG miModeId; USHORT usType; USHORT usInt10ModeSet; USHORT usXResolution; USHORT usYResolution; ULONG ulBufferAddress; ULONG ulApertureSize; BYTE bBitsPerPixel; BYTE bBitPlanes; BYTE bXCharSize; BYTE bYCharSize; USHORT usBytesPerScanLine; USHORT usTextRows; ULONG ulPageLength; ULONG ulSaveSize; BYTE bVrtRefresh; BYTE bHrtRefresh; BYTE bVrtPolPos; BYTE bHrtPolPos; CHAR bRedMaskSize; CHAR bRedFieldPosition; CHAR bGreenMaskSize; CHAR bGreenFieldPosition; CHAR bBlueMaskSize; CHAR bBlueFieldPosition; CHAR bRsvdMaskSize; CHAR bRsvdFieldPosition; ULONG ulColors; ULONG ulReserved[3]; } VIDEOMODEINFO, FAR *PVIDEOMODEINFO;typedef struct _ADAPTERINFO { ULONG ulAdapterID; CHAR szOEMString[128]; CHAR szDACString[128]; CHAR szRevision[128]; ULONG ulTotalMemory; ULONG ulMMIOBaseAddress; ULONG ulPIOBaseAddress; BYTE bBusType; BYTE bEndian; USHORT usDeviceBusID; USHORT usVendorBusID; USHORT SlotID; } ADAPTERINFO, FAR *PADAPTERINFO;typedef struct _VIDEO_ADAPTER { void *hvideo; ADAPTERINFO Adapter; VIDEOMODEINFO ModeInfo; } VIDEO_ADAPTER, FAR *PVIDEO_ADAPTER;typedef struct { BYTE bBufferType;#define BUFFER_NONE 0#define INPUT_BUFFER 1#define OUTPUT_BUFFER 2 BYTE bReserved; BYTE bSelCRF; BYTE bOffCRF; PVOID pAddress; ULONG ulSize; } BUFFER, *PBUFFER;typedef struct vcrf_s { ULONG reg_eax; ULONG reg_ebx; ULONG reg_ecx; ULONG reg_edx; ULONG reg_ebp; ULONG reg_esi; ULONG reg_edi; ULONG reg_ds; ULONG reg_es; ULONG reg_fs; ULONG reg_gs; ULONG reg_cs; ULONG reg_eip; ULONG reg_eflag; ULONG reg_ss; ULONG reg_esp; } VCRF;typedef struct { ULONG ulBIOSIntNo; VCRF aCRF; BUFFER pB[2]; } INTCRF;#define PMIREQUEST_LOADPMIFILE 21#define PMIREQUEST_IDENTIFYADAPTER 22#define PMIREQUEST_SOFTWAREINT 23#ifdef PTR_DECL_IN_FRONT#define EXPENTRYP * EXPENTRY#else#define EXPENTRYP EXPENTRY *#endif/* Entry point to VIDEOPMI32Request. This may be overridden by external * code that has already loaded VIDEOPMI to avoid loading it twice. */APIRET (EXPENTRYP PM_VIDEOPMI32Request)(PVIDEO_ADAPTER, ULONG, PVOID, PVOID) = NULL;static KBDKEYINFO key; /* Must not cross a 64K boundary */static uchar * lowMem = NULL;static ulong parmsIn[3]; /* Must not cross 64Kb boundary! */static ulong parmsOut[2]; /* Must not cross 64Kb boundary! */static VIDEO_ADAPTER Adapter; /* Video adapter for VIDEOPMI */static uchar RMBuf[1024]; /* Fake real mode transfer buffer */extern ushort _PM_gdt;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;/*----------------------------- Implementation ----------------------------*//* External functions */void MTRR_init(void);/****************************************************************************PARAMETERS:func - Helper device driver function to callRETURNS:First return value from the device driver in parmsOut[0]REMARKS:Function to open our helper device driver, call it and close the filehandle. Note that we have to open the device driver for every call becauseof two problems: 1. We cannot open a single file handle in a DLL that is shared amongst programs, since every process must have it's own open file handle. 2. For some reason there appears to be a limit of about 12 open file handles on a device driver in the system. Hence when we open more than about 12 file handles things start to go very strange.Hence we simply open the file handle every time that we need to call thedevice driver to work around these problems.****************************************************************************/static ulong CallSDDHelp( int func){ static ulong inLen; /* Must not cross 64Kb boundary! */ static ulong outLen; /* Must not cross 64Kb boundary! */ HFILE hSDDHelp; ulong result; if (DosOpen(PMHELP_NAME,&hSDDHelp,&result,0,0, FILE_OPEN, OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, NULL) != 0) PM_fatalError("Unable to open SDDHELP$ helper device driver!"); if (DosDevIOCtl(hSDDHelp,PMHELP_IOCTL,func, &parmsIn, inLen = sizeof(parmsIn), &inLen, &parmsOut, outLen = sizeof(parmsOut), &outLen) != 0) PM_fatalError("Failure calling SDDHELP$ helper device driver!"); DosClose(hSDDHelp); return parmsOut[0];}/****************************************************************************REMARKS:Initialise the PM library and connect to our helper device driver. If wecannot connect to our helper device driver, we bail out with an errormessage.****************************************************************************/void PMAPI PM_init(void){ if (!lowMem) { /* Obtain the 32->16 callgate from the device driver to enable IOPL */ if ((_PM_gdt = CallSDDHelp(PMHELP_GETGDT32)) == 0) PM_fatalError("Unable to obtain call gate selector!"); PM_setIOPL(3); /* Map the first Mb of physical memory into lowMem */ if ((lowMem = PM_mapPhysicalAddr(0,0xFFFFF,true)) == NULL) PM_fatalError("Unable to map first Mb physical memory!"); /* Initialise the MTRR interface functions */ MTRR_init(); } PM_mapToProcess(lowMem,0xFFFFF); PCI_mapShared();}/****************************************************************************REMARKS:Initialise the PM library for BIOS access via VIDEOPMI. This should workwith any GRADD driver, including SDD/2.****************************************************************************/static ibool InitInt10(void){ HMODULE hModVideoPMI; char buf[80],path[_MAX_PATH]; if (!PM_VIDEOPMI32Request) { /* Connect to VIDEOPMI and get entry point */ PM_init(); if (DosLoadModule((PSZ)buf,sizeof(buf),(PSZ)"VIDEOPMI.DLL",&hModVideoPMI) == 0) { if (DosQueryProcAddr(hModVideoPMI,0,(PSZ)"VIDEOPMI32Request",(void*)&PM_VIDEOPMI32Request) != 0) PM_fatalError("Unable to get VIDEOPMI32Request entry point!"); strcpy(path,"X:\\OS2\\SVGADATA.PMI"); path[0] = PM_getBootDrive(); if (PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_LOADPMIFILE,path,NULL) != 0) { DosFreeModule(hModVideoPMI); PM_VIDEOPMI32Request = NULL; } } } return (PM_VIDEOPMI32Request != NULL);}/****************************************************************************REMARKS:We do have BIOS access under OS/2, although it is limited.****************************************************************************/ibool PMAPI PM_haveBIOSAccess(void){ return true;}/****************************************************************************REMARKS:Return the operating system type identifier.****************************************************************************/long PMAPI PM_getOSType(void){ return _OS_OS2;}/****************************************************************************REMARKS:Return the runtime type identifier.****************************************************************************/int PMAPI PM_getModeType(void){ return PM_386;}/****************************************************************************REMARKS:Add a file directory separator to the end of the filename.****************************************************************************/void PMAPI PM_backslash( char *s){ uint pos = strlen(s); if (s[pos-1] != '\\') { s[pos] = '\\'; s[pos+1] = '\0'; }}/****************************************************************************REMARKS:Add a user defined PM_fatalError cleanup function.****************************************************************************/void PMAPI PM_setFatalErrorCleanup( void (PMAPIP cleanup)(void)){ fatalErrorCleanup = cleanup;}/****************************************************************************REMARKS:Report a fatal error condition and halt the program.****************************************************************************/void PMAPI PM_fatalError( const char *msg){ if (fatalErrorCleanup) fatalErrorCleanup(); fprintf(stderr,"%s\n", msg); exit(1);}/****************************************************************************REMARKS:Allocate the real mode VESA transfer buffer for communicating with the BIOS.****************************************************************************/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; } *len = VESABuf_len; *rseg = VESABuf_rseg; *roff = VESABuf_roff; return VESABuf_ptr;}/****************************************************************************REMARKS:Check if a key has been pressed.****************************************************************************/int PMAPI PM_kbhit(void){ KbdPeek(&key, 0); return (key.fbStatus & KBDTRF_FINAL_CHAR_IN);}/****************************************************************************REMARKS:Wait for and return the next keypress.****************************************************************************/int PMAPI PM_getch(void){ KbdCharIn(&key,IO_WAIT,0); return key.chChar;}/****************************************************************************REMARKS:Open a fullscreen console for output to the screen. This requires thatthe application be a fullscreen VIO program.****************************************************************************/PM_HWND PMAPI PM_openConsole( PM_HWND hwndUser, int device, int xRes, int yRes, int bpp, ibool fullScreen){ static VIOPHYSBUF vpb; vpb.pBuf = (PBYTE)0xb8000; vpb.cb = 80*25*2; if (VioGetPhysBuf (&vpb, 0) == ERROR_VIO_EXTENDED_SG) PM_fatalError("This program must be run in a full-screen OS/2 session!"); (void)hwndUser; (void)device; (void)xRes; (void)yRes; (void)bpp; (void)fullScreen; return 0;}/****************************************************************************REMARKS:Find the size of the console state buffer.****************************************************************************/int PMAPI PM_getConsoleStateSize(void){ return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -