#ifndef IDT_H
#define IDT_H

#include <stdint.h>
#include <stdbool.h>
#include <shade/platform/gdt.h>

#define IDT_DESCRIPTORS 256

extern void* isr_stub_table[];

typedef struct idt_entry_struct {
    uint16_t isr_low;   // Low 16 bits of handler address
    uint16_t kernel_cs; // The selector in the GDT that the CPU will load into CS before calling the handler
    uint8_t ist;        // The IST in the TSS that the CPU will load into RSP; set to zero for now
    uint8_t attributes; // Type and attributes
    uint16_t isr_mid;   // Middle 16 bits of handler address
    uint32_t isr_high;  // Upper 32 bits of handler address
    uint32_t reserved;  // Reserved, set to 0
} __attribute__((packed)) idt_descriptor_t;

typedef struct idt_ptr_struct {
    uint16_t limit;
    uint64_t base;
} __attribute__((packed)) idt_ptr_t;

__attribute__((aligned(0x10)))
static idt_descriptor_t idt[IDT_DESCRIPTORS];
static idt_ptr_t idt_ptr;
static bool vectors[IDT_DESCRIPTORS];

void idt_set_gate(uint8_t index, void* isr, uint8_t flags);
void idt_assemble();

void idt_enable_interrupts();
void idt_disable_interrupts();

#endif