diff options
author | Kevin | 2014-11-15 11:48:36 +0800 |
---|---|---|
committer | Kevin | 2014-11-15 11:48:36 +0800 |
commit | d04075478d378d9e15f3e1abfd14b0bd124077d4 (patch) | |
tree | 733dd964582f388b9e3e367c249946cd32a2851f /board/MAI/bios_emulator/scitech/src/pm/vxd | |
download | FOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.tar.gz FOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.tar.bz2 FOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.zip |
init commit via android 4.4 uboot
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/pm/vxd')
-rwxr-xr-x | board/MAI/bios_emulator/scitech/src/pm/vxd/_pm.asm | 299 | ||||
-rwxr-xr-x | board/MAI/bios_emulator/scitech/src/pm/vxd/cpuinfo.c | 66 | ||||
-rwxr-xr-x | board/MAI/bios_emulator/scitech/src/pm/vxd/fileio.c | 304 | ||||
-rwxr-xr-x | board/MAI/bios_emulator/scitech/src/pm/vxd/oshdr.h | 29 | ||||
-rwxr-xr-x | board/MAI/bios_emulator/scitech/src/pm/vxd/pm.c | 1359 | ||||
-rwxr-xr-x | board/MAI/bios_emulator/scitech/src/pm/vxd/vflat.c | 45 | ||||
-rwxr-xr-x | board/MAI/bios_emulator/scitech/src/pm/vxd/ztimer.c | 105 |
7 files changed, 2207 insertions, 0 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/pm/vxd/_pm.asm b/board/MAI/bios_emulator/scitech/src/pm/vxd/_pm.asm new file mode 100755 index 0000000..64a7cec --- /dev/null +++ b/board/MAI/bios_emulator/scitech/src/pm/vxd/_pm.asm @@ -0,0 +1,299 @@ +;**************************************************************************** +;* +;* 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: 80386 Assembler, TASM 4.0 or NASM +;* Environment: 32-bit Windows VxD +;* +;* Description: Low level assembly support for the PM library specific to +;* Windows VxDs. +;* +;**************************************************************************** + + IDEAL + +include "scitech.mac" ; Memory model macros + +header _pm ; Set up memory model + +begdataseg _pm + + cextern _PM_savedDS,USHORT + +enddataseg _pm + +P586 + +begcodeseg _pm ; Start of code segment + +;---------------------------------------------------------------------------- +; void PM_segread(PMSREGS *sregs) +;---------------------------------------------------------------------------- +; Read the current value of all segment registers +;---------------------------------------------------------------------------- +cprocstart PM_segread + + ARG sregs:DPTR + + enter_c + + mov ax,es + _les _si,[sregs] + mov [_ES _si],ax + mov [_ES _si+2],cs + mov [_ES _si+4],ss + mov [_ES _si+6],ds + mov [_ES _si+8],fs + mov [_ES _si+10],gs + + leave_c + ret + +cprocend + +;---------------------------------------------------------------------------- +; int PM_int386x(int intno, PMREGS *in, PMREGS *out,PMSREGS *sregs) +;---------------------------------------------------------------------------- +; Issues a software interrupt in protected mode. This routine has been +; written to allow user programs to load CS and DS with different values +; other than the default. +;---------------------------------------------------------------------------- +cprocstart PM_int386x + +; Not used for VxDs + + ret + +cprocend + +;---------------------------------------------------------------------------- +; void PM_saveDS(void) +;---------------------------------------------------------------------------- +; Save the value of DS into a section of the code segment, so that we can +; quickly load this value at a later date in the PM_loadDS() routine from +; inside interrupt handlers etc. The method to do this is different +; depending on the DOS extender being used. +;---------------------------------------------------------------------------- +cprocstart PM_saveDS + + mov [_PM_savedDS],ds ; Store away in data segment + ret + +cprocend + +;---------------------------------------------------------------------------- +; void PM_loadDS(void) +;---------------------------------------------------------------------------- +; Routine to load the DS register with the default value for the current +; DOS extender. Only the DS register is loaded, not the ES register, so +; if you wish to call C code, you will need to also load the ES register +; in 32 bit protected mode. +;---------------------------------------------------------------------------- +cprocstart PM_loadDS + + mov ds,[cs:_PM_savedDS] ; We can access the proper DS through CS + ret + +cprocend + +;---------------------------------------------------------------------------- +; void PM_setBankA(int bank) +;---------------------------------------------------------------------------- +cprocstart PM_setBankA + +; Not used for VxDs + + ret + +cprocend + +;---------------------------------------------------------------------------- +; void PM_setBankAB(int bank) +;---------------------------------------------------------------------------- +cprocstart PM_setBankAB + +; Not used for VxDs + + ret + +cprocend + +;---------------------------------------------------------------------------- +; void PM_setCRTStart(int x,int y,int waitVRT) +;---------------------------------------------------------------------------- +cprocstart PM_setCRTStart + +; Not used for VxDs + + ret + +cprocend + +; Macro to delay briefly to ensure that enough time has elapsed between +; successive I/O accesses so that the device being accessed can respond +; to both accesses even on a very fast PC. + +ifdef USE_NASM +%macro DELAY 0 + jmp short $+2 + jmp short $+2 + jmp short $+2 +%endmacro +%macro IODELAYN 1 +%rep %1 + DELAY +%endrep +%endmacro +else +macro DELAY + jmp short $+2 + jmp short $+2 + jmp short $+2 +endm +macro IODELAYN N + rept N + DELAY + endm +endm +endif + +;---------------------------------------------------------------------------- +; uchar _PM_readCMOS(int index) +;---------------------------------------------------------------------------- +; Read the value of a specific CMOS register. We do this with both +; normal interrupts and NMI disabled. +;---------------------------------------------------------------------------- +cprocstart _PM_readCMOS + + ARG index:UINT + + push _bp + mov _bp,_sp + pushfd + mov al,[BYTE index] + or al,80h ; Add disable NMI flag + cli + out 70h,al + IODELAYN 5 + in al,71h + mov ah,al + xor al,al + IODELAYN 5 + out 70h,al ; Re-enable NMI + mov al,ah ; Return value in AL + popfd + pop _bp + ret + +cprocend + +;---------------------------------------------------------------------------- +; void _PM_writeCMOS(int index,uchar value) +;---------------------------------------------------------------------------- +; Read the value of a specific CMOS register. We do this with both +; normal interrupts and NMI disabled. +;---------------------------------------------------------------------------- +cprocstart _PM_writeCMOS + + ARG index:UINT, value:UCHAR + + push _bp + mov _bp,_sp + pushfd + mov al,[BYTE index] + or al,80h ; Add disable NMI flag + cli + out 70h,al + IODELAYN 5 + mov al,[value] + out 71h,al + xor al,al + IODELAYN 5 + out 70h,al ; Re-enable NMI + popfd + pop _bp + ret + +cprocend + +;---------------------------------------------------------------------------- +; double _ftol(double f) +;---------------------------------------------------------------------------- +; Calls to __ftol are generated by the Borland C++ compiler for code +; that needs to convert a floating point type to an integral type. +; +; Input: floating point number on the top of the '87. +; +; Output: a (signed or unsigned) long in EAX +; All other registers preserved. +;----------------------------------------------------------------------- +cprocstart _ftol + + LOCAL temp1:WORD, temp2:QWORD = LocalSize + + push ebp + mov ebp,esp + sub esp,LocalSize + + fstcw [temp1] ; save the control word + fwait + mov al,[BYTE temp1+1] + or [BYTE temp1+1],0Ch ; set rounding control to chop + fldcw [temp1] + fistp [temp2] ; convert to 64-bit integer + mov [BYTE temp1+1],al + fldcw [temp1] ; restore the control word + mov eax,[DWORD temp2] ; return LS 32 bits + mov edx,[DWORD temp2+4] ; MS 32 bits + + mov esp,ebp + pop ebp + ret + +cprocend + +;---------------------------------------------------------------------------- +; _PM_getPDB - Return the Page Table Directory Base address +;---------------------------------------------------------------------------- +cprocstart _PM_getPDB + + mov eax,cr3 + and eax,0FFFFF000h + ret + +cprocend + +;---------------------------------------------------------------------------- +; Flush the Translation Lookaside buffer +;---------------------------------------------------------------------------- +cprocstart PM_flushTLB + + wbinvd ; Flush the CPU cache + mov eax,cr3 + mov cr3,eax ; Flush the TLB + ret + +cprocend + +endcodeseg _pm + + END ; End of module diff --git a/board/MAI/bios_emulator/scitech/src/pm/vxd/cpuinfo.c b/board/MAI/bios_emulator/scitech/src/pm/vxd/cpuinfo.c new file mode 100755 index 0000000..3c7eaae --- /dev/null +++ b/board/MAI/bios_emulator/scitech/src/pm/vxd/cpuinfo.c @@ -0,0 +1,66 @@ +/**************************************************************************** +* +* Ultra Long Period Timer +* +* ======================================================================== +* +* 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 Windows VxD +* +* Description: VxD specific code for the CPU detection module. +* +****************************************************************************/ + +/*----------------------------- Implementation ----------------------------*/ + +/**************************************************************************** +REMARKS: +Do nothing for VxD's +****************************************************************************/ +#define SetMaxThreadPriority() 0 + +/**************************************************************************** +REMARKS: +Do nothing for VxD's +****************************************************************************/ +#define RestoreThreadPriority(i) (void)(i) + +/**************************************************************************** +REMARKS: +Initialise the counter and return the frequency of the counter. +****************************************************************************/ +static void GetCounterFrequency( + CPU_largeInteger *freq) +{ + freq->low = 1193180; + freq->high = 0; +} + +/**************************************************************************** +REMARKS: +Read the counter and return the counter value. +****************************************************************************/ +#define GetCounter(t) \ +{ \ + CPU_largeInteger count; \ + VTD_Get_Real_Time(&count.high,&count.low); \ + (t)->low = count.low; \ + (t)->high = count.high; \ +} diff --git a/board/MAI/bios_emulator/scitech/src/pm/vxd/fileio.c b/board/MAI/bios_emulator/scitech/src/pm/vxd/fileio.c new file mode 100755 index 0000000..3c6ce99 --- /dev/null +++ b/board/MAI/bios_emulator/scitech/src/pm/vxd/fileio.c @@ -0,0 +1,304 @@ +/**************************************************************************** +* +* 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 Windows VxD +* +* Description: C library compatible I/O functions for use within a VxD. +* +****************************************************************************/ + +#include "pmapi.h" +#include "vxdfile.h" + +/*------------------------ Main Code Implementation -----------------------*/ + +#define EOF -1 + +/**************************************************************************** +REMARKS: +VxD implementation of the ANSI C fopen function. +****************************************************************************/ +FILE * fopen( + const char *filename, + const char *mode) +{ + FILE *f = PM_malloc(sizeof(FILE)); + long oldpos; + + if (f) { + f->offset = 0; + f->text = (mode[1] == 't' || mode[2] == 't'); + f->writemode = (mode[0] == 'w') || (mode[0] == 'a'); + if (initComplete) { + WORD omode,error; + BYTE action; + + if (mode[0] == 'r') { + omode = OPEN_ACCESS_READONLY | OPEN_SHARE_COMPATIBLE; + action = ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_FAIL; + } + else if (mode[0] == 'w') { + omode = OPEN_ACCESS_WRITEONLY | OPEN_SHARE_COMPATIBLE; + action = ACTION_IFEXISTS_TRUNCATE | ACTION_IFNOTEXISTS_CREATE; + } + else { + omode = OPEN_ACCESS_READWRITE | OPEN_SHARE_COMPATIBLE; + action = ACTION_IFEXISTS_OPEN | ACTION_IFNOTEXISTS_CREATE; + } + f->handle = (int)R0_OpenCreateFile(false,(char*)filename,omode,ATTR_NORMAL,action,0,&error,&action); + if (f->handle == 0) { + PM_free(f); + return NULL; + } + f->filesize = R0_GetFileSize((HANDLE)f->handle,&error); + if (mode[0] == 'a') + fseek(f,0,2); + } + else { + int oflag,pmode; + + if (mode[0] == 'r') { + pmode = _S_IREAD; + oflag = _O_RDONLY; + } + else if (mode[0] == 'w') { + pmode = _S_IWRITE; + oflag = _O_WRONLY | _O_CREAT | _O_TRUNC; + } + else { + pmode = _S_IWRITE; + oflag = _O_RDWR | _O_CREAT | _O_APPEND; + } + if (f->text) + oflag |= _O_TEXT; + else + oflag |= _O_BINARY; + if ((f->handle = i_open(filename,oflag,pmode)) == -1) { + PM_free(f); + return NULL; + } + oldpos = i_lseek(f->handle,0,1); + f->filesize = i_lseek(f->handle,0,2); + i_lseek(f->handle,oldpos,0); + } + } + return f; +} + +/**************************************************************************** +REMARKS: +VxD implementation of the ANSI C fread function. Note that the VxD file I/O +functions are layered on DOS, so can only read up to 64K at a time. Since +we are expected to handle much larger chunks than this, we handle larger +blocks automatically in here. +****************************************************************************/ +size_t fread( + void *ptr, + size_t size, + size_t n, + FILE *f) +{ + char *buf = ptr; + WORD error; + int bytes = size * n; + int readbytes,totalbytes = 0; + + while (bytes > 0x10000) { + if (initComplete) { + readbytes = R0_ReadFile(false,(HANDLE)f->handle,buf,0x8000,f->offset,&error); + readbytes += R0_ReadFile(false,(HANDLE)f->handle,buf+0x8000,0x8000,f->offset+0x8000,&error); + } + else { + readbytes = i_read(f->handle,buf,0x8000); + readbytes += i_read(f->handle,buf+0x8000,0x8000); + } + totalbytes += readbytes; + f->offset += readbytes; + buf += 0x10000; + bytes -= 0x10000; + } + if (bytes) { + if (initComplete) + readbytes = R0_ReadFile(false,(HANDLE)f->handle,buf,bytes,f->offset,&error); + else + readbytes = i_read(f->handle,buf,bytes); + totalbytes += readbytes; + f->offset += readbytes; + } + return totalbytes / size; +} + +/**************************************************************************** +REMARKS: +VxD implementation of the ANSI C fwrite function. Note that the VxD file I/O +functions are layered on DOS, so can only read up to 64K at a time. Since +we are expected to handle much larger chunks than this, we handle larger +blocks automatically in here. +****************************************************************************/ +size_t fwrite( + const void *ptr, + size_t size, + size_t n, + FILE *f) +{ + const char *buf = ptr; + WORD error; + int bytes = size * n; + int writtenbytes,totalbytes = 0; + + if (!f->writemode) + return 0; + while (bytes > 0x10000) { + if (initComplete) { + writtenbytes = R0_WriteFile(false,(HANDLE)f->handle,buf,0x8000,f->offset,&error); + writtenbytes += R0_WriteFile(false,(HANDLE)f->handle,buf+0x8000,0x8000,f->offset+0x8000,&error); + } + else { + writtenbytes = i_write(f->handle,buf,0x8000); + writtenbytes += i_write(f->handle,buf+0x8000,0x8000); + } + totalbytes += writtenbytes; + f->offset += writtenbytes; + buf += 0x10000; + bytes -= 0x10000; + } + if (initComplete) + writtenbytes = R0_WriteFile(false,(HANDLE)f->handle,buf,bytes,f->offset,&error); + else + writtenbytes = i_write(f->handle,buf,bytes); + totalbytes += writtenbytes; + f->offset += writtenbytes; + if (f->offset > f->filesize) + f->filesize = f->offset; + return totalbytes / size; +} + +/**************************************************************************** +REMARKS: +VxD implementation of the ANSI C fflush function. +****************************************************************************/ +int fflush( + FILE *f) +{ + /* Nothing to do since we are not doing buffered file I/O */ + (void)f; + return 0; +} + +/**************************************************************************** +REMARKS: +VxD implementation of the ANSI C fseek function. +****************************************************************************/ +int fseek( + FILE *f, + long int offset, + int whence) +{ + if (whence == 0) + f->offset = offset; + else if (whence == 1) + f->offset += offset; + else if (whence == 2) + f->offset = f->filesize + offset; + if (!initComplete) + i_lseek(f->handle,f->offset,0); + return 0; +} + +/**************************************************************************** +REMARKS: +VxD implementation of the ANSI C ftell function. +****************************************************************************/ +long ftell( + FILE *f) +{ + return f->offset; +} + +/**************************************************************************** +REMARKS: +VxD implementation of the ANSI C feof function. +****************************************************************************/ +int feof( + FILE *f) +{ + return (f->offset == f->filesize); +} + +/**************************************************************************** +REMARKS: +NT driver implementation of the ANSI C fgets function. +****************************************************************************/ +char *fgets( + char *s, + int n, + FILE *f) +{ + int len; + char *cs; + + /* Read the entire buffer into memory (our functions are unbuffered!) */ + if ((len = fread(s,1,n,f)) == 0) + return NULL; + + /* Search for '\n' or end of string */ + if (n > len) + n = len; + cs = s; + while (--n > 0) { + if (*cs == '\n') + break; + cs++; + } + *cs = '\0'; + return s; +} + +/**************************************************************************** +REMARKS: +NT driver implementation of the ANSI C fputs function. +****************************************************************************/ +int fputs( + const char *s, + FILE *f) +{ + return fwrite(s,1,strlen(s),f); +} + +/**************************************************************************** +REMARKS: +VxD implementation of the ANSI C fclose function. +****************************************************************************/ +int fclose( + FILE *f) +{ + WORD error; + + if (initComplete) + R0_CloseFile((HANDLE)f->handle,&error); + else + i_close(f->handle); + PM_free(f); + return 0; +} diff --git a/board/MAI/bios_emulator/scitech/src/pm/vxd/oshdr.h b/board/MAI/bios_emulator/scitech/src/pm/vxd/oshdr.h new file mode 100755 index 0000000..7efc0f9 --- /dev/null +++ b/board/MAI/bios_emulator/scitech/src/pm/vxd/oshdr.h @@ -0,0 +1,29 @@ +/**************************************************************************** +* +* 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 Windows VxD +* +* Description: Include file to include all OS specific header files. +* +****************************************************************************/ diff --git a/board/MAI/bios_emulator/scitech/src/pm/vxd/pm.c b/board/MAI/bios_emulator/scitech/src/pm/vxd/pm.c new file mode 100755 index 0000000..4cb7f19 --- /dev/null +++ b/board/MAI/bios_emulator/scitech/src/pm/vxd/pm.c @@ -0,0 +1,1359 @@ +/**************************************************************************** +* +* 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 Windows VxD +* +* 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 "sdd/sddhelp.h" +#include "mtrr.h" + +/*--------------------------- Global variables ----------------------------*/ + +#define MAX_MEMORY_SHARED 100 +#define MAX_MEMORY_MAPPINGS 100 + +typedef struct { + void *linear; + ulong global; + ulong length; + int npages; + } memshared; + +typedef struct { + ulong physical; + ulong linear; + ulong length; + int npages; + ibool isCached; + } mmapping; + +static int numMappings = 0; +static memshared shared[MAX_MEMORY_MAPPINGS] = {0}; +static mmapping maps[MAX_MEMORY_MAPPINGS]; +extern ibool _PM_haveBIOS; +char _PM_cntPath[PM_MAX_PATH] = ""; +char _PM_nucleusPath[PM_MAX_PATH] = ""; +uchar *_PM_rmBufAddr = NULL; +ushort _VARAPI _PM_savedDS = 0; +static uchar _PM_oldCMOSRegA; +static uchar _PM_oldCMOSRegB; +PM_intHandler _PM_rtcHandler = NULL; +IRQHANDLE RTCIRQHandle = 0; +VPICD_HWInt_THUNK RTCInt_Thunk; + +static char *szWindowsKey = "Software\\Microsoft\\Windows\\CurrentVersion"; +static char *szSystemRoot = "SystemRoot"; +static char *szMachineNameKey = "System\\CurrentControlSet\\control\\ComputerName\\ComputerName"; +static char *szMachineName = "ComputerName"; +static void (PMAPIP fatalErrorCleanup)(void) = NULL; + +/*----------------------------- Implementation ----------------------------*/ + +/* Functions to read and write CMOS registers */ + +ulong PMAPI _PM_getPDB(void); +uchar PMAPI _PM_readCMOS(int index); +void PMAPI _PM_writeCMOS(int index,uchar value); + +/**************************************************************************** +REMARKS: +PM_malloc override function for Nucleus drivers loaded in VxD's. +****************************************************************************/ +void * VXD_malloc( + size_t size) +{ + return PM_mallocShared(size); +} + +/**************************************************************************** +REMARKS: +PM_calloc override function for Nucleus drivers loaded in VxD's. +****************************************************************************/ +void * VXD_calloc( + size_t nelem, + size_t size) +{ + void *p = PM_mallocShared(nelem * size); + if (p) + memset(p,0,nelem * size); + return p; +} + +/**************************************************************************** +REMARKS: +PM_realloc override function for Nucleus drivers loaded in VxD's. +****************************************************************************/ +void * VXD_realloc( + void *ptr, + size_t size) +{ + void *p = PM_mallocShared(size); + if (p) { + memcpy(p,ptr,size); + PM_freeShared(ptr); + } + return p; +} + +/**************************************************************************** +REMARKS: +PM_free override function for Nucleus drivers loaded in VxD's. +****************************************************************************/ +void VXD_free( + void *p) +{ + PM_freeShared(p); +} + +/**************************************************************************** +REMARKS: +Initialise the PM library. +****************************************************************************/ +void PMAPI PM_init(void) +{ + /* Override the default memory allocators for all Nucleus drivers + * loaded in SDDHELP/PMHELP. We do this so that we can ensure all memory + * dynamically allocated by Nucleus drivers and internal C runtime + * library functions are shared memory blocks that all processes + * connecting to SDDHELP can see. + */ + PM_useLocalMalloc(VXD_malloc,VXD_calloc,VXD_realloc,VXD_free); + + /* Initialiase the MTRR module */ + MTRR_init(); +} + +ibool PMAPI PM_haveBIOSAccess(void) +{ return _PM_haveBIOS; } + +long PMAPI PM_getOSType(void) +{ return _OS_WIN32VXD; } + +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 PMAPI PM_fatalError(const char *msg) +{ + if (fatalErrorCleanup) + fatalErrorCleanup(); + Fatal_Error_Handler(msg,0); +} + +/**************************************************************************** +PARAMETERS: +len - Place to store the length of the buffer +rseg - Place to store the real mode segment of the buffer +roff - Place to store the real mode offset of the buffer + +REMARKS: +This function returns the address and length of the global VESA transfer +buffer that is used for communicating with the VESA BIOS functions from +Win16 and Win32 programs under Windows. +****************************************************************************/ +void * PMAPI PM_getVESABuf( + uint *len, + uint *rseg, + uint *roff) +{ + /* If the VxD is dynamically loaded we will not have a real mode + * transfer buffer to return, so we fail the call. + */ + if (_PM_rmBufAddr) { + *len = VESA_BUF_SIZE; + *rseg = (ulong)(_PM_rmBufAddr) >> 4; + *roff = (ulong)(_PM_rmBufAddr) & 0xF; + return _PM_rmBufAddr; + } + return NULL; +} + +int PMAPI PM_int386( + int intno, + PMREGS *in, + PMREGS *out) +{ + /* Unused in VxDs */ + return 0; +} + +void PMAPI _PM_getRMvect( + int intno, + long *realisr) +{ + WORD seg; + DWORD off; + + Get_V86_Int_Vector(intno,&seg,&off); + *realisr = ((long)seg << 16) | (off & 0xFFFF); +} + +void PMAPI _PM_setRMvect( + int intno, + long realisr) +{ + Set_V86_Int_Vector(intno,realisr >> 16,realisr & 0xFFFF); +} + +char * PMAPI PM_getCurrentPath( + char *path, + int maxLen) +{ + strncpy(path,_PM_cntPath,maxLen); + path[maxLen-1] = 0; + return path; +} + +char PMAPI PM_getBootDrive(void) +{ return 'c'; } + +const char * PMAPI PM_getVBEAFPath(void) +{ return "c:\\"; } + +/**************************************************************************** +PARAMETERS: +szKey - Key to query (can contain version number formatting) +szValue - Value to get information for +value - Place to store the registry key data read +size - Size of the string buffer to read into + +RETURNS: +true if the key was found, false if not. +****************************************************************************/ +static ibool REG_queryString( + char *szKey, + char *szValue, + char *value, + ulong size) +{ + HKEY hKey; + ulong type; + ibool status = false; + + memset(value,0,sizeof(value)); + if (RegOpenKey(HKEY_LOCAL_MACHINE,szKey,&hKey) == ERROR_SUCCESS) { + if (RegQueryValueEx(hKey,(PCHAR)szValue,(ulong*)NULL,(ulong*)&type,value,(ulong*)&size) == ERROR_SUCCESS) + status = true; + RegCloseKey(hKey); + } + return status; +} + +const char * PMAPI PM_getNucleusPath(void) +{ + static char path[256]; + + if (strlen(_PM_nucleusPath) > 0) { + strcpy(path,_PM_nucleusPath); + PM_backslash(path); + return path; + } + if (!REG_queryString(szWindowsKey,szSystemRoot,path,sizeof(path))) + strcpy(path,"c:\\windows"); + PM_backslash(path); + strcat(path,"system\\nucleus"); + return path; +} + +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 PM_getMachineName(); } + +const char * PMAPI PM_getMachineName(void) +{ + static char name[256]; + if (REG_queryString(szMachineNameKey,szMachineName,name,sizeof(name))) + return name; + return "Unknown"; +} + +int PMAPI PM_kbhit(void) +{ return 1; } + +int PMAPI PM_getch(void) +{ return 0; } + +PM_HWND PMAPI PM_openConsole( + PM_HWND hwndUser, + int device, + int xRes, + int yRes, + int bpp, + ibool fullScreen) +{ + /* Unused in VxDs */ + return NULL; +} + +int PMAPI PM_getConsoleStateSize(void) +{ + /* Unused in VxDs */ + return 1; +} + +void PMAPI PM_saveConsoleState( + void *stateBuf, + PM_HWND hwndConsole) +{ + /* Unused in VxDs */ +} + +void PMAPI PM_setSuspendAppCallback( + int (_ASMAPIP saveState)( + int flags)) +{ + /* Unused in VxDs */ +} + +void PMAPI PM_restoreConsoleState( + const void *stateBuf, + PM_HWND hwndConsole) +{ + /* Unused in VxDs */ +} + +void PMAPI PM_closeConsole( + PM_HWND hwndConsole) +{ + /* Unused in VxDs */ +} + +void PM_setOSCursorLocation( + int x, + int y) +{ + uchar *_biosPtr = PM_getBIOSPointer(); + PM_setByte(_biosPtr+0x50,x); + PM_setByte(_biosPtr+0x51,y); +} + +void PM_setOSScreenWidth( + int width, + int height) +{ + uchar *_biosPtr = PM_getBIOSPointer(); + PM_setByte(_biosPtr+0x4A,width); + PM_setByte(_biosPtr+0x84,height-1); +} + +/**************************************************************************** +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) +{ + MEMHANDLE hMem; + DWORD pgNum,nPages = (size + 0xFFF) >> 12; + int i; + + /* First find a free slot in our shared memory table */ + for (i = 0; i < MAX_MEMORY_SHARED; i++) { + if (shared[i].linear == 0) + break; + } + if (i < MAX_MEMORY_SHARED) { + PageAllocate(nPages,PG_SYS,0,0,0,0,NULL,0,&hMem,&shared[i].linear); + shared[i].npages = nPages; + pgNum = (ulong)shared[i].linear >> 12; + shared[i].global = LinPageLock(pgNum,nPages,PAGEMAPGLOBAL); + return (void*)shared[i].global; + } + return NULL; +} + +/**************************************************************************** +REMARKS: +Free a block of shared memory +****************************************************************************/ +void PMAPI PM_freeShared(void *p) +{ + int i; + + /* Find a shared memory block in our table and free it */ + for (i = 0; i < MAX_MEMORY_SHARED; i++) { + if (shared[i].global == (ulong)p) { + LinPageUnLock(shared[i].global >> 12,shared[i].npages,PAGEMAPGLOBAL); + PageFree((ulong)shared[i].linear,0); + shared[i].linear = 0; + break; + } + } +} + +/**************************************************************************** +REMARKS: +Maps a shared memory block into process address space. Does nothing since +the memory blocks are already globally7 mapped into all processes. +****************************************************************************/ +void * PMAPI PM_mapToProcess( + void *base, + ulong limit) +{ + return (void*)base; +} + +ibool PMAPI PM_doBIOSPOST( + ushort axVal, + ulong BIOSPhysAddr, + void *mappedBIOS, + ulong BIOSLen) +{ + /* TODO: Figure out how to do this */ + return false; +} + +void * PMAPI PM_getBIOSPointer(void) +{ return (void*)0x400; } + +void * PMAPI PM_getA0000Pointer(void) +{ return PM_mapPhysicalAddr(0xA0000,0xFFFF,true); } + +/**************************************************************************** +PARAMETERS: +base - Physical base address of the memory to maps in +limit - Limit of physical memory to region to maps in + +RETURNS: +Linear address of the newly mapped memory. + +REMARKS: +Maps a physical memory range to a linear memory range. +****************************************************************************/ +ulong _PM_mapPhysicalToLinear( + ulong base, + ulong limit, + int *npages) +{ + ulong linear,length = limit+1; + int i,ppage,flags; + + if (base < 0x100000) { + /* Windows 9x is zero based for the first meg of memory */ + return base; + } + ppage = base >> 12; + *npages = (length + (base & 0xFFF) + 4095) >> 12; + flags = PR_FIXED | PR_STATIC; + if (base == 0xA0000) { + /* We require the linear address to be aligned to a 64Kb boundary + * for mapping the banked framebuffer (so we can do efficient + * carry checking for bank changes in the assembler code). The only + * way to ensure this is to force the linear address to be aligned + * to a 4Mb boundary. + */ + flags |= PR_4MEG; + } + if ((linear = (ulong)PageReserve(PR_SYSTEM,*npages,flags)) == (ulong)-1) + return 0xFFFFFFFF; + if (!PageCommitPhys(linear >> 12,*npages,ppage,PC_INCR | PC_USER | PC_WRITEABLE)) + return 0xFFFFFFFF; + return linear + (base & 0xFFF); +} + +/* Page table flags */ + +#define PAGE_FLAGS_PRESENT 0x00000001 +#define PAGE_FLAGS_WRITEABLE 0x00000002 +#define PAGE_FLAGS_USER 0x00000004 +#define PAGE_FLAGS_WRITE_THROUGH 0x00000008 +#define PAGE_FLAGS_CACHE_DISABLE 0x00000010 +#define PAGE_FLAGS_ACCESSED 0x00000020 +#define PAGE_FLAGS_DIRTY 0x00000040 +#define PAGE_FLAGS_4MB 0x00000080 + +/**************************************************************************** +PARAMETERS: +base - Physical base address of the memory to maps in +limit - Limit of physical memory to region to maps in +isCached - True if the memory should be cached, false if not + +RETURNS: +Linear address of the newly mapped memory. + +REMARKS: +This function maps physical memory to linear memory, which can then be used +to create a selector or used directly from 32-bit protected mode programs. +This is better than DPMI 0x800, since it allows you to maps physical +memory below 1Mb, which gets this memory out of the way of the Windows VDD's +sticky paws. + +NOTE: If the memory is not expected to be cached, this function will + directly re-program the PCD (Page Cache Disable) bit in the + page tables. There does not appear to be a mechanism in the VMM + to control this bit via the regular interface. +****************************************************************************/ +void * PMAPI PM_mapPhysicalAddr( + ulong base, + ulong limit, + ibool isCached) +{ + ulong linear,length = limit+1; + int i,npages; + ulong PDB,*pPDB; + + /* Search table of existing mappings to see if we have already mapped + * a region of memory that will serve this purpose. + */ + for (i = 0; i < numMappings; i++) { + if (maps[i].physical == base && maps[i].length == length && maps[i].isCached == isCached) + return (void*)maps[i].linear; + } + if (numMappings == MAX_MEMORY_MAPPINGS) + return NULL; + + /* We did not find any previously mapped memory region, so maps it in. + * Note that we do not use MapPhysToLinear, since this function appears + * to have problems mapping memory in the 1Mb physical address space. + * Hence we use PageReserve and PageCommitPhys. + */ + if ((linear = _PM_mapPhysicalToLinear(base,limit,&npages)) == 0xFFFFFFFF) + return NULL; + maps[numMappings].physical = base; + maps[numMappings].length = length; + maps[numMappings].linear = linear; + maps[numMappings].npages = npages; + maps[numMappings].isCached = isCached; + numMappings++; + + /* Finally disable caching where necessary */ + if (!isCached && (PDB = _PM_getPDB()) != 0) { + int startPDB,endPDB,iPDB,startPage,endPage,start,end,iPage; + ulong pageTable,*pPageTable; + pPDB = (ulong*)_PM_mapPhysicalToLinear(PDB,0xFFF,&npages); + if (pPDB) { + startPDB = (linear >> 22) & 0x3FF; + startPage = (linear >> 12) & 0x3FF; + endPDB = ((linear+limit) >> 22) & 0x3FF; + endPage = ((linear+limit) >> 12) & 0x3FF; + for (iPDB = startPDB; iPDB <= endPDB; iPDB++) { + /* Set the bits in the page directory entry - required as per */ + /* Pentium 4 manual. This also takes care of the 4MB page entries */ + pPDB[iPDB] = pPDB[iPDB] |= (PAGE_FLAGS_WRITE_THROUGH | PAGE_FLAGS_CACHE_DISABLE); + if (!(pPDB[iPDB] & PAGE_FLAGS_4MB)) { + /* If we are dealing with 4KB pages then we need to iterate */ + /* through each of the page table entries */ + pageTable = pPDB[iPDB] & ~0xFFF; + pPageTable = (ulong*)_PM_mapPhysicalToLinear(pageTable,0xFFF,&npages); + start = (iPDB == startPDB) ? startPage : 0; + end = (iPDB == endPDB) ? endPage : 0x3FF; + for (iPage = start; iPage <= end; iPage++) + pPageTable[iPage] |= (PAGE_FLAGS_WRITE_THROUGH | PAGE_FLAGS_CACHE_DISABLE); + PageFree((ulong)pPageTable,PR_STATIC); + } + } + PageFree((ulong)pPDB,PR_STATIC); + PM_flushTLB(); + } + } + return (void*)linear; +} + +void PMAPI PM_freePhysicalAddr( + void *ptr, + ulong limit) +{ + /* We never free the mappings */ +} + +void PMAPI PM_sleep(ulong milliseconds) +{ + /* We never sleep in a VxD */ +} + +int PMAPI PM_getCOMPort(int port) +{ + /* TODO: Re-code this to determine real values using the Plug and Play */ + /* manager for the OS. */ + switch (port) { + case 0: return 0x3F8; + case 1: return 0x2F8; + case 2: return 0x3E8; + case 3: return 0x2E8; + } + return 0; +} + +int PMAPI PM_getLPTPort(int port) +{ + /* TODO: Re-code this to determine real values using the Plug and Play */ + /* manager for the OS. */ + switch (port) { + case 0: return 0x3BC; + case 1: return 0x378; + case 2: return 0x278; + } + return 0; +} + +ulong PMAPI PM_getPhysicalAddr( + void *p) +{ + DWORD pte; + + /* Touch the memory before calling CopyPageTable. For some reason */ + /* we need to do this on Windows 9x, otherwise the memory may not */ + /* be paged in correctly. Of course if the passed in pointer is */ + /* invalid, this function will fault, but we shouldn't be passed bogus */ + /* pointers anyway ;-) */ + pte = *((ulong*)p); + + /* Return assembled address value only if VMM service succeeds */ + if (CopyPageTable(((DWORD)p) >> 12, 1, (PVOID*)&pte, 0)) + return (pte & ~0xFFF) | (((DWORD)p) & 0xFFF); + + /* Return failure to the caller! */ + return 0xFFFFFFFFUL; +} + +ibool PMAPI PM_getPhysicalAddrRange( + void *p, + ulong length, + ulong *physAddress) +{ + int i; + ulong linear = (ulong)p & ~0xFFF; + + for (i = (length + 0xFFF) >> 12; i > 0; i--) { + if ((*physAddress++ = PM_getPhysicalAddr((void*)linear)) == 0xFFFFFFFF) + return false; + linear += 4096; + } + return true; +} + +void PMAPI _PM_freeMemoryMappings(void) +{ + int i; + for (i = 0; i < numMappings; i++) + PageFree(maps[i].linear,PR_STATIC); +} + +void * PMAPI PM_mapRealPointer( + uint r_seg, + uint r_off) +{ + return (void*)MK_PHYS(r_seg,r_off); +} + +void * PMAPI PM_allocRealSeg( + uint size, + uint *r_seg, + uint *r_off) +{ + return NULL; +} + +void PMAPI PM_freeRealSeg( + void *mem) +{ +} + +void PMAPI DPMI_int86( + int intno, + DPMI_regs *regs) +{ + /* Unsed in VxD's */ +} + +/**************************************************************************** +REMARKS: +Load the V86 registers in the client state, and save the original state +before loading the registers. +****************************************************************************/ +static void LoadV86Registers( + CLIENT_STRUCT *saveRegs, + RMREGS *in, + RMSREGS *sregs) +{ + CLIENT_STRUCT newRegs; + + Save_Client_State(saveRegs); + newRegs = *saveRegs; + newRegs.CRS.Client_EAX = in->e.eax; + newRegs.CRS.Client_EBX = in->e.ebx; + newRegs.CRS.Client_ECX = in->e.ecx; + newRegs.CRS.Client_EDX = in->e.edx; + newRegs.CRS.Client_ESI = in->e.esi; + newRegs.CRS.Client_EDI = in->e.edi; + newRegs.CRS.Client_ES = sregs->es; + newRegs.CRS.Client_DS = sregs->ds; + Restore_Client_State(&newRegs); +} + +/**************************************************************************** +REMARKS: +Read the V86 registers from the client state and restore the original state. +****************************************************************************/ +static void ReadV86Registers( + CLIENT_STRUCT *saveRegs, + RMREGS *out, + RMSREGS *sregs) +{ + CLIENT_STRUCT newRegs; + + Save_Client_State(&newRegs); + out->e.eax = newRegs.CRS.Client_EAX; + out->e.ebx = newRegs.CRS.Client_EBX; + out->e.ecx = newRegs.CRS.Client_ECX; + out->e.edx = newRegs.CRS.Client_EDX; + out->e.esi = newRegs.CRS.Client_ESI; + out->e.edi = newRegs.CRS.Client_EDI; + sregs->es = newRegs.CRS.Client_ES; + sregs->ds = newRegs.CRS.Client_DS; + Restore_Client_State(saveRegs); +} + +/**************************************************************************** +REMARKS: +Call a V86 real mode function with the specified register values +loaded before the call. The call returns with a far ret. +****************************************************************************/ +void PMAPI PM_callRealMode( + uint seg, + uint off, + RMREGS *regs, + RMSREGS *sregs) +{ + CLIENT_STRUCT saveRegs; + + /* Bail if we do not have BIOS access (ie: the VxD was dynamically + * loaded, and not statically loaded. + */ + if (!_PM_haveBIOS) + return; + + _TRACE("SDDHELP: Entering PM_callRealMode()\n"); + Begin_Nest_V86_Exec(); + LoadV86Registers(&saveRegs,regs,sregs); + Simulate_Far_Call(seg, off); + Resume_Exec(); + ReadV86Registers(&saveRegs,regs,sregs); + End_Nest_Exec(); + _TRACE("SDDHELP: Exiting PM_callRealMode()\n"); +} + +/**************************************************************************** +REMARKS: +Issue a V86 real mode interrupt with the specified register values +loaded before the interrupt. +****************************************************************************/ +int PMAPI PM_int86( + int intno, + RMREGS *in, + RMREGS *out) +{ + RMSREGS sregs = {0}; + CLIENT_STRUCT saveRegs; + ushort oldDisable; + + /* Bail if we do not have BIOS access (ie: the VxD was dynamically + * loaded, and not statically loaded. + */ + if (!_PM_haveBIOS) { + *out = *in; + return out->x.ax; + } + + /* Disable pass-up to our VxD handler so we directly call BIOS */ + _TRACE("SDDHELP: Entering PM_int86()\n"); + if (disableTSRFlag) { + oldDisable = *disableTSRFlag; + *disableTSRFlag = 0; + } + Begin_Nest_V86_Exec(); + LoadV86Registers(&saveRegs,in,&sregs); + Exec_Int(intno); + ReadV86Registers(&saveRegs,out,&sregs); + End_Nest_Exec(); + + /* Re-enable pass-up to our VxD handler if previously enabled */ + if (disableTSRFlag) + *disableTSRFlag = oldDisable; + + _TRACE("SDDHELP: Exiting PM_int86()\n"); + return out->x.ax; +} + +/**************************************************************************** +REMARKS: +Issue a V86 real mode interrupt with the specified register values +loaded before the interrupt. +****************************************************************************/ +int PMAPI PM_int86x( + int intno, + RMREGS *in, + RMREGS *out, + RMSREGS *sregs) +{ + CLIENT_STRUCT saveRegs; + ushort oldDisable; + + /* Bail if we do not have BIOS access (ie: the VxD was dynamically + * loaded, and not statically loaded. + */ + if (!_PM_haveBIOS) { + *out = *in; + return out->x.ax; + } + + /* Disable pass-up to our VxD handler so we directly call BIOS */ + _TRACE("SDDHELP: Entering PM_int86x()\n"); + if (disableTSRFlag) { + oldDisable = *disableTSRFlag; + *disableTSRFlag = 0; + } + Begin_Nest_V86_Exec(); + LoadV86Registers(&saveRegs,in,sregs); + Exec_Int(intno); + ReadV86Registers(&saveRegs,out,sregs); + End_Nest_Exec(); + + /* Re-enable pass-up to our VxD handler if previously enabled */ + if (disableTSRFlag) + *disableTSRFlag = oldDisable; + + _TRACE("SDDHELP: Exiting PM_int86x()\n"); + return out->x.ax; +} + +/**************************************************************************** +REMARKS: +Returns available memory. Not possible under Windows. +****************************************************************************/ +void PMAPI PM_availableMemory( + ulong *physical, + ulong *total) +{ + *physical = *total = 0; +} + +/**************************************************************************** +REMARKS: +Allocates a block of locked physical memory. +****************************************************************************/ +void * PMAPI PM_allocLockedMem( + uint size, + ulong *physAddr, + ibool contiguous, + ibool below16M) +{ + MEMHANDLE hMem; + DWORD nPages = (size + 0xFFF) >> 12; + DWORD flags = PAGEFIXED | PAGEUSEALIGN | (contiguous ? PAGECONTIG : 0); + DWORD maxPhys = below16M ? 0x00FFFFFF : 0xFFFFFFFF; + void *p; + + /* TODO: This may need to be modified if the memory needs to be globally */ + /* accessible. Check how we implemented PM_mallocShared() as we */ + /* may need to do something similar in here. */ + PageAllocate(nPages,PG_SYS,0,0,0,maxPhys,physAddr,flags,&hMem,&p); + + /* TODO: We may need to modify the memory blocks to disable caching via */ + /* the page tables (PCD|PWT) since DMA memory blocks *cannot* be */ + /* cached! */ + return p; +} + +/**************************************************************************** +REMARKS: +Frees a block of locked physical memory. +****************************************************************************/ +void PMAPI PM_freeLockedMem( + void *p, + uint size, + ibool contiguous) +{ + if (p) + PageFree((ulong)p,0); +} + +/**************************************************************************** +REMARKS: +Allocates a page aligned and page sized block of memory +****************************************************************************/ +void * PMAPI PM_allocPage( + ibool locked) +{ + MEMHANDLE hMem; + void *p; + + /* TODO: This will need to be modified if the memory needs to be globally */ + /* accessible. Check how we implemented PM_mallocShared() as we */ + /* may need to do something similar in here. */ + PageAllocate(1,PG_SYS,0,0,0,0,0,PAGEFIXED,&hMem,&p); + return p; +} + +/**************************************************************************** +REMARKS: +Free a page aligned and page sized block of memory +****************************************************************************/ +void PMAPI PM_freePage( + void *p) +{ + if (p) + PageFree((ulong)p,0); +} + +/**************************************************************************** +REMARKS: +Lock linear memory so it won't be paged. +****************************************************************************/ +int PMAPI PM_lockDataPages( + void *p, + uint len, + PM_lockHandle *lh) +{ + DWORD pgNum = (ulong)p >> 12; + DWORD nPages = (len + (ulong)p - (pgNum << 12) + 0xFFF) >> 12; + return LinPageLock(pgNum,nPages,0); +} + +/**************************************************************************** +REMARKS: +Unlock linear memory so it won't be paged. +****************************************************************************/ +int PMAPI PM_unlockDataPages( + void *p, + uint len, + PM_lockHandle *lh) +{ + DWORD pgNum = (ulong)p >> 12; + DWORD nPages = (len + (ulong)p - (pgNum << 12) + 0xFFF) >> 12; + return LinPageUnLock(pgNum,nPages,0); +} + +/**************************************************************************** +REMARKS: +Lock linear memory so it won't be paged. +****************************************************************************/ +int PMAPI PM_lockCodePages( + void (*p)(), + uint len, + PM_lockHandle *lh) +{ + return PM_lockDataPages((void*)p,len,lh); +} + +/**************************************************************************** +REMARKS: +Unlock linear memory so it won't be paged. +****************************************************************************/ +int PMAPI PM_unlockCodePages( + void (*p)(), + uint len, + PM_lockHandle *lh) +{ + return PM_unlockDataPages((void*)p,len,lh); +} + +/**************************************************************************** +REMARKS: +Set the real time clock frequency (for stereo modes). +****************************************************************************/ +void PMAPI PM_setRealTimeClockFrequency( + int frequency) +{ + static short convert[] = { + 8192, + 4096, + 2048, + 1024, + 512, + 256, + 128, + 64, + 32, + 16, + 8, + 4, + 2, + -1, + }; + int i; + + /* First clear any pending RTC timeout if not cleared */ + _PM_readCMOS(0x0C); + if (frequency == 0) { + /* Disable RTC timout */ + _PM_writeCMOS(0x0A,_PM_oldCMOSRegA); + _PM_writeCMOS(0x0B,_PM_oldCMOSRegB & 0x0F); + } + else { + /* Convert frequency value to RTC clock indexes */ + for (i = 0; convert[i] != -1; i++) { + if (convert[i] == frequency) + break; + } + + /* Set RTC timout value and enable timeout */ + _PM_writeCMOS(0x0A,0x20 | (i+3)); + _PM_writeCMOS(0x0B,(_PM_oldCMOSRegB & 0x0F) | 0x40); + } +} + +/**************************************************************************** +REMARKS: +Real time clock interrupt handler, which calls the user registered C code. +****************************************************************************/ +static BOOL __stdcall RTCInt_Handler( + VMHANDLE hVM, + IRQHANDLE hIRQ) +{ + static char inside = 0; + + /* Clear priority interrupt controller and re-enable interrupts so we + * dont lock things up for long. + */ + VPICD_Phys_EOI(hIRQ); + + /* Clear real-time clock timeout */ + _PM_readCMOS(0x0C); + + /* Now call the C based interrupt handler (but check for mutual + * exclusion since we may still be servicing an old interrupt when a + * new one comes along; if that happens we ignore the old one). + */ + if (!inside) { + inside = 1; + enable(); + _PM_rtcHandler(); + inside = 0; + } + return TRUE; +} + +/**************************************************************************** +REMARKS: +Set the real time clock handler (used for software stereo modes). +****************************************************************************/ +ibool PMAPI PM_setRealTimeClockHandler( + PM_intHandler ih, + int frequency) +{ + struct VPICD_IRQ_Descriptor IRQdesc; + + /* Save the old CMOS real time clock values */ + _PM_oldCMOSRegA = _PM_readCMOS(0x0A); + _PM_oldCMOSRegB = _PM_readCMOS(0x0B); + + /* Set the real time clock interrupt handler */ + CHECK(ih != NULL); + _PM_rtcHandler = ih; + IRQdesc.VID_IRQ_Number = 0x8; + IRQdesc.VID_Options = 0; + IRQdesc.VID_Hw_Int_Proc = (DWORD)VPICD_Thunk_HWInt(RTCInt_Handler, &RTCInt_Thunk); + IRQdesc.VID_EOI_Proc = 0; + IRQdesc.VID_Virt_Int_Proc = 0; + IRQdesc.VID_Mask_Change_Proc= 0; + IRQdesc.VID_IRET_Proc = 0; + IRQdesc.VID_IRET_Time_Out = 500; + if ((RTCIRQHandle = VPICD_Virtualize_IRQ(&IRQdesc)) == 0) + return false; + + /* Program the real time clock default frequency */ + PM_setRealTimeClockFrequency(frequency); + + /* Unmask IRQ8 in the PIC */ + VPICD_Physically_Unmask(RTCIRQHandle); + return true; +} + +/**************************************************************************** +REMARKS: +Restore the original real time clock handler. +****************************************************************************/ +void PMAPI PM_restoreRealTimeClockHandler(void) +{ + if (RTCIRQHandle) { + /* Restore CMOS registers and mask RTC clock */ + _PM_writeCMOS(0x0A,_PM_oldCMOSRegA); + _PM_writeCMOS(0x0B,_PM_oldCMOSRegB); + + /* Restore the interrupt vector */ + VPICD_Set_Auto_Masking(RTCIRQHandle); + VPICD_Force_Default_Behavior(RTCIRQHandle); + RTCIRQHandle = 0; + } +} + +/**************************************************************************** +REMARKS: +OS specific shared libraries not supported inside a VxD +****************************************************************************/ +PM_MODULE PMAPI PM_loadLibrary( + const char *szDLLName) +{ + (void)szDLLName; + return NULL; +} + +/**************************************************************************** +REMARKS: +OS specific shared libraries not supported inside a VxD +****************************************************************************/ +void * PMAPI PM_getProcAddress( + PM_MODULE hModule, + const char *szProcName) +{ + (void)hModule; + (void)szProcName; + return NULL; +} + +/**************************************************************************** +REMARKS: +OS specific shared libraries not supported inside a VxD +****************************************************************************/ +void PMAPI PM_freeLibrary( + PM_MODULE hModule) +{ + (void)hModule; +} + +/**************************************************************************** +REMARKS: +Function to find the first file matching a search criteria in a directory. +****************************************************************************/ +void *PMAPI PM_findFirstFile( + const char *filename, + PM_findData *findData) +{ + /* TODO: This function should start a directory enumeration search */ + /* given the filename (with wildcards). The data should be */ + /* converted and returned in the findData standard form. */ + (void)filename; + (void)findData; + 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) +{ + /* TODO: This function should find the next file in directory enumeration */ + /* search given the search criteria defined in the call to */ + /* PM_findFirstFile. The data should be converted and returned */ + /* in the findData standard form. */ + (void)handle; + (void)findData; + return false; +} + +/**************************************************************************** +REMARKS: +Function to close the find process +****************************************************************************/ +void PMAPI PM_findClose( + void *handle) +{ + /* TODO: This function should close the find process. This may do */ + /* nothing for some OS'es. */ + (void)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: + + 1 - Drive A: + 2 - Drive B: + 3 - Drive C: + etc + +****************************************************************************/ +ibool PMAPI PM_driveValid( + char drive) +{ + /* Not supported in a VxD */ + (void)drive; + return false; +} + +/**************************************************************************** +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) +{ + /* Not supported in a VxD */ + (void)drive; + (void)dir; + (void)len; +} + +/**************************************************************************** +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); +} + +/**************************************************************************** +REMARKS: +Function to change the file attributes for a specific file. +****************************************************************************/ +void PMAPI PM_setFileAttr( + const char *filename, + uint attrib) +{ + /* TODO: Implement this */ + (void)filename; + (void)attrib; + PM_fatalError("PM_setFileAttr not implemented yet!"); +} + +/**************************************************************************** +REMARKS: +Function to get the file attributes for a specific file. +****************************************************************************/ +uint PMAPI PM_getFileAttr( + const char *filename) +{ + /* TODO: Implement this */ + (void)filename; + PM_fatalError("PM_getFileAttr not implemented yet!"); + return 0; +} + +/**************************************************************************** +REMARKS: +Function to create a directory. +****************************************************************************/ +ibool PMAPI PM_mkdir( + const char *filename) +{ + /* TODO: Implement this */ + (void)filename; + PM_fatalError("PM_mkdir not implemented yet!"); + return false; +} + +/**************************************************************************** +REMARKS: +Function to remove a directory. +****************************************************************************/ +ibool PMAPI PM_rmdir( + const char *filename) +{ + /* TODO: Implement this */ + (void)filename; + PM_fatalError("PM_rmdir not implemented yet!"); + return false; +} + +/**************************************************************************** +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) +{ + /* TODO: Implement this! */ + (void)filename; + (void)gmTime; + (void)time; + PM_fatalError("PM_getFileTime not implemented yet!"); + return false; +} + +/**************************************************************************** +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) +{ + /* TODO: Implement this! */ + (void)filename; + (void)gmTime; + (void)time; + PM_fatalError("PM_setFileTime not implemented yet!"); + return false; +} diff --git a/board/MAI/bios_emulator/scitech/src/pm/vxd/vflat.c b/board/MAI/bios_emulator/scitech/src/pm/vxd/vflat.c new file mode 100755 index 0000000..901ce1c --- /dev/null +++ b/board/MAI/bios_emulator/scitech/src/pm/vxd/vflat.c @@ -0,0 +1,45 @@ +/**************************************************************************** +* +* 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: Any +* +* Description: Dummy module; no virtual framebuffer for this OS +* +****************************************************************************/ + +#include "pmapi.h" + +ibool PMAPI VF_available(void) +{ + return false; +} + +void * PMAPI VF_init(ulong baseAddr,int bankSize,int codeLen,void *bankFunc) +{ + return NULL; +} + +void PMAPI VF_exit(void) +{ +} diff --git a/board/MAI/bios_emulator/scitech/src/pm/vxd/ztimer.c b/board/MAI/bios_emulator/scitech/src/pm/vxd/ztimer.c new file mode 100755 index 0000000..76df48c --- /dev/null +++ b/board/MAI/bios_emulator/scitech/src/pm/vxd/ztimer.c @@ -0,0 +1,105 @@ +/**************************************************************************** +* +* Ultra Long Period Timer +* +* ======================================================================== +* +* 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 Windows VxD +* +* Description: OS specific implementation for the Zen Timer functions. +* +****************************************************************************/ + +/*---------------------------- Global variables ---------------------------*/ + +static ulong frequency = 1193180; + +/*----------------------------- Implementation ----------------------------*/ + +/**************************************************************************** +REMARKS: +Initialise the Zen Timer module internals. +****************************************************************************/ +#define __ZTimerInit() + +/**************************************************************************** +REMARKS: +Call the assembler Zen Timer functions to do the timing. +****************************************************************************/ +#define __LZTimerOn(tm) VTD_Get_Real_Time(&tm->start.high,&tm->start.low) + +/**************************************************************************** +REMARKS: +Call the assembler Zen Timer functions to do the timing. +****************************************************************************/ +static ulong __LZTimerLap( + LZTimerObject *tm) +{ + CPU_largeInteger lap,count; + VTD_Get_Real_Time(&lap.high,&lap.low); + _CPU_diffTime64(&tm->start,&lap,&count); + return _CPU_calcMicroSec(&count,frequency); +} + +/**************************************************************************** +REMARKS: +Call the assembler Zen Timer functions to do the timing. +****************************************************************************/ +#define __LZTimerOff(tm) VTD_Get_Real_Time(&tm->end.high,&tm->end.low) + +/**************************************************************************** +REMARKS: +Call the assembler Zen Timer functions to do the timing. +****************************************************************************/ +static ulong __LZTimerCount( + LZTimerObject *tm) +{ + CPU_largeInteger tmCount; + _CPU_diffTime64(&tm->start,&tm->end,&tmCount); + return _CPU_calcMicroSec(&tmCount,frequency); +} + +/**************************************************************************** +REMARKS: +Define the resolution of the long period timer as microseconds per timer tick. +****************************************************************************/ +#define ULZTIMER_RESOLUTION 1000 + +/**************************************************************************** +REMARKS: +Read the Long Period timer value from the BIOS timer tick. +****************************************************************************/ +static ulong __ULZReadTime(void) +{ + CPU_largeInteger count; + VTD_Get_Real_Time(&count.high,&count.low); + return (count.low * 1000.0 / frequency); +} + +/**************************************************************************** +REMARKS: +Compute the elapsed time from the BIOS timer tick. Note that we check to see +whether a midnight boundary has passed, and if so adjust the finish time to +account for this. We cannot detect if more that one midnight boundary has +passed, so if this happens we will be generating erronous results. +****************************************************************************/ +ulong __ULZElapsedTime(ulong start,ulong finish) +{ return finish - start; } |