/* 
	時計表示用タスク管理＆CMOSいろいろ 
	
	1/8 未使用のfifoとタイマの変数を削除。
		ついでにio_hlt()をfor文内に追加することによりCPU使用率100%は改善 by is2os
*/

#include "bootpack.h"
#include <stdio.h>

/* CMOSデータ取得 */
int read_cmos(unsigned char *a) 
{
	char ef;
	static unsigned char adr[7] = { 0x00, 0x02, 0x04, 0x07, 0x08, 0x09, 0x32 };
	static unsigned char max[7] = { 0x60, 0x59, 0x23, 0x31, 0x12, 0x99, 0x99 };
	int i;	
	
	/*  ** 詳細情報 **
		0x00 秒
		0x02 分
		0x04 時
		0x07 日
		0x08 月
		0x09 年の下２桁
		0x32 年の上２桁
	*/

	/* 二度読みが成功までのループ */
	for (;;) {
		ef = 0;
		for (i = 0;i < 7;i++) {
			io_out8(0x70, adr[i]);
			a[i] = io_in8(0x71);
		}
		for (i = 0;i < 7;i++) {
			io_out8(0x70, adr[i]);
			if (a[i] != io_in8(0x71) || (a[i] & 0x0f) > 9 || a[i] > max[i]) {
				ef = 1;
			}
		}
		if (ef == 0) {
			return 0;
		}
	}	
}

/* 時計タスク起動 */
struct TASK *open_clocktask(struct SHEET *sht, unsigned char *buf)
{
	struct MEMMAN *memman = (struct MEMMAN *)MEMMAN_ADDR;
	struct TASK *task = task_alloc();
	task->ds_base = memman_alloc_4k(memman, 64 * 1024);
	task->tss.esp = task->ds_base + 64 * 1024 - 12;
	task->tss.eip = (int)&clock_task;
	task->tss.es = 1 * 8;
	task->tss.cs = 2 * 8;
	task->tss.ss = 1 * 8;
	task->tss.ds = 1 * 8;
	task->tss.fs = 1 * 8;
	task->tss.gs = 1 * 8;
	*((int *)(task->tss.esp + 4)) = (int)sht;
	*((int *)(task->tss.esp + 8)) = (int)buf;
	task_run(task, 4, 2, "clock");	/* ここの優先度は具合に応じて変更 */
	return task;
}

/* 時計タスク終了 */
void close_clocktask(struct TASK *task)
{
	struct MEMMAN *memman = (struct MEMMAN *)MEMMAN_ADDR;
	memman_free_4k(memman, task->ds_base, 64 * 1024);
	task_sleep(task);
	task->flags = 0;	
	return;
}

/* 時計表示用メインタスク */
void clock_task(struct SHEET *sht, unsigned char *buf)
{
	struct BOOTINFO *binfo = (struct BOOTINFO *)ADR_BOOTINFO;
	char datebuf[40];
	unsigned char date_add[7], date_old[7];

	/* 
		○時刻表示○ 
		ほんとうはタイマをつけて一秒ごとに更新する予定だったけどダルいからやめた。
		最初のデータと二回目のデータを比較する方法で更新しています。
		io_hlt()が入っているのはCPUへの負荷を減らすため。これで100%から半分以下になった(^o^)
	*/
	read_cmos(date_add);	/* 読み間違えがある可能性を考えて */
	for (;;)
	{
		read_cmos(date_add);
		if (date_old[0] != date_add[0]) {
		  	sprintf(datebuf, "%02x%02x/%02x/%02x %02x:%02x:%02x", date_add[6], date_add[5], 
		            		date_add[4], date_add[3], date_add[2], date_add[1], date_add[0]);
			sheet_refresh(sht, 84, binfo->scrny - 20, 245, binfo->scrny - 5);
			boxfill8(buf, binfo->scrnx, COL8_FFFFFF, 85, binfo->scrny - 20, 245, binfo->scrny - 5);	
			putfonts8_asc(buf, binfo->scrnx, 87, binfo->scrny - 20, COL8_000000, datebuf);
			date_old[0] = date_add[0];
		}
		io_hlt();
	}
	
	return;
}

