📄 _pmdos.asm
字号:
popfd pop ecx pop ebx pop eaxelse pushfifdef USE_NASM call far dword [_PM_prevKey15]else call [_PM_prevKey15]endifendif@@Exit: pop es pop dsifdef flatmodel retf 4else retf 2endifcprocend;----------------------------------------------------------------------------; 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 registerifdef 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 interruptcprocend;----------------------------------------------------------------------------; 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 esifdef 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 retcprocend;----------------------------------------------------------------------------; 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 registerifdef 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 iretdcprocend;----------------------------------------------------------------------------; 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 esifdef 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 retcprocend;----------------------------------------------------------------------------; 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 registerifdef 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 interruptcprocend;----------------------------------------------------------------------------; 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 esifdef 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 retcprocend;----------------------------------------------------------------------------; 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 retcprocendifdef 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!cprocendendifcpublic _PM_pmdosCodeEndendcodeseg _pmdos END ; End of module
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -