section .text

%include "cpu.inc"

global __interrupt_vector
extern interrupt_handler


%macro CREATE_INTERRUPT_NAME 1  
    dq entry_interrupt_handler%1
%endmacro

; functions

%macro GLOBAL_INTERRUPT_HANDLER_ENTRY 1
    %assign y %1*2
    SWAPGS_IF_NECESSARY y
    PUSH_REG

    cld
    
    mov rdi, rsp
    mov rsi, [gs:0x0]
    
    call interrupt_handler

    POP_REG

    %assign y y+1
    SWAPGS_IF_NECESSARY y

    add    rsp, 16  ; remove error code and interrupt number from stack 
    iretq
%endmacro

; entries

%macro INTERRUPT_WITHOUT_ERROR_CODE  1
entry_interrupt_handler%1:
    push 0  ; fill the stack
    push %1
    GLOBAL_INTERRUPT_HANDLER_ENTRY %1
%endmacro

%macro INTERRUPT_WITH_ERROR_CODE  1
entry_interrupt_handler%1:
    push %1
    GLOBAL_INTERRUPT_HANDLER_ENTRY %1
%endmacro

; create functions

INTERRUPT_WITHOUT_ERROR_CODE 0
INTERRUPT_WITHOUT_ERROR_CODE 1
INTERRUPT_WITHOUT_ERROR_CODE 2
INTERRUPT_WITHOUT_ERROR_CODE 3
INTERRUPT_WITHOUT_ERROR_CODE 4
INTERRUPT_WITHOUT_ERROR_CODE 5
INTERRUPT_WITHOUT_ERROR_CODE 6
INTERRUPT_WITHOUT_ERROR_CODE 7
INTERRUPT_WITH_ERROR_CODE   8
INTERRUPT_WITHOUT_ERROR_CODE 9
INTERRUPT_WITH_ERROR_CODE   10
INTERRUPT_WITH_ERROR_CODE   11
INTERRUPT_WITH_ERROR_CODE   12
INTERRUPT_WITH_ERROR_CODE   13
INTERRUPT_WITH_ERROR_CODE   14
INTERRUPT_WITHOUT_ERROR_CODE 15
INTERRUPT_WITHOUT_ERROR_CODE 16
INTERRUPT_WITH_ERROR_CODE   17
INTERRUPT_WITHOUT_ERROR_CODE 18
INTERRUPT_WITHOUT_ERROR_CODE 19
INTERRUPT_WITHOUT_ERROR_CODE 20
INTERRUPT_WITHOUT_ERROR_CODE 21
INTERRUPT_WITHOUT_ERROR_CODE 22
INTERRUPT_WITHOUT_ERROR_CODE 23
INTERRUPT_WITHOUT_ERROR_CODE 24
INTERRUPT_WITHOUT_ERROR_CODE 25
INTERRUPT_WITHOUT_ERROR_CODE 26
INTERRUPT_WITHOUT_ERROR_CODE 27
INTERRUPT_WITHOUT_ERROR_CODE 28
INTERRUPT_WITHOUT_ERROR_CODE 29
INTERRUPT_WITH_ERROR_CODE   30
INTERRUPT_WITHOUT_ERROR_CODE 31


%assign i 32
%rep 256 - i
    INTERRUPT_WITHOUT_ERROR_CODE i
%assign i i+1
%endrep

; ; link functions

__interrupt_vector:
    %assign i 0
    %rep 256
        CREATE_INTERRUPT_NAME i
    %assign i i+1
    %endrep