summaryrefslogtreecommitdiffstats
path: root/board/MAI/bios_emulator/scitech/src/pm/os2/pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/pm/os2/pm.c')
-rw-r--r--board/MAI/bios_emulator/scitech/src/pm/os2/pm.c2008
1 files changed, 0 insertions, 2008 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/pm/os2/pm.c b/board/MAI/bios_emulator/scitech/src/pm/os2/pm.c
deleted file mode 100644
index 756eead1dd..0000000000
--- a/board/MAI/bios_emulator/scitech/src/pm/os2/pm.c
+++ /dev/null
@@ -1,2008 +0,0 @@
-/****************************************************************************
-*
-* 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>
-#include <process.h>
-#ifndef __EMX__
-#include <direct.h>
-#endif
-#define INCL_DOSERRORS
-#define INCL_DOS
-#define INCL_SUB
-#define INCL_VIO
-#define INCL_KBD
-#include <os2.h>
-
-/* Semaphore for communication with our background daemon */
-#define SHAREDSEM ((PSZ)"\\SEM32\\SDD\\DAEMON")
-#define DAEMON_NAME "SDDDAEMN.EXE"
-
-/*--------------------------- 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;
-
-/* PMIREQUEST_SOFTWAREINT structures from OS/2 DDK */
-
-typedef struct {
- ULONG ulFlags; /* VDM initialization type */
-#define VDM_POSTLOAD 0x1 /* adapter just loaded, used internally for initialization */
-#define VDM_INITIALIZE 0x2 /* force initialization of a permanently open VDM, even if previously initialized */
-#define VDM_TERMINATE_POSTINITIALIZE 0x6 /*start VDM with initialization, but close it afterwards (includes VDM_INITIALIZE) */
-#define VDM_QUERY_CAPABILITY 0x10 /* query the current int 10 capability */
-#define VDM_FULL_VDM_CREATED 0x20 /* a full VDM is created */
-#define VDM_MINI_VDM_CREATED 0x40 /* a mini VDM is created */
-#define VDM_MINI_VDM_SUPPORTED 0x80 /* mini VDM support is available */
- PCHAR szName; /* VDM initialization program */
- PCHAR szArgs; /* VDM initialization arguments */
- }INITVDM;
-
-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 ibool haveInt10 = -1; /* True if we have Int 10 support */
-static ibool useVPMI = true; /* False if VIDEOPMI unavailable */
-static VIDEO_ADAPTER Adapter; /* Video adapter for VIDEOPMI */
-static uchar RMBuf[1024]; /* Fake real mode transfer buffer */
-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 uchar * lowMem = NULL;
-static ibool isSessionSwitching = false;
-static ulong parmsIn[4]; /* Must not cross 64Kb boundary! */
-static ulong parmsOut[4]; /* Must not cross 64Kb boundary! */
-extern ushort _PM_gdt;
-static void (PMAPIP fatalErrorCleanup)(void) = NULL;
-
-/* DosSysCtl prototype. It is not declared in the headers but it is in the
- * standard import libraries (DOSCALLS.876). Funny.
- */
-APIRET APIENTRY DosSysCtl(ULONG ulFunction, PVOID pvData);
-
-/* This is the stack size for the threads that track the session switch event */
-#define SESSION_SWITCH_STACK_SIZE 32768
-
-typedef struct {
- VIOMODEINFO vmi;
- USHORT CursorX;
- USHORT CursorY;
- UCHAR FrameBuffer[1];
- } CONSOLE_SAVE;
-
-typedef struct _SESWITCHREC {
- /* The following variable is volatile because of PM_SUSPEND_APP */
- volatile int Flags; /* -1 or PM_DEACTIVATE or PM_REACTIVATE */
- PM_saveState_cb Callback; /* Save/restore context callback */
- HMTX Mutex; /* Exclusive access mutex */
- HEV Event; /* Posted after callback is called */
- } SESWITCHREC;
-
-/* Page sized block cache */
-
-#define PAGES_PER_BLOCK 32
-#define PAGE_BLOCK_SIZE (PAGES_PER_BLOCK * PM_PAGE_SIZE + (PM_PAGE_SIZE-1) + sizeof(pageblock))
-#define FREELIST_NEXT(p) (*(void**)(p))
-typedef struct pageblock {
- struct pageblock *next;
- struct pageblock *prev;
- void *freeListStart;
- void *freeList;
- void *freeListEnd;
- int freeCount;
- PM_lockHandle lockHandle;
- } pageblock;
-
-static pageblock *pageBlocks = NULL;
-
-/*----------------------------- Implementation ----------------------------*/
-
-/****************************************************************************
-PARAMETERS:
-func - Helper device driver function to call
-
-RETURNS:
-First return value from the device driver in parmsOut[0]
-
-REMARKS:
-Function to open our helper device driver, call it and close the file
-handle. Note that we have to open the device driver for every call because
-of 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 the
-device 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 rc;
- ulong result;
-
- if ((rc = DosOpen(PMHELP_NAME,&hSDDHelp,&result,0,0,
- FILE_OPEN, OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
- NULL)) != 0) {
- if (rc == 4) { /* Did we run out of file handles? */
- ULONG ulNewFHs;
- LONG lAddFHs = 5;
-
- if (DosSetRelMaxFH(&lAddFHs, &ulNewFHs) != 0)
- PM_fatalError("Failed to raise the file handles limit!");
- else {
- if ((rc = 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! (#2)");
- }
- }
- }
- else
- 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:
-Determine if we're running on a DBCS system.
-****************************************************************************/
-ibool __IsDBCSSystem(void)
-{
- CHAR achDBCSInfo[12];
- COUNTRYCODE ccStruct = {0, 0};
-
- memset(achDBCSInfo, 0, 12);
-
- /* Get the DBCS vector - if it's not empty, we're on DBCS */
- DosQueryDBCSEnv(sizeof(achDBCSInfo), &ccStruct, achDBCSInfo);
- if (achDBCSInfo[0] != 0)
- return true;
- else
- return false;
-}
-
-/****************************************************************************
-REMARKS:
-Determine if PMSHELL is running - if it isn't, we can't use certain calls
-****************************************************************************/
-ibool __isShellLoaded(void)
-{
- PVOID ptr;
-
- if (DosGetNamedSharedMem(&ptr, (PSZ)"\\SHAREMEM\\PMGLOBAL.MEM", PAG_READ) == NO_ERROR) {
- DosFreeMem(ptr);
- return true;
- }
- return false;
-}
-
-/****************************************************************************
-REMARKS:
-Initialise the PM library and connect to our helper device driver. If we
-cannot connect to our helper device driver, we bail out with an error
-message.
-****************************************************************************/
-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();
- }
-}
-
-/****************************************************************************
-REMARKS:
-Initialise the PM library for BIOS access via VIDEOPMI. This should work
-with any GRADD driver, including SDD/2.
-****************************************************************************/
-static ibool InitInt10(void)
-{
- HMODULE hModGENPMI,hModSDDPMI,hModVideoPMI;
- CHAR buf[80],path[_MAX_PATH];
- HEV hevDaemon = NULLHANDLE;
- RESULTCODES resCodes;
-
- if (haveInt10 == -1) {
- /* Connect to VIDEOPMI and get entry point. Note that we only
- * do this if GENPMI or SDDPMI are already loaded, since we need
- * a GRADD based driver for this to work.
- */
- PM_init();
- haveInt10 = false;
- if (DosQueryModuleHandle((PSZ)"GENPMI.DLL",&hModGENPMI) != 0)
- hModGENPMI = NULLHANDLE;
- if (DosQueryModuleHandle((PSZ)"SDDPMI.DLL",&hModSDDPMI) != 0)
- hModSDDPMI = NULLHANDLE;
- if (hModGENPMI || hModSDDPMI) {
- 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;
- haveInt10 = false;
- }
- else {
- /* Attempt to initialise the full VDM in the system. This will only
- * work if VPRPMI.SYS is loaded, but it provides support for passing
- * values in ES/DS/ESI/EDI between the BIOS which does not work with
- * kernel VDM's in fixpacks earlier than FP15. FP15 and later and
- * the new Warp 4.51 and Warp Server convenience packs should work
- * fine with the kernel mini-VDM.
- *
- * Also the full VDM is the only solution for really old kernels
- * (but GRADD won't run on them so this is superfluous ;-).
- */
- INITVDM InitVDM = {VDM_INITIALIZE,NULL,NULL};
- PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&InitVDM,NULL);
- haveInt10 = true;
- }
- }
- }
- else {
- /* A GRADD driver isn't loaded, hence we can't use VIDEOPMI. But we will try
- * to access the mini-VDM directly, first verifying that the support is
- * available in the kernel (it should be for kernels that support GRADD).
- * This may be needed in a command line boot or if non-GRADD driver is
- * used (Matrox or classic VGA).
- * Note: because of problems with mini-VDM support in the kernel, we have to
- * spawn a daemon process that will do the actual mini-VDM access for us.
- */
- /* Try to open shared semaphore to see if our daemon is already up */
- if (DosOpenEventSem(SHAREDSEM, &hevDaemon) == NO_ERROR) {
- if (DosWaitEventSem(hevDaemon, 1) == NO_ERROR) {
- /* If semaphore is posted, all is well */
- useVPMI = false;
- haveInt10 = true;
- }
- }
- else {
- /* Create shared event semaphore */
- if (DosCreateEventSem(SHAREDSEM, &hevDaemon, DC_SEM_SHARED, FALSE) == NO_ERROR) {
- PM_findBPD(DAEMON_NAME, path);
- strcat(path, DAEMON_NAME);
- if (DosExecPgm(buf, sizeof(buf), EXEC_BACKGROUND, (PSZ)DAEMON_NAME,
- NULL, &resCodes, (PSZ)path) == NO_ERROR) {
- /* The daemon was successfully spawned, now give it a sec to come up */
- if (DosWaitEventSem(hevDaemon, 2000) == NO_ERROR) {
- /* It's up! */
- useVPMI = false;
- haveInt10 = true;
- }
- }
- }
- }
- }
- }
- return haveInt10;
-}
-
-/****************************************************************************
-REMARKS:
-We "probably" have BIOS access under OS/2 but we have to verify/initialize it
-first.
-****************************************************************************/
-ibool PMAPI PM_haveBIOSAccess(void)
-{
- return InitInt10();
-}
-
-/****************************************************************************
-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)
-{
- /* Be prepare to be called recursively (failed to fail situation :-) */
- static int fatalErrorCount = 0;
- if (fatalErrorCount++ == 0) {
- 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)
-{
- KBDKEYINFO key; /* Must not cross a 64K boundary */
-
- KbdPeek(&key, 0);
- return (key.fbStatus & KBDTRF_FINAL_CHAR_IN);
-}
-
-/****************************************************************************
-REMARKS:
-Wait for and return the next keypress.
-****************************************************************************/
-int PMAPI PM_getch(void)
-{
- KBDKEYINFO key; /* Must not cross a 64K boundary */
-
- KbdCharIn(&key,IO_WAIT,0);
- return key.chChar;
-}
-
-/****************************************************************************
-REMARKS:
-Open a fullscreen console for output to the screen. This requires that
-the application be a fullscreen VIO program.
-****************************************************************************/
-PM_HWND PMAPI PM_openConsole(
- PM_HWND hwndUser,
- int device,
- int xRes,
- int yRes,
- int bpp,
- ibool fullScreen)
-{
- (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)
-{
- VIOMODEINFO vmi;
- vmi.cb = sizeof (VIOMODEINFO);
- VioGetMode (&vmi, (HVIO)0);
- return sizeof (CONSOLE_SAVE) - 1 + vmi.col * vmi.row * 2;
-}
-
-/****************************************************************************
-REMARKS:
-Save the state of the console.
-****************************************************************************/
-void PMAPI PM_saveConsoleState(
- void *stateBuf,
- PM_HWND hwndConsole)
-{
- USHORT fblen;
- CONSOLE_SAVE *cs = (CONSOLE_SAVE*)stateBuf;
- VIOMODEINFO vmi;
-
- /* The reason for the VIOMODEINFO juggling is 16-bit code. Because the user
- * allocates the state buffer, cd->vmi might be crossing the 64K boundary and
- * the 16-bit API would fail. If we create another copy on stack, the compiler
- * should ensure that the 64K boundary will not be crossed (it adjusts the stack
- * if it should cross).
- */
- vmi.cb = sizeof(VIOMODEINFO);
- VioGetMode(&vmi,(HVIO)0);
- memcpy(&cs->vmi, &vmi, sizeof(VIOMODEINFO));
- VioGetCurPos(&cs->CursorY, &cs->CursorX, (HVIO)0);
- fblen = cs->vmi.col * cs->vmi.row * 2;
- VioReadCellStr((PCH)cs->FrameBuffer, &fblen, 0, 0, (HVIO)0);
-}
-
-/* Global variable to communicate between threads */
-static SESWITCHREC SesSwitchRec = { -1 };
-
-/****************************************************************************
-REMARKS:
-Called by external routines at least once per frame to check whenever a
-session save/restore should be performed. Since we receive such notifications
-asyncronously, we can't perform all required operations at that time.
-****************************************************************************/
-void __PM_checkConsoleSwitch(void)
-{
- int Flags, Mode;
- PM_saveState_cb Callback;
-
- /* Quick optimized path for most common case */
- if (SesSwitchRec.Flags == -1)
- return;
-
-again:
- if (DosRequestMutexSem(SesSwitchRec.Mutex, 100))
- return;
- Flags = SesSwitchRec.Flags;
- Callback = SesSwitchRec.Callback;
- SesSwitchRec.Flags = -1;
- DosReleaseMutexSem(SesSwitchRec.Mutex);
-
- isSessionSwitching = true; /* Prevent VIO calls */
- Mode = Callback(Flags);
- isSessionSwitching = false;
- DosPostEventSem(SesSwitchRec.Event);
- if (Flags == PM_DEACTIVATE && Mode == PM_SUSPEND_APP)
- /* Suspend application until we switch back to our application */
- for (;;) {
- DosSleep (500);
- /* SesSwitchRec.Flags is volatile so optimizer
- * won't load it into a register
- */
- if (SesSwitchRec.Flags != -1)
- goto again;
- }
-}
-
-/****************************************************************************
-REMARKS:
-Waits until main thread processes the session switch event.
-****************************************************************************/
-static void _PM_SessionSwitchEvent(
- PM_saveState_cb saveState,
- int flags)
-{
- ULONG Count;
-
- if (DosRequestMutexSem(SesSwitchRec.Mutex, 10000))
- return;
-
- /* We're going to wait on that semaphore */
- DosResetEventSem(SesSwitchRec.Event, &Count);
- SesSwitchRec.Callback = saveState;
- SesSwitchRec.Flags = flags;
- DosReleaseMutexSem(SesSwitchRec.Mutex);
-
- /* Now wait until all required operations are complete */
- DosWaitEventSem (SesSwitchRec.Event, 10000);
-}
-
-/****************************************************************************
-REMARKS:
-This is the thread responsible for tracking switches back to our
-fullscreen session.
-****************************************************************************/
-static void _PM_ConsoleSwitch(
- PM_saveState_cb saveState)
-{
- USHORT NotifyType;
-
- for (;;) {
- if (VioModeWait(VMWR_POPUP, &NotifyType, 0) != 0)
- break;
- _PM_SessionSwitchEvent(saveState, PM_REACTIVATE);
- }
- VioModeUndo(UNDOI_RELEASEOWNER, UNDOK_ERRORCODE, (HVIO)0);
-}
-
-/****************************************************************************
-REMARKS:
-This is the thread responsible for tracking screen popups (usually fatal
-error handler uses them).
-****************************************************************************/
-static void _PM_ConsolePopup(
- PM_saveState_cb saveState)
-{
- USHORT NotifyType;
- for (;;) {
- if (VioSavRedrawWait(VSRWI_SAVEANDREDRAW, &NotifyType, 0) != 0)
- break;
- if (NotifyType == VSRWN_SAVE)
- _PM_SessionSwitchEvent(saveState, PM_DEACTIVATE);
- else if (NotifyType == VSRWN_REDRAW)
- _PM_SessionSwitchEvent(saveState, PM_REACTIVATE);
- }
- VioSavRedrawUndo(UNDOI_RELEASEOWNER, UNDOK_ERRORCODE, (HVIO)0);
-}
-
-/****************************************************************************
-REMARKS:
-Set the suspend application callback for the fullscreen console.
-****************************************************************************/
-void PMAPI PM_setSuspendAppCallback(
- PM_saveState_cb saveState)
-{
- /* If PM isn't loaded, this stuff will cause crashes! */
- if (__isShellLoaded()) {
- if (saveState) {
- /* Create the threads responsible for tracking console switches */
- SesSwitchRec.Flags = -1;
- DosCreateMutexSem(NULL, &SesSwitchRec.Mutex, 0, FALSE);
- DosCreateEventSem(NULL, &SesSwitchRec.Event, 0, FALSE);
- _beginthread ((void(*)(void*))_PM_ConsoleSwitch,NULL,SESSION_SWITCH_STACK_SIZE, (void*)saveState);
- _beginthread ((void(*)(void*))_PM_ConsolePopup,NULL,SESSION_SWITCH_STACK_SIZE, (void*)saveState);
- }
- else {
- /* Kill the threads responsible for tracking console switches */
- VioModeUndo(UNDOI_RELEASEOWNER, UNDOK_TERMINATE, (HVIO)0);
- VioSavRedrawUndo(UNDOI_RELEASEOWNER, UNDOK_TERMINATE, (HVIO)0);
- DosCloseEventSem(SesSwitchRec.Event);
- DosCloseMutexSem(SesSwitchRec.Mutex);
- }
- }
-}
-
-/****************************************************************************
-REMARKS:
-Restore the console state.
-****************************************************************************/
-void PMAPI PM_restoreConsoleState(
- const void *stateBuf,
- PM_HWND hwndConsole)
-{
- CONSOLE_SAVE *cs = (CONSOLE_SAVE *)stateBuf;
- VIOMODEINFO vmi;
-
- if (!cs)
- return;
-
- memcpy(&vmi, &cs->vmi, sizeof (VIOMODEINFO));
- VioSetMode(&vmi, (HVIO)0);
- VioSetCurPos(cs->CursorY, cs->CursorX, (HVIO)0);
- VioWrtCellStr((PCH)cs->FrameBuffer, cs->vmi.col * cs->vmi.row * 2,0, 0, (HVIO)0);
-}
-
-/****************************************************************************
-REMARKS:
-Close the fullscreen console.
-****************************************************************************/
-void PMAPI PM_closeConsole(
- PM_HWND hwndConsole)
-{
- /* Kill the threads responsible for tracking console switches */
- PM_setSuspendAppCallback(NULL);
- (void)hwndConsole;
-}
-
-/****************************************************************************
-REMARKS:
-Set the location of the OS console cursor.
-****************************************************************************/
-void PM_setOSCursorLocation(
- int x,
- int y)
-{
- /* If session switch is in progress, calling into VIO causes deadlocks! */
- /* Also this call to VIO screws up our console library on DBCS boxes... */
- if (!isSessionSwitching && !__IsDBCSSystem())
- VioSetCurPos(y,x,0);
-}
-
-/****************************************************************************
-REMARKS:
-Set the width of the OS console.
-****************************************************************************/
-void PM_setOSScreenWidth(
- int width,
- int height)
-{
- /* Nothing to do in here */
- (void)width;
- (void)height;
-}
-
-/****************************************************************************
-REMARKS:
-Set the real time clock handler (used for software stereo modes).
-****************************************************************************/
-ibool PMAPI PM_setRealTimeClockHandler(
- PM_intHandler ih,
- int frequency)
-{
- /* TODO: Implement this! */
- (void)ih;
- (void)frequency;
- return false;
-}
-
-/****************************************************************************
-REMARKS:
-Set the real time clock frequency (for stereo modes).
-****************************************************************************/
-void PMAPI PM_setRealTimeClockFrequency(
- int frequency)
-{
- /* TODO: Implement this! */
- (void)frequency;
-}
-
-/****************************************************************************
-REMARKS:
-Restore the original real time clock handler.
-****************************************************************************/
-void PMAPI PM_restoreRealTimeClockHandler(void)
-{
- /* TODO: Implement this! */
-}
-
-/****************************************************************************
-REMARKS:
-Return the current operating system path or working directory.
-****************************************************************************/
-char * PMAPI PM_getCurrentPath(
- char *path,
- int maxLen)
-{
- return getcwd(path,maxLen);
-}
-
-/****************************************************************************
-REMARKS:
-Return the drive letter for the boot drive.
-****************************************************************************/
-char PMAPI PM_getBootDrive(void)
-{
- ulong boot = 3;
- DosQuerySysInfo(QSV_BOOT_DRIVE,QSV_BOOT_DRIVE,&boot,sizeof(boot));
- return (char)('a' + boot - 1);
-}
-
-/****************************************************************************
-REMARKS:
-Return the path to the VBE/AF driver files.
-****************************************************************************/
-const char * PMAPI PM_getVBEAFPath(void)
-{
- static char path[CCHMAXPATH];
- strcpy(path,"x:\\");
- path[0] = PM_getBootDrive();
- return path;
-}
-
-/****************************************************************************
-REMARKS:
-Return the path to the Nucleus driver files.
-****************************************************************************/
-const char * PMAPI PM_getNucleusPath(void)
-{
- static char path[CCHMAXPATH];
- if (getenv("NUCLEUS_PATH") != NULL)
- return getenv("NUCLEUS_PATH");
- strcpy(path,"x:\\os2\\drivers");
- path[0] = PM_getBootDrive();
- PM_backslash(path);
- strcat(path,"nucleus");
- return path;
-}
-
-/****************************************************************************
-REMARKS:
-Return the path to the Nucleus configuration files.
-****************************************************************************/
-const char * PMAPI PM_getNucleusConfigPath(void)
-{
- static char path[CCHMAXPATH];
- strcpy(path,PM_getNucleusPath());
- PM_backslash(path);
- strcat(path,"config");
- return path;
-}
-
-/****************************************************************************
-REMARKS:
-Return a unique identifier for the machine if possible.
-****************************************************************************/
-const char * PMAPI PM_getUniqueID(void)
-{
- return PM_getMachineName();
-}
-
-/****************************************************************************
-REMARKS:
-Get the name of the machine on the network.
-****************************************************************************/
-const char * PMAPI PM_getMachineName(void)
-{
- static char name[40],*env;
-
- if ((env = getenv("HOSTNAME")) != NULL) {
- strncpy(name,env,sizeof(name));
- name[sizeof(name)-1] = 0;
- return name;
- }
- return "OS2";
-}
-
-/****************************************************************************
-REMARKS:
-Return a pointer to the real mode BIOS data area.
-****************************************************************************/
-void * PMAPI PM_getBIOSPointer(void)
-{
- PM_init();
- return lowMem + 0x400;
-}
-
-/****************************************************************************
-REMARKS:
-Return a pointer to 0xA0000 physical VGA graphics framebuffer.
-****************************************************************************/
-void * PMAPI PM_getA0000Pointer(void)
-{
- PM_init();
- return lowMem + 0xA0000;
-}
-
-/****************************************************************************
-REMARKS:
-Map a physical address to a linear address in the callers process.
-****************************************************************************/
-void * PMAPI PM_mapPhysicalAddr(
- ulong base,
- ulong limit,
- ibool isCached)
-{
- ulong baseAddr,baseOfs,linear;
-
- /* Round the physical address to a 4Kb boundary and the limit to a
- * 4Kb-1 boundary before passing the values to mmap. If we round the
- * physical address, then we also add an extra offset into the address
- * that we return.
- */
- baseOfs = base & 4095;
- baseAddr = base & ~4095;
- limit = ((limit+baseOfs+1+4095) & ~4095)-1;
- parmsIn[0] = baseAddr;
- parmsIn[1] = limit;
- parmsIn[2] = isCached;
- if ((linear = CallSDDHelp(PMHELP_MAPPHYS)) == 0)
- return NULL;
- return (void*)(linear + baseOfs);
-}
-
-/****************************************************************************
-REMARKS:
-Free a physical address mapping allocated by PM_mapPhysicalAddr.
-****************************************************************************/
-void PMAPI PM_freePhysicalAddr(
- void *ptr,
- ulong limit)
-{
- parmsIn[0] = (ulong)ptr;
- parmsIn[1] = limit;
- CallSDDHelp(PMHELP_FREEPHYS);
-}
-
-/****************************************************************************
-REMARKS:
-Find the physical address of a linear memory address in current process.
-****************************************************************************/
-ulong PMAPI PM_getPhysicalAddr(
- void *p)
-{
- parmsIn[0] = (ulong)p;
- return CallSDDHelp(PMHELP_GETPHYSICALADDR);
-}
-
-/****************************************************************************
-REMARKS:
-Find the physical address of a linear memory address in current process.
-****************************************************************************/
-ibool PMAPI PM_getPhysicalAddrRange(
- void *p,
- ulong length,
- ulong *physAddress)
-{
- parmsIn[0] = (ulong)p;
- parmsIn[1] = (ulong)length;
- parmsIn[2] = (ulong)physAddress;
- return CallSDDHelp(PMHELP_GETPHYSICALADDRRANGE);
-}
-
-/****************************************************************************
-REMARKS:
-Sleep for the specified number of milliseconds.
-****************************************************************************/
-void PMAPI PM_sleep(
- ulong milliseconds)
-{
- DosSleep(milliseconds);
-}
-
-/****************************************************************************
-REMARKS:
-Return the base I/O port for the specified COM port.
-****************************************************************************/
-int PMAPI PM_getCOMPort(
- int port)
-{
- switch (port) {
- case 0: return 0x3F8;
- case 1: return 0x2F8;
- }
- return 0;
-}
-
-/****************************************************************************
-REMARKS:
-Return the base I/O port for the specified LPT port.
-****************************************************************************/
-int PMAPI PM_getLPTPort(
- int port)
-{
- switch (port) {
- case 0: return 0x3BC;
- case 1: return 0x378;
- case 2: return 0x278;
- }
- return 0;
-}
-
-/****************************************************************************
-REMARKS:
-Allocate a block of shared memory. For Win9x we allocate shared memory
-as locked, global memory that is accessible from any memory context
-(including interrupt time context), which allows us to load our important
-data structure and code such that we can access it directly from a ring
-0 interrupt context.
-****************************************************************************/
-void * PMAPI PM_mallocShared(
- long size)
-{
- parmsIn[0] = size;
- return (void*)CallSDDHelp(PMHELP_MALLOCSHARED);
-}
-
-/****************************************************************************
-REMARKS:
-Free a block of shared memory.
-****************************************************************************/
-void PMAPI PM_freeShared(
- void *ptr)
-{
- parmsIn[0] = (ulong)ptr;
- CallSDDHelp(PMHELP_FREESHARED);
-}
-
-/****************************************************************************
-REMARKS:
-Map a linear memory address to the calling process address space. The
-address will have been allocated in another process using the
-PM_mapPhysicalAddr function.
-****************************************************************************/
-void * PMAPI PM_mapToProcess(
- void *base,
- ulong limit)
-{
- ulong baseAddr,baseOfs;
-
- /* Round the physical address to a 4Kb boundary and the limit to a
- * 4Kb-1 boundary before passing the values to mmap. If we round the
- * physical address, then we also add an extra offset into the address
- * that we return.
- */
- baseOfs = (ulong)base & 4095;
- baseAddr = (ulong)base & ~4095;
- limit = ((limit+baseOfs+1+4095) & ~4095)-1;
- parmsIn[0] = (ulong)baseAddr;
- parmsIn[1] = limit;
- return (void*)(CallSDDHelp(PMHELP_MAPTOPROCESS)+baseOfs);
-}
-
-/****************************************************************************
-REMARKS:
-Map a real mode pointer to a protected mode pointer.
-****************************************************************************/
-void * PMAPI PM_mapRealPointer(
- uint r_seg,
- uint r_off)
-{
- if (r_seg == 0xFFFF)
- return &RMBuf[r_off];
- return lowMem + MK_PHYS(r_seg,r_off);
-}
-
-/****************************************************************************
-REMARKS:
-Allocate a block of real mode memory
-****************************************************************************/
-void * PMAPI PM_allocRealSeg(
- uint size,
- uint *r_seg,
- uint *r_off)
-{
- if (size > sizeof(RMBuf))
- return NULL;
- *r_seg = 0xFFFF;
- *r_off = 0x0000;
- return &RMBuf;
-}
-
-/****************************************************************************
-REMARKS:
-Free a block of real mode memory.
-****************************************************************************/
-void PMAPI PM_freeRealSeg(
- void *mem)
-{
- /* Nothing to do in here */
- (void)mem;
-}
-
-#define INDPMI(reg) rmregs.aCRF.reg_##reg = regs->reg
-#define OUTDPMI(reg) regs->reg = rmregs.aCRF.reg_##reg
-
-#define REG_OFFSET(field) (((ULONG)&(((VCRF*)0)->field)) / sizeof(ULONG))
-
-/****************************************************************************
-REMARKS:
-Issue a real mode interrupt (parameters in DPMI compatible structure)
-****************************************************************************/
-void PMAPI DPMI_int86(
- int intno,
- DPMI_regs *regs)
-{
- INTCRF rmregs;
- ulong eax = 0;
-
- if (!InitInt10())
- return;
- memset(&rmregs, 0, sizeof(rmregs));
- rmregs.ulBIOSIntNo = intno;
- INDPMI(eax); INDPMI(ebx); INDPMI(ecx); INDPMI(edx); INDPMI(esi); INDPMI(edi);
- rmregs.aCRF.reg_ds = regs->ds;
- rmregs.aCRF.reg_es = regs->es;
- if (intno == 0x10) {
- eax = rmregs.aCRF.reg_eax;
- switch (eax & 0xFFFF) {
- case 0x4F00:
- /* We have to hack the way this function works, due to
- * some bugs in the IBM mini-VDM BIOS support. Specifically
- * we need to make the input buffer and output buffer the
- * 'same' buffer, and that ES:SI points to the output
- * buffer (ignored by the BIOS). The data will end up
- * being returned in the input buffer, except for the
- * first four bytes ('VESA') that will not be returned.
- */
- rmregs.pB[0].bBufferType = INPUT_BUFFER;
- rmregs.pB[0].bSelCRF = REG_OFFSET(reg_es);
- rmregs.pB[0].bOffCRF = REG_OFFSET(reg_edi);
- rmregs.pB[0].pAddress = RMBuf;
- rmregs.pB[0].ulSize = 4;
- rmregs.pB[1].bBufferType = OUTPUT_BUFFER;
- rmregs.pB[1].bSelCRF = REG_OFFSET(reg_es);
- rmregs.pB[1].bOffCRF = REG_OFFSET(reg_esi);
- rmregs.pB[1].pAddress = ((PBYTE)RMBuf)+4;
- rmregs.pB[1].ulSize = 512-4;
- break;
- case 0x4F01:
- rmregs.pB[0].bBufferType = OUTPUT_BUFFER;
- rmregs.pB[0].bSelCRF = REG_OFFSET(reg_es);
- rmregs.pB[0].bOffCRF = REG_OFFSET(reg_edi);
- rmregs.pB[0].pAddress = RMBuf;
- rmregs.pB[0].ulSize = 256;
- break;
- case 0x4F02:
- rmregs.pB[0].bBufferType = INPUT_BUFFER;
- rmregs.pB[0].bSelCRF = REG_OFFSET(reg_es);
- rmregs.pB[0].bOffCRF = REG_OFFSET(reg_edi);
- rmregs.pB[0].pAddress = RMBuf;
- rmregs.pB[0].ulSize = 256;
- break;
- case 0x4F09:
- rmregs.pB[0].bBufferType = INPUT_BUFFER;
- rmregs.pB[0].bSelCRF = REG_OFFSET(reg_es);
- rmregs.pB[0].bOffCRF = REG_OFFSET(reg_edi);
- rmregs.pB[0].pAddress = RMBuf;
- rmregs.pB[0].ulSize = 1024;
- break;
- case 0x4F0A:
- /* Due to bugs in the mini-VDM in OS/2, the 0x4F0A protected
- * mode interface functions will not work (we never get any
- * selectors returned), so we fail this function here. The
- * rest of the VBE/Core driver will work properly if this
- * function is failed, because the VBE 2.0 and 3.0 specs
- * allow for this.
- */
- regs->eax = 0x014F;
- return;
- }
- }
- if (useVPMI)
- PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,NULL,&rmregs);
- else {
- DosSysCtl(6, &rmregs);
- }
-
- OUTDPMI(eax); OUTDPMI(ebx); OUTDPMI(ecx); OUTDPMI(edx); OUTDPMI(esi); OUTDPMI(edi);
- if (((regs->eax & 0xFFFF) == 0x004F) && ((eax & 0xFFFF) == 0x4F00)) {
- /* Hack to fix up the missing 'VESA' string for mini-VDM */
- memcpy(RMBuf,"VESA",4);
- }
- regs->ds = rmregs.aCRF.reg_ds;
- regs->es = rmregs.aCRF.reg_es;
- regs->flags = rmregs.aCRF.reg_eflag;
-}
-
-#define IN(reg) rmregs.reg = in->e.reg
-#define OUT(reg) out->e.reg = rmregs.reg
-
-/****************************************************************************
-REMARKS:
-Issue a real mode interrupt.
-****************************************************************************/
-int PMAPI PM_int86(
- int intno,
- RMREGS *in,
- RMREGS *out)
-{
- DPMI_regs rmregs;
-
- memset(&rmregs, 0, sizeof(rmregs));
- IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi);
- DPMI_int86(intno,&rmregs);
- OUT(eax); OUT(ebx); OUT(ecx); OUT(edx); OUT(esi); OUT(edi);
- out->x.cflag = rmregs.flags & 0x1;
- return out->x.ax;
-}
-
-/****************************************************************************
-REMARKS:
-Issue a real mode interrupt.
-****************************************************************************/
-int PMAPI PM_int86x(
- int intno,
- RMREGS *in,
- RMREGS *out,
- RMSREGS *sregs)
-{
- DPMI_regs rmregs;
-
- memset(&rmregs, 0, sizeof(rmregs));
- IN(eax); IN(ebx); IN(ecx); IN(edx); IN(esi); IN(edi);
- rmregs.es = sregs->es;
- rmregs.ds = sregs->ds;
- DPMI_int86(intno,&rmregs);
- OUT(eax); OUT(ebx); OUT(ecx); OUT(edx); OUT(esi); OUT(edi);
- sregs->es = rmregs.es;
- sregs->cs = rmregs.cs;
- sregs->ss = rmregs.ss;
- sregs->ds = rmregs.ds;
- out->x.cflag = rmregs.flags & 0x1;
- return out->x.ax;
-}
-
-/****************************************************************************
-REMARKS:
-Call a real mode far function.
-****************************************************************************/
-void PMAPI PM_callRealMode(
- uint seg,
- uint off,
- RMREGS *in,
- RMSREGS *sregs)
-{
- PM_fatalError("PM_callRealMode not supported on OS/2!");
-}
-
-/****************************************************************************
-REMARKS:
-Return the amount of available memory.
-****************************************************************************/
-void PMAPI PM_availableMemory(
- ulong *physical,
- ulong *total)
-{
- /* Unable to get reliable values from OS/2 for this */
- *physical = *total = 0;
-}
-
-/****************************************************************************
-REMARKS:
-Allocate a block of locked, physical memory for DMA operations.
-****************************************************************************/
-void * PMAPI PM_allocLockedMem(
- uint size,
- ulong *physAddr,
- ibool contiguous,
- ibool below16M)
-{
- parmsIn[0] = size;
- parmsIn[1] = contiguous;
- parmsIn[2] = below16M;
- CallSDDHelp(PMHELP_ALLOCLOCKED);
- *physAddr = parmsOut[1];
- return (void*)parmsOut[0];
-}
-
-/****************************************************************************
-REMARKS:
-Free a block of locked physical memory.
-****************************************************************************/
-void PMAPI PM_freeLockedMem(
- void *p,
- uint size,
- ibool contiguous)
-{
- parmsIn[0] = (ulong)p;
- CallSDDHelp(PMHELP_FREELOCKED);
-}
-
-/****************************************************************************
-REMARKS:
-Allocates a new block of pages for the page block manager.
-****************************************************************************/
-static pageblock *PM_addNewPageBlock(void)
-{
- int i;
- pageblock *newBlock;
- char *p,*next;
-
- /* Allocate memory for the new page block, and add to head of list */
- if (DosAllocSharedMem((void**)&newBlock,NULL,PAGE_BLOCK_SIZE,OBJ_GETTABLE | PAG_READ | PAG_WRITE | PAG_COMMIT))
- return NULL;
- if (!PM_lockDataPages(newBlock,PAGE_BLOCK_SIZE,&newBlock->lockHandle))
- return NULL;
- newBlock->prev = NULL;
- newBlock->next = pageBlocks;
- if (pageBlocks)
- pageBlocks->prev = newBlock;
- pageBlocks = newBlock;
-
- /* Initialise the page aligned free list for the page block */
- newBlock->freeCount = PAGES_PER_BLOCK;
- newBlock->freeList = p = (char*)(((ulong)(newBlock + 1) + (PM_PAGE_SIZE-1)) & ~(PM_PAGE_SIZE-1));
- newBlock->freeListStart = newBlock->freeList;
- newBlock->freeListEnd = p + (PAGES_PER_BLOCK-1) * PM_PAGE_SIZE;
- for (i = 0; i < PAGES_PER_BLOCK; i++,p = next)
- FREELIST_NEXT(p) = next = p + PM_PAGE_SIZE;
- FREELIST_NEXT(p - PM_PAGE_SIZE) = NULL;
- return newBlock;
-}
-
-/****************************************************************************
-REMARKS:
-Allocates a page aligned and page sized block of memory
-****************************************************************************/
-void * PMAPI PM_allocPage(
- ibool locked)
-{
- pageblock *block;
- void *p;
-
- /* Scan the block list looking for any free blocks. Allocate a new
- * page block if no free blocks are found.
- */
- for (block = pageBlocks; block != NULL; block = block->next) {
- if (block->freeCount)
- break;
- }
- if (block == NULL && (block = PM_addNewPageBlock()) == NULL)
- return NULL;
- block->freeCount--;
- p = block->freeList;
- block->freeList = FREELIST_NEXT(p);
- (void)locked;
- return p;
-}
-
-/****************************************************************************
-REMARKS:
-Free a page aligned and page sized block of memory
-****************************************************************************/
-void PMAPI PM_freePage(
- void *p)
-{
- pageblock *block;
-
- /* First find the page block that this page belongs to */
- for (block = pageBlocks; block != NULL; block = block->next) {
- if (p >= block->freeListStart && p <= block->freeListEnd)
- break;
- }
- CHECK(block != NULL);
-
- /* Now free the block by adding it to the free list */
- FREELIST_NEXT(p) = block->freeList;
- block->freeList = p;
- if (++block->freeCount == PAGES_PER_BLOCK) {
- /* If all pages in the page block are now free, free the entire
- * page block itself.
- */
- if (block == pageBlocks) {
- /* Delete from head */
- pageBlocks = block->next;
- if (block->next)
- block->next->prev = NULL;
- }
- else {
- /* Delete from middle of list */
- CHECK(block->prev != NULL);
- block->prev->next = block->next;
- if (block->next)
- block->next->prev = block->prev;
- }
-
- /* Unlock the memory and free it */
- PM_unlockDataPages(block,PAGE_BLOCK_SIZE,&block->lockHandle);
- DosFreeMem(block);
- }
-}
-
-/****************************************************************************
-REMARKS:
-Map in all the shared memory blocks for managing the memory pages above.
-****************************************************************************/
-void PMAPI PM_mapSharedPages(void)
-{
- pageblock *block;
-
- /* Map all the page blocks above into the shared memory for process */
- for (block = pageBlocks; block != NULL; block = block->next) {
- DosGetSharedMem(block, PAG_READ | PAG_WRITE);
- }
-}
-
-/****************************************************************************
-REMARKS:
-Lock linear memory so it won't be paged.
-****************************************************************************/
-int PMAPI PM_lockDataPages(
- void *p,
- uint len,
- PM_lockHandle *lockHandle)
-{
- parmsIn[0] = (ulong)p;
- parmsIn[1] = len;
- CallSDDHelp(PMHELP_LOCKPAGES);
- lockHandle->h[0] = parmsOut[1];
- lockHandle->h[1] = parmsOut[2];
- lockHandle->h[2] = parmsOut[3];
- return parmsOut[0];
-}
-
-/****************************************************************************
-REMARKS:
-Unlock linear memory so it won't be paged.
-****************************************************************************/
-int PMAPI PM_unlockDataPages(
- void *p,
- uint len,
- PM_lockHandle *lockHandle)
-{
- parmsIn[0] = lockHandle->h[0];
- parmsIn[1] = lockHandle->h[1];
- parmsIn[2] = lockHandle->h[2];
- return CallSDDHelp(PMHELP_UNLOCKPAGES);
-}
-
-/****************************************************************************
-REMARKS:
-Lock linear memory so it won't be paged.
-****************************************************************************/
-int PMAPI PM_lockCodePages(
- void (*p)(),
- uint len,
- PM_lockHandle *lockHandle)
-{
- parmsIn[0] = (ulong)p;
- parmsIn[1] = len;
- CallSDDHelp(PMHELP_LOCKPAGES);
- lockHandle->h[0] = parmsOut[1];
- lockHandle->h[1] = parmsOut[2];
- lockHandle->h[2] = parmsOut[3];
- return parmsOut[0];
-}
-
-/****************************************************************************
-REMARKS:
-Unlock linear memory so it won't be paged.
-****************************************************************************/
-int PMAPI PM_unlockCodePages(
- void (*p)(),
- uint len,
- PM_lockHandle *lockHandle)
-{
- parmsIn[0] = lockHandle->h[0];
- parmsIn[1] = lockHandle->h[1];
- parmsIn[2] = lockHandle->h[2];
- return CallSDDHelp(PMHELP_UNLOCKPAGES);
-}
-
-/****************************************************************************
-REMARKS:
-Call the VBE/Core software interrupt to change display banks.
-****************************************************************************/
-void PMAPI PM_setBankA(
- int bank)
-{
- INTCRF rmregs;
-
- if (!InitInt10())
- return;
- memset(&rmregs, 0, sizeof(rmregs));
- rmregs.ulBIOSIntNo = 0x10;
- rmregs.aCRF.reg_eax = 0x4F05;
- rmregs.aCRF.reg_ebx = 0x0000;
- rmregs.aCRF.reg_edx = bank;
- PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&rmregs,NULL);
-}
-
-/****************************************************************************
-REMARKS:
-Call the VBE/Core software interrupt to change display banks.
-****************************************************************************/
-void PMAPI PM_setBankAB(
- int bank)
-{
- INTCRF rmregs;
-
- if (!InitInt10())
- return;
- memset(&rmregs, 0, sizeof(rmregs));
- rmregs.ulBIOSIntNo = 0x10;
- rmregs.aCRF.reg_eax = 0x4F05;
- rmregs.aCRF.reg_ebx = 0x0000;
- rmregs.aCRF.reg_edx = bank;
- PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&rmregs,NULL);
- rmregs.ulBIOSIntNo = 0x10;
- rmregs.aCRF.reg_eax = 0x4F05;
- rmregs.aCRF.reg_ebx = 0x0001;
- rmregs.aCRF.reg_edx = bank;
- PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&rmregs,NULL);
-}
-
-/****************************************************************************
-REMARKS:
-Call the VBE/Core software interrupt to change display start address.
-****************************************************************************/
-void PMAPI PM_setCRTStart(
- int x,
- int y,
- int waitVRT)
-{
- INTCRF rmregs;
-
- if (!InitInt10())
- return;
- memset(&rmregs, 0, sizeof(rmregs));
- rmregs.ulBIOSIntNo = 0x10;
- rmregs.aCRF.reg_eax = 0x4F07;
- rmregs.aCRF.reg_ebx = waitVRT;
- rmregs.aCRF.reg_ecx = x;
- rmregs.aCRF.reg_edx = y;
- PM_VIDEOPMI32Request(&Adapter,PMIREQUEST_SOFTWAREINT,&rmregs,NULL);
-}
-
-/****************************************************************************
-REMARKS:
-Execute the POST on the secondary BIOS for a controller.
-****************************************************************************/
-ibool PMAPI PM_doBIOSPOST(
- ushort axVal,
- ulong BIOSPhysAddr,
- void *mappedBIOS,
- ulong BIOSLen)
-{
- (void)axVal;
- (void)BIOSPhysAddr;
- (void)mappedBIOS;
- (void)BIOSLen;
- return false;
-}
-
-/****************************************************************************
-PARAMETERS:
-base - The starting physical base address of the region
-size - The size in bytes of the region
-type - Type to place into the MTRR register
-
-RETURNS:
-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)
-{
- return MTRR_enableWriteCombine(base,size,type);
-}
-
-/* TODO: Move the MTRR helper stuff into the call gate, or better yet */
-/* entirely into the ring 0 helper driver!! */
-
-/* MTRR helper functions. To make it easier to implement the MTRR support
- * under OS/2, we simply put our ring 0 helper functions into the
- * helper device driver rather than the entire MTRR module. This makes
- * it easier to maintain the MTRR support since we don't need to deal
- * with 16-bit ring 0 code in the MTRR library.
- */
-
-/****************************************************************************
-REMARKS:
-Flush the translation lookaside buffer.
-****************************************************************************/
-void PMAPI PM_flushTLB(void)
-{
- CallSDDHelp(PMHELP_FLUSHTLB);
-}
-
-/****************************************************************************
-REMARKS:
-Return true if ring 0 (or if we can call the helpers functions at ring 0)
-****************************************************************************/
-ibool _ASMAPI _MTRR_isRing0(void)
-{
- return true;
-}
-
-/****************************************************************************
-REMARKS:
-Read and return the value of the CR4 register
-****************************************************************************/
-ulong _ASMAPI _MTRR_saveCR4(void)
-{
- return CallSDDHelp(PMHELP_SAVECR4);
-}
-
-/****************************************************************************
-REMARKS:
-Restore the value of the CR4 register
-****************************************************************************/
-void _ASMAPI _MTRR_restoreCR4(ulong cr4Val)
-{
- parmsIn[0] = cr4Val;
- CallSDDHelp(PMHELP_RESTORECR4);
-}
-
-/****************************************************************************
-REMARKS:
-Read a machine status register for the CPU.
-****************************************************************************/
-void _ASMAPI _MTRR_readMSR(
- ulong reg,
- ulong *eax,
- ulong *edx)
-{
- parmsIn[0] = reg;
- CallSDDHelp(PMHELP_READMSR);
- *eax = parmsOut[0];
- *edx = parmsOut[1];
-}
-
-/****************************************************************************
-REMARKS:
-Write a machine status register for the CPU.
-****************************************************************************/
-void _ASMAPI _MTRR_writeMSR(
- ulong reg,
- ulong eax,
- ulong edx)
-{
- parmsIn[0] = reg;
- parmsIn[1] = eax;
- parmsIn[2] = edx;
- CallSDDHelp(PMHELP_WRITEMSR);
-}
-
-PM_MODULE PMAPI PM_loadLibrary(
- const char *szDLLName)
-{
- /* TODO: Implement this to load shared libraries! */
- (void)szDLLName;
- return NULL;
-}
-
-void * PMAPI PM_getProcAddress(
- PM_MODULE hModule,
- const char *szProcName)
-{
- /* TODO: Implement this! */
- (void)hModule;
- (void)szProcName;
- return NULL;
-}
-
-void PMAPI PM_freeLibrary(
- PM_MODULE hModule)
-{
- /* TODO: Implement this! */
- (void)hModule;
-}
-
-/****************************************************************************
-REMARKS:
-Internal function to convert the find data to the generic interface.
-****************************************************************************/
-static void convertFindData(
- PM_findData *findData,
- FILEFINDBUF3 *blk)
-{
- ulong dwSize = findData->dwSize;
-
- memset(findData,0,findData->dwSize);
- findData->dwSize = dwSize;
- if (blk->attrFile & FILE_READONLY)
- findData->attrib |= PM_FILE_READONLY;
- if (blk->attrFile & FILE_DIRECTORY)
- findData->attrib |= PM_FILE_DIRECTORY;
- if (blk->attrFile & FILE_ARCHIVED)
- findData->attrib |= PM_FILE_ARCHIVE;
- if (blk->attrFile & FILE_HIDDEN)
- findData->attrib |= PM_FILE_HIDDEN;
- if (blk->attrFile & FILE_SYSTEM)
- findData->attrib |= PM_FILE_SYSTEM;
- findData->sizeLo = blk->cbFile;
- findData->sizeHi = 0;
- strncpy(findData->name,blk->achName,PM_MAX_PATH);
- findData->name[PM_MAX_PATH-1] = 0;
-}
-
-#define FIND_MASK (FILE_ARCHIVED | FILE_DIRECTORY | FILE_SYSTEM | FILE_HIDDEN | FILE_READONLY)
-
-/****************************************************************************
-REMARKS:
-Function to find the first file matching a search criteria in a directory.
-****************************************************************************/
-void *PMAPI PM_findFirstFile(
- const char *filename,
- PM_findData *findData)
-{
- FILEFINDBUF3 blk;
- HDIR hdir = HDIR_CREATE;
- ulong count = 1;
-
- if (DosFindFirst((PSZ)filename,&hdir,FIND_MASK,&blk,sizeof(blk),&count,FIL_STANDARD) == NO_ERROR) {
- convertFindData(findData,&blk);
- return (void*)hdir;
- }
- return PM_FILE_INVALID;
-}
-
-/****************************************************************************
-REMARKS:
-Function to find the next file matching a search criteria in a directory.
-****************************************************************************/
-ibool PMAPI PM_findNextFile(
- void *handle,
- PM_findData *findData)
-{
- FILEFINDBUF3 blk;
- ulong count = 1;
-
- if (DosFindNext((HDIR)handle,&blk,sizeof(blk),&count) == NO_ERROR) {
- convertFindData(findData,&blk);
- return true;
- }
- return false;
-}
-
-/****************************************************************************
-REMARKS:
-Function to close the find process
-****************************************************************************/
-void PMAPI PM_findClose(
- void *handle)
-{
- DosFindClose((HDIR)handle);
-}
-
-/****************************************************************************
-REMARKS:
-Function to determine if a drive is a valid drive or not. Under Unix this
-function will return false for anything except a value of 3 (considered
-the root drive, and equivalent to C: for non-Unix systems). The drive
-numbering is:
-
- 0 - Current drive
- 1 - Drive A:
- 2 - Drive B:
- 3 - Drive C:
- etc
-
-****************************************************************************/
-ibool PMAPI PM_driveValid(
- char drive)
-{
- ulong cntDisk,cntDriveMap;
- ibool valid;
-
- DosQueryCurrentDisk(&cntDisk,&cntDriveMap);
- valid = (DosSetDefaultDisk(drive) == NO_ERROR);
- DosSetDefaultDisk(cntDisk);
- return valid;
-}
-
-/****************************************************************************
-REMARKS:
-Function to get the current working directory for the specififed drive.
-Under Unix this will always return the current working directory regardless
-of what the value of 'drive' is.
-****************************************************************************/
-void PMAPI PM_getdcwd(
- int drive,
- char *dir,
- int len)
-{
- ulong length = len;
-
- DosQueryCurrentDir(drive, (PSZ)dir, &length);
-}
-
-/****************************************************************************
-REMARKS:
-Function to change the file attributes for a specific file.
-****************************************************************************/
-void PMAPI PM_setFileAttr(
- const char *filename,
- uint attrib)
-{
- FILESTATUS3 s;
-
- if (DosQueryPathInfo((PSZ)filename,FIL_STANDARD,(PVOID)&s,sizeof(s)))
- return;
- s.attrFile = 0;
- if (attrib & PM_FILE_READONLY)
- s.attrFile |= FILE_READONLY;
- if (attrib & PM_FILE_ARCHIVE)
- s.attrFile |= FILE_ARCHIVED;
- if (attrib & PM_FILE_HIDDEN)
- s.attrFile |= FILE_HIDDEN;
- if (attrib & PM_FILE_SYSTEM)
- s.attrFile |= FILE_SYSTEM;
- DosSetPathInfo((PSZ)filename,FIL_STANDARD,(PVOID)&s,sizeof(s),0L);
-}
-
-/****************************************************************************
-REMARKS:
-Function to get the file attributes for a specific file.
-****************************************************************************/
-uint PMAPI PM_getFileAttr(
- const char *filename)
-{
- FILESTATUS3 fs3;
- uint retval = 0;
-
- if (DosQueryPathInfo((PSZ)filename, FIL_STANDARD, &fs3, sizeof(FILESTATUS3)))
- return 0;
- if (fs3.attrFile & FILE_READONLY)
- retval |= PM_FILE_READONLY;
- if (fs3.attrFile & FILE_ARCHIVED)
- retval |= PM_FILE_ARCHIVE;
- if (fs3.attrFile & FILE_HIDDEN)
- retval |= PM_FILE_HIDDEN;
- if (fs3.attrFile & FILE_SYSTEM)
- retval |= PM_FILE_SYSTEM;
- return retval;
-}
-
-/****************************************************************************
-REMARKS:
-Function to create a directory.
-****************************************************************************/
-ibool PMAPI PM_mkdir(
- const char *filename)
-{
- return DosCreateDir((PSZ)filename,NULL) == NO_ERROR;
-}
-
-/****************************************************************************
-REMARKS:
-Function to remove a directory.
-****************************************************************************/
-ibool PMAPI PM_rmdir(
- const char *filename)
-{
- return DosDeleteDir((PSZ)filename) == NO_ERROR;
-}
-
-/****************************************************************************
-REMARKS:
-Function to get the file time and date for a specific file.
-****************************************************************************/
-ibool PMAPI PM_getFileTime(
- const char *filename,
- ibool gmTime,
- PM_time *time)
-{
- FILESTATUS3 fs3;
- struct tm tc;
- struct tm *ret;
- time_t tt;
-
- if (DosQueryPathInfo((PSZ)filename, FIL_STANDARD, &fs3, sizeof(FILESTATUS3)))
- return false;
- if (gmTime) {
- tc.tm_year = fs3.fdateLastWrite.year + 80;
- tc.tm_mon = fs3.fdateLastWrite.month - 1;
- tc.tm_mday = fs3.fdateLastWrite.day;
- tc.tm_hour = fs3.ftimeLastWrite.hours;
- tc.tm_min = fs3.ftimeLastWrite.minutes;
- tc.tm_sec = fs3.ftimeLastWrite.twosecs * 2;
- if((tt = mktime(&tc)) == -1)
- return false;
- if(!(ret = gmtime(&tt)))
- return false;
- time->sec = ret->tm_sec;
- time->day = ret->tm_mday;
- time->mon = ret->tm_mon + 1;
- time->year = ret->tm_year - 80;
- time->min = ret->tm_min;
- time->hour = ret->tm_hour;
- }
- else {
- time->sec = fs3.ftimeLastWrite.twosecs * 2;
- time->day = fs3.fdateLastWrite.day;
- time->mon = fs3.fdateLastWrite.month;
- time->year = fs3.fdateLastWrite.year;
- time->min = fs3.ftimeLastWrite.minutes;
- time->hour = fs3.ftimeLastWrite.hours;
- }
- return true;
-}
-
-/****************************************************************************
-REMARKS:
-Function to set the file time and date for a specific file.
-****************************************************************************/
-ibool PMAPI PM_setFileTime(
- const char *filename,
- ibool gmTime,
- PM_time *time)
-{
- FILESTATUS3 fs3;
- struct tm tc;
- struct tm *ret;
- time_t tt;
-
- if (DosQueryPathInfo((PSZ)filename,FIL_STANDARD,(PVOID)&fs3,sizeof(fs3)))
- return false;
- if (gmTime) {
- tc.tm_year = time->year + 80;
- tc.tm_mon = time->mon - 1;
- tc.tm_mday = time->day;
- tc.tm_hour = time->hour;
- tc.tm_min = time->min;
- tc.tm_sec = time->sec;
- if((tt = mktime(&tc)) == -1)
- return false;
- ret = localtime(&tt);
- fs3.ftimeLastWrite.twosecs = ret->tm_sec / 2;
- fs3.fdateLastWrite.day = ret->tm_mday;
- fs3.fdateLastWrite.month = ret->tm_mon + 1;
- fs3.fdateLastWrite.year = ret->tm_year - 80;
- fs3.ftimeLastWrite.minutes = ret->tm_min;
- fs3.ftimeLastWrite.hours = ret->tm_hour;
- }
- else {
- fs3.ftimeLastWrite.twosecs = time->sec / 2;
- fs3.fdateLastWrite.day = time->day;
- fs3.fdateLastWrite.month = time->mon;
- fs3.fdateLastWrite.year = time->year;
- fs3.ftimeLastWrite.minutes = time->min;
- fs3.ftimeLastWrite.hours = time->hour;
- }
- memcpy(&fs3.fdateLastAccess, &fs3.fdateLastWrite, sizeof(FDATE));
- memcpy(&fs3.fdateCreation, &fs3.fdateLastWrite, sizeof(FDATE));
- memcpy(&fs3.ftimeLastAccess, &fs3.ftimeLastWrite, sizeof(FTIME));
- memcpy(&fs3.ftimeCreation, &fs3.ftimeLastWrite, sizeof(FTIME));
- DosSetPathInfo((PSZ)filename,FIL_STANDARD,(PVOID)&fs3,sizeof(FILESTATUS3),0L);
- return true;
-}
OpenPOWER on IntegriCloud