.code32
.macro ISR_NOERRCODE num
.global isr\num
isr\num:
    pushl $0           
    pushl $\num        
    jmp isr_common_stub
.endm

.macro ISR_ERRCODE num
.global isr\num
isr\num:
    pushl $\num       
    jmp isr_common_stub
.endm

.extern common_interrupt_handler # interrupts.c
isr_common_stub:
    pushal             

    xor %eax, %eax
    mov %ds, %ax    
    pushl %eax

    mov $0x10, %ax
    mov %ax, %ds
    mov %ax, %es

    pushl %esp         
    call common_interrupt_handler
    addl $4, %esp      

    popl %eax
    mov %ax, %ds
    mov %ax, %es

    popal              
    addl $8, %esp      
    iret            

.extern idtr
.global load_idt
load_idt:
    lidt idtr 
    ret

ISR_NOERRCODE 0    # Divide by Zero
ISR_NOERRCODE 1    # Debug
ISR_ERRCODE   8    # Double Fault (Has Error Code!)
ISR_ERRCODE   13   # General Protection Fault (Has Error Code!)
ISR_ERRCODE   14   # Page Fault (Has Error Code!)

// This is a special case so we need to handle it for task switching
.global isr32
.extern switch_context  # scheduler.c
.extern send_eoi_master     # drivers/pic/pic.S
isr32:
    cli
    pushal
    push %ds

    mov $0x10, %ax
    mov %ax, %ds
    
    pushl %esp 
    call switch_context
    movl %eax, %esp 

    call send_eoi_master

    pop %ds
    popal
    sti
    iret

ISR_NOERRCODE 33   # IRQ1 - Keyboard

ISR_NOERRCODE 46   # IRQ14
ISR_NOERRCODE 47   # IRQ15