#include "willepr.h"

//---------------------------------------
//              AT29Cxx
//---------------------------------------
class AT29C{

	public:
		unsigned char data[1024];
		unsigned int  Ssize,flag_err,tWC;
		unsigned long index_adres;
}at29Cxxx;

unsigned long  BB_29C_Ad_h[] = {0x5555,0x2AAA,0x5555,0x5555,0x2AAA,0x5555,0xFFFFF};
unsigned char  BB_29C_Da_h[] = {0xAA,0x55,0x80,0xAA,0x55,0x40,0xFF};
unsigned long  BB_29C_Ad_l[] = {0x5555,0x2AAA,0x5555,0x5555,0x2AAA,0x5555,0x00000};
unsigned char  BB_29C_Da_l[] = {0xAA,0x55,0x80,0xAA,0x55,0x40,0x00};
unsigned char  Erase_29C_data[] = {0xAA,0x55,0x80,0xAA,0x55,0x10};

void r_adres_29C(unsigned long adr)
{
	unsigned long bit,r = 0x80000;
	int b;
	for ( b=19;b!=0;b--){		// DW: used to start at A18
		r = r>>1;
		bit=(adr&r);
		bit? adrhi: adrlo; asadres;
		clkhi, asadres;	clklo, asadres;
	}

}

int getch_yes()
{
	int i = 0;
	char k;
	tcu_open_window(&window2, 24,13, 30,3,NULL,
				tcu_colour_attrib (WHITE, LIGHTBLUE),
				tcu_colour_attrib (BLACK, LIGHTGRAY),
				tcu_colour_attrib (CYAN, BLUE),
				TCU_BOX_SINGLE);
	tcu_wprintf(&window2," Boot Block Enable Yes/no");
	k=getch();
	if(k=='Y') i = 1;
	tcu_close_window (&window2);
	return(i);
}

void enable_29C(void)
{
	oe_lo;r_adres_29C(0x5555);
	oe_hi;outportb(poort,0xaa);
	we_lo;ms_delay(1);we_hi;
	oe_lo;r_adres_29C(0x2AAA);
	oe_hi;outportb(poort,0x55);
	we_lo;ms_delay(1);we_hi;
	oe_lo;r_adres_29C(0x5555);
	oe_hi;outportb(poort,0xA0);
	we_lo;ms_delay(1);we_hi;
}

void Boot_Block_29C(void)
{
	int i,j;

	tcu_display_menu(&B_Block29C,30,10);
	i=tcu_read_menu_selection (&B_Block29C);
	tcu_remove_menu (&B_Block29C);
	if (i>0) {
		show_action("Boot Block Lockout");
		setup_28C();
		if(i == 1) {
			for(j=0;j<7;j++) {
				oe_lo;r_adres_29C(BB_29C_Ad_l[j]);
				oe_hi;outportb(poort,BB_29C_Da_l[j]);
				we_lo;ms_delay(1);we_hi;
			}
		}
		if(i == 2) {
			for(j=0;j<7;j++) {
				oe_lo;r_adres_29C(BB_29C_Ad_h[j]);
				oe_hi;outportb(poort,BB_29C_Da_h[j]);
				we_lo;ms_delay(1);we_hi;
			}
		}
		// delay 200 mS.
		reset_timer();delay(200);setup_timer(0xb0);
		power_down();
		tcu_wprintf(&window4,"-----completed-----");getch();
		tcu_close_window(&window4);
	}
}

void prog_sector(unsigned long i_adres)			// DW: added void
{
	enable_29C();
	for(int i=0;i<at29Cxxx.Ssize;i++){
		oe_lo;r_adres_29C(i_adres);
		oe_hi;outportb(poort,at29Cxxx.data[i]);
		we_lo;ms_delay(1);we_hi;
		i_adres++;
	}
}

int verify_sector(unsigned long i_adres)			// DW: added void
{
	int i,g,q,error = OFF;
	q = 0;
	oe_lo;
	for(i=0;i<at29Cxxx.Ssize;i++){
loop_v:
		r_adres_28C(i_adres);
		g = in_word_28C();
		if(g!=*(rombuf+XMSCurrent(i_adres,0))) {
		     if(q == 4) {
			error = ON;
			break;
		     }
		     q++;
		     goto loop_v;
		}
		i_adres++;
	}
	return error;
}

