#ifndef INT_H
#define INT_H

#include "../types.h"

typedef struct {
	u16 isr_low;      // The lower 16 bits of the ISR's address
	u16 kernel_cs;    // The GDT segment selector that the CPU will load into CS before calling the ISR
	u8  reserved;     // Set to zero
	u8  attributes;   // Type and attributes; see the IDT page
	u16 isr_high;     // The higher 16 bits of the ISR's address
} __attribute__((packed)) idt_entry_t;

__attribute__((aligned(0x10))) 
static idt_entry_t idt[256]; // Create an array of IDT entries; aligned for performance

typedef struct {
	u16	limit;
	u32	base;
} __attribute__((packed)) idtr_t;

static idtr_t idtr;

typedef struct {
   u32 ds; /* Data segment selector */
   u32 edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */
   u32 int_no, err_code; /* Interrupt number and error code (if applicable) */
   u32 eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */
} registers_t;

__attribute__((noreturn))
void exception_handler(registers_t r);

void idt_set_descriptor(u8 vector, void* isr, u8 flags);

extern void* isr_stub_table[];
 
void idt_init(void);

#endif