Ok, but it'll be a lot of code...
Code: Select all
//Exception messages
char *exception_messages[32] = {
"Division by Zero",
"Debug",
"Non Maskable Interrupt",
"Breakpoint",
"Info Detected Overflow",
"Out of Bounds",
"Invalid Opcode",
"No Coprocessor",
"Double Fault",
"Coprocessor Segment Overrun",
"Bad TSS",
"Segment Not Present",
"Stack Fault",
"General Protection Fault",
"Page Fault",
"Unknown Interrupt",
"Coprocessor Fault",
"Alignment Check",
"Machine Code",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
};
//ISR (interrupt service routine definitions
//they all jump to our common stub which then passes the stack
//(represented by the regs structure) as a parameter to the
//fault_handler function
//remember, we push dummy error codes to keep the stack frame uniform
void isr0() {
_asm {
cli
push 0
push 0
jmp isr_common_stub
}
}
void isr1() {
_asm {
cli
push 0
push 1
jmp isr_common_stub
}
}
void isr2() {
_asm {
cli
push 0
push 2
jmp isr_common_stub
}
}
void isr3() {
_asm {
cli
push 0
push 3
jmp isr_common_stub
}
}
void isr4() {
_asm {
cli
push 0
push 4
jmp isr_common_stub
}
}
void isr5() {
_asm {
cli
push 0
push 5
jmp isr_common_stub
}
}
void isr6() {
_asm {
cli
push 0
push 6
jmp isr_common_stub
}
}
void isr7() {
_asm {
cli
push 0
push 7
jmp isr_common_stub
}
}
void isr8() {
_asm {
cli
push 8
jmp isr_common_stub
}
}
void isr9() {
_asm {
cli
push 0
push 9
jmp isr_common_stub
}
}
void isr10() {
_asm {
cli
push 10
jmp isr_common_stub
}
}
void isr11() {
_asm {
cli
push 11
jmp isr_common_stub
}
}
void isr12() {
_asm {
cli
push 12
jmp isr_common_stub
}
}
void isr13() {
_asm {
cli
push 13
jmp isr_common_stub
}
}
void isr14() {
_asm {
cli
push 14
jmp isr_common_stub
}
}
void isr15() {
_asm {
cli
push 0
push 15
jmp isr_common_stub
}
}
void isr16() {
_asm {
cli
push 0
push 16
jmp isr_common_stub
}
}
void isr17() {
_asm {
cli
push 0
push 17
jmp isr_common_stub
}
}
void isr18() {
_asm {
cli
push 0
push 18
jmp isr_common_stub
}
}
void isr19() {
_asm {
cli
push 0
push 19
jmp isr_common_stub
}
}
void isr20() {
_asm {
cli
push 0
push 20
jmp isr_common_stub
}
}
void isr21() {
_asm {
cli
push 0
push 21
jmp isr_common_stub
}
}
void isr22() {
_asm {
cli
push 0
push 22
jmp isr_common_stub
}
}
void isr23() {
_asm {
cli
push 0
push 23
jmp isr_common_stub
}
}
void isr24() {
_asm {
cli
push 0
push 24
jmp isr_common_stub
}
}
void isr25() {
_asm {
cli
push 0
push 25
jmp isr_common_stub
}
}
void isr26() {
_asm {
cli
push 0
push 26
jmp isr_common_stub
}
}
void isr27() {
_asm {
cli
push 0
push 27
jmp isr_common_stub
}
}
void isr28() {
_asm {
cli
push 0
push 28
jmp isr_common_stub
}
}
void isr29() {
_asm {
cli
push 0
push 29
jmp isr_common_stub
}
}
void isr30() {
_asm {
cli
push 0
push 30
jmp isr_common_stub
}
}
void isr31() {
_asm {
cli
push 0
push 31
jmp isr_common_stub
}
}
void isr_common_stub() {
_asm {
pusha
push ds
push es
push fs
push gs
mov ax, 10h
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
call fault_handler
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8 ; Cleans up the stack
iret
}
return;
}
void fault_handler(struct regs *stack) {
setattrib(4, 15);
clrscr();
if(stack->int_no < 32) {
printf("fault_handler: Exception occurred: %s\n", exception_messages[stack->int_no]);
}
else {
printf("fault_handler: Unhandled exception occurred\n");
}
}
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags) {
idt[num].base_lo = (base & 0xFFFF);
idt[num].base_hi = (base >> 16) & 0xFFFF;
idt[num].sel = sel;
idt[num].always0 = 0;
idt[num].flags = flags;
}
void install_idt() {
idtp.limit = (sizeof(struct idt_entry)*256)-1;
idtp.base = &idt;
// blank out the IDT entries
memset(idt, 0, (sizeof(struct idt_entry)*256)-1);
// install all of our ISRs
idt_set_gate(0, (unsigned)isr0, 0x08, 0x8E);
idt_set_gate(1, (unsigned)isr1, 0x08, 0x8E);
idt_set_gate(2, (unsigned)isr2, 0x08, 0x8E);
idt_set_gate(3, (unsigned)isr3, 0x08, 0x8E);
idt_set_gate(4, (unsigned)isr4, 0x08, 0x8E);
idt_set_gate(5, (unsigned)isr5, 0x08, 0x8E);
idt_set_gate(6, (unsigned)isr6, 0x08, 0x8E);
idt_set_gate(7, (unsigned)isr7, 0x08, 0x8E);
idt_set_gate(8, (unsigned)isr8, 0x08, 0x8E);
idt_set_gate(9, (unsigned)isr9, 0x08, 0x8E);
idt_set_gate(10, (unsigned)isr10, 0x08, 0x8E);
idt_set_gate(11, (unsigned)isr11, 0x08, 0x8E);
idt_set_gate(12, (unsigned)isr12, 0x08, 0x8E);
idt_set_gate(13, (unsigned)isr13, 0x08, 0x8E);
idt_set_gate(14, (unsigned)isr14, 0x08, 0x8E);
idt_set_gate(15, (unsigned)isr15, 0x08, 0x8E);
idt_set_gate(16, (unsigned)isr16, 0x08, 0x8E);
idt_set_gate(17, (unsigned)isr17, 0x08, 0x8E);
idt_set_gate(18, (unsigned)isr18, 0x08, 0x8E);
idt_set_gate(19, (unsigned)isr19, 0x08, 0x8E);
idt_set_gate(20, (unsigned)isr20, 0x08, 0x8E);
idt_set_gate(21, (unsigned)isr21, 0x08, 0x8E);
idt_set_gate(22, (unsigned)isr22, 0x08, 0x8E);
idt_set_gate(23, (unsigned)isr23, 0x08, 0x8E);
idt_set_gate(24, (unsigned)isr24, 0x08, 0x8E);
idt_set_gate(25, (unsigned)isr25, 0x08, 0x8E);
idt_set_gate(26, (unsigned)isr26, 0x08, 0x8E);
idt_set_gate(27, (unsigned)isr27, 0x08, 0x8E);
idt_set_gate(28, (unsigned)isr28, 0x08, 0x8E);
idt_set_gate(29, (unsigned)isr29, 0x08, 0x8E);
idt_set_gate(30, (unsigned)isr30, 0x08, 0x8E);
idt_set_gate(31, (unsigned)isr31, 0x08, 0x8E);
// load our IDT
idt_load();
}
That was all the relevant things in idt.c (well things I thought were relevant), and here's the declaration of the regs structure in idt.h