diff options
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.asm | 1105 |
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 5c741f346c2..00000000000 --- 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 |