//kernel.c
//08/13/03 Josh Holtrop
//Holtrop's Operating System
//Version: 0.12
//Modified: 11/12/03

#include "k_defines.h"		//#DEFINE's for kernel

#include "lib/string.h"		//library string functions
#include "lib/io.h"		//library input/output functions

#include "functions.h"		//general functions
#include "video.h"		//video functions
#include "mm.h"			//physical memory management functions
#include "vmm.h"		//virtual memory management & paging functions
#include "keyboard.h"		//generic keyboard driver & functions
#include "mouse.h"		//generic ps/2 mouse driver & functions
#include "fdc.h"		//Floppy Disk Controller functions
#include "stdfont.h"		//Standard font bitmask array

void isr(dword num);
void k_init();
extern dword write_cr0(dword cr0);
extern dword read_cr0();
extern dword write_cr3(dword cr3);
extern dword read_cr3();

#include "fdc.c"
#include "mouse.c"
#include "keyboard.c"
#include "mm.c"
#include "vmm.c"
#include "functions.c"
#include "video.c"

dword	timer = 0;
dword	*videoMode;

//Main kernel initialization method
void k_init()
{
		// ===== Initialization
	fdc_sendDOR(0x0C);		//turn off floppy motor!!
	console_cls();
	remap_pics(0x20, 0x28);
	init_timer();
	mm_init();
	videoMode = (dword *)0x90002;
	if (*videoMode)
		video_init((ModeInfoBlock *) 0x90306);
	vmm_init();
	mouse_init();
	vmm_enable_paging();
	pic1_mask(0);			//unmask IRQ's 0-7
	pic2_mask(0);			//unmask IRQ's 8-15
	enable_ints();
	kbd_resetLEDs();		//after enabling interrupts!!
	
	char *bmpptr = (char *)0x108000+54;
	int a = 0;
	int x = 0;
	int y = 479;
	for (a=0; a < 640*480; a++)
	{
		video_pset(x, y, *(dword *)bmpptr);
		bmpptr += 3;
		x++;
		if (x == 640)
		{
			x = 0;
			y--;
		}
	}

	printf("HOS 0.12 - Kernel Size: %d kb\n", kernel_size()/1024);
	printf("Memory available to OS: %d MB (Bytes: %d)\n", mm_totalmem/0x100000, mm_totalmem);
	printf("Free memory: %d bytes\n", mm_freemem());

	dword key = 0;
	for (;;)
	{
		key = kbdWaitKey();
		if ((key & 0xFF) > 2)	//key is not a control key
			putc(key);
	}
}

// main Interrupt Service Routine - handles all interrupts unless caught by kernel.asm
void isr(dword num)
{
	switch(num)
	{
	case 0x20:         		// IRQ0 - timer interrupt
		timer++;
		(*(byte *)(0xb8000))++;
		eoi();
		break;
	case 0x21:  			// IRQ1 - keyboard interrupt
		isr_keyboard();    	//isr_keybard() takes care of calling eoi()
		break;
	case 0x2C:			// IRQ12 - PS/2 mouse
		isr_mouse();
		eoi2();
		break;
	default:
		printf("Interrupt %d (0x%x) Unhandled!!\n", num, num);
		break;
	}
}





