]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/MEMM/MEMM/VMTRAP.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / MEMM / MEMM / VMTRAP.ASM
1
2
3 page 58,132
4 ;******************************************************************************
5 title VMTRAP - 386 Virtual Mode interrupt handler routines
6 ;******************************************************************************
7 ;
8 ; (C) Copyright MICROSOFT Corp. 1986
9 ;
10 ; Title: MEMM.EXE - MICROSOFT Expanded Memory Manager 386 Driver
11 ;
12 ; Module: VMTRAP - 386 Virtual Mode interrupt handler routines
13 ;
14 ; Version: 0.02
15 ;
16 ; Date: January 26, 1986
17 ;
18 ; Author:
19 ;
20 ;******************************************************************************
21 ;
22 ; Change log:
23 ;
24 ; DATE REVISION DESCRIPTION
25 ; -------- -------- ------------------------------------------------------
26 ; 01/26/86 Original
27 ; 02/05/86 A- Added int 15h trap to move block function.
28 ; 05/12/86 A Cleanup and segment reorganization
29 ; 06/19/86 0.01 Added emul_reflect entry point for preserving
30 ; IF and TF flags bits on reflections done by
31 ; instruction emulators.
32 ; 06/28/86 0.02 Name change from MEMM386 to MEMM
33 ; 07/20/88 Removed debugger codes (pc)
34 ;
35 ;******************************************************************************
36 ;
37 ; Functional Description:
38 ;
39 ; This module contains the interrupt and trap handlers for Virtual DOS.
40 ;
41 ; Note that a conscious decision has been made to attempt to field the
42 ; Master 8259 interrupts at the normal PC location (vectors 8 - F). The
43 ; main problem is that these overlap CPU exception vectors. While the
44 ; 8259 base vector address could be changed (there's lots of room in the
45 ; IDT, since we're fielding S/W INTs through GP 13), the primary reason
46 ; for not doing so is to avoid any potential trouble with an application
47 ; reprogramming the 8259. We don't know of any that do, and you could
48 ; trap them if they tried anyway.
49 ;
50 ; "to do:" marks potential holes/things to consider
51 ;
52 ;******************************************************************************
53 .lfcond ; list false conditionals
54 .386p
55 page
56 ;******************************************************************************
57 ; P U B L I C D E C L A R A T I O N S
58 ;******************************************************************************
59 ;
60 public VmTrap ; module label
61
62 public hw_int
63 public emul_reflect
64
65 public vm_trap00
66 public vm_trap01
67 public vm_trap02
68 public vm_trap03
69 public vm_trap04
70 public vm_trap05
71 public vm_trap06
72 public vm_trap07
73 public vm_trap08
74 public vm_trap09
75 public vm_trap0a
76 public vm_trap0b
77 public vm_trap0c
78 public vm_trap0d
79 public vm_trap0e
80 public vm_trap0f
81 public vm_trap10
82 public vm_trap50
83 public vm_trap51
84 public vm_trap52
85 public vm_trap53
86 public vm_trap54
87 public vm_trap55
88 public vm_trap56
89 public vm_trap57
90 public vm_trap70
91 public vm_trap71
92 public vm_trap72
93 public vm_trap73
94 public vm_trap74
95 public vm_trap75
96 public vm_trap76
97 public vm_trap77
98
99 page
100 ;******************************************************************************
101 ; E X T E R N A L R E F E R E N C E S
102 ;******************************************************************************
103 ;
104 _TEXT segment
105 extrn VmFault:near ; V Mode GP fault handler (VMINST)
106 extrn ErrHndlr:near ; Error Handler (ERRHNDLR)
107 extrn DisableNMI:near ; Disable NMI for NMI trap handler
108 _TEXT ends
109 page
110 ;******************************************************************************
111 ; I N C L U D E F I L E S
112 ;******************************************************************************
113 ;
114 include VDMseg.inc
115 include VDMsel.inc
116 include vm386.inc
117 include pic_def.equ
118 include instr386.inc
119 include oemdep.inc
120
121 page
122 ;******************************************************************************
123 ; L O C A L C O N S T A N T S
124 ;******************************************************************************
125 ;
126 FALSE equ 0
127 TRUE equ not FALSE
128
129 ProcessExcep macro ExcepNum
130 mov bx, ExcepNum
131 mov ax, ExcpErr
132 jmp ErrHndlr
133 endm
134 ;
135 ;******************************************************************************
136 ; S E G M E N T D E F I N I T I O N
137 ;******************************************************************************
138 ;
139 ABS0 segment at 0000h
140 ABS0 ends
141 ;
142 ;------------------------------------------------------------------------------
143 _TEXT segment
144 assume cs:_TEXT, ds:NOTHING, es:NOTHING, ss:NOTHING
145 VmTrap label byte
146 ;
147 db 'WCC'
148 ;
149 page
150 ;******************************************************************************
151 ; CPU: Divide error fault
152 ;
153 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
154 ; No error code on stack
155 ; EXIT: to handler or debugger as appropriate
156 ; USED:
157 ; STACK:
158 ;------------------------------------------------------------------------------
159 vm_trap00 proc near
160 PUSH_EBP
161 mov bp,sp
162 test [bp.VTFO+VMTF_EFLAGShi],2 ; Q: client in Virtual Mode ?
163 jz vmt0_dexit ; N: exit to debugger
164 push 0000 ; Y: interrupt 00
165 jmp hw_int ; reflect it to virtual mode
166 vmt0_dexit:
167 ProcessExcep ErrDIV
168 vm_trap00 endp
169
170 ;******************************************************************************
171 ; CPU: Debug trap
172 ;
173 ; Traps from Virtual mode are reflected to virtual mode. Unfortunately
174 ; this breaks the debugger's ability to GO and TRACE the VM program.
175 ;
176 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
177 ; No error code on stack
178 ; EXIT: to handler or debugger as appropriate
179 ; USED:
180 ; STACK:
181 ;------------------------------------------------------------------------------
182 vm_trap01 proc near
183 PUSH_EBP
184 mov bp,sp
185 test [bp.VTFO+VMTF_EFLAGShi],2 ; Q: client in Virtual Mode ?
186 jz vmt1_dexit ; N: exit to debugger
187 push 0001 ; Y: interrupt 01
188 jmp hw_int ; reflect it to virtual mode
189 vmt1_dexit:
190 ProcessExcep ErrINT1
191 vm_trap01 endp
192
193 ;******************************************************************************
194 ; H/W: NMI
195 ;
196 ; For now, this always traps to the debugger. It's a general purpose hook
197 ; to let the debugger get control via an NMI button.
198 ;
199 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
200 ; No error code on stack
201 ; EXIT: to handler or debugger as appropriate
202 ; USED:
203 ; STACK:
204 ;------------------------------------------------------------------------------
205 vm_trap02 proc near
206 PUSH_EBP
207 mov bp,sp
208
209 call DisableNMI
210
211 test [bp.VTFO+VMTF_EFLAGShi],2 ; Q: client in Virtual Mode ?
212 jz vmt2_parity ; N: error/debug trap
213 ; Y: reflect it/debugger
214 push 02 ; reflect it
215 jmp hw_int
216 vmt2_parity:
217 ProcessExcep ErrNMI
218
219 vm_trap02 endp
220
221 ;******************************************************************************
222 ; CPU: Breakpoint trap (INT 3 instruction)
223 ;
224 ; Traps from Virtual mode are reflected to virtual mode. Unfortunately
225 ; this breaks the debugger's ability to GO and TRACE the VM program.
226 ;
227 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
228 ; No error code on stack
229 ; EXIT: to handler or debugger as appropriate
230 ; USED:
231 ; STACK:
232 ;------------------------------------------------------------------------------
233 vm_trap03 proc near
234 ProcessExcep ErrINT3
235 vm_trap03 endp
236
237 ;******************************************************************************
238 ; CPU: Overflow trap (INTO instruction)
239 ;
240 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
241 ; No error code on stack
242 ; EXIT: to handler or debugger as appropriate
243 ; USED:
244 ; STACK:
245 ;------------------------------------------------------------------------------
246 vm_trap04 proc near
247 ProcessExcep ErrINTO
248 vm_trap04 endp
249
250
251 ;******************************************************************************
252 ; CPU: Array bounds fault
253 ;
254 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
255 ; No error code on stack
256 ; EXIT: to handler or debugger as appropriate
257 ; USED:
258 ; STACK:
259 ;------------------------------------------------------------------------------
260 vm_trap05 proc near
261 PUSH_EBP
262 mov bp,sp
263 test [bp.VTFO+VMTF_EFLAGShi],2 ; Q: client in Virtual Mode ?
264 jz vmt5_dexit ; N: exit to debugger
265 push 0005 ; Y: interrupt 01
266 jmp hw_int ; reflect it to virtual mode
267 vmt5_dexit:
268 ProcessExcep ErrBounds
269 vm_trap05 endp
270
271 ;******************************************************************************
272 ; CPU: Invalid Opcode fault
273 ;
274 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
275 ; No error code on stack
276 ; EXIT: to handler or debugger as appropriate
277 ; USED:
278 ; STACK:
279 ;
280 ; add Invalid instruction emulator ??? (specifically LOCK prefix)
281 ;
282 ;------------------------------------------------------------------------------
283 vm_trap06 proc near
284 push 0 ; align stack with error offset
285 push 0 ; for VmFault
286 PUSH_EBP
287 mov bp,sp
288 test [bp.VTFOE+VMTF_EFLAGShi],2 ; Q: client in Virtual Mode ?
289 jz vmt6_dexit ; N: exit to debugger
290 jmp VmFault ; Y: enter VM 06 Invalid handler
291
292 vmt6_dexit:
293 ProcessExcep ErrOpCode
294 vm_trap06 endp
295
296 ;******************************************************************************
297 ; CPU: Coprocessor not present fault
298 ;
299 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
300 ; No error code on stack
301 ; EXIT: to handler or debugger as appropriate
302 ; USED:
303 ; STACK:
304 ;------------------------------------------------------------------------------
305 vm_trap07 proc near
306 PUSH_EBP
307 mov bp,sp
308 test [bp.VTFO+VMTF_EFLAGShi],2 ; Q: client in Virtual Mode ?
309 jz vmt7_dexit ; N: exit to debugger
310 push 0007 ; Y: interrupt 07
311 jmp hw_int ; reflect it to virtual mode
312 vmt7_dexit:
313 ProcessExcep ErrCoPNA
314 vm_trap07 endp
315
316
317 ;******************************************************************************
318 ; CPU: Double Fault
319 ; H/W: IRQ0 - System timer
320 ;
321 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
322 ; Error Code on stack = 0000
323 ; EXIT: to handler or debugger as appropriate
324 ; USED:
325 ; STACK:
326 ;------------------------------------------------------------------------------
327 vm_trap08 proc near
328 PUSH_EBP
329 mov bp,sp
330 cmp sp,VMT_STACK ; Q: H/W interrupt from VM ?
331 jne vmt8_dexit ; N: exit to debugger
332 push 0008 ; Y: interrupt 8
333 jmp hw_int ; reflect it to virtual mode
334 vmt8_dexit:
335 ProcessExcep ErrDouble
336 vm_trap08 endp
337
338
339 ;******************************************************************************
340 ; CPU: (none for 386)
341 ; H/W: IRQ1 - Keyboard
342 ;
343 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
344 ; No error code on stack
345 ; EXIT: to handler or debugger as appropriate
346 ; USED:
347 ; STACK:
348 ;------------------------------------------------------------------------------
349 vm_trap09 proc near
350 PUSH_EBP
351 mov bp,sp
352 push 0009 ; Y: interrupt 9
353 jmp hw_int ; reflect it to virtual mode
354 vm_trap09 endp
355
356 ;******************************************************************************
357 ; CPU: Invalid TSS fault
358 ; H/W: IRQ2 - Cascade from slave 8259 (see INT 70-77)
359 ; (shouldn't get H/W interrupts here)
360 ;
361 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
362 ; Error Code on stack = Selector
363 ; EXIT: to handler or debugger as appropriate
364 ; USED:
365 ; STACK:
366
367 ; to do: someone could reprogram master 8259 - need to handle ?
368 ;------------------------------------------------------------------------------
369 vm_trap0A proc near
370 ProcessExcep ErrTSS
371 vm_trap0A endp
372
373
374 ;******************************************************************************
375 ; CPU: Segment Not Present fault
376 ; H/W: IRQ3 - COM2
377 ;
378 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
379 ; Error Code on stack = Selector
380 ; EXIT: to handler or debugger as appropriate
381 ; USED:
382 ; STACK:
383 ;------------------------------------------------------------------------------
384 vm_trap0B proc near
385 PUSH_EBP
386 mov bp,sp
387 test [bp.VTFO+VMTF_EFLAGShi],2 ; Q: client in Virtual Mode ?
388 jz vmtB_dexit ; N: exit to debugger
389 push 000Bh ; Y: interrupt 0B
390 jmp hw_int ; reflect it to virtual mode
391 vmtB_dexit:
392 ProcessExcep ErrSegNP
393 vm_trap0B endp
394
395 ;******************************************************************************
396 ; CPU: Stack fault
397 ; H/W: IRQ4 - COM1
398 ;
399 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
400 ; Error Code on stack = Selector or 0000
401 ; EXIT: to handler or debugger as appropriate
402 ; USED:
403 ; STACK:
404 ;------------------------------------------------------------------------------
405 vm_trap0C proc near
406 PUSH_EBP
407 mov bp,sp
408 test [bp.VTFO+VMTF_EFLAGShi],2 ; Q: client in Virtual Mode ?
409 jz vmtC_dexit ; N: exit to debugger
410 push 000Ch ; Y: interrupt 0C
411 jmp hw_int ; reflect it to virtual mode
412 vmtC_dexit:
413 ProcessExcep ErrStack
414 vm_trap0C endp
415
416 ;******************************************************************************
417 ; CPU: General Protection fault
418 ; H/W: IRQ5 - Second parallel printer
419 ;
420 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
421 ; Error Code on stack = Selector or 0000
422 ; EXIT: to handler or debugger as appropriate
423 ; USED:
424 ; STACK:
425 ;------------------------------------------------------------------------------
426 vm_trap0D proc near
427 PUSH_EBP
428 mov bp,sp
429 cmp sp,VMT_STACK ; Q: H/W interrupt from VM ?
430 jne vmtD_1 ; N: continue
431 push 000Dh ; Y: interrupt vector 0Dh
432 jmp hw_int ; reflect it to virtual mode
433 ;
434 ; Here we have a GP fault that was not a H/W interrupt 13 from VM.
435 ;
436 vmtD_1:
437 cmp sp,VMTERR_STACK ; Q: 'normal' exception w/error code ?
438 jne vmtD_dexit ; N: what the hell was it ???? - exit
439 jmp VmFault ; Y: enter VM GP fault handler
440 ; (fall thru to debugger)
441 vmtD_dexit:
442 ProcessExcep ErrGP
443 vm_trap0D endp
444
445 ;******************************************************************************
446 ; CPU: Page fault
447 ; H/W: IRQ6 - diskette interrupt
448 ;
449 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
450 ; Error Code on stack = type of fault
451 ; EXIT: to handler or debugger as appropriate
452 ; USED:
453 ; STACK:
454 ;------------------------------------------------------------------------------
455 vm_trap0E proc near
456 PUSH_EBP
457 mov bp,sp
458 cmp sp,VMT_STACK ; Q: H/W interrupt from VM ?
459 jne vmtE_dexit ; N: exit to debugger
460 push 000Eh ; Y: interrupt vector 0Eh
461 jmp hw_int ; reflect it to virtual mode
462 vmtE_dexit:
463 ProcessExcep ErrPage
464 vm_trap0E endp
465
466 ;******************************************************************************
467 ; CPU: (none)
468 ; H/W: IRQ7 - parallel printer
469 ;
470 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
471 ; No error code on stack
472 ; EXIT: to handler or debugger as appropriate
473 ; USED:
474 ; STACK:
475 ;------------------------------------------------------------------------------
476 vm_trap0F proc near
477 PUSH_EBP
478 mov bp,sp
479 push 000Fh ; push interrupt number
480 jmp hw_int ; enter common H/W interrupt handler
481 vm_trap0F endp
482
483 ;******************************************************************************
484 ; CPU: Coprocessor Error - GOES TO NOT PRESENT FAULT IN DEBUGGER FOR NOW
485 ;
486 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
487 ; No error code on stack
488 ; EXIT: to handler or debugger as appropriate
489 ; USED:
490 ; STACK:
491 ;------------------------------------------------------------------------------
492 vm_trap10 proc near
493 ProcessExcep ErrCoPerr
494 vm_trap10 endp
495
496 ;******************************************************************************
497 ; VmTrap5x - Handlers for hardware interrupts. Sometimes the master 8259
498 ; is set to here.
499 ;
500 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
501 ; EXIT: EBP pushed on stack
502 ; BP = normal stack frame pointer
503 ; Interrupt number pushed on stack
504 ; USED:
505 ; STACK: (4 bytes)
506 ;------------------------------------------------------------------------------
507 vm_trap50 proc near
508 PUSH_EBP
509 mov bp,sp ; set up BP frame pointer
510 push 0050h
511 jmp short hw_int ; enter common code
512 vm_trap50 endp
513
514 ;------------------------------------------------------------------------------
515 vm_trap51 proc near
516 PUSH_EBP
517 mov bp,sp ; set up BP frame pointer
518 push 0051h
519 jmp short hw_int ; enter common code
520 vm_trap51 endp
521
522 ;------------------------------------------------------------------------------
523 vm_trap52 proc near
524 PUSH_EBP
525 mov bp,sp ; set up BP frame pointer
526 push 0052h
527 jmp short hw_int ; enter common code
528 vm_trap52 endp
529
530 ;------------------------------------------------------------------------------
531 vm_trap53 proc near
532 PUSH_EBP
533 mov bp,sp ; set up BP frame pointer
534 push 0053h
535 jmp short hw_int ; enter common code
536 vm_trap53 endp
537
538 ;------------------------------------------------------------------------------
539 vm_trap54 proc near
540 PUSH_EBP
541 mov bp,sp ; set up BP frame pointer
542 push 0054h
543 jmp short hw_int ; enter common code
544 vm_trap54 endp
545
546 ;------------------------------------------------------------------------------
547 vm_trap55 proc near
548 PUSH_EBP
549 mov bp,sp ; set up BP frame pointer
550 push 0055h
551 jmp short hw_int ; enter common code
552 vm_trap55 endp
553
554 ;------------------------------------------------------------------------------
555 vm_trap56 proc near
556 PUSH_EBP
557 mov bp,sp ; set up BP frame pointer
558 push 0056h
559 jmp short hw_int ; enter common code
560 vm_trap56 endp
561
562 ;------------------------------------------------------------------------------
563 vm_trap57 proc near
564 PUSH_EBP
565 mov bp,sp ; set up BP frame pointer
566 push 0057h
567 jmp short hw_int ; enter common code
568 vm_trap57 endp
569
570 ;******************************************************************************
571 ; VmTrap7x - handlers for hardware interrupts from the slave 8259
572 ;
573 ; ENTRY: 386 Protected Mode via 386 Interrupt gate
574 ; EXIT: EBP pushed on stack
575 ; BP = normal stack frame pointer
576 ; Interrupt number pushed on stack
577 ; USED:
578 ; STACK: (4 bytes)
579 ;------------------------------------------------------------------------------
580 vm_trap70 proc near
581 PUSH_EBP
582 mov bp,sp ; set up BP frame pointer
583 push 0070h
584 jmp short hw_int ; enter common code
585 vm_trap70 endp
586
587 ;------------------------------------------------------------------------------
588 vm_trap71 proc near
589 PUSH_EBP
590 mov bp,sp ; set up BP frame pointer
591 push 0071h
592 jmp short hw_int ; enter common code
593 vm_trap71 endp
594
595 ;------------------------------------------------------------------------------
596 vm_trap72 proc near
597 PUSH_EBP
598 mov bp,sp ; set up BP frame pointer
599 push 0072h
600 jmp short hw_int ; enter common code
601 vm_trap72 endp
602
603 ;------------------------------------------------------------------------------
604 vm_trap73 proc near
605 PUSH_EBP
606 mov bp,sp ; set up BP frame pointer
607 push 0073h
608 jmp short hw_int ; enter common code
609 vm_trap73 endp
610
611 ;------------------------------------------------------------------------------
612 vm_trap74 proc near
613 PUSH_EBP
614 mov bp,sp ; set up BP frame pointer
615 push 0074h
616 jmp short hw_int ; enter common code
617 vm_trap74 endp
618
619 ;------------------------------------------------------------------------------
620 vm_trap75 proc near
621 PUSH_EBP
622 mov bp,sp ; set up BP frame pointer
623 push 0075h
624 jmp short hw_int ; enter common code
625 vm_trap75 endp
626
627 ;------------------------------------------------------------------------------
628 vm_trap76 proc near
629 PUSH_EBP
630 mov bp,sp ; set up BP frame pointer
631 push 0076h
632 jmp short hw_int ; enter common code
633 vm_trap76 endp
634
635 ;------------------------------------------------------------------------------
636 vm_trap77 proc near
637 PUSH_EBP
638 mov bp,sp ; set up BP frame pointer
639 push 0077h
640 jmp short hw_int ; enter common code
641 vm_trap77 endp
642
643 page
644 ;******************************************************************************
645 ; HW_INT - common handler for hardware interrupts. The interrupt is
646 ; reflected directly to the appropriate Real Mode (Virtual) handler.
647 ; This entry point clear the trace flag (TF) and int flag (IF), since
648 ; a h/w interrupt would (NOTE: INT n and INTO instructions also clear
649 ; TF and IF - so this entry is suitable for reflecting these also).
650 ;
651 ; EMUL_REFLECT - entry point for reflecting emulations.
652 ; This entry point does not clear the trace flag (TF) and int flag (IF).
653 ;
654 ; 386 interrupt gate switched us to the Ring 0 stack on the way in
655 ; from Virtual Mode and pushed 32-bit values as follows:
656 ;
657 ; hiword loword offset (in addition to EBP push)
658 ; +------+------+ <-------- Top of 'kernel' stack
659 ; | 0000 | GS | +32 (decimal)
660 ; |------|------|
661 ; | 0000 | FS | +28
662 ; |------|------|
663 ; | 0000 | DS | +24
664 ; |------|------|
665 ; | 0000 | ES | +20
666 ; |------|------|
667 ; | 0000 | SS | +16
668 ; |------|------|
669 ; | ESP | +12
670 ; |------|------|
671 ; | EFLAGS | +08
672 ; |------|------|
673 ; | 0000 | CS | +04
674 ; |------|------|
675 ; | EIP | +00
676 ; +------+------+ <-------- Ring 0 SS:SP
677 ; | (ebp) |
678 ; +-------------+ <-------- Ring 0 SS:BP
679 ;
680 ; The object of this routine is to massage the trap stack frame (above)
681 ; and build a 'real mode' stack frame for the virtual mode client so that
682 ; we can transfer control to virtual mode at the address specified in
683 ; the appropriate real mode IDT vector. The client's IRET out of the
684 ; interrupt routine will proceed normally (assuming we're letting him
685 ; run with IOPL = 3). Since we're fielding the trap from Virtual Mode,
686 ; we assume the high word of ESP and EIP is 0000.
687 ;
688 ; +-------+ <-------- Client's current SS:SP
689 ; | Flags | +4
690 ; |-------|
691 ; | CS | +2
692 ; |-------|
693 ; | IP | +0
694 ; +-------+ <-------- Client's SS:SP when we let him have control
695 ;
696 ; Assume entry from Virtual Mode, for now. We shouldn't be getting entered
697 ; here except via Hardware interrupt, so no sanity checks are performed.
698 ;
699 ; ENTRY: 386 Protected Mode
700 ; BP -> standard frame
701 ; EBP and Interrupt number have been pushed onto stack
702 ; EXIT: via IRET to VM86 program
703 ; appropriate real mode IRET set up @ client's SS:SP
704 ; USED: (none) (note that DS & ES are free to use - saved during trap)
705 ; STACK:
706 ;
707 ; to do: Need to check for entry mode ?
708 ;------------------------------------------------------------------------------
709 hw_int proc near
710 push bx
711 push si ;
712 mov si,[bp.VTFO+VMTF_EFLAGS] ; SI = saved low word of EFLAGS
713 ;
714 ; *** clear IF bit and Trace Flag on flags for reflect, but leave them
715 ; unchanged for the flags on the IRET stack we build on the
716 ; client's stack.
717 ;
718 and [bp.VTFO+VMTF_EFLAGS],not 300h ; clear IF and TF
719 reflect_common:
720 ;
721 ; Build a selector (VM1_GSEL) to client's stack. VM1_GSEL is already set
722 ; up with limit (0FFFFh) and access (D_DATA0), so just fill in the base.
723 ;
724 HwTabUnlock ; disable HW protection on high ram
725 mov bx,GDTD_GSEL ; get GDT data alias
726 mov ds,bx ; DS -> GDT
727 mov bx,[bp.VTFO+VMTF_SS] ; BX = VM SS (segment form)
728 shl bx,4 ; BX = low 16 bits of base
729 mov ds:[VM1_GSEL+2],bx ; place in descriptor
730 mov bx,[bp.VTFO+VMTF_SS] ; BX = VM SS (again)
731 shr bx,4 ; BH = high 8 bits of base
732 mov ds:[VM1_GSEL+4],bh ; place in descriptor
733 ;
734 ; Adjust client's SP to make room for building his IRET frame
735 ;
736 sub word ptr [bp.VTFO+VMTF_ESP],6 ; adjust client's SP
737 mov bx, VM1_GSEL
738 mov ds, bx ; DS = VM stack segment
739 ;
740 mov bx,si ; BX = low word of client's EFLAGS
741 ;
742 mov si,[bp.VTFO+VMTF_ESP] ; DS:SI = pointer to client's frame
743 ;
744 ; Move low 16 bits of Flags, CS, and EIP from IRET frame to client stack frame
745 ;
746 mov ds:[si.4],bx ; to client's flags
747 mov bx,[bp.VTFO+VMTF_CS] ;
748 mov ds:[si.2],bx ; to client's CS
749 mov bx,[bp.VTFO+VMTF_EIP] ; low word of EIP
750 mov ds:[si.0],bx ; to client's IP
751 ;
752 ; Replace low 16 bits of IRET frame CS:EIP with vector from real mode IDT
753 ;
754 mov bx,[bp-2] ; get the interrupt vector
755 shl bx,2 ; BX = BX * 4 (vector table index)
756 mov si,RM_IDT_GSEL ; get real mode IDT alias
757 mov ds,si ; DS -> Real Mode IDT
758 mov si,ds:[bx] ;
759 mov [bp.VTFO+VMTF_EIP],si ; move the IP
760 mov si,ds:[bx+2] ;
761 mov [bp.VTFO+VMTF_CS],si ; move the CS
762 ;
763 ; 32-bit IRET back to client
764 ;
765 HwTabLock ; enable HW protection on high ram
766 pop si ; restore local regs
767 pop bx
768 pop bp ; throw away fake interrupt number
769 POP_EBP
770 db 66h
771 iret ; *** RETURN *** to client
772 hw_int endp
773
774 ;******************************************************************************
775 ; EMUL_REFLECT
776 ;******************************************************************************
777 ;
778 ; emulation relfection entry point - don't mess with client's flags
779 ;
780 emul_reflect label near
781 push bx ; local registers
782 push si ;
783 mov si,[bp.VTFO+VMTF_EFLAGS] ; SI = saved low word of EFLAGS
784 jmp reflect_common
785
786
787 ;
788 _TEXT ends ; end of segment
789 ;
790 end ; end of module
791 \1a