-
Notifications
You must be signed in to change notification settings - Fork 1
/
V86INT.ASM
159 lines (126 loc) · 3.67 KB
/
V86INT.ASM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
page ,132
title V86INT.ASM
;
; V86INT.ASM
; V86-mode interrupt support
;
; by Jeff Parsons 05-Jun-1992
; with a little help from Intel's 386 Programmer's Reference Manual :)
;
include all.inc
OPEN_CODE
extrn Debugger:near ; in 386trap.asm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EmulateINT
;
; ENTRY
; EBX -> megabyte alias (eg, pmbZero)
; ESI -> current instruction
; EBP -> ESF with valid v86* fields
; Interrupts disabled (so don't dink around!)
;
; EXIT
; Nothing in particular
;
; USES
; Anything it pleases
;
assume cs:CODE_SEG,ds:DATA_SEG,es:DATA_SEG,ss:DATA_SEG
public EmulateINT
EmulateINT proc near
movzx edi,byte ptr [ebx+esi+1]; EDI == nn byte of the INT nn
push DEBUG_VINT
call Debugger
test [_flTrace],TRACE_REEXEC
jnz short EmExit
add word ptr [ebp].esf_EIP,2; advance instruction pointer now
;
; BUGBUG: Until I implement support for VM stubs and VM breakpoints,
; I have to have these hacks to fake out certain calls. Other than
; being slow and ugly, this code also suffers from being incompatible,
; because the v86-mode hook chain, if any, doesn't get a chance to run.
;
; Hack #1: INT 15h, function AH=88h (Read Extended Memory Size) needs to
; return 0 so that no one will try switching to protected-mode to access
; it.
;
cmp edi,INT_SYSSERV ; INT 15h? (System Services)
jne short SimulateINT ; nope
cmp byte ptr [ebp].esf_EAX+1,INT15AH_EXTMEM
jne short SimulateINT ;
mov word ptr [ebp].esf_EAX,0; return 0Kb extended memory size
EmExit:
ret ; fake emulation complete!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EmulateINT3
;
; ENTRY
; EBX -> megabyte alias (eg, pmbZero)
; ESI -> current instruction
; EBP -> ESF with valid v86* fields
; Interrupts disabled (so don't dink around!)
;
; EXIT
; Nothing in particular
;
; USES
; Anything it pleases
;
assume cs:CODE_SEG,ds:DATA_SEG,es:DATA_SEG,ss:DATA_SEG
public EmulateINT3
EmulateINT3 label near
push DEBUG_VINT3
call Debugger
test [_flTrace],TRACE_REEXEC
jnz short EmExit
mov edi,3 ; EDI == interrupt #
inc word ptr [ebp].esf_EIP ; advance instruction pointer now
; Fall into SimulateINT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SimulateINT
;
; ENTRY
; EBX -> megabyte alias (eg, pmbZero)
; EDI == IVT interrupt #
; EBP -> ESF with valid v86* fields
; Interrupts disabled (so don't dink around!)
;
public SimulateINT
SimulateINT label near
mov eax,[ebp].esf_v86ESP ;
sub ax,size VIRF ; check for stack wrap
jb short intem_wrap ; yup, it's going to wrap; what a pain
intem_cont:
mov [ebp].esf_v86ESP,eax ; update VM's SP
movzx esi,word ptr [ebp].esf_v86SS
shl esi,4 ;
add esi,eax ; ESI -> place to put VIRF
mov eax,[ebp].esf_EIP ; create VIRF now
mov [ebx+esi].virf_IP,ax ;
mov eax,[ebp].esf_CS ;
mov [ebx+esi].virf_CS,ax ;
mov eax,[ebp].esf_Flags ;
mov [ebx+esi].virf_Flags,ax ; VIRF creation complete
IFDEF DEBUG
and eax,NOT (FLAGS_IF)
cmp [ebp].esf_iTrap,IDT_MASTER_BASE
jb short @F
and eax,NOT (FLAGS_TF) ; on h/w int simulation, clear TF too
@@:
ELSE
and eax,NOT (FLAGS_IF or FLAGS_TF)
ENDIF
mov [ebp].esf_Flags,eax ;
mov eax,[ebx+edi*4] ; EAX == IVT vector address
mov word ptr [ebp].esf_EIP,ax
ror eax,16 ;
mov word ptr [ebp].esf_CS,ax; CS:IP updated
ret ; return to GPFault in 386trap.asm
intem_wrap:
cmp ax,-(size VIRF) ; determine if initial SP was zero
je intem_cont ; yes, it was
int 3 ; BUGBUG
jmp intem_cont ;
EmulateINT endp
CLOSE_CODE
end