/*
	○sysinfo○
	
	要はシステムの表示とかやる。
	参考までに他の機能をいろいろ追加。
	
	3/6 0.0.5 表示を少し変更、細かいことじゃない。
*/

#include "apilib.h"
#include <stdio.h>
#include <string.h>

void HariMain(void)
{
	HWND win;
	HTIME timer; 
	int x = 400, y = 350, i;
	char wbuf[x * y];
	char str1[] = "◆System infomation◆";
	char buf[120], cpu_dat[13], name[49];
	unsigned int eax, ebx, ecx, edx; 
	unsigned int family, model, stepping;
	unsigned int family_ex, model_ex, stepping_ex;
	unsigned int max_cpuid_ex;
	unsigned int tsc_start_high, tsc_start_low, tsc_end_high, tsc_end_low, clock;

	win = api_openwin(wbuf, x, y, -1, "sysinfo");
	timer = api_alloctimer();
	api_inittimer(timer, 128);

	api_boxfilwin(win, 10, 25, 390, 50, COL_L_BLUE);
	api_putstrwin(win, 115, 30, 0, sizeof(str1), str1);
	api_linewin(win, 10, 55, x - 10, 55, 0);
	
	/********** CPU情報 ************/
	api_cpuid(0x00000000, 0x0, &eax, &ebx, &ecx, &edx);
	memcpy(cpu_dat, &ebx, 4);
	memcpy(cpu_dat+4, &edx, 4);
	memcpy(cpu_dat+8, &ecx, 4);
	cpu_dat[12] = '\0';
	api_putstrwin(win, 150, 70, 0, 12, cpu_dat);
	
	api_cpuid(0x00000001, 0x0, &eax, &ebx, &ecx, &edx);
	family   = (((eax >> 20) & 0xFF) << 4)
             + ((eax >> 8) & 0xF);
	model    = (((eax >> 16) & 0xF) << 4)
             + ((eax >> 4) & 0xF);
	stepping = (eax >> 0) & 0xF;
	sprintf(buf, "Family = %Xh, Model = %Xh, Stepping = %Xh",
					family, model, stepping);
	api_putstrwin(win, 50, 95, 0, strlen(buf), buf);	

	api_cpuid(0x80000000, 0x0, &eax, &ebx, &ecx, &edx);
	max_cpuid_ex = eax;
	if (max_cpuid_ex >= 0x80000001) {
		api_cpuid(0x80000001, 0x0, &eax, &ebx, &ecx, &edx);
		family_ex   = (((eax >> 20) & 0xFF) << 4)
	                    + ((eax >> 8) & 0xF);
		model_ex    = (((eax >> 16) & 0xF) << 4)
	                    + ((eax >> 4) & 0xF);
		stepping_ex = (eax >> 0) & 0xF;
		sprintf(buf, "FamilyEx = %Xh, ModelEx = %Xh, SteppingEx = %Xh",
				family_ex, model_ex, stepping_ex);
		api_putstrwin(win, 40, 110, 0, strlen(buf), buf);	
	}
	if (max_cpuid_ex >= 0x80000004) {
		api_cpuid(0x80000002, 0x0, &eax, &ebx, &ecx, &edx);
		memcpy(name     , &eax, 4);
		memcpy(name +  4, &ebx, 4);
		memcpy(name +  8, &ecx, 4);
		memcpy(name + 12, &edx, 4);
		api_cpuid(0x80000003, 0x0, &eax, &ebx, &ecx, &edx);
		memcpy(name + 16, &eax, 4);
		memcpy(name + 20, &ebx, 4);
		memcpy(name + 24, &ecx, 4);
		memcpy(name + 28, &edx, 4);
		api_cpuid(0x80000004, 0x0, &eax, &ebx, &ecx, &edx);
		memcpy(name + 32, &eax, 4);
		memcpy(name + 36, &ebx, 4);
		memcpy(name + 40, &ecx, 4);
		memcpy(name + 44, &edx, 4);
		name[49] = '\0';
		api_putstrwin(win, 50, 130, 0, 48, name);
	}

	/* そのほかいろいろ */
	api_boxfilwin(win, 40, 164, 355, 322, COL_WHITE);
	api_putstrwin(win, 50, 165, COL_BLACK, 9, "○Devices");
	api_putstrwin(win, 50, 185, COL_BLACK, 18, "80x87 coprocessor");
	api_putstrwin(win, 50, 205, COL_BLACK, 9, "Gameport");
	api_putstrwin(win, 50, 225, COL_BLACK, 16, "Pointing device");
	api_putstrwin(win, 50, 245, COL_BLACK, 19, "Floppy disk device");
		
	for (i = 0;i <= 4;i++) {
		switch (i) {
			case 0:	
				if (api_getpcinfo(PCIF_COPROCESS) == 1) 
					api_putstrwin(win, 250, 185 + 20 * i, COL_BLACK, 10, "installed");
				else
					api_putstrwin(win, 250, 185 + 20 * i, COL_RED, 14, "not installed");
				break;
			case 1:
				if (api_getpcinfo(PCIF_GAMEPORT) == 1) 
					api_putstrwin(win, 250, 185 + 20 * i, COL_BLACK, 10, "installed");
				else 
					api_putstrwin(win, 250, 185 + 20 * i, COL_RED, 14, "not installed");
				break;
			case 2:
				if (api_getpcinfo(PCIF_PDEVICE) == 1) 
					api_putstrwin(win, 250, 185 + 20 * i, COL_BLACK, 10, "installed");
				else
					api_putstrwin(win, 250, 185 + 20 * i, COL_RED, 14, "not installed");
				break;
			case 3:
				if (api_getpcinfo(PCIF_FDINST) == 1) 
					api_putstrwin(win, 250, 185 + 20 * i, COL_BLACK, 10, "installed");
				else
					api_putstrwin(win, 250, 185 + 20 * i, COL_RED, 14, "not installed");
				break;
		}
	}	

	/* APMデータ */
	api_putstrwin(win, 50, 300, COL_BLACK, 13, "APM shutdown");
	sprintf(buf, "○APM version %04d.", (unsigned)api_getpcinfo(PCIF_FNDAPM));
	api_putstrwin(win, 50, 280, COL_BLACK, strlen(buf), buf);
	if ((unsigned)api_getpcinfo(PCIF_FNDAPM) > 101)
		api_putstrwin(win, 250, 300, COL_BLACK, 8, "possible");
	else 
		api_putstrwin(win, 250, 300, COL_RED, 11, "impossible");

	/* 周波数 */
	api_rdtsc(&tsc_start_high, &tsc_start_low);
	for (;;) {
		api_settimer(timer, 100);
		if (api_getkey(1) != 128) goto end;
	
		api_rdtsc(&tsc_end_high, &tsc_end_low);
		clock = (tsc_end_low - tsc_start_low) / 1000 / 1000;
		sprintf(buf, "Clock = %dMHz", clock);
		api_boxfilwin(win, 150, 140, 290, 160, COL_L_GRAY);
		api_putstrwin(win, 145, 140, 0, strlen(buf), buf);
		tsc_start_high = tsc_end_high;
		tsc_start_low = tsc_end_low;
	}

end:
	api_closewin(win);
	api_end();
}
