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 *******************************************************************/
19 #include "registers.h"
21 /* PRIVATE VARIABLES **********************************************************/
23 LPCWSTR ExceptionName
[] =
30 L
"Bound Range Exceeded",
36 * This is the list of registered 32-bit Interrupt handlers.
38 EMULATOR_INT32_PROC Int32Proc
[EMULATOR_MAX_INT32_NUM
] = { NULL
};
41 #define BOP_CONTROL 0xFF // Control BOP Handler
42 #define BOP_CONTROL_DEFFUNC 0x00 // Default Control BOP Function
44 /* 32-bit Interrupt dispatcher function code for the Control BOP Handler */
45 #define BOP_CONTROL_INT32 0xFF
47 /* PUBLIC FUNCTIONS ***********************************************************/
49 VOID WINAPI
Exception(BYTE ExceptionNumber
, LPWORD Stack
)
51 WORD CodeSegment
, InstructionPointer
;
54 ASSERT(ExceptionNumber
< 8);
57 InstructionPointer
= Stack
[STACK_IP
];
58 CodeSegment
= Stack
[STACK_CS
];
59 Opcode
= (PBYTE
)SEG_OFF_TO_PTR(CodeSegment
, InstructionPointer
);
61 /* Display a message to the user */
62 DisplayMessage(L
"Exception: %s occured at %04X:%04X\n"
63 L
"Opcode: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
64 ExceptionName
[ExceptionNumber
],
84 VOID WINAPI
IrqDispatch(BYTE IrqNumber
, LPWORD Stack
)
86 /* Check if this was an PIC IRQ */
87 if (IntNum
>= BIOS_PIC_MASTER_INT
&& IntNum
< BIOS_PIC_MASTER_INT
+ 8)
89 /* It was an IRQ from the master PIC */
90 BiosHandleIrq(IntNum
- BIOS_PIC_MASTER_INT
, Stack
);
92 else if (IntNum
>= BIOS_PIC_SLAVE_INT
&& IntNum
< BIOS_PIC_SLAVE_INT
+ 8)
94 /* It was an IRQ from the slave PIC */
95 BiosHandleIrq(IntNum
- BIOS_PIC_SLAVE_INT
+ 8, Stack
);
102 VOID WINAPI
Int32Dispatch(LPWORD Stack
)
106 /* Get the interrupt number */
107 IntNum
= LOBYTE(Stack
[STACK_INT_NUM
]);
109 /* Check if this was an exception */
112 Exception(IntNum
, Stack
);
116 /* Check if this was an PIC IRQ */
117 if (IntNum
>= BIOS_PIC_MASTER_INT
&& IntNum
< BIOS_PIC_MASTER_INT
+ 8)
119 /* It was an IRQ from the master PIC */
120 BiosHandleIrq(IntNum
- BIOS_PIC_MASTER_INT
, Stack
);
123 else if (IntNum
>= BIOS_PIC_SLAVE_INT
&& IntNum
< BIOS_PIC_SLAVE_INT
+ 8)
125 /* It was an IRQ from the slave PIC */
126 BiosHandleIrq(IntNum
- BIOS_PIC_SLAVE_INT
+ 8, Stack
);
130 /* Call the 32-bit Interrupt handler */
131 if (Int32Proc
[IntNum
] != NULL
)
132 Int32Proc
[IntNum
](Stack
);
134 DPRINT("Unhandled 32-bit interrupt: 0x%02X, AX = 0x%04X\n", IntNum
, getAX());
137 VOID WINAPI
ControlBop(LPWORD Stack
)
139 /* Get the Function Number and skip it */
140 BYTE FuncNum
= *(PBYTE
)SEG_OFF_TO_PTR(getCS(), getIP());
143 if (FuncNum
== BOP_CONTROL_INT32
)
144 Int32Dispatch(Stack
);
146 DPRINT("Unassigned Control BOP Function: 0x%02X\n", FuncNum
);
149 VOID
InitializeInt32(WORD BiosSegment
)
151 LPDWORD IntVecTable
= (LPDWORD
)BaseAddress
;
152 LPBYTE BiosCode
= (LPBYTE
)SEG_OFF_TO_PTR(BiosSegment
, 0);
154 WORD BopSeqOffset
, Offset
= 0;
156 /* Generate ISR stubs and fill the IVT */
157 for (i
= 0x00; i
<= 0xFF; i
++)
159 Offset
= INT_HANDLER_OFFSET
+ (i
<< 4);
160 IntVecTable
[i
] = MAKELONG(Offset
, BiosSegment
);
162 BiosCode
[Offset
++] = 0xFA; // cli
164 BiosCode
[Offset
++] = 0x6A; // push i
165 BiosCode
[Offset
++] = (UCHAR
)i
;
167 BiosCode
[Offset
++] = 0x6A; // push 0
168 BiosCode
[Offset
++] = 0x00;
170 BopSeqOffset
= COMMON_STUB_OFFSET
- (Offset
+ 3);
172 BiosCode
[Offset
++] = 0xE9; // jmp near BOP_SEQ
173 BiosCode
[Offset
++] = LOBYTE(BopSeqOffset
);
174 BiosCode
[Offset
++] = HIBYTE(BopSeqOffset
);
177 /* Write the common stub code */
178 Offset
= COMMON_STUB_OFFSET
;
181 BiosCode
[Offset
++] = 0xF8; // clc
183 BiosCode
[Offset
++] = LOBYTE(EMULATOR_BOP
); // BOP sequence
184 BiosCode
[Offset
++] = HIBYTE(EMULATOR_BOP
);
185 BiosCode
[Offset
++] = BOP_CONTROL
; // Control BOP
186 BiosCode
[Offset
++] = BOP_CONTROL_INT32
; // 32-bit Interrupt dispatcher
188 BiosCode
[Offset
++] = 0x73; // jnc EXIT (offset +4)
189 BiosCode
[Offset
++] = 0x04;
191 BiosCode
[Offset
++] = 0xFB; // sti
193 // HACK: The following instruction should be HLT!
194 BiosCode
[Offset
++] = 0x90; // nop
196 BiosCode
[Offset
++] = 0xEB; // jmp BOP_SEQ (offset -11)
197 BiosCode
[Offset
++] = 0xF5;
200 BiosCode
[Offset
++] = 0x83; // add sp, 4
201 BiosCode
[Offset
++] = 0xC4;
202 BiosCode
[Offset
++] = 0x04;
204 BiosCode
[Offset
++] = 0xCF; // iret
206 /* Register the Control BOP */
207 RegisterBop(BOP_CONTROL
, ControlBop
);
210 VOID
RegisterInt32(BYTE IntNumber
, EMULATOR_INT32_PROC IntHandler
)
212 Int32Proc
[IntNumber
] = IntHandler
;