Subversion Repositories Kolibri OS

Rev

Rev 9828 | Details | Compare with Previous | Last modification | View Log | RSS feed

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