; interrupt.asm
[extern isr_handler]
[extern irq_handler]

%macro ISR_NOERR 1
global isr%1
isr%1:
    cli
    push 0
    push %1
    jmp common_isr_stub
%endmacro

%macro ISR_ERR 1
global isr%1
isr%1:
    cli
    push %1
    jmp common_isr_stub
%endmacro

; --- Исключения (0-31) ---
%assign i 0
%rep 32
    %if i == 8 || (i >= 10 && i <= 14) || i == 17
        ISR_ERR i
    %else
        ISR_NOERR i
    %endif
    %assign i i+1
%endrep

; --- Аппаратные прерывания (IRQ -> Векторы 32, 33, 44) ---
%macro IRQ 2
global irq%1
irq%1:
    cli
    push 0
    push %2
    jmp common_irq_stub
%endmacro

IRQ 0, 32
IRQ 1, 33
IRQ 12, 44

common_isr_stub:
    pusha
    mov ax, ds
    push eax
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    push esp
    call isr_handler
    pop eax
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    popa
    add esp, 8
    iret

common_irq_stub:
    pusha
    mov ax, ds
    push eax
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    push esp
    call irq_handler
    pop eax
    pop eax
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    popa
    add esp, 8
    iret
