summaryrefslogtreecommitdiffstats
path: root/board/MAI/bios_emulator/scitech/src/pm/dos/_pmdos.asm
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/pm/dos/_pmdos.asm')
-rw-r--r--board/MAI/bios_emulator/scitech/src/pm/dos/_pmdos.asm1105
1 files changed, 0 insertions, 1105 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/pm/dos/_pmdos.asm b/board/MAI/bios_emulator/scitech/src/pm/dos/_pmdos.asm
deleted file mode 100644
index 5c741f346c..0000000000
--- a/board/MAI/bios_emulator/scitech/src/pm/dos/_pmdos.asm
+++ /dev/null
@@ -1,1105 +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 interrupt handling.
-;*
-;****************************************************************************
-
- IDEAL
-
-include "scitech.mac" ; Memory model macros
-
-header _pmdos ; Set up memory model
-
-; Define the size of our local stacks. For real mode code they cant be
-; that big, but for 32 bit protected mode code we can make them nice and
-; large so that complex C functions can be used.
-
-ifdef flatmodel
-MOUSE_STACK EQU 4096
-TIMER_STACK EQU 4096
-KEY_STACK EQU 1024
-INT10_STACK EQU 1024
-IRQ_STACK EQU 1024
-else
-MOUSE_STACK EQU 1024
-TIMER_STACK EQU 512
-KEY_STACK EQU 256
-INT10_STACK EQU 256
-IRQ_STACK EQU 256
-endif
-
-ifdef USE_NASM
-
-; Macro to load DS and ES registers with correct value.
-
-%imacro LOAD_DS 0
-%ifdef flatmodel
- mov ds,[cs:_PM_savedDS]
- mov es,[cs:_PM_savedDS]
-%else
- push ax
- mov ax,_DATA
- mov ds,ax
- pop ax
-%endif
-%endmacro
-
-; Note that interrupts we disable interrupts during the following stack
-; %imacro for correct operation, but we do not enable them again. Normally
-; these %imacros are used within interrupt handlers so interrupts should
-; already be off. We turn them back on explicitly later if the user code
-; needs them to be back on.
-
-; Macro to switch to a new local stack.
-
-%imacro NEWSTK 1
- cli
- mov [seg_%1],ss
- mov [ptr_%1],_sp
- mov [TempSeg],ds
- mov ss,[TempSeg]
- mov _sp,offset %1
-%endmacro
-
-; %imacro to switch back to the old stack.
-
-%imacro RESTSTK 1
- cli
- mov ss,[seg_%1]
- mov _sp,[ptr_%1]
-%endmacro
-
-; %imacro to swap the current stack with the one saved away.
-
-%imacro SWAPSTK 1
- cli
- mov ax,ss
- xchg ax,[seg_%1]
- mov ss,ax
- xchg _sp,[ptr_%1]
-%endmacro
-
-else
-
-; Macro to load DS and ES registers with correct value.
-
-MACRO LOAD_DS
-ifdef flatmodel
- mov ds,[cs:_PM_savedDS]
- mov es,[cs:_PM_savedDS]
-else
- push ax
- mov ax,_DATA
- mov ds,ax
- pop ax
-endif
-ENDM
-
-; Note that interrupts we disable interrupts during the following stack
-; macro for correct operation, but we do not enable them again. Normally
-; these macros are used within interrupt handlers so interrupts should
-; already be off. We turn them back on explicitly later if the user code
-; needs them to be back on.
-
-; Macro to switch to a new local stack.
-
-MACRO NEWSTK stkname
- cli
- mov [seg_&stkname&],ss
- mov [ptr_&stkname&],_sp
- mov [TempSeg],ds
- mov ss,[TempSeg]
- mov _sp,offset stkname
-ENDM
-
-; Macro to switch back to the old stack.
-
-MACRO RESTSTK stkname
- cli
- mov ss,[seg_&stkname&]
- mov _sp,[ptr_&stkname&]
-ENDM
-
-; Macro to swap the current stack with the one saved away.
-
-MACRO SWAPSTK stkname
- cli
- mov ax,ss
- xchg ax,[seg_&stkname&]
- mov ss,ax
- xchg _sp,[ptr_&stkname&]
-ENDM
-
-endif
-
-begdataseg _pmdos
-
-ifdef flatmodel
- cextern _PM_savedDS,USHORT
-endif
- cextern _PM_critHandler,CPTR
- cextern _PM_breakHandler,CPTR
- cextern _PM_timerHandler,CPTR
- cextern _PM_rtcHandler,CPTR
- cextern _PM_keyHandler,CPTR
- cextern _PM_key15Handler,CPTR
- cextern _PM_mouseHandler,CPTR
- cextern _PM_int10Handler,CPTR
-
- cextern _PM_ctrlCPtr,DPTR
- cextern _PM_ctrlBPtr,DPTR
- cextern _PM_critPtr,DPTR
-
- cextern _PM_prevTimer,FCPTR
- cextern _PM_prevRTC,FCPTR
- cextern _PM_prevKey,FCPTR
- cextern _PM_prevKey15,FCPTR
- cextern _PM_prevBreak,FCPTR
- cextern _PM_prevCtrlC,FCPTR
- cextern _PM_prevCritical,FCPTR
- cextern _PM_prevRealTimer,ULONG
- cextern _PM_prevRealRTC,ULONG
- cextern _PM_prevRealKey,ULONG
- cextern _PM_prevRealKey15,ULONG
- cextern _PM_prevRealInt10,ULONG
-
-cpublic _PM_pmdosDataStart
-
-; Allocate space for all of the local stacks that we need. These stacks
-; are not very large, but should be large enough for most purposes
-; (generally you want to handle these interrupts quickly, simply storing
-; the information for later and then returning). If you need bigger
-; stacks then change the appropriate value in here.
-
- ALIGN 4
- dclb MOUSE_STACK ; Space for local stack (small)
-MsStack: ; Stack starts at end!
-ptr_MsStack DUINT 0 ; Place to store old stack offset
-seg_MsStack dw 0 ; Place to store old stack segment
-
- ALIGN 4
- dclb INT10_STACK ; Space for local stack (small)
-Int10Stack: ; Stack starts at end!
-ptr_Int10Stack DUINT 0 ; Place to store old stack offset
-seg_Int10Stack dw 0 ; Place to store old stack segment
-
- ALIGN 4
- dclb TIMER_STACK ; Space for local stack (small)
-TmStack: ; Stack starts at end!
-ptr_TmStack DUINT 0 ; Place to store old stack offset
-seg_TmStack dw 0 ; Place to store old stack segment
-
- ALIGN 4
- dclb TIMER_STACK ; Space for local stack (small)
-RtcStack: ; Stack starts at end!
-ptr_RtcStack DUINT 0 ; Place to store old stack offset
-seg_RtcStack dw 0 ; Place to store old stack segment
-RtcInside dw 0 ; Are we still handling current interrupt
-
- ALIGN 4
- dclb KEY_STACK ; Space for local stack (small)
-KyStack: ; Stack starts at end!
-ptr_KyStack DUINT 0 ; Place to store old stack offset
-seg_KyStack dw 0 ; Place to store old stack segment
-KyInside dw 0 ; Are we still handling current interrupt
-
- ALIGN 4
- dclb KEY_STACK ; Space for local stack (small)
-Ky15Stack: ; Stack starts at end!
-ptr_Ky15Stack DUINT 0 ; Place to store old stack offset
-seg_Ky15Stack dw 0 ; Place to store old stack segment
-
-TempSeg dw 0 ; Place to store stack segment
-
-cpublic _PM_pmdosDataEnd
-
-enddataseg _pmdos
-
-begcodeseg _pmdos ; Start of code segment
-
-cpublic _PM_pmdosCodeStart
-
-;----------------------------------------------------------------------------
-; PM_mouseISR - Mouse interrupt subroutine dispatcher
-;----------------------------------------------------------------------------
-; Interrupt subroutine called by the mouse driver upon interrupts, to
-; dispatch control to high level C based subroutines. Interrupts are on
-; when we call the user code.
-;
-; It is _extremely_ important to save the state of the extended registers
-; as these may well be trashed by the routines called from here and not
-; restored correctly by the mouse interface module.
-;
-; NOTE: This routine switches to a local stack before calling any C code,
-; and hence is _not_ re-entrant. For mouse handlers this is not a
-; problem, as the mouse driver arbitrates calls to the user mouse
-; handler for us.
-;
-; Entry: AX - Condition mask giving reason for call
-; BX - Mouse button state
-; CX - Horizontal cursor coordinate
-; DX - Vertical cursor coordinate
-; SI - Horizontal mickey value
-; DI - Vertical mickey value
-;
-;----------------------------------------------------------------------------
-ifdef DJGPP
-cprocstart _PM_mouseISR
-else
-cprocfar _PM_mouseISR
-endif
-
- push ds ; Save value of DS
- push es
- pushad ; Save _all_ extended registers
- cld ; Clear direction flag
-
- LOAD_DS ; Load DS register
- NEWSTK MsStack ; Switch to local stack
-
-; Call the installed high level C code routine
-
- clrhi dx ; Clear out high order values
- clrhi cx
- clrhi bx
- clrhi ax
- sgnhi si
- sgnhi di
-
- push _di
- push _si
- push _dx
- push _cx
- push _bx
- push _ax
- sti ; Enable interrupts
- call [CPTR _PM_mouseHandler]
- _add sp,12,24
-
- RESTSTK MsStack ; Restore previous stack
-
- popad ; Restore all extended registers
- pop es
- pop ds
- ret ; We are done!!
-
-cprocend
-
-;----------------------------------------------------------------------------
-; PM_timerISR - Timer interrupt subroutine dispatcher
-;----------------------------------------------------------------------------
-; Hardware interrupt handler for the timer interrupt, to dispatch control
-; to high level C based subroutines. We save the state of all registers
-; in this routine, and switch to a local stack. Interrupts are *off*
-; when we call the user code.
-;
-; NOTE: This routine switches to a local stack before calling any C code,
-; and hence is _not_ re-entrant. Make sure your C code executes as
-; quickly as possible, since a timer overrun will simply hang the
-; system.
-;----------------------------------------------------------------------------
-cprocfar _PM_timerISR
-
- push ds ; Save value of DS
- push es
- pushad ; Save _all_ extended registers
- cld ; Clear direction flag
-
- LOAD_DS ; Load DS register
-
- NEWSTK TmStack ; Switch to local stack
- call [CPTR _PM_timerHandler]
- RESTSTK TmStack ; Restore previous stack
-
- popad ; Restore all extended registers
- pop es
- pop ds
- iret ; Return from interrupt
-
-cprocend
-
-;----------------------------------------------------------------------------
-; PM_chainPrevTimer - Chain to previous timer interrupt and return
-;----------------------------------------------------------------------------
-; Chains to the previous timer interrupt routine and returns control
-; back to the high level interrupt handler.
-;----------------------------------------------------------------------------
-cprocstart PM_chainPrevTimer
-
-ifdef TNT
- push eax
- push ebx
- push ecx
- pushfd ; Push flags on stack to simulate interrupt
- mov ax,250Eh ; Call real mode procedure function
- mov ebx,[_PM_prevRealTimer]
- mov ecx,1 ; Copy real mode flags to real mode stack
- int 21h ; Call the real mode code
- popfd
- pop ecx
- pop ebx
- pop eax
- ret
-else
- SWAPSTK TmStack ; Swap back to previous stack
- pushf ; Save state of interrupt flag
- pushf ; Push flags on stack to simulate interrupt
-ifdef USE_NASM
- call far dword [_PM_prevTimer]
-else
- call [_PM_prevTimer]
-endif
- popf ; Restore state of interrupt flag
- SWAPSTK TmStack ; Swap back to C stack again
- ret
-endif
-
-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
-
-;----------------------------------------------------------------------------
-; PM_rtcISR - Real time clock interrupt subroutine dispatcher
-;----------------------------------------------------------------------------
-; Hardware interrupt handler for the timer interrupt, to dispatch control
-; to high level C based subroutines. We save the state of all registers
-; in this routine, and switch to a local stack. Interrupts are *off*
-; when we call the user code.
-;
-; NOTE: This routine switches to a local stack before calling any C code,
-; and hence is _not_ re-entrant. Make sure your C code executes as
-; quickly as possible, since a timer overrun will simply hang the
-; system.
-;----------------------------------------------------------------------------
-cprocfar _PM_rtcISR
-
- push ds ; Save value of DS
- push es
- pushad ; Save _all_ extended registers
- cld ; Clear direction flag
-
-; Clear priority interrupt controller and re-enable interrupts so we
-; dont lock things up for long.
-
- mov al,20h
- out 0A0h,al
- out 020h,al
-
-; Clear real-time clock timeout
-
- in al,70h ; Read CMOS index register
- push _ax ; and save for later
- IODELAYN 3
- mov al,0Ch
- out 70h,al
- IODELAYN 5
- in al,71h
-
-; Call the C interrupt handler function
-
- LOAD_DS ; Load DS register
- cmp [BYTE RtcInside],1 ; Check for mutual exclusion
- je @@Exit
- mov [BYTE RtcInside],1
- NEWSTK RtcStack ; Switch to local stack
- sti ; Re-enable interrupts
- call [CPTR _PM_rtcHandler]
- RESTSTK RtcStack ; Restore previous stack
- mov [BYTE RtcInside],0
-
-@@Exit: pop _ax
- out 70h,al ; Restore CMOS index register
- popad ; Restore all extended registers
- pop es
- pop ds
- iret ; Return from interrupt
-
-cprocend
-
-ifdef flatmodel
-;----------------------------------------------------------------------------
-; PM_irqISRTemplate - Hardware interrupt handler IRQ template
-;----------------------------------------------------------------------------
-; Hardware interrupt handler for any interrupt, to dispatch control
-; to high level C based subroutines. We save the state of all registers
-; in this routine, and switch to a local stack. Interrupts are *off*
-; when we call the user code.
-;
-; NOTE: This routine switches to a local stack before calling any C code,
-; and hence is _not_ re-entrant. Make sure your C code executes as
-; quickly as possible.
-;----------------------------------------------------------------------------
-cprocfar _PM_irqISRTemplate
-
- push ebx
- mov ebx,0 ; Relocation adjustment factor
- jmp __IRQEntry
-
-; Global variables stored in the IRQ thunk code segment
-
-_CHandler dd 0 ; Pointer to C interrupt handler
-_PrevIRQ dd 0 ; Previous IRQ handler
- dd 0
-_IRQ dd 0 ; IRQ we are hooked for
-ptr_IRQStack DUINT 0 ; Place to store old stack offset
-seg_IRQStack dw 0 ; Place to store old stack segment
-_Inside db 0 ; Mutual exclusion flag
- ALIGN 4
- dclb IRQ_STACK ; Space for local stack
-_IRQStack: ; Stack starts at end!
-
-; Check for and reject spurious IRQ 7 signals
-
-__IRQEntry:
- cmp [BYTE cs:ebx+_IRQ],7 ; Spurious IRQs occur only on IRQ 7
- jmp @@ValidIRQ
- push eax
- mov al,1011b ; OCW3: read ISR
- out 20h,al ; (Intel Peripheral Components, 1991,
- in al,20h ; p. 3-188)
- shl al,1 ; Set C = bit 7 (IRQ 7) of ISR register
- pop eax
- jc @@ValidIRQ
- iret ; Return from interrupt
-
-; Save all registers for duration of IRQ handler
-
-@@ValidIRQ:
- push ds ; Save value of DS
- push es
- pushad ; Save _all_ extended registers
- cld ; Clear direction flag
- LOAD_DS ; Load DS register
-
-; Send an EOI to the PIC
-
- mov al,20h ; Send EOI to PIC
- cmp [BYTE ebx+_IRQ],8 ; Clear PIC1 first if IRQ >= 8
- jb @@1
- out 0A0h,al
-@@1: out 20h,al
-
-; Check for mutual exclusion
-
- cmp [BYTE ebx+_Inside],1
- je @@ChainOldHandler
- mov [BYTE ebx+_Inside],1
-
-; Call the C interrupt handler function
-
- mov [ebx+seg_IRQStack],ss ; Switch to local stack
- mov [ebx+ptr_IRQStack],esp
- mov [TempSeg],ds
- mov ss,[TempSeg]
- lea esp,[ebx+_IRQStack]
- sti ; Re-enable interrupts
- push ebx
- call [DWORD ebx+_CHandler]
- pop ebx
- cli
- mov ss,[ebx+seg_IRQStack] ; Restore previous stack
- mov esp,[ebx+ptr_IRQStack]
- or eax,eax
- jz @@ChainOldHandler ; Chain if not handled for shared IRQ
-
-@@Exit: mov [BYTE ebx+_Inside],0
- popad ; Restore all extended registers
- pop es
- pop ds
- pop ebx
- iret ; Return from interrupt
-
-@@ChainOldHandler:
- cmp [DWORD ebx+_PrevIRQ],0
- jz @@Exit
- mov [BYTE ebx+_Inside],0
- mov eax,[DWORD ebx+_PrevIRQ]
- mov ebx,[DWORD ebx+_PrevIRQ+4]
- mov [DWORD _PrevIRQ],eax
- mov [DWORD _PrevIRQ+4],ebx
- popad ; Restore all extended registers
- pop es
- pop ds
- pop ebx
- jmp [cs:_PrevIRQ] ; Chain to previous IRQ handler
-
-cprocend
-cpublic _PM_irqISRTemplateEnd
-endif
-
-;----------------------------------------------------------------------------
-; PM_keyISR - keyboard interrupt subroutine dispatcher
-;----------------------------------------------------------------------------
-; Hardware interrupt handler for the keyboard interrupt, to dispatch control
-; to high level C based subroutines. We save the state of all registers
-; in this routine, and switch to a local stack. Interrupts are *off*
-; when we call the user code.
-;
-; NOTE: This routine switches to a local stack before calling any C code,
-; and hence is _not_ re-entrant. However we ensure within this routine
-; mutual exclusion to the keyboard handling routine.
-;----------------------------------------------------------------------------
-cprocfar _PM_keyISR
-
- push ds ; Save value of DS
- push es
- pushad ; Save _all_ extended registers
- cld ; Clear direction flag
-
- LOAD_DS ; Load DS register
-
- cmp [BYTE KyInside],1 ; Check for mutual exclusion
- je @@Reissued
-
- mov [BYTE KyInside],1
- NEWSTK KyStack ; Switch to local stack
- call [CPTR _PM_keyHandler] ; Call C code
- RESTSTK KyStack ; Restore previous stack
- mov [BYTE KyInside],0
-
-@@Exit: popad ; Restore all extended registers
- pop es
- pop ds
- iret ; Return from interrupt
-
-; When the BIOS keyboard handler needs to change the SHIFT status lights
-; on the keyboard, in the process of doing this the keyboard controller
-; re-issues another interrupt, while the current handler is still executing.
-; If we recieve another interrupt while still handling the current one,
-; then simply chain directly to the previous handler.
-;
-; Note that for most DOS extenders, the real mode interrupt handler that we
-; install takes care of this for us.
-
-@@Reissued:
-ifdef TNT
- push eax
- push ebx
- push ecx
- pushfd ; Push flags on stack to simulate interrupt
- mov ax,250Eh ; Call real mode procedure function
- mov ebx,[_PM_prevRealKey]
- mov ecx,1 ; Copy real mode flags to real mode stack
- int 21h ; Call the real mode code
- popfd
- pop ecx
- pop ebx
- pop eax
-else
- pushf
-ifdef USE_NASM
- call far dword [_PM_prevKey]
-else
- call [_PM_prevKey]
-endif
-endif
- jmp @@Exit
-
-cprocend
-
-;----------------------------------------------------------------------------
-; PM_chainPrevkey - Chain to previous key interrupt and return
-;----------------------------------------------------------------------------
-; Chains to the previous key interrupt routine and returns control
-; back to the high level interrupt handler.
-;----------------------------------------------------------------------------
-cprocstart PM_chainPrevKey
-
-ifdef TNT
- push eax
- push ebx
- push ecx
- pushfd ; Push flags on stack to simulate interrupt
- mov ax,250Eh ; Call real mode procedure function
- mov ebx,[_PM_prevRealKey]
- mov ecx,1 ; Copy real mode flags to real mode stack
- int 21h ; Call the real mode code
- popfd
- pop ecx
- pop ebx
- pop eax
- ret
-else
-
-; YIKES! For some strange reason, when execution returns from the
-; previous keyboard handler, interrupts are re-enabled!! Since we expect
-; interrupts to remain off during the duration of our handler, this can
-; cause havoc. However our stack macros always turn off interrupts, so they
-; will be off when we exit this routine. Obviously there is a tiny weeny
-; window when interrupts will be enabled, but there is nothing we can
-; do about this.
-
- SWAPSTK KyStack ; Swap back to previous stack
- pushf ; Push flags on stack to simulate interrupt
-ifdef USE_NASM
- call far dword [_PM_prevKey]
-else
- call [_PM_prevKey]
-endif
- SWAPSTK KyStack ; Swap back to C stack again
- ret
-endif
-
-cprocend
-
-;----------------------------------------------------------------------------
-; PM_key15ISR - Int 15h keyboard interrupt subroutine dispatcher
-;----------------------------------------------------------------------------
-; This routine gets called if we have been called to handle the Int 15h
-; keyboard interrupt callout from real mode.
-;
-; Entry: AX - Hardware scan code to process
-; Exit: AX - Hardware scan code to process (0 to ignore)
-;----------------------------------------------------------------------------
-cprocfar _PM_key15ISR
-
- push ds
- push es
- LOAD_DS
- cmp ah,4Fh
- jnz @@NotOurs ; Quit if not keyboard callout
-
- pushad
- cld ; Clear direction flag
- xor ah,ah ; AX := scan code
- NEWSTK Ky15Stack ; Switch to local stack
- push _ax
- call [CPTR _PM_key15Handler] ; Call C code
- _add sp,2,4
- RESTSTK Ky15Stack ; Restore previous stack
- test ax,ax
- jz @@1
- stc ; Set carry to process as normal
- jmp @@2
-@@1: clc ; Clear carry to ignore scan code
-@@2: popad
- jmp @@Exit ; We are done
-
-@@NotOurs:
-ifdef TNT
- push eax
- push ebx
- push ecx
- pushfd ; Push flags on stack to simulate interrupt
- mov ax,250Eh ; Call real mode procedure function
- mov ebx,[_PM_prevRealKey15]
- mov ecx,1 ; Copy real mode flags to real mode stack
- int 21h ; Call the real mode code
- popfd
- pop ecx
- pop ebx
- pop eax
-else
- pushf
-ifdef USE_NASM
- call far dword [_PM_prevKey15]
-else
- call [_PM_prevKey15]
-endif
-endif
-@@Exit: pop es
- pop ds
-ifdef flatmodel
- retf 4
-else
- retf 2
-endif
-
-cprocend
-
-;----------------------------------------------------------------------------
-; PM_breakISR - Control Break interrupt subroutine dispatcher
-;----------------------------------------------------------------------------
-; Hardware interrupt handler for the Ctrl-Break interrupt. We simply set
-; the Ctrl-Break flag to a 1 and leave (note that this is accessed through
-; a far pointer, as it may well be located in conventional memory).
-;----------------------------------------------------------------------------
-cprocfar _PM_breakISR
-
- sti
- push ds ; Save value of DS
- push es
- push _bx
-
- LOAD_DS ; Load DS register
-ifdef flatmodel
- mov ebx,[_PM_ctrlBPtr]
-else
- les bx,[_PM_ctrlBPtr]
-endif
- mov [UINT _ES _bx],1
-
-; Run alternate break handler code if installed
-
- cmp [CPTR _PM_breakHandler],0
- je @@Exit
-
- pushad
- mov _ax,1
- push _ax
- call [CPTR _PM_breakHandler] ; Call C code
- pop _ax
- popad
-
-@@Exit: pop _bx
- pop es
- pop ds
- iret ; Return from interrupt
-
-cprocend
-
-;----------------------------------------------------------------------------
-; int PM_ctrlBreakHit(int clearFlag)
-;----------------------------------------------------------------------------
-; Returns the current state of the Ctrl-Break flag and possibly clears it.
-;----------------------------------------------------------------------------
-cprocstart PM_ctrlBreakHit
-
- ARG clearFlag:UINT
-
- enter_c
- pushf ; Save interrupt status
- push es
-ifdef flatmodel
- mov ebx,[_PM_ctrlBPtr]
-else
- les bx,[_PM_ctrlBPtr]
-endif
- cli ; No interrupts thanks!
- mov _ax,[_ES _bx]
- test [BYTE clearFlag],1
- jz @@Done
- mov [UINT _ES _bx],0
-
-@@Done: pop es
- popf ; Restore interrupt status
- leave_c
- ret
-
-cprocend
-
-;----------------------------------------------------------------------------
-; PM_ctrlCISR - Control Break interrupt subroutine dispatcher
-;----------------------------------------------------------------------------
-; Hardware interrupt handler for the Ctrl-C interrupt. We simply set
-; the Ctrl-C flag to a 1 and leave (note that this is accessed through
-; a far pointer, as it may well be located in conventional memory).
-;----------------------------------------------------------------------------
-cprocfar _PM_ctrlCISR
-
- sti
- push ds ; Save value of DS
- push es
- push _bx
-
- LOAD_DS ; Load DS register
-ifdef flatmodel
- mov ebx,[_PM_ctrlCPtr]
-else
- les bx,[_PM_ctrlCPtr]
-endif
- mov [UINT _ES _bx],1
-
-; Run alternate break handler code if installed
-
- cmp [CPTR _PM_breakHandler],0
- je @@Exit
-
- pushad
- mov _ax,0
- push _ax
- call [CPTR _PM_breakHandler] ; Call C code
- pop _ax
- popad
-
-@@Exit: pop _bx
- pop es
- pop ds
- iret ; Return from interrupt
- iretd
-
-cprocend
-
-;----------------------------------------------------------------------------
-; int PM_ctrlCHit(int clearFlag)
-;----------------------------------------------------------------------------
-; Returns the current state of the Ctrl-C flag and possibly clears it.
-;----------------------------------------------------------------------------
-cprocstart PM_ctrlCHit
-
- ARG clearFlag:UINT
-
- enter_c
- pushf ; Save interrupt status
- push es
-ifdef flatmodel
- mov ebx,[_PM_ctrlCPtr]
-else
- les bx,[_PM_ctrlCPtr]
-endif
- cli ; No interrupts thanks!
- mov _ax,[_ES _bx]
- test [BYTE clearFlag],1
- jz @@Done
- mov [UINT _ES _bx],0
-
-@@Done:
- pop es
- popf ; Restore interrupt status
- leave_c
- ret
-
-cprocend
-
-;----------------------------------------------------------------------------
-; PM_criticalISR - Control Error handler interrupt subroutine dispatcher
-;----------------------------------------------------------------------------
-; Interrupt handler for the MSDOS Critical Error interrupt, to dispatch
-; control to high level C based subroutines. We save the state of all
-; registers in this routine, and switch to a local stack. We also pass
-; the values of the AX and DI registers to the as pointers, so that the
-; values can be modified before returning to MSDOS.
-;----------------------------------------------------------------------------
-cprocfar _PM_criticalISR
-
- sti
- push ds ; Save value of DS
- push es
- push _bx ; Save register values changed
- cld ; Clear direction flag
-
- LOAD_DS ; Load DS register
-ifdef flatmodel
- mov ebx,[_PM_critPtr]
-else
- les bx,[_PM_critPtr]
-endif
- mov [_ES _bx],ax
- mov [_ES _bx+2],di
-
-; Run alternate critical handler code if installed
-
- cmp [CPTR _PM_critHandler],0
- je @@NoAltHandler
-
- pushad
- push _di
- push _ax
- call [CPTR _PM_critHandler] ; Call C code
- _add sp,4,8
- popad
-
- pop _bx
- pop es
- pop ds
- iret ; Return from interrupt
-
-@@NoAltHandler:
- mov ax,3 ; Tell MSDOS to fail the operation
- pop _bx
- pop es
- pop ds
- iret ; Return from interrupt
-
-cprocend
-
-;----------------------------------------------------------------------------
-; int PM_criticalError(int *axVal,int *diVal,int clearFlag)
-;----------------------------------------------------------------------------
-; Returns the current state of the critical error flags, and the values that
-; MSDOS passed in the AX and DI registers to our handler.
-;----------------------------------------------------------------------------
-cprocstart PM_criticalError
-
- ARG axVal:DPTR, diVal:DPTR, clearFlag:UINT
-
- enter_c
- pushf ; Save interrupt status
- push es
-ifdef flatmodel
- mov ebx,[_PM_critPtr]
-else
- les bx,[_PM_critPtr]
-endif
- cli ; No interrupts thanks!
- xor _ax,_ax
- xor _di,_di
- mov ax,[_ES _bx]
- mov di,[_ES _bx+2]
- test [BYTE clearFlag],1
- jz @@NoClear
- mov [ULONG _ES _bx],0
-@@NoClear:
- _les _bx,[axVal]
- mov [_ES _bx],_ax
- _les _bx,[diVal]
- mov [_ES _bx],_di
- pop es
- popf ; Restore interrupt status
- leave_c
- ret
-
-cprocend
-
-;----------------------------------------------------------------------------
-; void PM_setMouseHandler(int mask, PM_mouseHandler mh)
-;----------------------------------------------------------------------------
-cprocstart _PM_setMouseHandler
-
- ARG mouseMask:UINT
-
- enter_c
- push es
-
- mov ax,0Ch ; AX := Function 12 - install interrupt sub
- mov _cx,[mouseMask] ; CX := mouse mask
- mov _dx,offset _PM_mouseISR
- push cs
- pop es ; ES:_DX -> mouse handler
- int 33h ; Call mouse driver
-
- pop es
- leave_c
- ret
-
-cprocend
-
-ifdef flatmodel
-
-;----------------------------------------------------------------------------
-; void PM_mousePMCB(void)
-;----------------------------------------------------------------------------
-; Mouse realmode callback routine. Upon entry to this routine, we recieve
-; the following from the DPMI server:
-;
-; Entry: DS:_SI -> Real mode stack at time of call
-; ES:_DI -> Real mode register data structure
-; SS:_SP -> Locked protected mode stack to use
-;----------------------------------------------------------------------------
-cprocfar _PM_mousePMCB
-
- pushad
- mov eax,[es:_di+1Ch] ; Load register values from real mode
- mov ebx,[es:_di+10h]
- mov ecx,[es:_di+18h]
- mov edx,[es:_di+14h]
- mov esi,[es:_di+04h]
- mov edi,[es:_di]
- call _PM_mouseISR ; Call the mouse handler
- popad
-
- mov ax,[ds:_si]
- mov [es:_di+2Ah],ax ; Plug in return IP address
- mov ax,[ds:_si+2]
- mov [es:_di+2Ch],ax ; Plug in return CS value
- add [WORD es:_di+2Eh],4 ; Remove return address from stack
- iret ; Go back to real mode!
-
-cprocend
-
-;----------------------------------------------------------------------------
-; void PM_int10PMCB(void)
-;----------------------------------------------------------------------------
-; int10 realmode callback routine. Upon entry to this routine, we recieve
-; the following from the DPMI server:
-;
-; Entry: DS:ESI -> Real mode stack at time of call
-; ES:EDI -> Real mode register data structure
-; SS:ESP -> Locked protected mode stack to use
-;----------------------------------------------------------------------------
-cprocfar _PM_int10PMCB
-
- pushad
- push ds
- push es
- push fs
-
- pushfd
- pop eax
- mov [es:edi+20h],ax ; Save return flag status
- mov ax,[ds:esi]
- mov [es:edi+2Ah],ax ; Plug in return IP address
- mov ax,[ds:esi+2]
- mov [es:edi+2Ch],ax ; Plug in return CS value
- add [WORD es:edi+2Eh],4 ; Remove return address from stack
-
-; Call the install int10 handler in protected mode. This function gets called
-; with DS set to the current data selector, and ES:EDI pointing the the
-; real mode DPMI register structure at the time of the interrupt. The
-; handle must be written in assembler to be able to extract the real mode
-; register values from the structure
-
- push es
- pop fs ; FS:EDI -> real mode registers
- LOAD_DS
- NEWSTK Int10Stack ; Switch to local stack
-
- call [_PM_int10Handler]
-
- RESTSTK Int10Stack ; Restore previous stack
- pop fs
- pop es
- pop ds
- popad
- iret ; Go back to real mode!
-
-cprocend
-
-endif
-
-cpublic _PM_pmdosCodeEnd
-
-endcodeseg _pmdos
-
- END ; End of module
OpenPOWER on IntegriCloud