diff options
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/pm/dos/_pm.asm')
-rw-r--r-- | board/MAI/bios_emulator/scitech/src/pm/dos/_pm.asm | 656 |
1 files changed, 0 insertions, 656 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/pm/dos/_pm.asm b/board/MAI/bios_emulator/scitech/src/pm/dos/_pm.asm deleted file mode 100644 index 42b5cf369..000000000 --- a/board/MAI/bios_emulator/scitech/src/pm/dos/_pm.asm +++ /dev/null @@ -1,656 +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: 80386 Assembler, TASM 4.0 or NASM -;* Environment: IBM PC Real mode and 16/32 bit protected mode -;* -;* Description: Low level assembly support for the PM library specific to -;* MSDOS. -;* -;**************************************************************************** - - IDEAL - -include "scitech.mac" ; Memory model macros - -header _pmdos ; Set up memory model - -begdataseg _pmdos - -ifndef flatmodel - -struc rmregs_s -ax dw ? -ax_high dw ? -bx dw ? -bx_high dw ? -cx dw ? -cx_high dw ? -dx dw ? -dx_high dw ? -si dw ? -si_high dw ? -di dw ? -di_high dw ? -cflag dw ? -cflag_high dw ? -ends rmregs_s -RMREGS = (rmregs_s PTR es:bx) - -struc rmsregs_s -es dw ? -cs dw ? -ss dw ? -ds dw ? -ends rmsregs_s -RMSREGS = (rmsregs_s PTR es:bx) - -endif ; !flatmodel - -ifdef flatmodel - cextern _PM_savedDS,USHORT - cextern _PM_VXD_off,UINT - cextern _PM_VXD_sel,UINT -ifdef DOS4GW - cextern _PM_haveCauseWay,UINT -endif -endif -intel_id db "GenuineIntel" ; Intel vendor ID - -PMHELP_GETPDB EQU 0026h -PMHELP_FLUSHTLB EQU 0027h - -enddataseg _pmdos - -P586 - -begcodeseg _pmdos ; Start of code segment - -ifndef flatmodel - -;---------------------------------------------------------------------------- -; void PM_callRealMode(unsigned s,unsigned o, RMREGS *regs, -; RMSREGS *sregs) -;---------------------------------------------------------------------------- -; Calls a real mode procedure, loading the appropriate registers values -; from the passed in structures. Only the DS and ES register are loaded -; from the SREGS structure. -;---------------------------------------------------------------------------- -cprocstart PM_callRealMode - - ARG s:WORD, o:WORD, regs:DWORD, sregs:DWORD - - LOCAL addr:DWORD, bxVal:WORD, esVal:WORD, flags:WORD = LocalSize - - enter_c - push ds - push es - - mov ax,[o] ; Build the address to call in 'addr' - mov [WORD addr],ax - mov ax,[s] - mov [WORD addr+2],ax - - les bx,[sregs] - mov ax,[RMSREGS.ds] - mov ds,ax ; DS := passed in value - mov ax,[RMSREGS.es] - mov [esVal],ax - les bx,[regs] - mov ax,[RMREGS.bx] - mov [bxVal],ax - mov ax,[RMREGS.ax] ; AX := passed in value - mov cx,[RMREGS.cx] ; CX := passed in value - mov dx,[RMREGS.dx] ; DX := passed in value - mov si,[RMREGS.si] ; SI := passed in value - mov di,[RMREGS.di] ; DI := passed in value - push bp - push [esVal] - pop es ; ES := passed in value - mov bx,[bxVal] ; BX := passed in value - - call [addr] ; Call the specified routine - - pushf ; Save flags for later - pop [flags] - - pop bp - push es - pop [esVal] - push bx - pop [bxVal] - les bx,[sregs] - push ds - pop [RMSREGS.ds] ; Save value of DS - push [esVal] - pop [RMSREGS.es] ; Save value of ES - les bx,[regs] - mov [RMREGS.ax],ax ; Save value of AX - mov [RMREGS.cx],cx ; Save value of CX - mov [RMREGS.dx],dx ; Save value of DX - mov [RMREGS.si],si ; Save value of SI - mov [RMREGS.di],di ; Save value of DI - mov ax,[flags] ; Return flags - and ax,1h ; Isolate carry flag - mov [RMREGS.cflag],ax ; Save carry flag status - mov ax,[bxVal] - mov [RMREGS.bx],ax ; Save value of BX - - pop es - pop ds - leave_c - ret - -cprocend - -endif - -;---------------------------------------------------------------------------- -; void PM_segread(PMSREGS *sregs) -;---------------------------------------------------------------------------- -; Read the current value of all segment registers -;---------------------------------------------------------------------------- -cprocstartdll16 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 - -; Create a table of the 256 different interrupt calls that we can jump -; into - -ifdef USE_NASM - -%assign intno 0 - -intTable: -%rep 256 - db 0CDh - db intno -%assign intno intno + 1 - ret - nop -%endrep - -else - -intno = 0 - -intTable: - REPT 256 - db 0CDh - db intno -intno = intno + 1 - ret - nop - ENDM - -endif - -;---------------------------------------------------------------------------- -; _PM_genInt - Generate the appropriate interrupt -;---------------------------------------------------------------------------- -cprocnear _PM_genInt - - push _ax ; Save _ax - push _bx ; Save _bx -ifdef flatmodel - mov ebx,[UINT esp+12] ; EBX := interrupt number -else - mov bx,sp ; Make sure ESP is zeroed - mov bx,[UINT ss:bx+6] ; BX := interrupt number -endif - mov _ax,offset intTable ; Point to interrupt generation table - shl _bx,2 ; _BX := index into table - add _ax,_bx ; _AX := pointer to interrupt code -ifdef flatmodel - xchg eax,[esp+4] ; Restore eax, and set for int -else - mov bx,sp - xchg ax,[ss:bx+2] ; Restore ax, and set for int -endif - pop _bx ; restore _bx - 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. -;---------------------------------------------------------------------------- -cprocstartdll16 PM_int386x - - ARG intno:UINT, inptr:DPTR, outptr:DPTR, sregs:DPTR - - LOCAL flags:UINT, sv_ds:UINT, sv_esi:ULONG = LocalSize - - enter_c - push ds - push es ; Save segment registers - push fs - push gs - - _lds _si,[sregs] ; DS:_SI -> Load segment registers - mov es,[_si] - mov bx,[_si+6] - mov [sv_ds],_bx ; Save value of user DS on stack - mov fs,[_si+8] - mov gs,[_si+10] - - _lds _si,[inptr] ; Load CPU registers - mov eax,[_si] - mov ebx,[_si+4] - mov ecx,[_si+8] - mov edx,[_si+12] - mov edi,[_si+20] - mov esi,[_si+16] - - push ds ; Save value of DS - push _bp ; Some interrupts trash this! - clc ; Generate the interrupt - push [UINT intno] - mov ds,[WORD sv_ds] ; Set value of user's DS selector - call _PM_genInt - pop _bp ; Pop intno from stack (flags unchanged) - pop _bp ; Restore value of stack frame pointer - pop ds ; Restore value of DS - - pushf ; Save flags for later - pop [UINT flags] - push esi ; Save ESI for later - pop [DWORD sv_esi] - push ds ; Save DS for later - pop [UINT sv_ds] - - _lds _si,[outptr] ; Save CPU registers - mov [_si],eax - mov [_si+4],ebx - mov [_si+8],ecx - mov [_si+12],edx - push [DWORD sv_esi] - pop [DWORD _si+16] - mov [_si+20],edi - - mov _bx,[flags] ; Return flags - and ebx,1h ; Isolate carry flag - mov [_si+24],ebx ; Save carry flag status - - _lds _si,[sregs] ; Save segment registers - mov [_si],es - mov _bx,[sv_ds] - mov [_si+6],bx ; Get returned DS from stack - mov [_si+8],fs - mov [_si+10],gs - - pop gs ; Restore segment registers - pop fs - pop es - pop ds - leave_c - ret - -cprocend - -ifndef flatmodel -_PM_savedDS dw _DATA ; Saved value of DS -endif - -;---------------------------------------------------------------------------- -; 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. -;---------------------------------------------------------------------------- -cprocstartdll16 PM_saveDS - -ifdef flatmodel - mov [_PM_savedDS],ds ; Store away in data segment -endif - 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. -;---------------------------------------------------------------------------- -cprocstartdll16 PM_loadDS - - mov ds,[cs:_PM_savedDS] ; We can access the proper DS through CS - ret - -cprocend - -ifdef flatmodel - -;---------------------------------------------------------------------------- -; ibool DPMI_allocateCallback(void (*pmcode)(), void *rmregs, long *RMCB) -;---------------------------------------------------------------------------- -cprocstart _DPMI_allocateCallback - - ARG pmcode:CPTR, rmregs:DPTR, RMCB:DPTR - - enter_c - push ds - push es - - push cs - pop ds - mov esi,[pmcode] ; DS:ESI -> protected mode code to call - mov edi,[rmregs] ; ES:EDI -> real mode register buffer - mov ax,303h ; AX := allocate realmode callback function - int 31h - mov eax,0 ; Return failure! - jc @@Fail - - mov eax,[RMCB] - shl ecx,16 - mov cx,dx - mov [es:eax],ecx ; Return real mode address - mov eax,1 ; Return success! - -@@Fail: pop es - pop ds - leave_c - ret - -cprocend - -;---------------------------------------------------------------------------- -; void DPMI_freeCallback(long RMCB) -;---------------------------------------------------------------------------- -cprocstart _DPMI_freeCallback - - ARG RMCB:ULONG - - enter_c - - mov cx,[WORD RMCB+2] - mov dx,[WORD RMCB] ; CX:DX := real mode callback - mov ax,304h - int 31h - - leave_c - ret - -cprocend - -endif - -; 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 - sti - 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 - sti - popfd - pop _bp - ret - -cprocend - -ifdef flatmodel - -;---------------------------------------------------------------------------- -; int _PM_pagingEnabled(void) -;---------------------------------------------------------------------------- -; Returns 1 if paging is enabled, 0 if not or -1 if not at ring 0 -;---------------------------------------------------------------------------- -cprocstart _PM_pagingEnabled - - mov eax,-1 -ifdef DOS4GW - mov cx,cs - and ecx,3 - jz @@Ring0 - cmp [UINT _PM_haveCauseWay],0 - jnz @@Ring0 - jmp @@Exit - -@@Ring0: - mov eax,cr0 ; Load CR0 - shr eax,31 ; Isolate paging enabled bit -endif -@@Exit: ret - -cprocend - -;---------------------------------------------------------------------------- -; _PM_getPDB - Return the Page Table Directory Base address -;---------------------------------------------------------------------------- -cprocstart _PM_getPDB - -ifdef DOS4GW - mov ax,cs - and eax,3 - jz @@Ring0 - cmp [UINT _PM_haveCauseWay],0 - jnz @@Ring0 -endif - -; Call VxD if running at ring 3 in a DOS box - - cmp [WORD _PM_VXD_sel],0 - jz @@Fail - mov eax,PMHELP_GETPDB -ifdef USE_NASM - call far dword [_PM_VXD_off] -else - call [FCPTR _PM_VXD_off] -endif - ret - -@@Ring0: -ifdef DOS4GW - mov eax,cr3 - and eax,0FFFFF000h - ret -endif -@@Fail: xor eax,eax - ret - -cprocend - -;---------------------------------------------------------------------------- -; PM_flushTLB - Flush the Translation Lookaside buffer -;---------------------------------------------------------------------------- -cprocstart PM_flushTLB - - mov ax,cs - and eax,3 - jz @@Ring0 -ifdef DOS4GW - cmp [UINT _PM_haveCauseWay],0 - jnz @@Ring0 -endif - -; Call VxD if running at ring 3 in a DOS box - - cmp [WORD _PM_VXD_sel],0 - jz @@Fail - mov eax,PMHELP_FLUSHTLB -ifdef USE_NASM - call far dword [_PM_VXD_off] -else - call [FCPTR _PM_VXD_off] -endif - ret - -@@Ring0: -ifdef DOS4GW - wbinvd ; Flush the CPU cache - mov eax,cr3 - mov cr3,eax ; Flush the TLB -endif -@@Fail: ret - -cprocend - -endif - -;---------------------------------------------------------------------------- -; void _PM_VxDCall(VXD_regs far *r,uint off,uint sel); -;---------------------------------------------------------------------------- -cprocstart _PM_VxDCall - - ARG r:DPTR, off:UINT, sel:UINT - - enter_c - -; Load all registers from the registers structure - - mov ebx,[r] - mov eax,[ebx+0] - mov ecx,[ebx+8] - mov edx,[ebx+12] - mov esi,[ebx+16] - mov edi,[ebx+20] - mov ebx,[ebx+4] ; Trashes BX structure pointer! - -; Call the VxD entry point (on stack) - -ifdef USE_NASM - call far dword [off] -else - call [FCPTR off] -endif - -; Save all registers back in the structure - - push ebx ; Push EBX onto stack for later - mov ebx,[r] - mov [ebx+0],eax - mov [ebx+8],ecx - mov [ebx+12],edx - mov [ebx+16],esi - mov [ebx+20],edi - pop [DWORD ebx+4] ; Save value of EBX from stack - - leave_c - ret - -cprocend - -endcodeseg _pmdos - - END ; End of module |