Subversion Repositories Kolibri OS

Rev

Rev 5356 | Rev 6333 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5356 Rev 5363
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2007-2012. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2007-2015. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 5356 $
8
$Revision: 5363 $
9
 
9
 
10
; Virtual-8086 mode manager
10
; Virtual-8086 mode manager
11
; diamond, 2007, 2008
11
; diamond, 2007, 2008
12
 
12
 
13
DEBUG_SHOW_IO = 0
13
DEBUG_SHOW_IO = 0
14
 
14
 
15
struct  V86_machine
15
struct  V86_machine
16
; page directory
16
; page directory
17
        process         dd ?
17
        process         dd ?
18
; mutex to protect all data from writing by multiple threads at one time
18
; mutex to protect all data from writing by multiple threads at one time
19
        mutex           dd ?
19
        mutex           dd ?
20
; i/o permission map
20
; i/o permission map
21
        iopm            dd ?
21
        iopm            dd ?
22
ends
22
ends
23
 
23
 
24
; Create V86 machine
24
; Create V86 machine
25
; in: nothing
25
; in: nothing
26
; out: eax = handle (pointer to struc V86_machine)
26
; out: eax = handle (pointer to struc V86_machine)
27
;      eax = NULL => failure
27
;      eax = NULL => failure
28
; destroys: ebx, ecx, edx (due to malloc)
28
; destroys: ebx, ecx, edx (due to malloc)
29
v86_create:
29
v86_create:
30
; allocate V86_machine structure
30
; allocate V86_machine structure
31
        mov     eax, sizeof.V86_machine
31
        mov     eax, sizeof.V86_machine
32
        call    malloc
32
        call    malloc
33
        test    eax, eax
33
        test    eax, eax
34
        jz      .fail
34
        jz      .fail
35
; initialize mutex
35
; initialize mutex
36
        and     dword [eax+V86_machine.mutex], 0
36
        and     dword [eax+V86_machine.mutex], 0
37
; allocate tables
37
; allocate tables
38
        mov     ebx, eax
38
        mov     ebx, eax
39
 
39
 
40
        stdcall create_process, 4096, eax, 4096       ;FIXME
40
        stdcall create_process, 4096, eax, 4096       ;FIXME
41
        test    eax, eax
41
        test    eax, eax
42
        jz      .fail2
42
        jz      .fail2
43
 
43
 
44
        mov     [eax+PROC.mem_used], 4096
44
        mov     [eax+PROC.mem_used], 4096
45
        mov     [ebx+V86_machine.process], eax
45
        mov     [ebx+V86_machine.process], eax
46
 
46
 
47
        push    2000h
47
        push    2000h
48
        call    kernel_alloc
48
        call    kernel_alloc
49
        test    eax, eax
49
        test    eax, eax
50
        jz      .fail2
50
        jz      .fail2
51
 
51
 
52
        mov     [ebx+V86_machine.iopm], eax
52
        mov     [ebx+V86_machine.iopm], eax
53
 
53
 
54
 
54
 
55
; initialize tables
55
; initialize tables
56
        push    edi
56
        push    edi
57
        mov     edi, eax
57
        mov     edi, eax
58
        mov     eax, -1
58
        mov     eax, -1
59
        mov     ecx, 2000h/4
59
        mov     ecx, 2000h/4
60
        rep stosd
60
        rep stosd
61
 
61
 
62
        mov     eax, [ebx+V86_machine.process]
62
        mov     eax, [ebx+V86_machine.process]
63
        mov     eax, [eax+PROC.pdt_0_phys]
63
        mov     eax, [eax+PROC.pdt_0_phys]
64
 
64
 
65
        pushfd
65
        pushfd
66
        cli
66
        cli
67
        mov     cr3, eax
67
        mov     cr3, eax
68
 
68
 
69
 
69
 
70
; now V86 specific: initialize known addresses in first Mb
70
; now V86 specific: initialize known addresses in first Mb
71
 
71
 
72
; first page - BIOS data (shared between all machines!)
72
; first page - BIOS data (shared between all machines!)
73
; physical address = 0
73
; physical address = 0
74
; linear address = OS_BASE
74
; linear address = OS_BASE
75
; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!)
75
; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!)
76
; physical address = 0x9C000
76
; physical address = 0x9C000
77
; linear address = 0x8009C000
77
; linear address = 0x8009C000
78
; (I have seen one computer with EBDA segment = 0x9D80,
78
; (I have seen one computer with EBDA segment = 0x9D80,
79
; all other computers use less memory)
79
; all other computers use less memory)
80
 
80
 
81
        mov     eax, PG_UWR
81
        mov     eax, PG_UWR
82
        mov     [page_tabs], eax
82
        mov     [page_tabs], eax
83
        invlpg  [eax]
83
        invlpg  [eax]
84
 
84
 
85
        mov     byte [0x500], 0xCD
85
        mov     byte [0x500], 0xCD
86
        mov     byte [0x501], 0x13
86
        mov     byte [0x501], 0x13
87
        mov     byte [0x502], 0xF4
87
        mov     byte [0x502], 0xF4
88
        mov     byte [0x503], 0xCD
88
        mov     byte [0x503], 0xCD
89
        mov     byte [0x504], 0x10
89
        mov     byte [0x504], 0x10
90
        mov     byte [0x505], 0xF4
90
        mov     byte [0x505], 0xF4
91
 
91
 
92
        mov     eax, 0x99000+PG_UWR
92
        mov     eax, 0x99000+PG_UWR
93
        mov     edi, page_tabs+0x99*4
93
        mov     edi, page_tabs+0x99*4
94
        mov     edx, 0x1000
94
        mov     edx, 0x1000
95
        mov     ecx, 7
95
        mov     ecx, 7
96
@@:
96
@@:
97
        stosd
97
        stosd
98
        add     eax, edx
98
        add     eax, edx
99
        loop    @b
99
        loop    @b
100
 
100
 
101
; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!)
101
; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!)
102
; physical address = 0xC0000
102
; physical address = 0xC0000
103
 
103
 
104
        mov     eax, 0xC0000+PG_UWR
104
        mov     eax, 0xC0000+PG_UWR
105
        mov     edi, page_tabs+0xC0*4
105
        mov     edi, page_tabs+0xC0*4
106
        mov     ecx, 64
106
        mov     ecx, 64
107
@@:
107
@@:
108
        stosd
108
        stosd
109
        add     eax, edx
109
        add     eax, edx
110
        loop    @b
110
        loop    @b
111
 
111
 
112
        mov     eax, sys_proc
112
        mov     eax, sys_proc
113
        push    ebx
113
        push    ebx
114
        call    set_cr3
114
        call    set_cr3
115
        pop     ebx
115
        pop     ebx
116
        popfd
116
        popfd
117
 
117
 
118
        pop     edi
118
        pop     edi
119
 
119
 
120
        mov     eax, ebx
120
        mov     eax, ebx
121
        ret
121
        ret
122
.fail2:
122
.fail2:
123
        mov     eax, ebx
123
        mov     eax, ebx
124
        call    free
124
        call    free
125
.fail:
125
.fail:
126
        xor     eax, eax
126
        xor     eax, eax
127
        ret
127
        ret
128
 
128
 
129
;not used
129
;not used
130
; Destroy V86 machine
130
; Destroy V86 machine
131
; in: eax = handle
131
; in: eax = handle
132
; out: nothing
132
; out: nothing
133
; destroys: eax, ebx, ecx, edx (due to free)
133
; destroys: eax, ebx, ecx, edx (due to free)
134
;v86_destroy:
134
;v86_destroy:
135
;        push    eax
135
;        push    eax
136
;        stdcall kernel_free, [eax+V86_machine.pagedir]
136
;        stdcall kernel_free, [eax+V86_machine.pagedir]
137
;        pop     eax
137
;        pop     eax
138
;        jmp     free
138
;        jmp     free
139
 
139
 
