//
// isr.c -- High level interrupt service routines and interrupt request handlers.
//		  Part of this code is modified from Bran's kernel development tutorials.
//		  Rewritten for JamesM's kernel development tutorials.
//

#include "platform.h"
#include "globals.h"
#include "iprintable.h"
#include "iirqhandler.h"
#include "log.h"
#include "common.h"
#include "isr.h"

	Sortix::IIRQHandler* interrupt_handlers[256];

	void register_interrupt_handler(u8int n, Sortix::IIRQHandler* handler)
	{
		interrupt_handlers[n] = handler;
	}

	// This gets called from our ASM interrupt handler stub.
	extern "C" void isr_handler(Sortix::InterruptRegisters Regs)
	{
		Sortix::GLog->PrintF("recieved interrupt: %zu eip=0x%p\n", Regs.int_no, Regs.eip);

		if (interrupt_handlers[Regs.int_no] != NULL)
		{
			interrupt_handlers[Regs.int_no]->OnIRQ(&Regs);
		}
	}

	// This gets called from our ASM interrupt handler stub.
	extern "C" void irq_handler(Sortix::InterruptRegisters Regs)
	{
		// TODO! IRQ 7 and 7 might be spurious and ought to be ignored.
		// See http://wiki.osdev.org/PIC for details (section Spurious IRQs).

		// Send an EOI (end of interrupt) signal to the PICs.		
		if (Regs.int_no >= 40) { Sortix::X86::OutPortB(0xA0, 0x20); } // Send reset signal to slave if this interrupt involved the slave.		
		Sortix::X86::OutPortB(0x20, 0x20); // Send reset signal to master.

		if ( interrupt_handlers[Regs.int_no] != NULL )
		{
			interrupt_handlers[Regs.int_no]->OnIRQ(&Regs);
		}
	}

