~kernel/irq.cr
.cr
Crystal
(text/x-crystal)
lib KernelShim
  fun outb(port : UInt16, value : UInt8) : Void
end

module IRQ
  IRQ_COUNT = 16
  HANDLERS = StaticArray(Proc(UInt8, Void)?, IRQ_COUNT).new()
  
  def self.init
    puts "IRQ initialized!\n"
  end

  def self.register(irq : Int32, handler : Proc(UInt8, Void)) : Proc(UInt8, Void)?
    return nil if irq < 0 || irq >= IRQ_COUNT
    prev = HANDLERS[irq]
    HANDLERS[irq] = handler
    puts "irq handler registered\n"
    prev
  end

  def self.dispatcher(irq : UInt32)
    puts "irq dispatcher called ...\n"
    i = irq.to_u8
    if handler = HANDLERS[i]
      handler.call(i)
    end
  end
end

fun irq_dispatcher_c(irq : UInt32)
  puts "irq_dispatcher_c\n"
  IRQ.dispatcher(irq)
end

fun pic_send_eoi(irq : UInt32)
  puts "pic_send_eoi\n"
  if irq >= 8
    KernelShim.outb(0xA0_u16, 0x20_u8)
  end
  KernelShim.outb(0x20_u16, 0x20_u8)
end