140
; Translate V86-address to linear address
140
; Translate V86-address to linear address
141
; in: eax=V86 address
141
; in: eax=V86 address
142
;     esi=handle
142
;     esi=handle
143
; out: eax=linear address
143
; out: eax=linear address
144
; destroys: nothing
144
; destroys: nothing
145
v86_get_lin_addr:
145
v86_get_lin_addr:
146
        push    ecx edx
146
        push    ecx edx
147
        mov     ecx, eax
147
        mov     ecx, eax
148
        shr     ecx, 12
148
        shr     ecx, 12
149
        mov     edx, [page_tabs+ecx*4]
149
        mov     edx, [page_tabs+ecx*4]
150
        and     eax, 0xFFF
150
        and     eax, 0xFFF
151
        and     edx, 0xFFFFF000
151
        and     edx, 0xFFFFF000
152
        or      eax, edx
152
        or      eax, edx
153
        pop     edx ecx
153
        pop     edx ecx
154
        ret
154
        ret
155
 
155
 
156
;not used
156
;not used
157
; Sets linear address for V86-page
157
; Sets linear address for V86-page
158
; in: eax=linear address (must be page-aligned)
158
; in: eax=linear address (must be page-aligned)
159
;     ecx=V86 page (NOT address!)
159
;     ecx=V86 page (NOT address!)
160
;     esi=handle
160
;     esi=handle
161
; out: nothing
161
; out: nothing
162
; destroys: nothing
162
; destroys: nothing
163
;v86_set_page:
163
;v86_set_page:
164
;        push    eax ebx
164
;        push    eax ebx
165
;        mov     ebx, [esi+V86_machine.pagedir]
165
;        mov     ebx, [esi+V86_machine.pagedir]
166
;        mov     [ebx+ecx*4+0x1800], eax
166
;        mov     [ebx+ecx*4+0x1800], eax
167
;        call    get_pg_addr
167
;        call    get_pg_addr
168
;        or      al, 111b
168
;        or      al, 111b
169
;        mov     [ebx+ecx*4+0x1000], eax
169
;        mov     [ebx+ecx*4+0x1000], eax
170
;        pop     ebx eax
170
;        pop     ebx eax
171
;        ret
171
;        ret
172
 
172
 
173
; Allocate memory in V86 machine
173
; Allocate memory in V86 machine
174
; in: eax=size (in bytes)
174
; in: eax=size (in bytes)
175
;     esi=handle
175
;     esi=handle
176
; out: eax=V86 address, para-aligned (0x10 multiple)
176
; out: eax=V86 address, para-aligned (0x10 multiple)
177
; destroys: nothing
177
; destroys: nothing
178
; недописана!!!
178
; недописана!!!
179
;v86_alloc:
179
;v86_alloc:
180
;        push    ebx ecx edx edi
180
;        push    ebx ecx edx edi
181
;        lea     ebx, [esi+V86_machine.mutex]
181
;        lea     ebx, [esi+V86_machine.mutex]
182
;        call    wait_mutex
182
;        call    wait_mutex
183
;        add     eax, 0x1F
183
;        add     eax, 0x1F
184
;        shr     eax, 4
184
;        shr     eax, 4
185
;        mov     ebx, 0x1000  ; start with address 0x1000 (second page)
185
;        mov     ebx, 0x1000  ; start with address 0x1000 (second page)
186
;        mov     edi, [esi+V86_machine.tables]
186
;        mov     edi, [esi+V86_machine.tables]
187
;.l:
187
;.l:
188
;        mov     ecx, ebx
188
;        mov     ecx, ebx
189
;        shr     ecx, 12
189
;        shr     ecx, 12
190
;        mov     edx, [edi+0x1000+ecx*4] ; get linear address
190
;        mov     edx, [edi+0x1000+ecx*4] ; get linear address
191
;        test    edx, edx                ; page allocated?
191
;        test    edx, edx                ; page allocated?
192
;        jz      .unalloc
192
;        jz      .unalloc
193
;        mov     ecx, ebx
193
;        mov     ecx, ebx
194
;        and     ecx, 0xFFF
194
;        and     ecx, 0xFFF
195
;        add     edx, ecx
195
;        add     edx, ecx
196
;        cmp     dword [edx], 0          ; free block?
196
;        cmp     dword [edx], 0          ; free block?
197
;        jnz     .n
197
;        jnz     .n
198
;        cmp     dword [edx+4],
198
;        cmp     dword [edx+4],
199
;        and     [esi+V86_machine.mutex], 0
199
;        and     [esi+V86_machine.mutex], 0
200
;        pop     edi edx ecx ebx
200
;        pop     edi edx ecx ebx
201
;        ret
201
;        ret
202
 
202
 
203
uglobal
203
uglobal
204
sys_v86_machine dd      ?
204
sys_v86_machine dd      ?
205
endg
205
endg
206
 
206
 
207
; Called from kernel.asm at first stages of loading
207
; Called from kernel.asm at first stages of loading
208
; Initialize system V86 machine (used to simulate BIOS int 13h)
208
; Initialize system V86 machine (used to simulate BIOS int 13h)
209
init_sys_v86:
209
init_sys_v86:
210
        call    v86_create
210
        call    v86_create
211
        mov     [sys_v86_machine], eax
211
        mov     [sys_v86_machine], eax
212
        test    eax, eax
212
        test    eax, eax
213
        jz      .ret
213
        jz      .ret
214
        mov     esi, eax
214
        mov     esi, eax
215
if ~DEBUG_SHOW_IO
215
if ~DEBUG_SHOW_IO
216
; allow access to all ports
216
; allow access to all ports
217
        mov     ecx, [esi+V86_machine.iopm]
217
        mov     ecx, [esi+V86_machine.iopm]
218
        xor     eax, eax
218
        xor     eax, eax
219
        mov     edi, ecx
219
        mov     edi, ecx
220
        mov     ecx, 10000h/8/4
220
        mov     ecx, 10000h/8/4
221
        rep stosd
221
        rep stosd
222
end if
222
end if
223
.ret:
223
.ret:
224
        ret
224
        ret
225
 
225
 
226
struct  v86_regs
226
struct  v86_regs
227
; don't change the order, it is important
227
; don't change the order, it is important
228
        edi             dd ?
228
        edi             dd ?
229
        esi             dd ?
229
        esi             dd ?
230
        ebp             dd ?
230
        ebp             dd ?
231
                        dd ?    ; ignored
231
                        dd ?    ; ignored
232
        ebx             dd ?
232
        ebx             dd ?
233
        edx             dd ?
233
        edx             dd ?
234
        ecx             dd ?
234
        ecx             dd ?
235
        eax             dd ?
235
        eax             dd ?
236
        eip             dd ?
236
        eip             dd ?
237
        cs              dd ?
237
        cs              dd ?
238
        eflags          dd ?    ; VM flag must be set!
238
        eflags          dd ?    ; VM flag must be set!
239
        esp             dd ?
239
        esp             dd ?
240
        ss              dd ?
240
        ss              dd ?
241
        es              dd ?
241
        es              dd ?
242
        ds              dd ?
242
        ds              dd ?
243
        fs              dd ?
243
        fs              dd ?
244
        gs              dd ?
244
        gs              dd ?
245
ends
245
ends
246
 
246
 
247
; Run V86 machine
247
; Run V86 machine
248
; in: ebx -> registers for V86 (two structures: in and out)
248
; in: ebx -> registers for V86 (two structures: in and out)
249
;     esi = handle
249
;     esi = handle
250
;     ecx = expected end address (CS:IP)
250
;     ecx = expected end address (CS:IP)
251
;     edx = IRQ to hook or -1 if not required
251
;     edx = IRQ to hook or -1 if not required
252
; out: structure pointed to by ebx is filled with new values
252
; out: structure pointed to by ebx is filled with new values
253
;     eax = 1 - exception has occured, cl contains code
253
;     eax = 1 - exception has occured, cl contains code
254
;     eax = 2 - access to disabled i/o port, ecx contains port address
254
;     eax = 2 - access to disabled i/o port, ecx contains port address
255
;     eax = 3 - IRQ is already hooked by another VM
255
;     eax = 3 - IRQ is already hooked by another VM
256
; destroys: nothing
256
; destroys: nothing
257
v86_start:
257
v86_start:
258
 
