I've added IRQs handling (i've remapped the iqrs to the 32-47th interrupts) to my IDT and tried to test it using the first channel of the PIT (which is the timer) and somehow it doesn't respond (the interrupt handler isn't even called from assembly)
Here are the sources:
this the interrupt handler:
Code: Select all
void interrupt_handler(registers_state registers)
{
change_bg_color(0x09);
change_foreground_color(0x0F);
screen_clear();
puts("Interrupt handling in action...\n");
if(registers.interrupt_number < 32) // if it's an exception
{
puts(exceptions_names[registers.interrupt_number]);
puts(" Exception has been caught!\n");
puts("Halting the system...");
for(;;) ;
}
if(registers.interrupt_number >= 32 && registers.interrupt_number <= 47) // IRQ
{
puts("An IRQ has been caught!\n");
if(registers.interrupt_number >= 40) // the IRQ came from the slave
outport(0x0A, 0x20); // sending an EOI (end of interrupt) to the slave
outport(0x20, 0x20); // sending an EOI to the master anyways
if(int_handlers[registers.interrupt_number] != 0) // if it's not NULL
int_handlers[registers.interrupt_number](registers);
}
}
Code: Select all
%macro ISR_NON_ERR_CODE 1
global exception%1
exception%1:
cli ; we don't want anyone to interrupt us
push 0 ; we want to keep up on an aligned stack frame
push %1 ; interrupt number
jmp call_isr
%endmacro
%macro ISR_DROP_ERR_CODE 1
global exception%1
exception%1:
cli
push %1
; push ERR_CODE (an error code is pushed already)
jmp call_isr
%endmacro
%macro IRQ 2
global IRQ%1
IRQ%1:
cli
push 0
push %2
jmp call_isr
%endmacro
ISR_NON_ERR_CODE 0
ISR_NON_ERR_CODE 1
ISR_NON_ERR_CODE 2
ISR_NON_ERR_CODE 3
ISR_NON_ERR_CODE 4
ISR_NON_ERR_CODE 5
ISR_NON_ERR_CODE 6
ISR_NON_ERR_CODE 7
ISR_DROP_ERR_CODE 8
ISR_NON_ERR_CODE 9
ISR_DROP_ERR_CODE 10
ISR_DROP_ERR_CODE 11
ISR_DROP_ERR_CODE 12
ISR_DROP_ERR_CODE 13
ISR_DROP_ERR_CODE 14
ISR_NON_ERR_CODE 15
ISR_NON_ERR_CODE 16
ISR_NON_ERR_CODE 17
ISR_NON_ERR_CODE 18
ISR_NON_ERR_CODE 19
ISR_NON_ERR_CODE 20
ISR_NON_ERR_CODE 21
ISR_NON_ERR_CODE 22
ISR_NON_ERR_CODE 23
ISR_NON_ERR_CODE 24
ISR_NON_ERR_CODE 25
ISR_NON_ERR_CODE 26
ISR_NON_ERR_CODE 27
ISR_NON_ERR_CODE 28
ISR_NON_ERR_CODE 29
ISR_NON_ERR_CODE 30
ISR_NON_ERR_CODE 31
IRQ 0, 32
IRQ 1, 33
IRQ 2, 34
IRQ 3, 35
IRQ 4, 36
IRQ 5, 37
IRQ 6, 38
IRQ 7, 39
IRQ 8, 40
IRQ 9, 41
IRQ 10, 42
IRQ 11, 43
IRQ 12, 44
IRQ 13, 45
IRQ 14, 46
IRQ 15, 47
extern interrupt_handler
global call_isr
call_isr:
pusha
mov ax, ds
push eax
mov ax, 0x10
mov ds, ax
mov fs, ax
mov gs, ax
mov es, ax
mov ss, ax
call interrupt_handler
pop eax
mov ds, ax
mov fs, ax
mov gs, ax
mov es, ax
mov ss, ax
add esp, 8 ; interrupts number and error code
popa
sti ; enable interrupts from here
iret
Code: Select all
#include "prototypes.h"
unsigned int ticks = 0;
void tick(registers_state registers)
{
ticks++;
puts("Whoops!\n");
/*if(ticks == 50)
{
puts("That's enough for me...\n");
int_handlers[32]/*IRQ #0*/ = 0;
}*/
}
void initialize_timer(unsigned int frequency)
{
register_int_handler(32/*IRQ #0*/, &tick);
unsigned int divisor = 1193180 / frequency;
outport(0x43, 0x36);
unsigned char l = divisor & 0xFF;
unsigned char h = (divisor >> 8) & 0xFF;
outport(0x40, l);
outport(0x40, h);
}
What am I doing wrong?