home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
caway349.zip
/
SOURCE
/
ALL
/
INTERRUP.ASM
< prev
next >
Wrap
Assembly Source File
|
1999-04-05
|
36KB
|
1,680 lines
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;
;Protected mode interrupt/exception handlers.
;
;-------------------------------------------------------------------------------
;
;Generate the initial entry points for the interupt handlers.
;
InterruptHandler proc near
rept 256
db 0e8h
dd offset IntHandler-($+4)
db 3 dup (-1)
endm
InterruptHandler endp
;-------------------------------------------------------------------------------
InterruptTable proc near
;
;Interupt handler entry points (Int nn and IntR).
;
IntNum = 0
rept 2fh
dd offset IntNN386Catch+IntNum
dw DpmiEmuCS
IntNum = IntNum+8
endm
dd offset Raw2FPatch
dw DpmiEmuCS
IntNum = IntNum+8
rept 30h-2fh
dd offset IntNN386Catch+IntNum
dw DpmiEmuCS
IntNum = IntNum+8
endm
dd offset RawDPMIPatch
dw DpmiEmuCS
IntNum = IntNum+8
rept 256-32h
dd offset IntNN386Catch+IntNum
dw DpmiEmuCS
IntNum = IntNum+8
endm
InterruptTable endp
;-------------------------------------------------------------------------------
IntNN386Catch proc near
rept 256
db 0e8h
dd offset IntNN386-($+4)
db 3 dup (-1)
endm
IntNN386Catch endp
;-------------------------------------------------------------------------------
ExceptionTable proc near
;
;Exception handler entry points (Processor exceptions).
;
IntNum = 0
rept 32
dd offset ExcepNN386Catch+IntNum
dw DpmiEmuCS
IntNum = IntNum+8
endm
ExceptionTable endp
;-------------------------------------------------------------------------------
ExcepNN386Catch proc near
rept 32
db 0e8h
dd offset ExcepNN386-($+4)
db 3 dup (-1)
endm
ExcepNN386Catch endp
;-------------------------------------------------------------------------------
;
;Get protected mode interupt handler address.
;
;On Entry:-
;
;BL - Interupt vector number.
;
;On Exit:-
;
;CF set on error. (no errors looked for).
;
;CX:EDX - selector:offset of current handler.
;
RawGetVector proc near
call RAWCopyCheck
;
pushm eax,ebx,esi,edi,ebp,ds,es,fs,gs
mov ax,DpmiEmuDS
mov ds,ax
movzx eax,bl
mov ebx,eax
shl ebx,1 ;*2
mov eax,ebx
shl ebx,1 ;*4
add ebx,eax ;*6
add ebx,offset InterruptTable
mov edx,[ebx] ;get offset.
mov cx,[ebx+4] ;get segment selector.
popm eax,ebx,esi,edi,ebp,ds,es,fs,gs
ret
RawGetVector endp
;-------------------------------------------------------------------------------
;
;Get real mode interupt handler address.
;
;On Entry:-
;
;BL - Interupt vector number.
;
;On Exit:-
;
;CF set on error. (no errors looked for).
;
;CX:DX - selector:offset of current handler.
;
RawGetRVector proc near
call RAWCopyCheck
;
pushm eax,ebx,esi,edi,ebp,ds,es,fs,gs
mov ax,KernalZero
mov es,ax
movzx ebx,bl
shl ebx,2
mov dx,es:[ebx]
mov cx,es:[ebx+2]
popm eax,ebx,esi,edi,ebp,ds,es,fs,gs
ret
RawGetRVector endp
;-------------------------------------------------------------------------------
;
;Get protected mode exception handler address.
;
;On Entry:-
;
;BL - Exception vector number.
;
;On Exit:-
;
;CF set on error.
;
;CX:EDX - selector:offset of current handler.
;
RawGetEVector proc near
call RAWCopyCheck
;
; pushm eax,ebx,esi,edi,ebp,ds,es,fs,gs
push ds
push es
push fs
push gs
push ebx
push esi
push edi
push ebp
push eax ; push last so is easily accessible for changing
mov ax,DpmiEmuDS
mov ds,ax
movzx eax,bl
mov edx,eax
mov ebx,eax
shl ebx,1 ;*2
mov eax,ebx
shl ebx,1 ;*4
add ebx,eax ;*6
add ebx,offset ExceptionTable
;
cmp dl,14 ;Special case for 14
; jnz @@Normal
je Special14 ; MED 01/17/96
cmp dl,20h
jc @@Normal
stc ; flag error
pop eax
mov ax,8021h ; flag invalid value
push eax
jmp @@GotVect ; don't get vector
Special14:
cmp w[OldExcep14+4],0 ;Virtual memory active?
jz @@Normal
;
;Vector 14 and VMM is installed.
;
mov edx,d[OldExcep14]
mov cx,w[OldExcep14+4]
jmp @@GotVect
@@Normal: ;
clc ; MED 01/17/96, flag no error
mov edx,[ebx] ;get offset.
mov cx,[ebx+4] ;get segment selector.
@@GotVect: ;
; popm eax,ebx,esi,edi,ebp,ds,es,fs,gs
pop eax
pop ebp
pop edi
pop esi
pop ebx
pop gs
pop fs
pop es
pop ds
ret
RawGetEVector endp
;-------------------------------------------------------------------------------
;
;Set protected mode interupt handler address.
;
;On Entry:-
;
;BL - Interupt vector number.
;CX:EDX - selector:offset of new handler.
;
;On Exit:-
;
;CF set on error.
;
RawSetVector proc near
call RAWCopyCheck
;
pushm eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
mov ax,DpmiEmuDS
mov ds,ax
test DpmiEmuSystemFlags,1
jz @@use32_add
movzx edx,dx
;
@@use32_add: ;Check if its a hardware interrupt.
;
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
movzx ebx,bl
mov al,[ebx+Int2CallCheck]
or al,al
jz @@NotHardware
;*** MED 11/30/95
cmp bl,23h ; always allow 23h callback
je med2
cmp bl,24h ; always allow 24h callback
je med2
test NoPassFlag,0ffh ; see if not passing hardware interrupts from real to protected mode
jne @@NotHardware
;
med2:
cmp cx,DpmiEmuCS ;restoreing previous vector?
jnz @@Setting
@@Restoreing: ;
pushad
movzx cx,bl
sub bl,al
movzx bx,bl
mov ax,size CallBackStruc
mul bx
mov bx,ax
add bx,offset CallBackTable
test CallBackFlags[bx],1 ;this one in use?
jz @@DoneHardware ;not likely.
pushf
cli
push es
mov ax,KernalZero
mov es,ax
mov CallBackFlags[bx],0 ;Mark this one as un-used.
push cx
mov cx,w[CallBackReal+2+bx] ;get origional real mode vector.
mov dx,w[CallBackReal+bx]
pop bx
shl bx,2
mov es:[bx],dx
mov es:[bx+2],cx
pop es
popf
jmp @@DoneHardware
@@Setting: ;
pushad
movzx cx,bl
sub bl,al
movzx bx,bl
mov ax,size CallBackStruc
mul bx
mov dx,bx
mov bx,ax
add bx,offset CallBackTable
test CallBackFlags[bx],1 ;this one in use?
jnz @@DoneHardware
pushf
cli
push es
mov ax,KernalZero
mov es,ax
mov CallBackNum[bx],cl ;set interupt number.
mov CallBackFlags[bx],1+2 ;mark call back as used interupt.
mov ax,CallBackSize
mul dx
mov si,offset ICallBackList
add si,ax ;index list of calls.
push bx
mov bx,cx
shl bx,2
mov dx,es:[bx]
mov cx,es:[bx+2]
mov es:[bx],si
mov es:w[bx+2],seg _cwRaw
pop bx
mov w[CallBackReal+2+bx],cx ;store origional real mode vector.
mov w[CallBackReal+bx],dx
pop es
popf
@@DoneHardware: popad
@@NotHardware: mov ax,DpmiEmuDS
mov ds,ax
assume ds:_cwDPMIEMU
movzx eax,bl
mov ebx,eax
shl ebx,1 ;*2
mov eax,ebx
shl ebx,1 ;*4
add ebx,eax ;*6
add ebx,offset InterruptTable
pushf
cli
mov [ebx],edx ;set offset.
mov [ebx+4],cx ;set segment selector.
popf
popm eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
ret
RawSetVector endp
;-------------------------------------------------------------------------------
;
;Set real mode interupt handler address.
;
;On Entry:-
;
;BL - Interupt vector number.
;CX:DX - selector:offset of new handler.
;
;On Exit:-
;
;CF set on error.
;
RawSetRVector proc near
call RAWCopyCheck
;
pushm eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
mov ax,KernalZero
mov es,ax
movzx ebx,bl
shl ebx,2
pushf
cli
mov es:[ebx],dx
mov es:[ebx+2],cx
popf
popm eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
ret
RawSetRVector endp
;-------------------------------------------------------------------------------
;
;Set protected mode exception handler address.
;
;On Entry:-
;
;BL - Exception vector number.
;CX:EDX - selector:offset of new handler.
;
;On Exit:-
;
;CF set on error.
;
RawSetEVector proc near
call RAWCopyCheck
;
; pushm eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
push ds
push es
push fs
push gs
push ebx
push ecx
push edx
push esi
push edi
push ebp
push eax ; push last so is easily accessible for changing
mov ax,DpmiEmuDS
mov ds,ax
movzx eax,bl
push eax
mov ebx,eax
shl ebx,1 ;*2
mov eax,ebx
shl ebx,1 ;*4
add ebx,eax ;*6
pop eax
add ebx,offset ExceptionTable
;
cmp al,14 ;Special case for 14
; jnz @@Normal
je Special14 ; MED 01/17/96
cmp al,20h
jc @@Normal
stc ; flag error
pop eax
mov ax,8021h ; flag invalid value
push eax
jmp @@GotVect ; don't set vector
Special14:
cmp w[OldExcep14+4],0 ;Virtual memory active?
jz @@Normal
;
;Vector 14 and VMM is still installed.
;
mov d[OldExcep14],edx
mov w[OldExcep14+4],cx
jmp @@GotVect
@@Normal: ;
clc ; MED 01/17/96, flag no error
mov [ebx],edx ;set offset.
mov [ebx+4],cx ;set segment selector.
@@GotVect: ;
; popm eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
pop eax
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
pop gs
pop fs
pop es
pop ds
ret
RawSetEVector endp
;-------------------------------------------------------------------------------
;
;Allocate a real mode call back address.
;
;On Entry:-
;
;DS:ESI - Protected mode code.
;ES:EDI - Real mode register structure.
;
;On Exit:-
;
;Carry set on error, else,
;
;CX:DX - Real mode address allocated.
;
RAWGetCallBack proc near
call RAWCopyCheck
;
pushm eax,ebx,esi,edi,ebp,ds,es
mov ax,ds
push ax
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
pop ax
;
;;MED 02/16/96
mov ebx,offset CallBackTable+((size CallBackStruc)*(16+3))
mov ecx,MaxCallBacks-(16+3)
mov edx,16+3
; mov ebx,offset CallBackTable+((size CallBackStruc)*(16+4))
; mov ecx,MaxCallBacks-(16+4)
; mov edx,16+4
@@0: test CallBackFlags[ebx],1 ;this one in use?
jz @@1
add ebx,size CallBackStruc
inc edx
dec ecx
jnz @@0
jmp @@9
;
@@1: pushad
xor eax,eax
mov cx,1
int 31h
mov w[CallBackStackSel+ebx],ax
popad
jc @@9
pushad
mov bx,w[CallBackStackSel+ebx]
mov eax,8
xor ecx,ecx
or edx,-1
int 31h
popad
;
mov w[CallBackProt+4+ebx],ax ;store protected mode code address.
mov d[CallBackProt+0+ebx],esi ;/
mov w[CallBackRegs+4+ebx],es ;store register table address.
mov d[CallBackRegs+0+ebx],edi ;/
mov ax,CallBackSize
mul dx
mov esi,offset CallBackList
movzx eax,ax
add esi,eax ;index list of calls.
mov CallBackOff[ebx],si ;store call back address.
mov CallBackFlags[ebx],1 ;flag this entry in use.
mov ax,_cwRaw
mov cx,ax ;get real mode code seg.
mov dx,si ;get real mode offset.
clc
jmp @@10
;
@@9: stc
@@10: popm eax,ebx,esi,edi,ebp,ds,es
ret
assume ds:_cwDPMIEMU
RAWGetCallBack endp
;-------------------------------------------------------------------------------
;
;Release a previously allocated real mode call back address.
;
;On Entry:-
;
;CX:DX - Real mode call back address.
;
RAWRelCallBack proc near
call RAWCopyCheck
;
pushad
pushm ds,es,fs,gs
push ax
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
pop ax
;
mov esi,offset CallBackTable
mov ebx,MaxCallBacks
@@0: test CallBackFlags[esi],1
jz @@1
cmp dx,CallBackOff[esi]
jnz @@1
mov CallBackFlags[esi],0
mov bx,CallBackStackSel[esi]
mov ax,1
int 31h
clc
jmp @@2
;
@@1: add esi,size CallBackStruc
dec ebx
jnz @@0
stc
;
@@2: popm ds,es,fs,gs
popad
ret
assume ds:_cwDPMIEMU
RAWRelCallBack endp
;-------------------------------------------------------------------------------
;
;Need to retrieve the interupt number.
;
IntHandler proc near
pushm ds,eax
mov ax,DpmiEmuDS ;make our data addresable.
mov ds,ax ;/
movzx esp,sp ;our stack never >64k.
mov eax,[esp+(4+4)] ;get return address.
sub eax,offset InterruptHandler
shr eax,3 ;convert it to an interrupt number.
mov ExceptionIndex,eax ;/
;
;Check if this is an exception or interrupt (any error code)
;
cmp esp,tPL0StackSize-4-((4+4)+(4)+(4)+(4+4+4)+(4+4))
; | | | | |
; EAX:DS --------------------/ | | | |
; | | | |
; Return address -----------------/ | | |
; | | |
; Error code -------------------------/ | |
; | |
; EIP:CS:Eflags ----------------------------/ |
; |
; ESP:SS ------------------------------------------/
;
jnz @@NoCode
and w[esp+(4+4)+(4)+(4)+(4+4)],0011111111010101b
; MED 12/02/95
; check if Exception Index is 0dh
; if so and instruction at CS:EIP is:
; mov eax,cr0 [0f 20 c0] or
; mov cr0,eax [0f 22 c0] or
; mov eax,cr3 [0f 20 d8] or
; mov cr3,eax [0f 22 d8]
; then emulate it here and return
; MED 11/12/98, emulate RDMSR [0f 32]
; MED 04/05/99, emulate WBINVD [0f 09]
; WRMSR [0f 30]
; mov eax,cr4 [0f 20 e0]
; mov cr4,eax [0f 22 e0]
push ds
cmp eax,0dh
jne mednoem ; not a GPF
mov ax,ss:[esp+(4+4)+(4)+(4+4)+4] ; ax==original CS
; verr ax ; check for looping lockup invalid value
; jnz mednoem
mov ds,ax
mov eax,ss:[esp+(4+4)+(4)+(4)+4] ; eax==original EIP
cmp BYTE PTR ds:[eax],0fh ; first opcode byte
jne mednoem ; no match
cmp WORD PTR ds:[eax+1],0c020h ; mov eax,cr0
jne med2
mov eax,cr0
mov ss:[esp+4],eax ; update original eax with cr0 value
jmp medemu
med2:
cmp WORD PTR ds:[eax+1],0c022h ; move cr0,eax
jne med3 ; no match
mov eax,ss:[esp+4] ; get original eax value
mov cr0,eax ; update cr0 value with original eax
jmp medemu
med3:
cmp WORD PTR ds:[eax+1],0d820h ; mov eax,cr3
jne med4
mov eax,cr3
mov ss:[esp+4],eax ; update original eax with cr3 value
jmp medemu
med4:
cmp WORD PTR ds:[eax+1],0d822h ; move cr3,eax
jne med5 ; no match
mov eax,ss:[esp+4] ; get original eax value
mov cr3,eax ; update cr3 value with original eax
jmp medemu
med5:
cmp WORD PTR ds:[eax+1],0e022h ; move cr4,eax
jne med6 ; no match
mov eax,ss:[esp+4] ; get original eax value
.586
mov cr4,eax ; update cr4 value with original eax
jmp medemu
med6:
cmp WORD PTR ds:[eax+1],0e020h ; mov eax,cr4
jne med7
.586
mov eax,cr4
mov ss:[esp+4],eax ; update original eax with cr4 value
jmp medemu
med7:
cmp BYTE PTR ds:[eax+1],9 ; WBINVD
jne med8
.586
wbinvd
mov eax,2
jmp medemu2
med8:
cmp BYTE PTR ds:[eax+1],30h ; WRMSR
jne med9
.586
wrmsr
mov eax,2
jmp medemu2
med9:
cmp BYTE PTR ds:[eax+1],32h ; RDMSR
jne mednoem
; push eax
.586
rdmsr
; DB 0fh ; RDMSR instruction
; DB 32h
; mov ss:[esp+8],eax ; update original eax value
; pop eax
mov ss:[esp+4],eax ; update original eax value
mov eax,2
jmp medemu2
medemu:
mov eax,3
medemu2:
add ss:[esp+(4+4)+(4)+(4)+4],eax ; adjust EIP past emulated instruction
pop ds
popm ds,eax ; restore original ds,eax
add esp,8 ; flush return address and error code off stack
iretd
mednoem:
pop ds
mov eax,[esp+(4+4)+(4)] ;get error code.
mov ExceptionCode,eax ;/
mov eax,[esp+(4+4)+(4)+(4)+(4+4)] ;Get flags.
or eax,65536
mov ExceptionFlags,eax ;Let dispatch know its an exception.
mov eax,cr2 ;Grab this now to save more PL
mov ExceptionCR2,eax ;switches for page faults.
popm ds,eax
add esp,4 ;skip error code.
jmp @@SortedCode2
@@NoCode: and w[esp+(4+4)+(4)+(4+4)],0011111111010101b
mov eax,[esp+(4+4)+(4)+(4+4)] ;Get flags.
and eax,not 65536
mov ExceptionFlags,eax
cmp ExceptionIndex,0
jz @@ForceException
cmp ExceptionIndex,1 ;int 1
jnz @@SortedCode
@@ForceException:
; or ExceptionFlags,65535 ;force an exception.
or ExceptionFlags,65536 ;force an exception.
@@SortedCode: popm ds,eax
@@SortedCode2: add esp,4 ;skip return address.
;
;Check which stack we should switch back to.
;
pushm ds,eax
cmp w[esp+(4+4)+(4+4+4)+(4)],KernalSS
jz KernalStack ;Already on system stack?
mov ax,DpmiEmuDS
mov ds,ax
test ExceptionFlags,65536 ;exception?
jnz KernalStack
;
push ebx
mov ebx,ExceptionIndex
mov ax,KernalDS ;make our data addresable.
mov ds,ax
assume ds:_cwRaw
cmp b[ebx+Int2CallCheck],0 ;Hardware INT?
pop ebx
assume ds:_cwDPMIEMU
jnz KernalStack
jmp IntStack
IntHandler endp
;-------------------------------------------------------------------------------
;
;It's a user stack and its not an exception or hardware interupt so switch back
;to the origional stack via a system stack to allow re-entrancy if origional
;stack needs to be fetched from disk.
;
IntStack proc near
popm ds,eax
;
;Get new stack address.
;
pushm eax,ebx,ds
mov ax,KernalDS ;make our data addresable.
mov ds,ax
assume ds:_cwRaw
mov ebx,RawStackPos ;get next stack address.
sub RawStackPos,RawStackDif
mov ax,KernalSS
mov ds,ax
assume ds:nothing
;
;Put old details onto new stack.
;
test cs:DpmiEmuSystemFlags,1
jz @@iUse32
mov eax,[esp+(4+4+4)+(4+4+4+4)]
sub ebx,2
mov [ebx],ax ;SS
mov eax,[esp+(4+4+4)+(4+4+4)]
sub ebx,2
mov [ebx],ax ;ESP
mov eax,[esp+(4+4+4)+(4+4)]
sub ebx,2
mov [ebx],ax ;EFlags
mov eax,[esp+(4+4+4)+(4)]
sub ebx,2
mov [ebx],ax ;CS
mov eax,[esp+(4+4+4)+(0)]
sub ebx,2
mov [ebx],ax ;EIP
jmp @@iUse0
;
@@iUse32: mov eax,[esp+(4+4+4)+(4+4+4+4)]
sub ebx,4
mov [ebx],eax ;SS
mov eax,[esp+(4+4+4)+(4+4+4)]
sub ebx,4
mov [ebx],eax ;ESP
mov eax,[esp+(4+4+4)+(4+4)]
sub ebx,4
mov [ebx],eax ;EFlags
mov eax,[esp+(4+4+4)+(4)]
sub ebx,4
mov [ebx],eax ;CS
mov eax,[esp+(4+4+4)+(0)]
sub ebx,4
mov [ebx],eax ;EIP
;
@@iUse0: ;Put new details into current stack.
;
mov eax,offset @@Int
mov [esp+(4+4+4)+(0)],eax ;EIP
xor eax,eax
mov ax,DpmiEmuCS
mov [esp+(4+4+4)+(4)],eax ;CS
pushfd
pop eax
mov [esp+(4+4+4)+(4+4)],eax ;EFlags
mov [esp+(4+4+4)+(4+4+4)],ebx ;ESP
xor eax,eax
mov ax,KernalSS
mov [esp+(4+4+4)+(4+4+4+4)],eax ;SS
popm eax,ebx,ds
assume ds:_cwDPMIEMU
iretd
;
@@Int: ;Now switch back to origional stack.
;
assume ds:nothing
push cs:ExceptionIndex ;need to know the INT number.
pushm eax,ebx,esi,ds
test cs:DpmiEmuSystemFlags,1
jz @@i2Use32
xor ebx,ebx
mov ax,ss
mov ds,ax
mov bx,sp
lss sp,[ebx+(4+4+4+4+4)+(2+2+2)] ;get origional stack again.
mov ax,[ebx+(4+4+4+4+4)+(2+2)] ;get flags.
push ax
mov ax,[ebx+(4+4+4+4+4)+(2)] ;get CS
push ax
mov ax,[ebx+(4+4+4+4+4)+(0)] ;get IP
push ax
xor eax,eax
mov ax,[ebx+(4+4+4+4+4)+(2+2)] ;get flags again.
and ax,1111110011111111b ;lose IF & TF
push eax ;int handler flags.
jmp @@i2Use0
;
@@i2Use32: mov ax,ss
mov ds,ax
mov ebx,esp
lss esp,[ebx+(4+4+4+4+4)+(4+4+4)] ;get origional stack again.
mov eax,[ebx+(4+4+4+4+4)+(4+4)] ;get flags.
push eax
mov eax,[ebx+(4+4+4+4+4)+(4)] ;get CS
push eax
mov eax,[ebx+(4+4+4+4+4)+(0)] ;get IP
push eax
mov eax,[ebx+(4+4+4+4+4)+(4+4)] ;get flags again.
and ax,1111110011111111b ;lose IF & TF
push eax ;int handler flags.
;
@@i2Use0: mov eax,[ebx+(4+4+4+4)] ;get INT index.
shl eax,1
mov esi,eax
shl eax,1
add esi,eax ;*6 for index into table.
add esi,offset InterruptTable
xor eax,eax
mov ax,cs:[esi+4] ;get int handler CS
push eax
mov eax,cs:[esi] ;get INT handler EIP.
push eax
mov eax,[ebx+(4+4+4)] ;EAX
push eax
mov eax,[ebx+(4+4)] ;EBX
push eax
mov eax,[ebx+(4)] ;ESI
push eax
mov eax,[ebx+(0)] ;DS
push eax
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
add RawStackPos,RawStackDif
assume ds:_cwDPMIEMU
popm eax,ebx,esi,ds
iretd ;pass control to INT handler.
IntStack endp
;-------------------------------------------------------------------------------
;
;Either we were already on the system stack or we have an exception or hardware
;interupt on our hands. Either way we need to switch to another piece of the
;system stack to make sure we're using a legitimate one.
;
KernalStack proc near
popm ds,eax
;
;Get new stack address.
;
pushm eax,ebx,ds
mov ax,KernalDS ;make our data addresable.
mov ds,ax
assume ds:_cwRaw
mov ebx,RawStackPos ;get next stack address.
sub RawStackPos,RawStackDif
mov ax,KernalSS
mov ds,ax
assume ds:nothing
;
@@Update: ;Put old details onto new stack.
;
test cs:DpmiEmuSystemFlags,1
jz @@Use32
mov eax,[esp+(4+4+4)+(4+4+4+4)]
sub ebx,2
mov [ebx],ax ;SS
mov eax,[esp+(4+4+4)+(4+4+4)]
sub ebx,2
mov [ebx],ax ;ESP
mov eax,[esp+(4+4+4)+(4+4)]
sub ebx,2
mov [ebx],ax ;EFlags
mov eax,[esp+(4+4+4)+(4)]
sub ebx,2
mov [ebx],ax ;CS
mov eax,[esp+(4+4+4)+(0)]
sub ebx,2
mov [ebx],ax ;EIP
jmp @@Use0
;
@@Use32: mov eax,[esp+(4+4+4)+(4+4+4+4)]
sub ebx,4
mov [ebx],eax ;SS
mov eax,[esp+(4+4+4)+(4+4+4)]
sub ebx,4
mov [ebx],eax ;ESP
mov eax,[esp+(4+4+4)+(4+4)]
sub ebx,4
mov [ebx],eax ;EFlags
mov eax,[esp+(4+4+4)+(4)]
sub ebx,4
mov [ebx],eax ;CS
mov eax,[esp+(4+4+4)+(0)]
sub ebx,4
mov [ebx],eax ;EIP
;
@@Use0: ;Put new details into current stack.
;
mov eax,offset IntDispatch
mov [esp+(4+4+4)+(0)],eax ;EIP
xor eax,eax
mov ax,DpmiEmuCS
mov [esp+(4+4+4)+(4)],eax ;CS
pushfd
pop eax
mov [esp+(4+4+4)+(4+4)],eax ;EFlags
mov [esp+(4+4+4)+(4+4+4)],ebx ;ESP
xor eax,eax
mov ax,KernalSS
mov [esp+(4+4+4)+(4+4+4+4)],eax ;SS
popm eax,ebx,ds
assume ds:_cwDPMIEMU
;
;Pass control to interupt dispatcher.
;
iretd
KernalStack endp
;-------------------------------------------------------------------------------
;
;Direct control to exception or interupt handler.
;
IntDispatch proc near
pushm eax,esi,edi,ds
mov ax,DpmiEmuDS
mov ds,ax
and w[ExceptionFlags],1111110011111111b
mov esi,ExceptionIndex ;Get the exception number.
add esi,esi ;*2
mov eax,esi
add esi,esi ;*4
add esi,eax ;*6
test ExceptionFlags,65536
jnz @@Excep
;
;Dispatch normal interrupt.
;
add esi,offset InterruptTable
test DpmiEmuSystemFlags,1
jz @@Use32Bit14
mov eax,[esi]
mov d[@@Call2],eax
mov ax,[esi+4]
mov w[@@Call2+4],ax
mov eax,offset @@Resume
mov w[@@Call20],ax
mov w[@@Call20+2],cs
popm eax,esi,edi,ds
assume ds:nothing
push cs:w[ExceptionFlags] ;EFlags before entry.
push cs:w[@@Call20+2] ;CS
push cs:w[@@Call20] ;EIP
jmp cs:f[@@Call2]
assume ds:_cwDPMIEMU
;
@@Use32Bit14: mov eax,[esi]
mov d[@@Call2],eax
mov ax,[esi+4]
mov w[@@Call2+4],ax
mov d[@@Call20],offset @@Resume
mov w[@@Call20+4],cs
popm eax,esi,edi,ds
assume ds:nothing
push cs:d[ExceptionFlags] ;EFlags before entry.
push cs:d[@@Call20+4] ;CS
push cs:d[@@Call20] ;EIP
jmp cs:f[@@Call2]
assume ds:_cwDPMIEMU
;
;; MED 08/13/96
; nop ; make debugger EIP adjustment from debug int benign?
@@Resume: ;Return from normal int.
;
pushfd
cli ;stop interupts interfering.
pushm eax,ebx,ds
mov ax,ss
mov ds,ax
mov ebx,esp
assume ds:nothing
test cs:DpmiEmuSystemFlags,1
assume ds:_cwDPMIEMU
jz @@Use32
;
movzx ebx,bx
lss sp,d[ebx+(4+4+4+4)+(2+2+2)] ;get old stack address.
and w[ebx+(4+4+4+4)+(2+2)],0000011100000000b ;retain IF & TF.
and w[ebx+(4+4+4)],1111100011111111b ;lose IF & TF.
mov ax,[ebx+(4+4+4)]
or ax,[ebx+(4+4+4+4)+(2+2)]
push ax ;EFlags.
mov ax,[ebx+(4+4+4+4)+(2)]
push ax ;CS
mov ax,[ebx+(4+4+4+4)+(0)]
push ax ;EIP
mov eax,[ebx+(4+4)]
push eax ;EAX
mov eax,[ebx+(4)]
push eax ;EBX
mov eax,[ebx+(0)]
push eax ;DS
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
add RawStackPos,RawStackDif ;update next stack.
assume ds:_cwDPMIEMU
popm eax,ebx,ds
db 66h
iret
;
@@Use32: lss esp,f[ebx+(4+4+4+4)+(4+4+4)] ;get old stack address.
and w[ebx+(4+4+4+4)+(4+4)],0000011100000000b ;retain IF & TF.
and w[ebx+(4+4+4)],1111100011111111b ;lose IF & TF.
mov eax,[ebx+(4+4+4)]
or eax,[ebx+(4+4+4+4)+(4+4)]
push eax ;EFlags.
mov eax,[ebx+(4+4+4+4)+(4)]
push eax ;CS
mov eax,[ebx+(4+4+4+4)+(0)]
push eax ;EIP
mov eax,[ebx+(4+4)]
push eax ;EAX
mov eax,[ebx+(4)]
push eax ;EBX
mov eax,[ebx+(0)]
push eax ;DS
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
add RawStackPos,RawStackDif ;update next stack.
assume ds:_cwDPMIEMU
popm eax,ebx,ds
iretd
;
@@Excep: ;Dispatch exception.
;
add esi,offset ExceptionTable
test DpmiEmuSystemFlags,1
jz @@eUse32Bit14
mov eax,[esi]
mov d[@@Call2],eax
mov ax,[esi+4]
mov w[@@Call2+4],ax
mov eax,offset @@ResumeExp
mov w[@@Call20],ax
mov w[@@Call20+2],cs
popm eax,esi,edi,ds
assume ds:nothing
push cs:w[ExceptionCode] ;EFlags before entry.
push cs:w[@@Call20+2] ;CS
push cs:w[@@Call20] ;EIP
jmp cs:f[@@Call2]
assume ds:_cwDPMIEMU
;
@@eUse32Bit14: mov eax,[esi]
mov d[@@Call2],eax
mov ax,[esi+4]
mov w[@@Call2+4],ax
mov d[@@Call20],offset @@ResumeExp
mov w[@@Call20+4],cs
popm eax,esi,edi,ds
assume ds:nothing
push cs:d[ExceptionCode] ;EFlags before entry.
push cs:d[@@Call20+4] ;CS
push cs:d[@@Call20] ;EIP
jmp cs:f[@@Call2]
assume ds:_cwDPMIEMU
;
@@ResumeExp: ;Return from exception.
;
cli
assume ds:nothing
test cs:DpmiEmuSystemFlags,1
assume ds:_cwDPMIEMU
jz @@ExpUse32
;
add sp,2
pushfd
pushm eax,ebx,ds
mov ax,ss
mov ds,ax
mov ebx,esp
movzx ebx,bx
lss sp,d[ebx+(4+4+4+4)+(2+2+2)] ;get old stack address.
mov ax,[ebx+(4+4+4+4)+(2+2)]
push ax ;EFlags.
mov ax,[ebx+(4+4+4+4)+(2)]
push ax ;CS
mov ax,[ebx+(4+4+4+4)+(0)]
push ax ;EIP
mov eax,[ebx+(4+4)]
push eax ;EAX
mov eax,[ebx+(4)]
push eax ;EBX
mov eax,[ebx+(0)]
push eax ;DS
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
add RawStackPos,RawStackDif ;update next stack.
assume ds:_cwDPMIEMU
popm eax,ebx,ds
db 66h
iret
;
@@ExpUse32: add esp,4
pushfd
pushm eax,ebx,ds
mov ax,ss
mov ds,ax
mov ebx,esp
lss esp,f[ebx+(4+4+4+4)+(4+4+4)] ;get old stack address.
mov eax,[ebx+(4+4+4+4)+(4+4)]
push eax ;EFlags.
mov eax,[ebx+(4+4+4+4)+(4)]
push eax ;CS
mov eax,[ebx+(4+4+4+4)+(0)]
push eax ;EIP
mov eax,[ebx+(4+4)]
push eax ;EAX
mov eax,[ebx+(4)]
push eax ;EBX
mov eax,[ebx+(0)]
push eax ;DS
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
add RawStackPos,RawStackDif ;update next stack.
assume ds:_cwDPMIEMU
popm eax,ebx,ds
iretd
;
@@Call2 df 0,0
@@Call20 df 0,0
IntDispatch endp
;-------------------------------------------------------------------------------
;
;Handle an INT nn instruction by retrieving registers from the stack and
;reflect to real mode.
;
IntNN386 proc far
sub esp,4+4
pushm ds,es,fs,gs
sub esp,10*2
pushad
;
mov ax,DpmiEmuDS ;make our data addresable.
mov ds,ax ;/
mov ebp,esp
test DpmiEmuSystemFlags,1
jz @@Use32Bit19
movzx ebp,bp
movzx eax,w[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4+4)+(2+2)]
jmp @@Use16Bit19
@@Use32Bit19: mov eax,[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4+4)+(4+4)]
@@Use16Bit19: mov [ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)],eax
mov edx,[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4)]
sub edx,offset IntNN386Catch
shr edx,3
mov d[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4)],0
;
mov edi,ebp
push ss
pop es
;
;If this is a "hardware" interrupt we should mark it as
;busy if it isn't already marked.
;
mov ebx,edx
push ds
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
mov al,[ebx+Int2CallCheck]
or al,al ;Hardware?
jz @@c2
sub bl,al
shl ebx,3 ;*8
mov eax,ebx
shl ebx,1 ;*16
add ebx,eax ;*24
add ebx,offset CallBackTable
test CallBackFlags[ebx],1
jz @@c2
test CallBackFlags[ebx],128 ;already busy?
jnz @@c2
or CallBackFlags[ebx],128 ;mark it as busy.
mov d[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4)],ebx
assume ds:_cwDPMIEMU
@@c2: pop ds
;
;Now pass control to the INT simulator.
;
mov eax,[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)]
and eax,1111100011111111b
push eax
popfd
mov ebx,edx
mov es:Real_SP[edi],0
mov es:Real_SS[edi],0
call EmuRAWSimulateINT
;
cmp d[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4)],0
jz @@NoCall
push ds
mov esi,d[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4)]
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
and CallBackFlags[esi],255-128
assume ds:_cwDPMIEMU
pop ds
@@NoCall: ;
;Update the flags.
;
mov ax,es:Real_Flags[edi]
and ax,1000100011111111b ;lose IF.
;
test DpmiEmuSystemFlags,1
jz @@Use32Bit
mov bx,[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4+4)+(2+2)]
and bx,0111011100000000b ;retain IF.
or ax,bx
mov [ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4+4)+(2+2)],ax
popad
add sp,10*2
popm ds,es,fs,gs
add sp,4+4+4
db 66h
iret ;Switch back to calling program.
;
@@Use32Bit: mov bx,[ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4+4)+(4+4)]
and bx,0111011100000000b ;retain IF.
or ax,bx
mov [ebp+(4+4+4+4+4+4+4+4)+(10*2)+(4+4+4+4)+(4+4+4)+(4+4)],ax
popad
add esp,10*2
popm ds,es,fs,gs
add esp,4+4+4
iretd ;Switch back to calling program.
IntNN386 endp
;-------------------------------------------------------------------------------
;
;An unhandled low level exception has occured so terminate the program.
;
ExcepNN386 proc far
pushm eax,ds
mov ax,DpmiEmuDS
mov ds,ax
mov eax,[esp+(4+4)]
sub eax,offset ExcepNN386Catch
shr eax,3
mov ExceptionIndex,eax
popm eax,ds
add esp,4 ;skip return address
;
pushm ds,es,fs,gs
pushm eax,ebx,ecx,edx,esi,edi,ebp ;save general registers.
mov ax,DpmiEmuDS ;make our data addresable.
mov ds,ax ;/
test DpmiEmuSystemFlags,1
jz @@Use32Bit16
movzx eax,w[esp+(4+4+4+4)+(4+4+4+4+4+4+4)+(2+2)]
mov ExceptionEFL,eax
jmp @@Use16Bit16
@@Use32Bit16: mov eax,[esp+(4+4+4+4)+(4+4+4+4+4+4+4)+(4+4)]
mov ExceptionEFL,eax
;
@@Use16Bit16: ;Retrieve register values and get outa here.
;
mov ax,DpmiEmuDS ;make sure our data is addresable.
mov es,ax ;/
assume es:_cwDPMIEMU
mov ax,ss
mov ds,ax
assume ds:nothing
mov esi,esp
mov edi,offset ExceptionEBP
mov ecx,(4+4+4+4+4+4+4)+(4+4+4+4)
cld
db 67h
rep movsb ;copy registers off the stack.
;
test cs:DpmiEmuSystemFlags,1
jz @@Use32Bit17
add esi,2+2+2 ;skip return address/flags.
db 67h
movsw
add edi,2
db 67h
movsw
add edi,2
db 67h
movsw
add edi,2
jmp @@Use16Bit17
@@Use32Bit17: add esi,4+4+4 ;skip return address/flags.
mov ecx,4+4+4
cld
db 67h
rep movsb ;get real return address.
@@Use16Bit17: ;
test cs:DpmiEmuSystemFlags,1
jz @@Use32Bit678
movzx eax,w[esi]
mov es:ExceptionESP,eax
mov ax,[esi+2]
mov es:ExceptionSS,ax
jmp @@Use16Bit678
;
@@Use32Bit678: mov eax,[esi]
mov es:ExceptionESP,eax
mov ax,[esi+4]
mov es:ExceptionSS,ax
@@Use16Bit678: ;
push es
pop ds
assume es:nothing
assume ds:_cwDPMIEMU
;
;Now switch to PL0 to get CR0-3 values.
;
call EmuRawPL32PL0
str ax ;get TR
mov ExceptionTR,ax
mov eax,cr0
mov ExceptionCR0,eax
mov eax,cr2
mov ExceptionCR2,eax
mov eax,cr3
mov ExceptionCR3,eax
mov cx,MainSS
mov edx,offset _cwStackEnd-256
call EmuRawPL02PL3
;
;Convert register values into ASCII ready for printing.
;
mov eax,ExceptionIndex
mov ecx,2
mov edi,offset ExceptionINum
call Bin2HexE
mov eax,ExceptionCode ;high word undefined upto 486.
mov ecx,4
mov edi,offset ExceptionENum
call Bin2HexE
;
movzx eax,ExceptionTR
mov ecx,4
mov edi,offset ExceptionTRt
call Bin2HexE
mov eax,ExceptionCR0
mov ecx,8
mov edi,offset ExceptionCR0t
call Bin2HexE
mov eax,ExceptionCR2
mov ecx,8
mov edi,offset ExceptionCR2t
call Bin2HexE
mov eax,ExceptionCR3
mov ecx,8
mov edi,offset ExceptionCR3t
call Bin2HexE
;
mov eax,ExceptionEAX
mov ecx,8
mov edi,offset ExceptionEAXt
call Bin2HexE
mov eax,ExceptionEBX
mov ecx,8
mov edi,offset ExceptionEBXt
call Bin2HexE
mov eax,ExceptionECX
mov ecx,8
mov edi,offset ExceptionECXt
call Bin2HexE
mov eax,ExceptionEDX
mov ecx,8
mov edi,offset ExceptionEDXt
call Bin2HexE
mov eax,ExceptionESI
mov ecx,8
mov edi,offset ExceptionESIt
call Bin2HexE
mov eax,ExceptionEDI
mov ecx,8
mov edi,offset ExceptionEDIt
call Bin2HexE
mov eax,ExceptionEBP
mov ecx,8
mov edi,offset ExceptionEBPt
call Bin2HexE
mov eax,ExceptionESP
mov ecx,8
mov edi,offset ExceptionESPt
call Bin2HexE
mov eax,ExceptionEIP
mov ecx,8
mov edi,offset ExceptionEIPt
call Bin2HexE
mov eax,ExceptionEFL
mov ecx,8
mov edi,offset ExceptionEFLt
call Bin2HexE
;
movzx eax,ExceptionCS
mov ecx,4
mov edi,offset ExceptionCSt
call Bin2HexE
movzx eax,ExceptionDS
mov ecx,4
mov edi,offset ExceptionDSt
call Bin2HexE
movzx eax,ExceptionES
mov ecx,4
mov edi,offset ExceptionESt
call Bin2HexE
movzx eax,ExceptionFS
mov ecx,4
mov edi,offset ExceptionFSt
call Bin2HexE
movzx eax,ExceptionGS
mov ecx,4
mov edi,offset ExceptionGSt
call Bin2HexE
movzx eax,ExceptionSS
mov ecx,4
mov edi,offset ExceptionSSt
call Bin2HexE
mov edi,offset ExceptionSysFlags
mov eax,DpmiEmuSystemFlags
mov ecx,8
call Bin2HexE
;
;Copy register details into the transfer buffer.
;
push ds
mov ax,MainDS
mov ds,ax
assume ds:_cwMain
movzx edi,TransferReal
assume ds:_cwDPMIEMU
pop ds
shl edi,4
mov esi,offset ExceptionHeader
mov ecx,offset ExceptionHeaderEnd-ExceptionHeader
mov ax,KernalZero
mov es,ax
rep movsb
push ds
pop es
;
;Print the message.
;
push ds
mov ax,MainDS
mov ds,ax
assume ds:_cwMain
mov ax,TransferReal
assume ds:_cwDPMIEMU
pop ds
mov edi,offset ExceptionIntBuffer
mov Real_DS[edi],ax
mov Real_EDX[edi],0
mov Real_EAX[edi],0900h
mov Real_SP[edi],0
mov Real_SS[edi],0
mov bl,21h
call EmuRawSimulateINT
;
;Now switch back to exit code.
;
mov ax,InitDS
mov ds,ax
assume ds:_cwInit
mov IErrorNumber,0
mov ax,InitCS
push ax
mov ax,offset InitError
push ax
db 66h
retf
assume ds:_cwDPMIEMU
ExcepNN386 endp
;
DpmiEmuSystemFlags dd 0
;
; do NOT change order of these variables (you can add at the end), MED 01/08/96
ExceptionCode dd 0
ExceptionFlags dd 0
ExceptionIndex dd 0
;
ExceptionEBP dd ?
ExceptionEDI dd ?
ExceptionESI dd ?
ExceptionEDX dd ?
ExceptionECX dd ?
ExceptionEBX dd ?
ExceptionEAX dd ?
ExceptionGS dw ?,?
ExceptionFS dw ?,?
ExceptionES dw ?,?
ExceptionDS dw ?,?
ExceptionEIP dd ?
ExceptionCS dw ?,?
ExceptionEFL dd ?
ExceptionESP dd ?
ExceptionSS dw ?,?
ExceptionTR dw ?
ExceptionCR0 dd ?
ExceptionCR2 dd ?
ExceptionCR3 dd ?
;
ExceptionHeader label byte
db 13,10,"CauseWay Error 09 : Unrecoverable internal exception, program terminated.",13,10
db 13,10,'Exception: '
ExceptionINum db '00, Error code: '
ExceptionENum db '0000',13,10,13,10
db 'EAX='
ExceptionEAXt db '00000000 '
db 'EBX='
ExceptionEBXt db '00000000 '
db 'ECX='
ExceptionECXt db '00000000 '
db 'EDX='
ExceptionEDXt db '00000000 '
db 'ESI='
ExceptionESIt db '00000000 '
db 13,10
db 'EDI='
ExceptionEDIt db '00000000 '
db 'EBP='
ExceptionEBPt db '00000000 '
db 'ESP='
ExceptionESPt db '00000000 '
db 'EIP='
ExceptionEIPt db '00000000 '
db 'EFL='
ExceptionEFLt db '00000000 '
db 13,10,13,10
db 'CS='
ExceptionCSt db '0000 '
db 'DS='
ExceptionDSt db '0000 '
db 'ES='
ExceptionESt db '0000 '
db 'FS='
ExceptionFSt db '0000 '
db 'GS='
ExceptionGSt db '0000 '
db 'SS='
ExceptionSSt db '0000 '
db 13,10,13,10
db 'CR0='
ExceptionCR0t db '00000000 '
db 'CR2='
ExceptionCR2t db '00000000 '
db 'CR3='
ExceptionCR3t db '00000000 '
db 'TR='
ExceptionTRt db '0000'
db 13,10,13,10
db 'SystemFlags='
ExceptionSysFlags db '00000000 '
db 13,10,13,10,'$'
ExceptionHeaderEnd label byte
;
ExceptionIntBuffer db size RealRegsStruc dup (?)
;