#include "../bootpack.h"

void system::inthandler20(int *esp)
// タイマー割り込み
{
	IO8 ocw2(PIC::PIC0_OCW2);
	bool taskswitch = false;
	
	ocw2 << 0x60; // IRQ-00受付完了をPICへ通知
	
	g_timerctl->countup();
	
//	task1_fifo->push(
//		Message::create(MSG::TYPE::TIMER, 1, g_timerctl->get_count())
//		);
	
	if (g_timerctl->get_timeout() > g_timerctl->get_count()) {
		// まだ先頭タイマーもタイムアウトしていないようだ
		return;
	}
	
	Timer* tim = g_timerctl->get_timer_top();
	
	for (;;) {
		if (tim->get_time() > g_timerctl->get_count()) {
			break;
		}
		
		// タイムアウトを通知
		tim->timeout();
		
		// tasktimerとtimが等しいか確認
		if (tim != g_task_timer) {
			tim->send_message();
		} else {
			taskswitch = true;
		}
		
		tim = tim->get_nexttimer();
	}
	
	// 先頭タイマーを更新する(同時にg_timerctl->next_timeout_も変更される)
	g_timerctl->set_timer_top(tim);
	
	if (taskswitch) {
		g_taskctl->task_switch();
	}
}

void system::inthandler21(int *esp)
// PS/2キーボードからの割り込み
{
	byte data;
	IO8 ocw2(PIC::PIC0_OCW2);
	IO8 keydat(Keyboard::PORT_KEYDAT);
	
	ocw2 << 0x61; // IRQ-01受付完了をPICへ通知
	keydat >> data;
	g_taskctl->send_message(
		TASK_KEYBOARD,
		Message::create(MSG::TYPE::KEYBOARD, data)
		);
//	task1_fifo->push(
//		Message::create(MSG::TYPE::KEYBOARD, data)
//		);
}

void system::inthandler27(int *esp)
{
	/* PIC0からの不完全割り込み対策 */
	IO8 ocw2(PIC::PIC0_OCW2);
	ocw2 << 0x67; // IRQ-07受付完了をPICへ通知
	return;
}

void system::inthandler2c(int *esp)
// PS/2マウスからの割り込み
{
	byte data;
	IO8 p0ocw2(PIC::PIC0_OCW2);
	IO8 p1ocw2(PIC::PIC1_OCW2);
	IO8 keydat(Keyboard::PORT_KEYDAT);
	p1ocw2 << 0x64; // IRQ-12受付完了をPIC1へ通知
	p0ocw2 << 0x62; // IRQ-02受付完了をPIC0へ通知
	keydat >> data;
	g_taskctl->send_message(
		TASK_MOUSE,
		Message::create(MSG::TYPE::MOUSE, data)
		);
//	task1_fifo->push(
//		Message::create(MSG::TYPE::MOUSE, data)
//		);
	//dbg("int mouse");
}