258
 
259
        pushad
259
        pushad
260
 
260
 
261
        cli
261
        cli
262
 
262
 
263
        mov     ecx, [current_slot]
263
        mov     ecx, [current_slot]
264
 
264
 
265
        push    dword [ecx+APPDATA.io_map]
265
        push    dword [ecx+APPDATA.io_map]
266
        push    dword [ecx+APPDATA.io_map+4]
266
        push    dword [ecx+APPDATA.io_map+4]
267
        push    [ecx+APPDATA.process]
267
        push    [ecx+APPDATA.process]
268
        push    [ecx+APPDATA.saved_esp0]
268
        push    [ecx+APPDATA.saved_esp0]
269
        mov     [ecx+APPDATA.saved_esp0], esp
269
        mov     [ecx+APPDATA.saved_esp0], esp
270
        mov     [tss._esp0], esp
270
        mov     [tss._esp0], esp
271
 
271
 
272
        mov     eax, [esi+V86_machine.iopm]
272
        mov     eax, [esi+V86_machine.iopm]
273
        call    get_pg_addr
273
        call    get_pg_addr
274
        inc     eax
274
        inc     eax
275
        mov     dword [ecx+APPDATA.io_map], eax
275
        mov     dword [ecx+APPDATA.io_map], eax
276
        mov     dword [page_tabs + (tss._io_map_0 shr 10)], eax
276
        mov     dword [page_tabs + (tss._io_map_0 shr 10)], eax
277
 
277
 
278
        mov     eax, [esi+V86_machine.iopm]
278
        mov     eax, [esi+V86_machine.iopm]
279
        add     eax, 0x1000
279
        add     eax, 0x1000
280
        call    get_pg_addr
280
        call    get_pg_addr
281
        inc     eax
281
        inc     eax
282
        mov     dword [ecx+APPDATA.io_map+4], eax
282
        mov     dword [ecx+APPDATA.io_map+4], eax
283
        mov     dword [page_tabs + (tss._io_map_1 shr 10)], eax
283
        mov     dword [page_tabs + (tss._io_map_1 shr 10)], eax
284
 
284
 
285
        mov     eax, [esi+V86_machine.process]
285
        mov     eax, [esi+V86_machine.process]
286
        mov     [ecx+APPDATA.process], eax
286
        mov     [ecx+APPDATA.process], eax
287
        mov     [current_process], eax
287
        mov     [current_process], eax
288
        mov     eax, [eax+PROC.pdt_0_phys]
288
        mov     eax, [eax+PROC.pdt_0_phys]
289
        mov     cr3, eax
289
        mov     cr3, eax
290
 
290
 
291
; We do not enable interrupts, because V86 IRQ redirector assumes that
291
; We do not enable interrupts, because V86 IRQ redirector assumes that
292
; machine is running
292
; machine is running
293
; They will be enabled by IRET.
293
; They will be enabled by IRET.
294
;        sti
294
;        sti
295
 
295
 
296
        mov     eax, esi
296
        mov     eax, esi
297
        sub     esp, sizeof.v86_regs
297
        sub     esp, sizeof.v86_regs
298
        mov     esi, ebx
298
        mov     esi, ebx
299
        mov     edi, esp
299
        mov     edi, esp
300
        mov     ecx, sizeof.v86_regs/4
300
        mov     ecx, sizeof.v86_regs/4
301
        rep movsd
301
        rep movsd
302
 
302
 
303
        cmp     edx, -1
303
        cmp     edx, -1
304
        jz      .noirqhook
304
        jz      .noirqhook
305
uglobal
305
uglobal
306
v86_irqhooks    rd      IRQ_RESERVED * 2
306
v86_irqhooks    rd      IRQ_RESERVED * 2
307
endg
307
endg
308
        cmp     [v86_irqhooks+edx*8], 0
308
        cmp     [v86_irqhooks+edx*8], 0
309
        jz      @f
309
        jz      @f
310
        cmp     [v86_irqhooks+edx*8], eax
310
        cmp     [v86_irqhooks+edx*8], eax
311
        jz      @f
311
        jz      @f
312
        mov     esi, v86_irqerr
312
        mov     esi, v86_irqerr
313
        call    sys_msg_board_str
313
        call    sys_msg_board_str
314
        inc     [v86_irqhooks+edx*8+4]
314
        inc     [v86_irqhooks+edx*8+4]
315
        mov     eax, 3
315
        mov     eax, 3
316
        jmp     v86_exc_c.exit
316
        jmp     v86_exc_c.exit
317
@@:
317
@@:
318
        mov     [v86_irqhooks+edx*8], eax
318
        mov     [v86_irqhooks+edx*8], eax
319
        inc     [v86_irqhooks+edx*8+4]
319
        inc     [v86_irqhooks+edx*8+4]
320
.noirqhook:
320
.noirqhook:
321
 
321
 
322
        popad
322
        popad
323
        iretd
323
        iretd
324
 
324
 
325
; It is only possible to leave virtual-8086 mode by faulting to
325
; It is only possible to leave virtual-8086 mode by faulting to
326
; a protected-mode interrupt handler (typically the general-protection
326
; a protected-mode interrupt handler (typically the general-protection
327
; exception handler, which in turn calls the virtual 8086-mode monitor).
327
; exception handler, which in turn calls the virtual 8086-mode monitor).
328
 
328
 
329
iglobal
329
iglobal
330
  v86_exc_str1  db      'V86 : unexpected exception ',0
330
  v86_exc_str1  db      'V86 : unexpected exception ',0
331
  v86_exc_str2  db      ' at ',0
331
  v86_exc_str2  db      ' at ',0
332
  v86_exc_str3  db      ':',0
332
  v86_exc_str3  db      ':',0
333
  v86_exc_str4  db      13,10,'V86 : faulted code:',0
333
  v86_exc_str4  db      13,10,'V86 : faulted code:',0
334
  v86_exc_str5  db      ' (unavailable)',0
334
  v86_exc_str5  db      ' (unavailable)',0
335
  v86_newline   db      13,10,0
335
  v86_newline   db      13,10,0
336
  v86_io_str1   db      'V86 : access to disabled i/o port ',0
336
  v86_io_str1   db      'V86 : access to disabled i/o port ',0
337
  v86_io_byte   db      ' (byte)',13,10,0
337
  v86_io_byte   db      ' (byte)',13,10,0
338
  v86_io_word   db      ' (word)',13,10,0
338
  v86_io_word   db      ' (word)',13,10,0
339
  v86_io_dword  db      ' (dword)',13,10,0
339
  v86_io_dword  db      ' (dword)',13,10,0
340
  v86_irqerr    db      'V86 : IRQ already hooked',13,10,0
340
  v86_irqerr    db      'V86 : IRQ already hooked',13,10,0
341
endg
341
endg
342
 
342
 
343
v86_exc_c:
343
v86_exc_c:
344
; Did we all that we have wanted to do?
344
; Did we all that we have wanted to do?
345
        cmp     bl, 1
345
        cmp     bl, 1
346
        jne     @f
346
        jne     @f
347
        xor     eax, eax
347
        xor     eax, eax
348
        mov     dr6, eax
348
        mov     dr6, eax
349
  @@:
349
  @@:
350
        mov     eax, [esp+sizeof.v86_regs+10h+18h]
350
        mov     eax, [esp+sizeof.v86_regs+10h+18h]
351
        cmp     word [esp+v86_regs.eip], ax
351
        cmp     word [esp+v86_regs.eip], ax
352
        jnz     @f
352
        jnz     @f
353
        shr     eax, 16
353
        shr     eax, 16
354
        cmp     word [esp+v86_regs.cs], ax
354
        cmp     word [esp+v86_regs.cs], ax
355
        jz      .done
355
        jz      .done
356
@@:
356
@@:
357
; Various system events, which must be handled, result in #GP
357
; Various system events, which must be handled, result in #GP
358
        cmp     bl, 13
358
        cmp     bl, 13
359
        jnz     .nogp
359
        jnz     .nogp
