⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intr.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;
; 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 + -