2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
5 * PURPOSE: 32-bit Interrupt Handlers
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
10 /* INCLUDES *******************************************************************/
20 /* PRIVATE VARIABLES **********************************************************/
22 LPCWSTR ExceptionName
[] =
29 L
"Bound Range Exceeded",
35 * This is the list of registered 32-bit Interrupt handlers.
37 EMULATOR_INT32_PROC Int32Proc
[EMULATOR_MAX_INT32_NUM
] = { NULL
};
39 /* PUBLIC FUNCTIONS ***********************************************************/
41 VOID WINAPI
Exception(BYTE ExceptionNumber
, LPWORD Stack
)
43 WORD CodeSegment
, InstructionPointer
;
46 ASSERT(ExceptionNumber
< 8);
49 InstructionPointer
= Stack
[STACK_IP
];
50 CodeSegment
= Stack
[STACK_CS
];
51 Opcode
= (PBYTE
)SEG_OFF_TO_PTR(CodeSegment
, InstructionPointer
);
53 /* Display a message to the user */
54 DisplayMessage(L
"Exception: %s occured at %04X:%04X\n"
55 L
"Opcode: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
56 ExceptionName
[ExceptionNumber
],
76 VOID WINAPI
IrqDispatch(BYTE IrqNumber
, LPWORD Stack
)
78 /* Check if this was an PIC IRQ */
79 if (IntNum
>= BIOS_PIC_MASTER_INT
&& IntNum
< BIOS_PIC_MASTER_INT
+ 8)
81 /* It was an IRQ from the master PIC */
82 BiosHandleIrq(IntNum
- BIOS_PIC_MASTER_INT
, Stack
);
84 else if (IntNum
>= BIOS_PIC_SLAVE_INT
&& IntNum
< BIOS_PIC_SLAVE_INT
+ 8)
86 /* It was an IRQ from the slave PIC */
87 BiosHandleIrq(IntNum
- BIOS_PIC_SLAVE_INT
+ 8, Stack
);
94 VOID WINAPI
Int32Dispatch(LPWORD Stack
)
98 /* Get the interrupt number */
99 IntNum
= LOBYTE(Stack
[STACK_INT_NUM
]);
101 /* Check if this was an exception */
104 Exception(IntNum
, Stack
);
108 /* Check if this was an PIC IRQ */
109 if (IntNum
>= BIOS_PIC_MASTER_INT
&& IntNum
< BIOS_PIC_MASTER_INT
+ 8)
111 /* It was an IRQ from the master PIC */
112 BiosHandleIrq(IntNum
- BIOS_PIC_MASTER_INT
, Stack
);
115 else if (IntNum
>= BIOS_PIC_SLAVE_INT
&& IntNum
< BIOS_PIC_SLAVE_INT
+ 8)
117 /* It was an IRQ from the slave PIC */
118 BiosHandleIrq(IntNum
- BIOS_PIC_SLAVE_INT
+ 8, Stack
);
122 /* Call the 32-bit Interrupt handler */
123 if (Int32Proc
[IntNum
] != NULL
)
124 Int32Proc
[IntNum
](Stack
);
126 DPRINT1("Unhandled 32-bit interrupt: 0x%02X\n", IntNum
);
129 VOID WINAPI
InitializeInt32(WORD BiosSegment
)
131 LPDWORD IntVecTable
= (LPDWORD
)BaseAddress
;
132 LPBYTE BiosCode
= (LPBYTE
)SEG_OFF_TO_PTR(BiosSegment
, 0);
134 WORD CommonStub
, BopSeqOffset
, Offset
;
136 CommonStub
= Offset
= 0;
138 /* Write the common stub code */
141 BiosCode
[Offset
++] = 0xF8; // clc
143 BiosCode
[Offset
++] = LOBYTE(EMULATOR_BOP
); // BOP sequence
144 BiosCode
[Offset
++] = HIBYTE(EMULATOR_BOP
);
145 BiosCode
[Offset
++] = EMULATOR_CTRL_BOP
; // Control BOP
146 BiosCode
[Offset
++] = CTRL_BOP_INT32
; // 32-bit Interrupt dispatcher
148 BiosCode
[Offset
++] = 0x73; // jnc EXIT (offset +4)
149 BiosCode
[Offset
++] = 0x04;
151 BiosCode
[Offset
++] = 0xFB; // sti
153 // HACK: The following instruction should be HLT!
154 BiosCode
[Offset
++] = 0x90; // nop
156 BiosCode
[Offset
++] = 0xEB; // jmp BOP_SEQ (offset -11)
157 BiosCode
[Offset
++] = 0xF5;
160 BiosCode
[Offset
++] = 0x83; // add sp, 4
161 BiosCode
[Offset
++] = 0xC4;
162 BiosCode
[Offset
++] = 0x04;
164 BiosCode
[Offset
++] = 0xCF; // iret
166 /* Generate ISR stubs and fill the IVT */
167 for (i
= 0x00; i
<= 0xFF; i
++)
169 IntVecTable
[i
] = MAKELONG(Offset
, BiosSegment
);
171 BiosCode
[Offset
++] = 0xFA; // cli
173 BiosCode
[Offset
++] = 0x6A; // push i
174 BiosCode
[Offset
++] = (UCHAR
)i
;
176 BiosCode
[Offset
++] = 0x6A; // push 0
177 BiosCode
[Offset
++] = 0x00;
179 BopSeqOffset
= CommonStub
- (Offset
+ 3);
181 BiosCode
[Offset
++] = 0xE9; // jmp near BOP_SEQ
182 BiosCode
[Offset
++] = LOBYTE(BopSeqOffset
);
183 BiosCode
[Offset
++] = HIBYTE(BopSeqOffset
);
187 VOID WINAPI
RegisterInt32(BYTE IntNumber
, EMULATOR_INT32_PROC IntHandler
)
189 Int32Proc
[IntNumber
] = IntHandler
;