/*
 *	PECLS Operating System
 *	(Parallel Execute Control Learning System)
 *	        Copyright (C) 1994,95,96,98,99 M.Suzuki
 *
 *	boot loader
 *
 */

/*
 *
 *	$Id: check.c,v 1.1.1.1 2000/02/25 08:06:37 suzuki Exp $
 *
 *	$Log: check.c,v $
 *	Revision 1.1.1.1  2000/02/25 08:06:37  suzuki
 *	Check in from LEVEL-05alpha version.
 *	
 *
 */

#include <stdio.h>
#include <iocslib.h>

#include <itron.h>		/* カーネル依存ヘッダ	*/
#include <boot.h>

#include "lowfnc.h"
#include "loader.h"

/*					*/
/*	機器情報を表示	*/
/*					*/

void TitleDisplay(void)
{
	{
		char name[60];
		char mpu[20];
		char clock[10];

		Null(info);
		name[0] = '\0';
		if( info->machine & MAC_EX68K ){
			strcat(name,"EX68K");
		} else {
			if( ((ROMVER()>>24)&0x0f)>3 ){
				strcat(name,"X68030");
			} else {
				strcat(name,"X68000");
				if( ((ROMVER()>>24)&0x0f)>2 ){
					strcat(name,"compact");
				} else
				if( ((ROMVER()>>24)&0x0f)==1 ){
					strcat(name,"XVI");
				} else
				if( info->machine & OPT_SCSIIN ){
					strcat(name,"SUPER");
				} else {
					strcat(name,"ACE/EXPERT/PRO");
				}
			}
			if( info->machine & MAC_XELLENT30 ){
				strcat(name,"+Xellent30");
			} else
			if( info->machine & MAC_EXCEL40 ){
				strcat(name,"+040Excel");
			} else
			if( info->machine & MAC_JUPITER ){
				strcat(name,"+Jupiter-X");
			} else
			if( info->machine & MAC_040TURBO ){
				strcat(name,"+040turbo");
			} else
			if( info->machine & MAC_060TURBO ){
				strcat(name,"+060turbo");
			}
			if( info->machine & MAC_VENUS ){
				strcat(name,"+Venus-X");
			}
		}

		strcpy(mpu,"(MC680x0");
		mpu[6] = info->mpu + '0';
		if( info->machine & MAC_FPU ){
			strcat(mpu,"+FPU");
		}
		if( info->machine & MAC_MMU ){
			strcat(mpu,"+MMU");
		}
		strcat(mpu,")");

		{
			int n = 0;
			int num = info->clock;
			if( num / 100 ){
				clock[n++] = (num/100) + '0';
				num = num%100;
			}
			clock[n++] = (num/10) + '0';
			clock[n++] = '.';
			clock[n++] = (num%10) + '0';
			clock[n] = '\0';
		}
		sprintf(version,"PECLS-OS loader (level %d) Copyright(c)1998-2000 M.Suzuki",LEVEL);
		printf("%s\n",version);
		printf("  機体      %s %s  %sMHz   %d MB\n",name,mpu,clock,info->ram);
	}
	{
		unsigned int ver = ROMVER();
		unsigned int verh,verl;
		unsigned int year,month,day;

		day = ver & 0xff;	ver >>= 8;
		day = ((day>>4)&0x0f)*10 + (day&0x0f);
		month = ver & 0xff;	ver >>= 8;
		month = ((month>>4)&0x0f)*10 + (month&0x0f);
		year = ver & 0xff;	ver >>= 8;
		year = ((year>>4)&0x0f)*10 + (year&0x0f);
		year += 1900;
		if( year < 50 ){
			year += 100;
		}
		verl = ver & 0x0f;	ver >>= 4;
		verh = ver;
	printf("  ROM版数       %d.%d 版  %d 年 %d 月 %d 日製\n",
			   verh,verl,year,month,day);
	}
	{
		unsigned int hour;
		unsigned int min;
		unsigned int sec;
		unsigned int msec;

		min = B_LPEEK((unsigned long*)0x0ed0040);	/* SRAMを参照	*/
		min *= 60 + ONTIME();
		msec = min % 100;	min /= 100;
		sec = min % 60;		min /= 60;
		hour = min / 60;	min %= 60;
	printf("  起動履歴  %d 回目    %d 時間 %d 分 %d 秒 %d 稼働\t",
			   B_LPEEK((unsigned long*)0x0ed0044),hour,min,sec,msec);
	}
	{
		unsigned int info;

		info = BOOTINF();
		if( isHDD(info) ){
			printf("ハードディスク %d番より",info&0x0f);
			bootDrive = info;
		} else
		if( isFDD(info) ){
			printf("フロッピーディスク %d番より",info&0x0f);
			bootDrive = info;
		} else
		if( isSRAM(info) ){
			printf("SRAM %p番地より",info);
		} else {
			printf("ROM %p番地より",info);
		}
		printf("\n");
	}
	{
		char ext[256];

		ext[0] = '\0';
		if( info->option & OPT_SCSIIN ){
			strcat(ext,"内蔵SCSI");
		} else {
			strcat(ext,"内蔵SASI");
		}
		if(info->option & OPT_SCSIEX ){
			if( info->option & OPT_MACH2 ){
				strcat(ext," + Mach2");
			} else
			if( info->option & OPT_MACH2P ){
				strcat(ext," + Mach2p");
			} else {
				strcat(ext," + 外付けSCSI");
			}
		}
		if( info->option & OPT_POLYPHON ){
			strcat(ext," + Polyphon");		/* FIXME	検出処理が無い	*/
		}
		if( info->option & OPT_PSX ){
			strcat(ext," + PSX16550");		/* FIXME	検出処理が無い	*/
		}
		if( info->option & OPT_NEPTUNE ){
			strcat(ext," + Neptune-X");		/* FIXME	検出処理が無い	*/
		}
		if( info->option & OPT_MIDI ){
			strcat(ext," + MIDI");
		}
		if( info->option & OPT_MARCURY ){
			strcat(ext," + Marcury-Unit");		/* FIXME	検出処理が無い	*/
		}
		if( info->option & OPT_GA ){
			strcat(ext," + GA");		/* FIXME	検出処理が無い	*/
		}
		printf("  補助装備  %s\n",ext);
	}
	printf("\n");
}

