// timer.c -- Initialises the PIT, and handles clock updates.
//            Written for JamesM's kernel development tutorials.

#include "platform.h"
#include "globals.h"
#include "iprintable.h"
#include "iirqhandler.h"
#include "log.h"
#include "panic.h"
#include "timer.h"
#include "isr.h"

namespace Sortix
{
	DEFINE_GLOBAL_OBJECT(Timer, Timer);

	void Timer::Init()
	{
		// Initialize our variables.
		Ticks = 0;
		Miliseconds = 0;

		uint32_t Frequency = 100; // 100 Hz

		// First, register our timer callback.
		register_interrupt_handler(IRQ0, this);

		// The value we send to the PIT is the value to divide it's input clock
		// (1193180 Hz) by, to get our required frequency. Important to note is
		// that the divisor must be small enough to fit into 16-bits.
		u32int Divisor = 1193180 / Frequency;

		// Send the command byte.
		X86::OutPortB(0x43, 0x36);

		// Divisor has to be sent byte-wise, so split here into upper/lower bytes.
		uint8_t L = (uint8_t) (Divisor & 0xFF);
		uint8_t H = (uint8_t) ((Divisor>>8) & 0xFF);

		// Send the frequency divisor.
		X86::OutPortB(0x40, L);
		X86::OutPortB(0x40, H);
	}

	void Timer::OnIRQ(InterruptRegisters* Regs)
	{
		Ticks++;
		//Sortix::GLog->PrintF("Tick: %u\n", (uint32_t) Ticks);

		//if ( 500 < Ticks ) { Sortix::Panic("Oh no! It's over 9000/18!"); }
	}
}
