#include <stdio.h>

main(){
	int d;
	printf("\n\t########## [transfer.hex] --> ROM Emulator ##########\n");
	system_init();
	if(hex_file_send()==1){
		printf("\n\n\t !!! Target File Missing !!!\n");
		exit(0);
	}
	system_start();
	printf("\n\n\t########## Let's Start ([r]eset/[s]end) ##########\n");
	while(1){
		d=csts();
		if(d==0x1b) break;
		else if(d=='r'){
			system_init();
			system_reset();
			printf("\n\n\t !!! Reset !!!\n");
		}
		else if(d=='s'){
			system_init();
			hex_file_send();
			system_start();
			printf("\n\n\t !!! Re-Send !!!\n");
		}
	}
}

system_init(){
	set_4bit(6,0x02);		/* 010 */	/* Bus Disable */
}

system_start(){
	long i,j=0;
	set_4bit(6,0x06);		/* 110 */	/* Bus Enable */
	for(i=0;i<100000;i++) j++;
	set_4bit(6,0x07);		/* 111 */	/* Go ! */
}

system_reset(){
	long i,j=0;
	set_4bit(6,0x06);		/* 110 */	/* Reset ! */
	for(i=0;i<300000;i++) j++;
	set_4bit(6,0x07);		/* 111 */	/* Go ! */
}

setting_1byte(address,data)
	unsigned int address;
	int data;
{
	set_address(address);
	set_data(data);
	set_4bit(6,0x00);		/* 000 */	/* Write Pulse */
	set_4bit(6,0x02);		/* 010 */	/* Bus Disable */
	putchar('.');
	return(0);
}

set_address(address)
	unsigned int address;
{
	unsigned int add;
	add=address;
	set_4bit(2,add%16);
	add=add/16;
	set_4bit(3,add%16);
	add=add/16;
	set_4bit(4,add%16);
	add=add/16;
	set_4bit(5,add%16);
}

set_data(data)
	int data;
{
	set_4bit(0,data%16);
	set_4bit(1,data/16);
}

set_4bit(add,data)
	int add;
	int data;
{
	_outb(16*add+data+128,0x378);
	_outb(16*add+data+0,0x378);
	_outb(16*add+data+128,0x378);
}

conv(a)
	int a;
{
	if(a<'9'+1) return(a-'0');
	else return(a-'A'+10);
}

hex_file_send(){
	unsigned int address;
	int data,d,a,dd[10],i,count,fds;
	fds=fopen("transfer.hex","rb");
	if(fds==NULL) return(1);
	while(1){
		d=fgetc(fds);
		if(d!=':') break;
		dd[0]=fgetc(fds); dd[1]=fgetc(fds);
		dd[2]=fgetc(fds); dd[3]=fgetc(fds);
		dd[4]=fgetc(fds); dd[5]=fgetc(fds);
		fgetc(fds); d=fgetc(fds); if(d=='1') break;
		a=dd[0]; count=16*conv(a);
		a=dd[1]; count=count+conv(a);
		a=dd[2]; address=4096*conv(a);
		a=dd[3]; address=address+256*conv(a);
		a=dd[4]; address=address+16*conv(a);
		a=dd[5]; address=address+conv(a);
		for(i=0;i<count;i++){
			dd[0]=fgetc(fds); dd[1]=fgetc(fds);
			a=dd[0]; data=16*conv(a);
			a=dd[1]; data=data+conv(a);
			setting_1byte(address,data);
			address++;
		}
		fgetc(fds); fgetc(fds); fgetc(fds); fgetc(fds);
	}
	fclose(fds);
	return(0);
}

