pm.c

来自「适合KS8695X」· C语言 代码 · 共 1,188 行 · 第 1/3 页

C
1,188
字号
/****************************************************************************
*
*                   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   10

static 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 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)
{
#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, &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;
}

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,&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_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,&regs,&regs);
	}
    (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 + =
减小字号Ctrl + -
显示快捷键?