void SystemCheck(void)
{
	PR(("MPUCheck"));
	Null(info);
	info->mpu = MPUCheck();
	info->machine |= EX68Check()?MAC_EX68K:0;
	if( info->mpu ){
		info->option |= OPT_MPU;	/* 68020以降のマークを設定	*/
		PR(("FPUCheck"));
		info->machine |= FPUCheck()?MAC_FPU:0;
		PR(("MMUCheck"));
		info->machine |= MMUCheck()?MAC_MMU:0;
		PR(("XellentCheck"));
#if	1
		if( ((ROMVER()>>24)&0x0f) < 3 ){	/* ROMのバージョンが古くて	*/
			if( info->mpu == 3 ){	/* 68030ならXellent30	*/
				info->machine |= MAC_XELLENT30;
			} else
			if( info->mpu == 4 ){	/* 68040ならExcel040	*/
				info->machine |= MAC_EXCEL40;
			} else {	/* それ以外は多分Jupiter	*/
				info->machine |= MAC_JUPITER;
			}
		} else {
			if( info->mpu == 4 ){	/* 68040なら040turbo	*/
				info->machine |= MAC_040TURBO;
			} else {	/* それ以外はおそらく060turbo	*/
				info->machine |= MAC_060TURBO;
			}
		}
#else
		info->machine |= XellentCheck()?MAC_XELLENT30:0;
#endif
	}
	{
		int scsi;

		PR(("SCSICheck"));
		scsi = SCSICheck();
		PR(("scsi[0x%x]\n",scsi));
		if( scsi & 1 ){			/* 内蔵SCSIを見つけた？	*/
			info->option |= OPT_SCSIIN;
		}
		if( scsi & 2 ){			/* 外付けSCSIを見つけた？	*/
			info->option |= OPT_SCSIEX;
		}
		if( scsi & 4 ){			/* Mach2だった？	*/
			unsigned char* ptr = (unsigned char*)0x00ea00a0;
			int i;
			/* 名前を検索してmach2とmach2pを区別する	*/
			for(i=0;i<0x2000-0xa0;i++,ptr++){
				if( memcmp("mach2",ptr,5) == 0 ){
					if( ptr[5] == 'p' ){
						info->option |= OPT_MACH2P;
					} else {
						info->option |= OPT_MACH2;
					}
					break;
				}
			}	/* end of for	*/
		}
	}
	if( MIDICheck() ){		/* MIDIボード有り？	*/
		info->option |= OPT_MIDI;
	}
	/*	FIXME	*/
	/*	RAMサイズは出来れば自分でチェックして検出したい	*/
	info->ram = B_WPEEK((unsigned short*)0x0ed0008)>>4;

	PR(("ClockCheck()"));
	info->clock = ClockCheck();
	if( info->mpu ){		/* ノーマル68000でない？	*/
		/*	FIXME	*/
		/*	Xellent30の68030モードで調整	*/
		/*	他のマシンではクロックの表示が違うかも知れない	*/
		/*	と、言うか違うハズ	*/
		info->clock = (info->clock<<8) / 18282;
	} else
	if( info->machine & MAC_XELLENT30 ){	/* Xellent30登載の68000モードの場合	*/
		info->clock = (info->clock<<8) / 7314;
	} else {			/* 68000マシンの場合	*/
		info->clock = (info->clock<<8) / 8286;
	}
}