360
; If faulted EIP exceeds 0xFFFF, we have #GP and it is an error
360
; If faulted EIP exceeds 0xFFFF, we have #GP and it is an error
361
        cmp     word [esp+v86_regs.eip+2], 0
361
        cmp     word [esp+v86_regs.eip+2], 0
362
        jnz     .nogp
362
        jnz     .nogp
363
; Otherwise we can safely access byte at CS:IP
363
; Otherwise we can safely access byte at CS:IP
364
; (because it is #GP, not #PF handler)
364
; (because it is #GP, not #PF handler)
365
; Если бы мы могли схлопотать исключение только из-за чтения байтов кода,
365
; Если бы мы могли схлопотать исключение только из-за чтения байтов кода,
366
; мы бы его уже схлопотали и это было бы не #GP
366
; мы бы его уже схлопотали и это было бы не #GP
367
        movzx   esi, word [esp+v86_regs.cs]
367
        movzx   esi, word [esp+v86_regs.cs]
368
        shl     esi, 4
368
        shl     esi, 4
369
        add     esi, [esp+v86_regs.eip]
369
        add     esi, [esp+v86_regs.eip]
370
        lodsb
370
        lodsb
371
        cmp     al, 0xCD        ; int xx command = CD xx
371
        cmp     al, 0xCD        ; int xx command = CD xx
372
        jz      .handle_int
372
        jz      .handle_int
373
        cmp     al, 0xCF
373
        cmp     al, 0xCF
374
        jz      .handle_iret
374
        jz      .handle_iret
375
        cmp     al, 0xF3
375
        cmp     al, 0xF3
376
        jz      .handle_rep
376
        jz      .handle_rep
377
        cmp     al, 0xEC
377
        cmp     al, 0xEC
378
        jz      .handle_in
378
        jz      .handle_in
379
        cmp     al, 0xED
379
        cmp     al, 0xED
380
        jz      .handle_in_word
380
        jz      .handle_in_word
381
        cmp     al, 0xEE
381
        cmp     al, 0xEE
382
        jz      .handle_out
382
        jz      .handle_out
383
        cmp     al, 0xEF
383
        cmp     al, 0xEF
384
        jz      .handle_out_word
384
        jz      .handle_out_word
385
        cmp     al, 0xE4
385
        cmp     al, 0xE4
386
        jz      .handle_in_imm
386
        jz      .handle_in_imm
387
        cmp     al, 0xE6
387
        cmp     al, 0xE6
388
        jz      .handle_out_imm
388
        jz      .handle_out_imm
389
        cmp     al, 0x9C
389
        cmp     al, 0x9C
390
        jz      .handle_pushf
390
        jz      .handle_pushf
391
        cmp     al, 0x9D
391
        cmp     al, 0x9D
392
        jz      .handle_popf
392
        jz      .handle_popf
393
        cmp     al, 0xFA
393
        cmp     al, 0xFA
394
        jz      .handle_cli
394
        jz      .handle_cli
395
        cmp     al, 0xFB
395
        cmp     al, 0xFB
396
        jz      .handle_sti
396
        jz      .handle_sti
397
        cmp     al, 0x66
397
        cmp     al, 0x66
398
        jz      .handle_66
398
        jz      .handle_66
399
        jmp     .nogp
399
        jmp     .nogp
400
.handle_int:
400
.handle_int:
401
        cmp     word [esp+v86_regs.eip], 0xFFFF
401
        cmp     word [esp+v86_regs.eip], 0xFFFF
402
        jae     .nogp
402
        jae     .nogp
403
        xor     eax, eax
403
        xor     eax, eax
404
        lodsb
404
        lodsb
405
;        call    sys_msg_board_byte
405
;        call    sys_msg_board_byte
406
; simulate INT command
406
; simulate INT command
407
; N.B. It is possible that some checks need to be corrected,
407
; N.B. It is possible that some checks need to be corrected,
408
;      but at least in case of normal execution the code works.
408
;      but at least in case of normal execution the code works.
409
.simulate_int:
409
.simulate_int:
410
        cmp     word [esp+v86_regs.esp], 6
410
        cmp     word [esp+v86_regs.esp], 6
411
        jae     @f
411
        jae     @f
412
        mov     bl, 12          ; #SS exception
412
        mov     bl, 12          ; #SS exception
413
        jmp     .nogp
413
        jmp     .nogp
414
@@:
414
@@:
415
        movzx   edx, word [esp+v86_regs.ss]
415
        movzx   edx, word [esp+v86_regs.ss]
416
        shl     edx, 4
416
        shl     edx, 4
417
        push    eax
417
        push    eax
418
        movzx   eax, word [esp+4+v86_regs.esp]
418
        movzx   eax, word [esp+4+v86_regs.esp]
419
        sub     eax, 6
419
        sub     eax, 6
420
        add     edx, eax
420
        add     edx, eax
421
        mov     eax, edx
421
        mov     eax, edx
422
        mov     esi, [esp+4+sizeof.v86_regs+10h+4]
422
        mov     esi, [esp+4+sizeof.v86_regs+10h+4]
423
        call    v86_get_lin_addr
423
        call    v86_get_lin_addr
424
        cmp     eax, 0x1000
424
        cmp     eax, 0x1000
425
        jae     @f
425
        jae     @f
426
        mov     bl, 14          ; #PF exception
426
        mov     bl, 14          ; #PF exception
427
        jmp     .nogp
427
        jmp     .nogp
428
@@:
428
@@:
429
        lea     eax, [edx+5]
429
        lea     eax, [edx+5]
430
        call    v86_get_lin_addr
430
        call    v86_get_lin_addr
431
        cmp     eax, 0x1000
431
        cmp     eax, 0x1000
432
        jae     @f
432
        jae     @f
433
        mov     bl, 14          ; #PF exception
433
        mov     bl, 14          ; #PF exception
434
        jmp     .nogp
434
        jmp     .nogp
435
@@:
435
@@:
436
        sub     word [esp+4+v86_regs.esp], 6
436
        sub     word [esp+4+v86_regs.esp], 6
437
        mov     eax, [esp+4+v86_regs.eip]
437
        mov     eax, [esp+4+v86_regs.eip]
438
        cmp     byte [esp+1], 0
438
        cmp     byte [esp+1], 0
439
        jnz     @f
439
        jnz     @f
440
        inc     eax
440
        inc     eax
441
        inc     eax
441
        inc     eax
442
@@:
442
@@:
443
        mov     word [edx], ax
443
        mov     word [edx], ax
444
        mov     eax, [esp+4+v86_regs.cs]
444
        mov     eax, [esp+4+v86_regs.cs]
445
        mov     word [edx+2], ax
445
        mov     word [edx+2], ax
446
        mov     eax, [esp+4+v86_regs.eflags]
446
        mov     eax, [esp+4+v86_regs.eflags]
447
        mov     word [edx+4], ax
447
        mov     word [edx+4], ax
448
        pop     eax
448
        pop     eax
449
        mov     ah, 0
449
        mov     ah, 0
450
        mov     cx, [eax*4]
450
        mov     cx, [eax*4]
451
        mov     word [esp+v86_regs.eip], cx
451
        mov     word [esp+v86_regs.eip], cx
452
        mov     cx, [eax*4+2]
452
        mov     cx, [eax*4+2]
453
        mov     word [esp+v86_regs.cs], cx
453
        mov     word [esp+v86_regs.cs], cx
454
; note that interrupts will be disabled globally at IRET
454
; note that interrupts will be disabled globally at IRET
455
        and     byte [esp+v86_regs.eflags+1], not 3 ; clear IF and TF flags
455
        and     byte [esp+v86_regs.eflags+1], not 3 ; clear IF and TF flags
456
; continue V86 execution
456
; continue V86 execution
457
        popad
457
        popad
458
        iretd
458
        iretd
459
.handle_iret:
459
.handle_iret:
460
        cmp     word [esp+v86_regs.esp], 0x10000 - 6
460
        cmp     word [esp+v86_regs.esp], 0x10000 - 6
461
        jbe     @f
461
        jbe     @f
462
        mov     bl, 12
462
        mov     bl, 12
463
        jmp     .nogp
463
        jmp     .nogp
464
@@:
464
@@:
465
        movzx   edx, word [esp+v86_regs.ss]
465
        movzx   edx, word [esp+v86_regs.ss]
466
        shl     edx, 4
466
        shl     edx, 4
467
        movzx   eax, word [esp+v86_regs.esp]
467
        movzx   eax, word [esp+v86_regs.esp]
468
        add     edx, eax
468
        add     edx, eax
469
        mov     eax, edx
469
        mov     eax, edx
470
        mov     esi, [esp+sizeof.v86_regs+10h+4]
470
        mov     esi, [esp+sizeof.v86_regs+10h+4]
471
        call    v86_get_lin_addr
471
        call    v86_get_lin_addr
472
        cmp     eax, 0x1000
472
        cmp     eax, 0x1000
473
        jae     @f
473
        jae     @f
474
        mov     bl, 14
474
        mov     bl, 14
475
        jmp     .nogp
475
        jmp     .nogp
476
@@:
476
@@:
477
        lea     eax, [edx+5]
477
        lea     eax, [edx+5]
478
        call    v86_get_lin_addr
478
        call    v86_get_lin_addr
479
        cmp     eax, 0x1000
479
        cmp     eax, 0x1000
480
        jae     @f
480
        jae     @f
481
        mov     bl, 14
481
        mov     bl, 14
482
        jmp     .nogp
482
        jmp     .nogp
483
@@:
483
@@:
484
        mov     ax, [edx]
484
        mov     ax, [edx]
485
        mov     word [esp+v86_regs.eip], ax
485
        mov     word [esp+v86_regs.eip], ax
486
        mov     ax, [edx+2]
486
        mov     ax, [edx+2]
487
        mov     word [esp+v86_regs.cs], ax
487
        mov     word [esp+v86_regs.cs], ax
488
        mov     ax, [edx+4]
488
        mov     ax, [edx+4]
489
        mov     word [esp+v86_regs.eflags], ax
489
        mov     word [esp+v86_regs.eflags], ax
490
        add     word [esp+v86_regs.esp], 6
490
        add     word [esp+v86_regs.esp], 6
491
        popad
491
        popad
492
        iretd
492
        iretd
493
.handle_pushf:
493
.handle_pushf:
494
        cmp     word [esp+v86_regs.esp], 1
494
        cmp     word [esp+v86_regs.esp], 1
495
        jnz     @f
495
        jnz     @f
496
        mov     bl, 12
496
        mov     bl, 12
497
        jmp     .nogp
497
        jmp     .nogp
498
@@:
498
@@:
499
        movzx   edx, word [esp+v86_regs.ss]
499
        movzx   edx, word [esp+v86_regs.ss]
500
        shl     edx, 4
500
        shl     edx, 4
501
        mov     eax, [esp+v86_regs.esp]
501
        mov     eax, [esp+v86_regs.esp]
502
        sub     eax, 2
502
        sub     eax, 2
503
        movzx   eax, ax
503
        movzx   eax, ax
504
        add     edx, eax
504
        add     edx, eax
505
        mov     eax, edx
505
        mov     eax, edx
506
        mov     esi, [esp+sizeof.v86_regs+10h+4]
506
        mov     esi, [esp+sizeof.v86_regs+10h+4]
507
        call    v86_get_lin_addr
507
        call    v86_get_lin_addr
508
        cmp     eax, 0x1000
508
        cmp     eax, 0x1000
509
        jae     @f
509
        jae     @f
510
        mov     bl, 14          ; #PF exception
510
        mov     bl, 14          ; #PF exception
511
        jmp     .nogp
511
        jmp     .nogp
512
@@:
512
@@:
513
        lea     eax, [edx+1]
513
        lea     eax, [edx+1]
514
        call    v86_get_lin_addr
514
        call    v86_get_lin_addr
515
        cmp     eax, 0x1000
515
        cmp     eax, 0x1000
516
        jae     @f
516
        jae     @f
517
        mov     bl, 14
517
        mov     bl, 14
518
        jmp     .nogp
518
        jmp     .nogp
519
@@:
519
@@:
520
        sub     word [esp+v86_regs.esp], 2
520
        sub     word [esp+v86_regs.esp], 2
521
        mov     eax, [esp+v86_regs.eflags]
521
        mov     eax, [esp+v86_regs.eflags]
522
        mov     [edx], ax
522
        mov     [edx], ax
523
        inc     word [esp+v86_regs.eip]
523
        inc     word [esp+v86_regs.eip]
524
        popad
524
        popad
525
        iretd
525
        iretd
526
.handle_pushfd:
526
.handle_pushfd:
527
        cmp     word [esp+v86_regs.esp], 4
527
        cmp     word [esp+v86_regs.esp], 4
528
        jae     @f
528
        jae     @f
529
        mov     bl, 12          ; #SS exception
529
        mov     bl, 12          ; #SS exception
530
        jmp     .nogp
530
        jmp     .nogp
531
@@:
531
@@:
532
        movzx   edx, word [esp+v86_regs.ss]
532
        movzx   edx, word [esp+v86_regs.ss]
533
        shl     edx, 4
533
        shl     edx, 4
534
        movzx   eax, word [esp+v86_regs.esp]
534
        movzx   eax, word [esp+v86_regs.esp]
535
        sub     eax, 4
535
        sub     eax, 4
536
        add     edx, eax
536
        add     edx, eax
537
        mov     eax, edx
537
        mov     eax, edx
538
        mov     esi, [esp+sizeof.v86_regs+10h+4]
538
        mov     esi, [esp+sizeof.v86_regs+10h+4]
539
        call    v86_get_lin_addr
539
        call    v86_get_lin_addr
540
        cmp     eax, 0x1000
540
        cmp     eax, 0x1000
541
        jae     @f
541
        jae     @f
542
        mov     bl, 14          ; #PF exception
542
        mov     bl, 14          ; #PF exception
543
        jmp     .nogp
543
        jmp     .nogp
544
@@:
544
@@:
545
        lea     eax, [edx+3]
545
        lea     eax, [edx+3]
546
        call    v86_get_lin_addr
546
        call    v86_get_lin_addr
547
        cmp     eax, 0x1000
547
        cmp     eax, 0x1000
548
        jae     @f
548
        jae     @f
549
        mov     bl, 14          ; #PF exception
549
        mov     bl, 14          ; #PF exception
550
        jmp     .nogp
550
        jmp     .nogp
551
@@:
551
@@:
552
        sub     word [esp+v86_regs.esp], 4
552
        sub     word [esp+v86_regs.esp], 4
553
        movzx   eax, word [esp+v86_regs.eflags]
553
        movzx   eax, word [esp+v86_regs.eflags]
554
        mov     [edx], eax
554
        mov     [edx], eax
555
        add     word [esp+v86_regs.eip], 2
555
        add     word [esp+v86_regs.eip], 2
556
        popad
556
        popad
557
        iretd
557
        iretd
558
.handle_popf:
558
.handle_popf:
559
        cmp     word [esp+v86_regs.esp], 0xFFFF
559
        cmp     word [esp+v86_regs.esp], 0xFFFF
560
        jnz     @f
560
        jnz     @f
561
        mov     bl, 12
561
        mov     bl, 12
562
        jmp     .nogp
562
        jmp     .nogp
563
@@:
563
@@:
564
        movzx   edx, word [esp+v86_regs.ss]
564
        movzx   edx, word [esp+v86_regs.ss]
565
        shl     edx, 4
565
        shl     edx, 4
566
        movzx   eax, word [esp+v86_regs.esp]
566
        movzx   eax, word [esp+v86_regs.esp]
567
        add     edx, eax
567
        add     edx, eax
568
        mov     eax, edx
568
        mov     eax, edx
569
        mov     esi, [esp+sizeof.v86_regs+10h+4]
569
        mov     esi, [esp+sizeof.v86_regs+10h+4]
570
        call    v86_get_lin_addr
570
        call    v86_get_lin_addr
571
        cmp     eax, 0x1000
571
        cmp     eax, 0x1000
572
        jae     @f
572
        jae     @f
573
        mov     bl, 14          ; #PF exception
573
        mov     bl, 14          ; #PF exception
574
        jmp     .nogp
574
        jmp     .nogp
575
@@:
575
@@:
576
        lea     eax, [edx+1]
576
        lea     eax, [edx+1]
577
        call    v86_get_lin_addr
577
        call    v86_get_lin_addr
578
        cmp     eax, 0x1000
578
        cmp     eax, 0x1000
579
        jae     @f
579
        jae     @f
580
        mov     bl, 14
580
        mov     bl, 14
581
        jmp     .nogp
581
        jmp     .nogp
582
@@:
582
@@:
583
        mov     ax, [edx]
583
        mov     ax, [edx]
584
        mov     word [esp+v86_regs.eflags], ax
584
        mov     word [esp+v86_regs.eflags], ax
585
        add     word [esp+v86_regs.esp], 2
585
        add     word [esp+v86_regs.esp], 2
586
        inc     word [esp+v86_regs.eip]
586
        inc     word [esp+v86_regs.eip]
587
        popad
587
        popad
588
        iretd
588
        iretd
589
.handle_popfd:
589
.handle_popfd:
590
        cmp     word [esp+v86_regs.esp], 0x10000 - 4
590
        cmp     word [esp+v86_regs.esp], 0x10000 - 4
591
        jbe     @f
591
        jbe     @f
592
        mov     bl, 12
592
        mov     bl, 12
593
        jmp     .nogp
593
        jmp     .nogp
594
@@:
594
@@:
595
        movzx   edx, word [esp+v86_regs.ss]
595
        movzx   edx, word [esp+v86_regs.ss]
596
        shl     edx, 4
596
        shl     edx, 4
597
        movzx   eax, word [esp+v86_regs.esp]
597
        movzx   eax, word [esp+v86_regs.esp]
598
        add     edx, eax
598
        add     edx, eax
599
        mov     eax, edx
599
        mov     eax, edx
600
        mov     esi, [esp+sizeof.v86_regs+10h+4]
600
        mov     esi, [esp+sizeof.v86_regs+10h+4]
601
        call    v86_get_lin_addr
601
        call    v86_get_lin_addr
602
        cmp     eax, 0x1000
602
        cmp     eax, 0x1000
603
        jae     @f
603
        jae     @f
604
        mov     bl, 14
604
        mov     bl, 14
605
        jmp     .nogp
605
        jmp     .nogp
606
@@:
606
@@:
607
        lea     eax, [edx+3]
607
        lea     eax, [edx+3]
608
        call    v86_get_lin_addr
608
        call    v86_get_lin_addr
609
        cmp     eax, 0x1000
609
        cmp     eax, 0x1000
610
        jae     @f
610
        jae     @f
611
        mov     bl, 14
611
        mov     bl, 14
612
        jmp     .nogp
612
        jmp     .nogp
613
@@:
613
@@:
614
        mov     eax, [edx]
614
        mov     eax, [edx]
615
        mov     word [esp+v86_regs.eflags], ax
615
        mov     word [esp+v86_regs.eflags], ax
616
        add     word [esp+v86_regs.esp], 4
616
        add     word [esp+v86_regs.esp], 4
617
        add     word [esp+v86_regs.eip], 2
617
        add     word [esp+v86_regs.eip], 2
618
        popad
618
        popad
619
        iretd
619
        iretd
620
.handle_cli:
620
.handle_cli:
621
        and     byte [esp+v86_regs.eflags+1], not 2
621
        and     byte [esp+v86_regs.eflags+1], not 2
622
        inc     word [esp+v86_regs.eip]
622
        inc     word [esp+v86_regs.eip]
623
        popad
623
        popad
624
        iretd
624
        iretd
625
.handle_sti:
625
.handle_sti:
626
        or      byte [esp+v86_regs.eflags+1], 2
626
        or      byte [esp+v86_regs.eflags+1], 2
627
        inc     word [esp+v86_regs.eip]
627
        inc     word [esp+v86_regs.eip]
628
        popad
628
        popad
629
        iretd
629
        iretd
630
.handle_rep:
630
.handle_rep:
631
        cmp     word [esp+v86_regs.eip], 0xFFFF
631
        cmp     word [esp+v86_regs.eip], 0xFFFF
632
        jae     .nogp
632
        jae     .nogp
633
        lodsb
633
        lodsb
634
        cmp     al, 6Eh
634
        cmp     al, 6Eh
635
        jz      .handle_rep_outsb
635
        jz      .handle_rep_outsb
636
        jmp     .nogp
636
        jmp     .nogp
637
.handle_rep_outsb:
637
.handle_rep_outsb:
638
.handle_in:
638
.handle_in:
639
.handle_out:
639
.handle_out:
640
.invalid_io_byte:
640
.invalid_io_byte:
641
        movzx   ebx, word [esp+v86_regs.edx]
641
        movzx   ebx, word [esp+v86_regs.edx]
642
        mov     ecx, 1
642
        mov     ecx, 1
643
        jmp     .invalid_io
643
        jmp     .invalid_io
644
.handle_in_imm:
644
.handle_in_imm:
645
.handle_out_imm:
645
.handle_out_imm:
646
        cmp     word [esp+v86_regs.eip], 0xFFFF
646
        cmp     word [esp+v86_regs.eip], 0xFFFF
647
        jae     .nogp
647
        jae     .nogp
648
        lodsb
648
        lodsb
649
        movzx   ebx, al
649
        movzx   ebx, al
650
        mov     ecx, 1
650
        mov     ecx, 1
651
        jmp     .invalid_io
651
        jmp     .invalid_io
652
.handle_66:
652
.handle_66:
653
        cmp     word [esp+v86_regs.eip], 0xFFFF
653
        cmp     word [esp+v86_regs.eip], 0xFFFF
654
        jae     .nogp
654
        jae     .nogp
655
        lodsb
655
        lodsb
656
        cmp     al, 0x9C
656
        cmp     al, 0x9C
657
        jz      .handle_pushfd
657
        jz      .handle_pushfd
658
        cmp     al, 0x9D
658
        cmp     al, 0x9D
659
        jz      .handle_popfd
659
        jz      .handle_popfd
660
        cmp     al, 0xEF
660
        cmp     al, 0xEF
661
        jz      .handle_out_dword
661
        jz      .handle_out_dword
662
        cmp     al, 0xED
662
        cmp     al, 0xED
663
        jz      .handle_in_dword
663
        jz      .handle_in_dword
664
        jmp     .nogp
664
        jmp     .nogp
665
.handle_in_word:
665
.handle_in_word:
666
.handle_out_word:
666
.handle_out_word:
667
        movzx   ebx, word [esp+v86_regs.edx]
667
        movzx   ebx, word [esp+v86_regs.edx]
668
        mov     ecx, 2
668
        mov     ecx, 2
669
        jmp     .invalid_io
669
        jmp     .invalid_io
670
.handle_in_dword:
670
.handle_in_dword:
671
.handle_out_dword:
671
.handle_out_dword:
672
.invalid_io_dword:
672
.invalid_io_dword:
673
        movzx   ebx, word [esp+v86_regs.edx]
673
        movzx   ebx, word [esp+v86_regs.edx]
674
        mov     ecx, 4
674
        mov     ecx, 4
675
.invalid_io:
675
.invalid_io:
676
        mov     esi, v86_io_str1
676
        mov     esi, v86_io_str1
677
        call    sys_msg_board_str
677
        call    sys_msg_board_str
678
        mov     eax, ebx
678
        mov     eax, ebx
679
        call    sys_msg_board_dword
679
        call    sys_msg_board_dword
680
        mov     esi, v86_io_byte
680
        mov     esi, v86_io_byte
681
        cmp     ecx, 1
681
        cmp     ecx, 1
682
        jz      @f
682
        jz      @f
683
        mov     esi, v86_io_word
683
        mov     esi, v86_io_word
684
        cmp     ecx, 2
684
        cmp     ecx, 2
685
        jz      @f
685
        jz      @f
686
        mov     esi, v86_io_dword
686
        mov     esi, v86_io_dword
687
@@:
687
@@:
688
        call    sys_msg_board_str
688
        call    sys_msg_board_str
689
if DEBUG_SHOW_IO
689
if DEBUG_SHOW_IO
690
        mov     edx, ebx
690
        mov     edx, ebx
691
        mov     ebx, 200
691
        mov     ebx, 200
692
        call    delay_hs
692
        call    delay_hs
693
        mov     esi, [esp+v86_regs.size+10h+4]
693
        mov     esi, [esp+v86_regs.size+10h+4]
694
        mov     eax, [esi+V86_machine.iopm]
694
        mov     eax, [esi+V86_machine.iopm]
695
@@:
695
@@:
696
        btr     [eax], edx
696
        btr     [eax], edx
697
        inc     edx
697
        inc     edx
698
        loop    @b
698
        loop    @b
699
        popad
699
        popad
700
        iretd
700
        iretd
701
else
701
else
702
        mov     eax, 2
702
        mov     eax, 2
703
        jmp     .exit
703
        jmp     .exit
704
end if
704
end if
705
.nogp:
705
.nogp:
706
 
706
 
707
        mov     esi, v86_exc_str1
707
        mov     esi, v86_exc_str1
708
        call    sys_msg_board_str
708
        call    sys_msg_board_str
709
        mov     al, bl
709
        mov     al, bl
710
        call    sys_msg_board_byte
710
        call    sys_msg_board_byte
711
        mov     esi, v86_exc_str2
711
        mov     esi, v86_exc_str2
712
        call    sys_msg_board_str
712
        call    sys_msg_board_str
713
        mov     ax, [esp+32+4]
713
        mov     ax, [esp+32+4]
714
        call    sys_msg_board_word
714
        call    sys_msg_board_word
715
        mov     esi, v86_exc_str3
715
        mov     esi, v86_exc_str3
716
        call    sys_msg_board_str
716
        call    sys_msg_board_str
717
        mov     ax, [esp+32]
717
        mov     ax, [esp+32]
718
        call    sys_msg_board_word
718
        call    sys_msg_board_word
719
        mov     esi, v86_exc_str4
719
        mov     esi, v86_exc_str4
720
        call    sys_msg_board_str
720
        call    sys_msg_board_str
721
        mov     ecx, 8
721
        mov     ecx, 8
722
        movzx   edx, word [esp+32+4]
722
        movzx   edx, word [esp+32+4]
723
        shl     edx, 4
723
        shl     edx, 4
724
        add     edx, [esp+32]
724
        add     edx, [esp+32]
725
@@:
725
@@:
726
        mov     esi, [esp+sizeof.v86_regs+10h+4]
726
        mov     esi, [esp+sizeof.v86_regs+10h+4]
727
        mov     eax, edx
727
        mov     eax, edx
728
        call    v86_get_lin_addr
728
        call    v86_get_lin_addr
729
        cmp     eax, 0x1000
729
        cmp     eax, 0x1000
730
        jb      .nopage
730
        jb      .nopage
731
        mov     esi, v86_exc_str3-2
731
        mov     esi, v86_exc_str3-2
732
        call    sys_msg_board_str
732
        call    sys_msg_board_str
733
        mov     al, [edx]
733
        mov     al, [edx]
734
        call    sys_msg_board_byte
734
        call    sys_msg_board_byte
735
        inc     edx
735
        inc     edx
736
        loop    @b
736
        loop    @b
737
        jmp     @f
737
        jmp     @f
738
.nopage:
738
.nopage:
739
        mov     esi, v86_exc_str5
739
        mov     esi, v86_exc_str5
740
        call    sys_msg_board_str
740
        call    sys_msg_board_str
741
@@:
741
@@:
742
        mov     esi, v86_newline
742
        mov     esi, v86_newline
743
        call    sys_msg_board_str
743
        call    sys_msg_board_str
744
        mov     eax, 1
744
        mov     eax, 1
745
        jmp     .exit
745
        jmp     .exit
746
 
746
 
747
.done:
747
.done:
748
        xor     eax, eax
748
        xor     eax, eax
749
 
749
 
750
.exit:
750
.exit:
751
        mov     [esp+sizeof.v86_regs+10h+1Ch], eax
751
        mov     [esp+sizeof.v86_regs+10h+1Ch], eax
752
        mov     [esp+sizeof.v86_regs+10h+18h], ebx
752
        mov     [esp+sizeof.v86_regs+10h+18h], ebx
753
 
753
 
754
        mov     edx, [esp+sizeof.v86_regs+10h+14h]
754
        mov     edx, [esp+sizeof.v86_regs+10h+14h]
755
        cmp     edx, -1
755
        cmp     edx, -1
756
        jz      @f
756
        jz      @f
757
        dec     [v86_irqhooks+edx*8+4]
757
        dec     [v86_irqhooks+edx*8+4]
758
        jnz     @f
758
        jnz     @f
759
        and     [v86_irqhooks+edx*8], 0
759
        and     [v86_irqhooks+edx*8], 0
760
@@:
760
@@:
761
 
761
 
762
        mov     esi, esp
762
        mov     esi, esp
763
        mov     edi, [esi+sizeof.v86_regs+10h+10h]
763
        mov     edi, [esi+sizeof.v86_regs+10h+10h]
764
        add     edi, sizeof.v86_regs
764
        add     edi, sizeof.v86_regs
765
        mov     ecx, sizeof.v86_regs/4
765
        mov     ecx, sizeof.v86_regs/4
766
        rep movsd
766
        rep movsd
767
        mov     esp, esi
767
        mov     esp, esi
768
 
768
 
769
        cli
769
        cli
770
        mov     ecx, [current_slot]
770
        mov     ecx, [current_slot]
771
        pop     eax
771
        pop     eax
772
 
772
 
773
        mov     [ecx+APPDATA.saved_esp0], eax
773
        mov     [ecx+APPDATA.saved_esp0], eax
774
        mov     [tss._esp0], eax
774
        mov     [tss._esp0], eax
775
        pop     eax
775
        pop     eax
776
        mov     [ecx+APPDATA.process], eax
776
        mov     [ecx+APPDATA.process], eax
777
        mov     [current_process], eax
777
        mov     [current_process], eax
778
        pop     ebx
778
        pop     ebx
779
        mov     dword [ecx+APPDATA.io_map+4], ebx
779
        mov     dword [ecx+APPDATA.io_map+4], ebx
780
        mov     dword [page_tabs + (tss._io_map_1 shr 10)], ebx
780
        mov     dword [page_tabs + (tss._io_map_1 shr 10)], ebx
781
        pop     ebx
781
        pop     ebx
782
        mov     dword [ecx+APPDATA.io_map], ebx
782
        mov     dword [ecx+APPDATA.io_map], ebx
783
        mov     dword [page_tabs + (tss._io_map_0 shr 10)], ebx
783
        mov     dword [page_tabs + (tss._io_map_0 shr 10)], ebx
784
        mov     eax, [eax+PROC.pdt_0_phys]
784
        mov     eax, [eax+PROC.pdt_0_phys]
785
        mov     cr3, eax
785
        mov     cr3, eax
786
        sti
786
        sti
787
 
787
 
788
        popad
788
        popad
789
        ret
789
        ret
790
 
790
 
791
;my05:
791
;my05:
792
;        mov     dx, 30C2h
792
;        mov     dx, 30C2h
793
;        mov     cx, 4
793
;        mov     cx, 4
794
;.0:
794
;.0:
795
;        in      al, dx
795
;        in      al, dx
796
;        cmp     al, 0FFh
796
;        cmp     al, 0FFh
797
;        jz      @f
797
;        jz      @f
798
;        test    al, 4
798
;        test    al, 4
799
;        jnz     .1
799
;        jnz     .1
800
;@@:
800
;@@:
801
;        add     dx, 8
801
;        add     dx, 8
802
;        in      al, dx
802
;        in      al, dx
803
;        cmp     al, 0FFh
803
;        cmp     al, 0FFh
804
;        jz      @f
804
;        jz      @f
805
;        test    al, 4
805
;        test    al, 4
806
;        jnz     .1
806
;        jnz     .1
807
;@@:
807
;@@:
808
;        loop    .0
808
;        loop    .0
809
;        ret
809
;        ret
810
;.1:
810
;.1:
811
;        or      al, 84h
811
;        or      al, 84h
812
;        out     dx, al
812
;        out     dx, al
813
;.2:
813
;.2:
814
;        mov     dx, 30F7h
814
;        mov     dx, 30F7h
815
;        in      al, dx
815
;        in      al, dx
816
;        mov     byte [BOOT_VAR + 48Eh], 0FFh
816
;        mov     byte [BOOT_VAR + 48Eh], 0FFh
817
;        ret
817
;        ret
818
 
818
 
819
align 4
819
align 4
820
v86_irq:
820
v86_irq:
821
; push irq/pushad/jmp v86_irq
821
; push irq/pushad/jmp v86_irq
822
; ebp = irq
822
; ebp = irq
823
        lea     esi, [esp+1Ch]
823
        lea     esi, [esp+1Ch]
824
        lea     edi, [esi+4]
824
        lea     edi, [esi+4]
825
        mov     ecx, 8
825
        mov     ecx, 8
826
        std
826
        std
827
        rep movsd
827
        rep movsd
828
        cld
828
        cld
829
        mov     edi, ebp
829
        mov     edi, ebp
830
        pop     eax
830
        pop     eax
831
v86_irq2:
831
v86_irq2:
832
        mov     esi, [v86_irqhooks+edi*8]       ; get VM handle
832
        mov     esi, [v86_irqhooks+edi*8]       ; get VM handle
833
        mov     eax, [esi+V86_machine.process]
833
        mov     eax, [esi+V86_machine.process]
834
        mov     ecx, [CURRENT_TASK]
834
        mov     ecx, [CURRENT_TASK]
835
        shl     ecx, 8
835
        shl     ecx, 8
836
        cmp     [SLOT_BASE+ecx+APPDATA.process], eax
836
        cmp     [SLOT_BASE+ecx+APPDATA.process], eax
837
        jnz     .notcurrent
837
        jnz     .notcurrent
838
        lea     eax, [edi+8]
838
        lea     eax, [edi+8]
839
        cmp     al, 10h
839
        cmp     al, 10h
840
        mov     ah, 1
840
        mov     ah, 1
841
        jb      @f
841
        jb      @f
842
        add     al, 60h
842
        add     al, 60h
843
@@:
843
@@:
844
        jmp     v86_exc_c.simulate_int
844
        jmp     v86_exc_c.simulate_int
845
.notcurrent:
845
.notcurrent:
846
        mov     ebx, SLOT_BASE + 0x100
846
        mov     ebx, SLOT_BASE + 0x100
847
        mov     ecx, [TASK_COUNT]
847
        mov     ecx, [TASK_COUNT]
848
.scan:
848
.scan:
849
        cmp     [ebx+APPDATA.process], eax
849
        cmp     [ebx+APPDATA.process], eax
850
        jnz     .cont
850
        jnz     .cont
851
        push    ecx
851
        push    ecx
852
        mov     ecx, [ebx+APPDATA.saved_esp0]
852
        mov     ecx, [ebx+APPDATA.saved_esp0]
853
        cmp     word [ecx-sizeof.v86_regs+v86_regs.esp], 6
853
        cmp     word [ecx-sizeof.v86_regs+v86_regs.esp], 6
854
        jb      .cont2
854
        jb      .cont2
855
        movzx   edx, word [ecx-sizeof.v86_regs+v86_regs.ss]
855
        movzx   edx, word [ecx-sizeof.v86_regs+v86_regs.ss]
856
        shl     edx, 4
856
        shl     edx, 4
857
        push    eax
857
        push    eax
858
        movzx   eax, word [ecx-sizeof.v86_regs+v86_regs.esp]
858
        movzx   eax, word [ecx-sizeof.v86_regs+v86_regs.esp]
859
        sub     eax, 6
859
        sub     eax, 6
860
        add     edx, eax
860
        add     edx, eax
861
        mov     eax, edx
861
        mov     eax, edx
862
        call    v86_get_lin_addr
862
        call    v86_get_lin_addr
863
        cmp     eax, 0x1000
863
        cmp     eax, 0x1000
864
        jb      .cont3
864
        jb      .cont3
865
        lea     eax, [edx+5]
865
        lea     eax, [edx+5]
866
        call    v86_get_lin_addr
866
        call    v86_get_lin_addr
867
        cmp     eax, 0x1000
867
        cmp     eax, 0x1000
868
        jb      .cont3
868
        jb      .cont3
869
        pop     eax
869
        pop     eax
870
        pop     ecx
870
        pop     ecx
871
        jmp     .found
871
        jmp     .found
872
.cont3:
872
.cont3:
873
        pop     eax
873
        pop     eax
874
.cont2:
874
.cont2:
875
        pop     ecx
875
        pop     ecx
876
.cont:
876
.cont:
877
        add     ebx, 0x100
877
        add     ebx, 0x100
878
        loop    .scan
878
        loop    .scan
879
        mov     ecx, edi
879
        mov     ecx, edi
880
        call    irq_eoi
880
        call    irq_eoi
881
        popad
881
        popad
882
        iretd
882
        iretd
883
.found:
883
.found:
884
        mov     eax, [eax+PROC.pdt_0_phys]
884
        mov     eax, [eax+PROC.pdt_0_phys]
885
        mov     cr3, eax
885
        mov     cr3, eax
886
        mov     esi, [ebx+APPDATA.saved_esp0]
886
        mov     esi, [ebx+APPDATA.saved_esp0]
887
        sub     word [esi-sizeof.v86_regs+v86_regs.esp], 6
887
        sub     word [esi-sizeof.v86_regs+v86_regs.esp], 6
888
        mov     ecx, [esi-sizeof.v86_regs+v86_regs.eip]
888
        mov     ecx, [esi-sizeof.v86_regs+v86_regs.eip]
889
        mov     word [edx], cx
889
        mov     word [edx], cx
890
        mov     ecx, [esi-sizeof.v86_regs+v86_regs.cs]
890
        mov     ecx, [esi-sizeof.v86_regs+v86_regs.cs]
891
        mov     word [edx+2], cx
891
        mov     word [edx+2], cx
892
        mov     ecx, [esi-sizeof.v86_regs+v86_regs.eflags]
892
        mov     ecx, [esi-sizeof.v86_regs+v86_regs.eflags]
893
        mov     word [edx+4], cx
893
        mov     word [edx+4], cx
894
        lea     eax, [edi+8]
894
        lea     eax, [edi+8]
895
        cmp     al, 10h
895
        cmp     al, 10h
896
        jb      @f
896
        jb      @f
897
        add     al, 60h
897
        add     al, 60h
898
@@:
898
@@:
899
        mov     cx, [eax*4]
899
        mov     cx, [eax*4]
900
        mov     word [esi-sizeof.v86_regs+v86_regs.eip], cx
900
        mov     word [esi-sizeof.v86_regs+v86_regs.eip], cx
901
        mov     cx, [eax*4+2]
901
        mov     cx, [eax*4+2]
902
        mov     word [esi-sizeof.v86_regs+v86_regs.cs], cx
902
        mov     word [esi-sizeof.v86_regs+v86_regs.cs], cx
903
        and     byte [esi-sizeof.v86_regs+v86_regs.eflags+1], not 3
903
        and     byte [esi-sizeof.v86_regs+v86_regs.eflags+1], not 3
904
        call    update_counters
904
        call    update_counters
905
        lea     edi, [ebx + 0x100000000 - SLOT_BASE]
905
        lea     edi, [ebx + 0x100000000 - SLOT_BASE]
906
        shr     edi, 3
906
        shr     edi, 3
907
        add     edi, CURRENT_TASK
907
        add     edi, CURRENT_TASK
908
        call    find_next_task.found
908
        call    find_next_task.found
909
        call    do_change_task
909
        call    do_change_task
910
        popad
910
        popad
911
        iretd
911
        iretd