void prog_29C(void)			// DW: added void
{
	long e=0, t=aantal/52, hgrot;
	unsigned long i, y;
	int loop;
	unsigned char g,q,flag_out;

	if(st!=0) getoff();
	hgrot=grot;
	show_action("programming chip");

	setup_28C();
	at29Cxxx.Ssize = sector_size;
	e = 0;
	if(grot>=aantal)grot=aantal-1;
	for(i=0;i<=grot;){
		at29Cxxx.index_adres = i+st;

		flag_out = OFF;
		for(int j = 0;flag_out == OFF;) {
			at29Cxxx.data[j] = *(rombuf+XMSCurrent(i,0));

			j++;i++;
			if(j==at29Cxxx.Ssize){
				flag_out = ON;
			}
		    //	else {  if(i==grot) {
		    //			flag_out = ON;
		    //		}
		    //	}
		 }
		 at29Cxxx.flag_err = OFF;
		 for(loop =0; loop < 10;loop++) {
			prog_sector(at29Cxxx.index_adres);
			tcu_wprintf(&window4,"  Sector Size = %d : write sector %4d loop = %d\r",sector_size,e,loop);
			ms_delay(at29Cxxx.tWC);
			at29Cxxx.flag_err = verify_sector(at29Cxxx.index_adres);
			if(at29Cxxx.flag_err == OFF) loop = 10;
		 }
		 if(at29Cxxx.flag_err == ON) goto exit_29C;
		 e++;
	}
exit_29C:
	if(!at29Cxxx.flag_err) {
		tcu_close_window(&window4);
		verify_28C();
	}else {
		tcu_wprintf(&window4,"  Error Sector =  %d loop = %d\r",e,loop);
		power_down();
		reset_timer();tcu_warnbeep();setup_timer(0xb0);getch();
		tcu_close_window(&window4);
	      }
	power_down();         // ARW: was powoff
}

void erase_29C(void)
{           // DW: added void
      int i;

      show_action("erasing chip");
      setup_28C();

     for(i=0;i<5;i++) {
	for(int j=0;j<6;j++) {
		    oe_lo;r_adres_29C(BB_29C_Ad_h[j]);
		    oe_hi;outportb(poort,Erase_29C_data[j]);
		    we_lo;ms_delay(1);we_hi;
	}
	tcu_wprintf(&window4,"    ----- delay 150 mS-----\r");
	reset_timer();delay(200);setup_timer(0xb0);
     }
     power_down();
     tcu_wprintf(&window4,"       -----erase completed-----");getch();
     tcu_close_window(&window4);
}

void id_29C(void)
{           // DW: added void
	unsigned char a,b;
	show_action("ID Code");

	setup_28C();
	oe_lo;r_adres_29C(0x5555);
	oe_hi;outportb(poort,0xAA);
		we_lo;ms_delay(1);we_hi;
	oe_lo;r_adres_29C(0x2AAA);
	oe_hi;outportb(poort,0x55);
		we_lo;ms_delay(1);we_hi;
	oe_lo;r_adres_29C(0x5555);
	oe_hi;outportb(poort,0x90);
		we_lo;ms_delay(1);we_hi;
		ms_delay(30000);
	oe_lo;r_adres_29C(0x0000);
	a = in_word();
	r_adres_29C(0x0001);
	b = in_word();
	tcu_wprintf(&window4," Manufacturer = 0x%X :Device ID = 0x%X",a,b);
	ms_delay(30000);

	r_adres_29C(0x5555);
	oe_hi;outportb(poort,0xAA);
	we_lo;ms_delay(1);we_hi;
	oe_lo;r_adres_29C(0x2AAA);
	oe_hi;outportb(poort,0x55);
	we_lo;ms_delay(1);we_hi;
	oe_lo;r_adres_29C(0x5555);
	oe_hi;outportb(poort,0xF0);
	we_lo;ms_delay(1);we_hi;

	ms_delay(30000);ms_delay(30000);
	power_down();
	tcu_wprintf(&window4," Manufacturer = 0x%X :Device ID = 0x%X",a,b);
	getch();
	tcu_close_window(&window4);
}
