📄 _pmdos.asm
字号:
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -