📄 intr.asm
字号:
;
; Copyright (C) 1996-2002 Supernar Systems, Ltd. All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are
; met:
;
; 1. Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
;
; 2. Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
;
; 3. The end-user documentation included with the redistribution, if any,
; must include the following acknowledgment:
;
; "This product uses DOS/32 Advanced DOS Extender technology."
;
; Alternately, this acknowledgment may appear in the software itself, if
; and wherever such third-party acknowledgments normally appear.
;
; 4. Products derived from this software may not be called "DOS/32A" or
; "DOS/32 Advanced".
;
; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED
; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
;
;=============================================================================
Align 16
int_matrix: ; INT redirectors
rept 256 ; 256 INTs
push ax
call near ptr int_main
endm
;=============================================================================
std_matrix: ; Standard IRQ redirectors
rept 16 ; 16 IRQs
push ax
call near ptr irq_standard
endm
;=============================================================================
back_matrix: ; Real mode IRQ callbacks
rept 16 ; 16 IRQs
push ax
call near ptr irq_callback
endm
;=============================================================================
exc_matrix: ; Exceptions
rept 16 ; 16 EXCs
push ax
call near ptr exc_handler
endm
; INT Redirector
;
; Used by INTs in protected mode to process real mode INT handlers
;
;=============================================================================
int_main:
cli ; disable interrupts (emul. real-mode)
pop ax ; get caller address in AX
sub ax,offs int_matrix+1 ; calculate INT number
shr ax,2 ; now AX = INT ##h
pushad
push ds es fs gs
xor esi,esi
mov ds,cs:seldata
inc _pc_intpmtorm ; increment INT PM->RM counter
mov dx,rmstacktop ; DX = SS for real mode redirection
mov bx,rmstacklen ; get size of real mode stack
mov si,dx ; EBP -> top of real mode stack
sub dx,bx ; adjust DX to next stack location
mov @@N,al ; modify code with interrupt number
shl esi,4
cmp dx,rmstackbase ; exceeded real mode stack space?
jb critical_error_rm ; if yes, critical error
mov rmstacktop,dx ; update ptr for possible reenterancy
shl bx,4 ; set real mode SP to top of stack
mov last_int,al
mov es,selzero ; copy registers from protected mode
mov ds,selzero ; DS -> 0 (beginning of memory)
lea edi,[esi-26h]
mov ecx,8
cld
mov [esi-2],ss ; store SS:ESP on real mode stack
mov [esi-6],esp
lea esi,[esp+8]
rep movs dword ptr es:[edi],ss:[esi]
mov ax,[esp+28h] ; move AX to real mode stack frame
mov [edi-04h],ax
mov si,_KERNEL ; real mode target CS:IP
mov di,offs @@0
sub bx,26h ; adjust real mode SP for stored vars
db 66h ; JMP DWORD PTR, as in 32bit offset,
jmp word ptr cs:pmtormswrout ; not seg:16bit offset
@@0: popad ; load regs with int call values
db 0CDh ; INT ##h
@@N db 000h
pushad ; store registers on stack
pushf ; store flags on stack
cli ; disable interrupts (emul. real-mode)
xor eax,eax ; EAX = linear ptr to SS
mov ebp,eax
mov ax,ss
shl eax,4
mov bp,sp ; EBP = SP
mov ebx,[bp+22h] ; get protected mode SS:ESP from stack
mov dx,[bp+26h]
add ebp,eax ; EBP -> stored regs on stack
mov ax,SELZERO ; DS selector value for protected mode
mov cx,SELDATA ; ES selector value for protected mode
mov si,SELCODE ; target CS:EIP in protected mode
mov edi,offs @@1
jmp cs:rmtopmswrout ; go back to protected mode
@@1: mov ax,es:rmstacklen ; restore top of real mode stack
add es:rmstacktop,ax
mov ax,ds:[ebp] ; move return FLAGS from real mode
and ax,08D5h ; stack to protected mode stack
mov dx,[esp+32h]
and dx,not 08D5h
or ax,dx
mov [esp+32h],ax
inc es:_pc_intrmtopm ; increment INT RM->PM counter
mov eax,ebp
mov edi,[eax+2] ; restore return registers from real
mov esi,[eax+6] ; mode stack
mov ebp,[eax+10]
mov ebx,[eax+18]
mov edx,[eax+22]
mov ecx,[eax+26]
mov eax,[eax+30]
pop gs fs es ds ; restore segment regs
add esp,22h ; skip old registers
iretd ;**no pop AX
;-----------------------------------------------------------------------------
; User IRQ Handler
;
irq_user:
mov [esp],bx ; handle user installed IRQ
mov bx,ax
shl bx,3
sub esp,4 ; 4 bytes on stack for 00:CS
mov ax,word ptr cs:irqtab_pm[bx+0] ; get offset low (EIP)
mov [esp+0],ax
mov ax,word ptr cs:irqtab_pm[bx+2] ; get offset high (EIP)
mov [esp+2],ax
mov bx,word ptr cs:irqtab_pm[bx+4] ; get selector (CS:)
xchg bx,[esp+4] ; put CS and restore BX
mov ax,[esp+6] ; restore AX
db 66h ; do 32bit far ret to the
retf ; appropriate interrupt handler
; Modifiable IRQ Handler
;
; This handler will, when called, send IRQs from protected mode to real mode
; by default, if protected mode handler is installed, it will be called
; instead.
;
;=============================================================================
irq_normal: ; Standard IRQ handler that will send
cli
pop ax ; all the IRQs that have not been
sub ax,offs int_matrix+1 ; hooked in protected mode to real
shr ax,2 ; mode
jmp irq_down
;=============================================================================
irq_tester: ; redirection for IRQs mapped on INT 08-0Fh
cli
mov al,0Bh
out 20h,al
in al,20h
test al,al
jz irq_fail
pop ax ; get caller address in AX
sub ax,offs int_matrix+1 ; calculate INT number
shr ax,2 ; now AX = INT ##h
irq_soft:
push ax
mov ah,al
and ax,0F807h
cmp ah,cs:picmaster
mov ah,0
jz @@1
add al,8
@@1: bt cs:irqset_pm,ax ; check if user handler is installed
jc irq_user ; if yes, branch
pop ax
;-----------------------------------------------------------------------------
irq_down:
pushad
push ds es fs gs
mov ds,cs:seldata
inc _pc_irqpmtorm ; increment IRQ PM->RM counter
xor esi,esi
mov dx,rmstacktop ; DX = SS for real mode redirection
xor ecx,ecx
mov bx,rmstacklen ; get size of real mode stack
mov si,dx ; ESI -> top of real mode stack
sub dx,bx ; adjust DX to next stack location
mov cl,al
shl esi,4
cmp dx,rmstackbase ; exceeded real mode stack space?
jb critical_error_rm ; if yes, critical error
mov rmstacktop,dx ; update ptr for possible reenterancy
shl bx,4 ; set real mode SP to top of stack
mov ds,selzero ; DS -> 0 (beginning of memory)
mov edi,ds:[ecx*4] ; get real mode interrupt CS:IP
mov [esi-2],ss ; store SS: on real mode stack
mov [esi-6],esp ; store ESP on real mode stack
mov dword ptr [esi-10],_KERNEL ; set target FLAGS and CS: on RM stack
mov word ptr [esi-12],offs @irq ; set target IP on RM stack
shld esi,edi,16
sub bx,12 ; adjust real mode SP for stored vars
db 66h ; JMP DWORD PTR, as in 32bit offset,
jmp word ptr cs:pmtormswrout ; not seg:16bit offset
; Exception Handler
;
; NOTE: this handler should be called only by interrupts in range
; INT 00h thru INT 0Fh which are exceptions.
;
;=============================================================================
irq_fail:
pop ax ; get call address
sub ax,offs int_matrix+1 ; calculate INT ##
shr ax,2
test cs:pm32_mode,00010000b ; check if software INTs are allowed
jnz @@1 ; if trap them down, then jump
push ax ; check if software INT was issued
push ds
push esi
lar si,[esp+8+6] ; get CS: rights assuming no errcode
jnz @@0 ; if CS: not valid, jump
verr word ptr [esp+8+6] ; verify selector read access
jnz @@0 ; if non-readable, jump
not si ; invert Present bit
test si,8000h ; test Present bit
jnz @@0 ; if segment was not present, jump
mov ah,al
mov al,0CDh
mov ds,[esp+8+6]
mov esi,[esp+8+2]
cmp ax,ds:[esi-2]
@@0: pop esi
pop ds
pop ax
jnz @@1
cmp al,8
jae irq_soft
@@1: bt cs:excset_pm,ax ; check if user handler is installed
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -