[Description]

Location = "Motorola\MC9S12XHZ512";

Info = " Module for programming EEPROMs memory of MC9S12XHZ512.",
	" Maskset  0M80F, 1M80F",
	" Manufacturer: Motorola.",
    " -----------------------------------------------------------",
    " Supported functions:",
    "    EEPROM read/write/verify",
    "    FLASH read/write/verify",
    " -----------------------------------------------------------",
    " NOTE: SPECIAL ADAPTER ARE REQUIRED! ",
    " ",
    " Author: iProg Group (C) 2009";

Picture = "MC9S12XHZ512.bmp";
Buffer1 = "EEPROM",0x1000;
Buffer2 = "FLASH",0x80000;
Voltage = 5.0;

VCC = 0;
GND = 0;

[Menu]

Read        = "&Read",ReadButton,"Read chip",F2;
Div0        = "-";
Write       = "&Write",WriteButton,"Write chip",F5;
//WriteChanges= "Write &changes",WriteChangesButton,"Write changes",F6;
Div1        = "-";
//Erase 	= "&Erase", EraseButton, "Erase memory", F9;
//Div2        = "-";
Compare     = "&Verify",CheckButton,"Compare with buffer",F3;
Div3        = "-";
Info        = "&About module",ModuleInfoButton,"Show module info",F1;
Div5        = "-";

[Interface]

ComboBox(Crystal,"Crystal frequency (KHz)",10,6,90,"2000","4000","8000","16000",3);
CheckBox(aCrystal,"Auto Crystal",250,5,1);
CheckBox(Preerase,"Erase before write?",350,5,1);

[Host]



dim Boot_EE[] = 
{
0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x1B,0xFA,0x02,0x7C,0x18,0x0B,0x19,0x00,0x0B,0x18,0x0B,0x19,0x00,0x0B,0x18,0x0B,
0x00,0x00,0x3C,0x18,0x0B,0xFF,0x01,0x14,0xFC,0x10,0x0A,0x27,0xFB,0xFC,0x10,0x02,
0x16,0x10,0xA2,0x8C,0x00,0x20,0x18,0x27,0x00,0x64,0x8C,0x00,0x30,0x18,0x27,0x01,
0x68,0x8C,0x00,0x40,0x18,0x27,0x00,0xC7,0x8C,0x00,0x50,0x18,0x27,0x00,0x91,0xCC,
0x00,0x80,0x20,0x03,0xCC,0x00,0x00,0x7C,0x10,0x0E,0xCC,0x00,0x00,0x7C,0x10,0x0A,
0x20,0xC6,0x37,0xC7,0x37,0x04,0x60,0x02,0x86,0x20,0xC6,0xFA,0x12,0x8C,0x03,0xE8,
0x25,0x28,0x8C,0x80,0xE8,0x22,0x23,0x8C,0x19,0x00,0x25,0x07,0x49,0x49,0x49,0x18,
0x08,0x80,0x40,0xCE,0x00,0x64,0x18,0x10,0xB7,0xC5,0xEA,0x80,0x7B,0x01,0x10,0xB6,
0x01,0x10,0x80,0x80,0x18,0x16,0x1B,0x81,0x33,0x3D,0x86,0xFF,0x20,0xF8,0x8B,0xFC,
0x5A,0x17,0xFC,0x10,0x06,0x8C,0x04,0x00,0x25,0x1A,0x72,0x00,0x17,0x8C,0x08,0x00,
0x25,0x12,0x72,0x00,0x17,0x8C,0x0C,0x00,0x25,0x0A,0x72,0x00,0x17,0x8C,0x10,0x00,
0x25,0x02,0x20,0x3A,0x84,0x03,0xC3,0x08,0x00,0xB7,0x46,0xF6,0x10,0x09,0x1A,0xFA,
0xFE,0xFE,0xA6,0x70,0x6A,0x30,0x04,0x31,0xF9,0x7D,0x10,0x06,0x18,0x20,0xFF,0x74,
0x8B,0xFC,0x5A,0x17,0xCD,0x08,0x00,0xCE,0x04,0x00,0x86,0xFF,0x07,0x17,0x41,0x26,
0x0D,0x72,0x00,0x17,0xD6,0x17,0xC4,0xFF,0x26,0xEA,0x18,0x27,0xFF,0x56,0xCC,0x00,
0xFD,0x18,0x20,0xFF,0x52,0x34,0x35,0xA4,0x70,0x04,0x35,0xFB,0x31,0x30,0x3D,0x1A,
0xFA,0xFE,0xBD,0x8B,0xFC,0x5A,0x17,0xFC,0x10,0x06,0x8C,0x04,0x00,0x25,0x1A,0x72,
0x00,0x17,0x8C,0x08,0x00,0x25,0x12,0x72,0x00,0x17,0x8C,0x0C,0x00,0x25,0x0A,0x72,
0x00,0x17,0x8C,0x10,0x00,0x25,0x02,0x20,0x5F,0x84,0x03,0xC3,0x08,0x00,0xB7,0x46,
0xF6,0x10,0x09,0x54,0x37,0x25,0x51,0x1E,0x10,0x07,0x01,0x4C,0x1F,0x01,0x15,0x40,
0xFB,0xEC,0x40,0xAC,0x00,0x27,0x24,0x8C,0xFF,0xFF,0x26,0x41,0x18,0x0B,0x30,0x01,
0x15,0x18,0x02,0x00,0x40,0x18,0x0B,0x20,0x01,0x16,0x18,0x0B,0x80,0x01,0x15,0xB6,
0x01,0x15,0x84,0x30,0x26,0x2C,0x1F,0x01,0x15,0x80,0xFB,0x08,0x08,0x02,0x02,0x63,
0x80,0x26,0xC9,0xCC,0x00,0x00,0x1B,0x81,0x1F,0x01,0x15,0x40,0xFB,0xB6,0x01,0x15,
0x84,0x30,0x26,0x0E,0x18,0x20,0xFE,0xBF,0xCC,0x00,0xFC,0x20,0xE9,0xCC,0x00,0xFD,
0x20,0xE4,0xCC,0x00,0xFF,0x1B,0x81,0x20,0xEB,0x18,0x0B,0x30,0x01,0x15,0x18,0x0B,
0x00,0x01,0x12,0x18,0x0B,0x02,0x01,0x15,0x18,0x0B,0x10,0x01,0x12,0x18,0x03,0x0C,
0x00,0x01,0x18,0x18,0x03,0xFF,0xFF,0x01,0x1A,0x18,0x0B,0x41,0x01,0x16,0x18,0x0B,
0x80,0x01,0x15,0xB6,0x01,0x15,0x84,0x30,0x26,0x15,0xA7,0xA7,0x1F,0x01,0x15,0x40,
0xFB,0x18,0x0B,0x00,0x01,0x12,0x18,0x0B,0x02,0x01,0x15,0x18,0x20,0xFE,0x65,0xCC,
0x00,0xFF,0x18,0x20,0xFE,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
//.................................................

dim Boot_FL[] = 
{
0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x1B,0xFA,0x02,0x7C,0x18,0x0B,0x10,0x01,0x02,0x18,0x0B,0xFF,0x01,0x04,0x79,0x01,
0x02,0xEC,0xF9,0xA6,0x27,0xFB,0xDC,0x1A,0x81,0xE4,0x26,0x29,0xEC,0xF9,0x93,0x15,
0xF8,0x36,0x8C,0x00,0x20,0x18,0x27,0x00,0x6B,0x8C,0x00,0x30,0x18,0x27,0x01,0x44,
0x8C,0x00,0x40,0x18,0x27,0x00,0xB8,0x8C,0x00,0x41,0x18,0x27,0x01,0x75,0x8C,0x00,
0x50,0x18,0x27,0x00,0x72,0xCC,0x00,0x80,0x20,0x03,0xCC,0x00,0x00,0x6C,0xF9,0x6E,
0xCC,0x00,0x00,0x6C,0xF9,0x64,0x20,0xB9,0x37,0xC7,0x37,0x04,0x60,0x02,0x86,0x20,
0xC6,0xFA,0x12,0x8C,0x03,0xE8,0x25,0x28,0x8C,0x9C,0x40,0x22,0x23,0x8C,0x19,0x00,
0x25,0x07,0x49,0x49,0x49,0x18,0x08,0x80,0x40,0xCE,0x00,0x64,0x18,0x10,0xB7,0xC5,
0xEA,0x80,0x7B,0x01,0x00,0xB6,0x01,0x00,0x80,0x80,0x18,0x16,0x1B,0x81,0x33,0x3D,
0x86,0xFF,0x20,0xF8,0x1A,0xF9,0x29,0xE6,0xF9,0x1F,0x37,0xEC,0xF9,0x16,0xED,0xF9,
0x15,0x15,0xFA,0x01,0x97,0x5B,0x30,0xA6,0x40,0x6A,0x30,0x15,0xFA,0x01,0x3B,0x63,
0x80,0x26,0xE8,0x1B,0x81,0x20,0x93,0xCD,0x80,0x00,0xCE,0x40,0x00,0x86,0xFF,0xC6,
0xE0,0x5B,0x30,0x07,0x20,0x52,0xC1,0xFF,0x26,0xF7,0x5B,0x30,0xCE,0x3F,0x0F,0x07,
0x14,0xCD,0xBF,0x10,0xCE,0x00,0xF0,0x07,0x0C,0x41,0x18,0x27,0xFF,0x6C,0xCC,0x00,
0xFD,0x18,0x20,0xFF,0x68,0x34,0x35,0xA4,0x70,0x04,0x35,0xFB,0x31,0x30,0x3D,0x1A,
0xFA,0xFE,0xCD,0xE6,0xFA,0xFE,0xC2,0x54,0x37,0x25,0x6A,0x0E,0xFA,0xFE,0xB6,0x01,
0x64,0xEC,0xFA,0xFE,0xAF,0xED,0xFA,0xFE,0xAD,0x15,0xFA,0x01,0x2F,0x5B,0x30,0x15,
0xF8,0xF7,0x1F,0x01,0x05,0x40,0xFB,0xEC,0x40,0xAC,0x00,0x27,0x33,0x8C,0xFF,0xFF,
0x27,0x14,0x8D,0xBF,0x0E,0x26,0x43,0x96,0x30,0x81,0xFF,0x26,0x3D,0xEC,0x00,0x8C,
0xFF,0xFF,0x26,0x36,0x20,0x1A,0x18,0x02,0x00,0x40,0x18,0x0B,0x20,0x01,0x06,0x18,
0x0B,0x80,0x01,0x05,0xB6,0x01,0x05,0x84,0x30,0x26,0x24,0x1F,0x01,0x05,0x80,0xFB,
0x08,0x08,0x15,0xF8,0x95,0x15,0xF8,0x92,0x63,0x80,0x26,0xA5,0xCC,0x00,0x00,0x1B,
0x81,0x18,0x20,0xFE,0xE8,0xCC,0x00,0xFC,0x20,0xF5,0xCC,0x00,0xFD,0x20,0xF0,0xCC,
0x00,0xFF,0x20,0xEB,0x15,0xF8,0x84,0x79,0x01,0x03,0x18,0x0B,0x10,0x01,0x02,0x7C,
0xC0,0x00,0x18,0x0B,0x41,0x01,0x06,0x18,0x0B,0x80,0x01,0x05,0x79,0x01,0x02,0xC6,
0x03,0x7B,0x01,0x03,0x1F,0x01,0x05,0x40,0xFB,0x53,0x2A,0xF5,0x07,0x5D,0xCC,0xFF,
0xFE,0x07,0x70,0x8C,0xFF,0xFE,0x26,0x04,0x18,0x20,0xFE,0x9E,0xCC,0x00,0xFF,0x18,
0x20,0xFE,0x9A,0xEC,0xFA,0xFD,0xFD,0x26,0x2A,0xEC,0xFA,0xFD,0xF9,0x8C,0xFF,0x0E,
0x26,0x21,0xEC,0xFA,0xFD,0xF2,0x8C,0x00,0x02,0x26,0x18,0x1A,0xFA,0xFD,0xF1,0xEC,
0x00,0x8C,0xFF,0xFC,0x26,0x0D,0x07,0x23,0x07,0x39,0x8C,0xFF,0xFC,0x26,0x04,0x18,
0x20,0xFE,0x67,0xCC,0x00,0xFF,0x18,0x20,0xFE,0x63,0x62,0xFA,0xFD,0xC9,0x26,0x0A,
0x62,0xFA,0xFD,0xC2,0x26,0x04,0x62,0xFA,0xFD,0xBB,0x3D,0x18,0x0B,0x10,0x01,0x02,
0x18,0x0B,0x30,0x01,0x05,0x79,0x01,0x02,0x3D,0x54,0x54,0x54,0x51,0xC4,0x03,0x7B,
0x01,0x03,0x3D,0x79,0x01,0x03,0x7C,0xFF,0x0E,0x18,0x0B,0x20,0x01,0x06,0x18,0x0B,
0x80,0x01,0x05,0x1E,0x01,0x05,0x10,0x10,0x1E,0x01,0x05,0x20,0x0B,0x1F,0x01,0x05,
0x40,0xFB,0xBC,0xFF,0x0E,0x26,0x01,0x3D,0x87,0xC7,0x20,0xFB,0x35,0x3B,0x68,0x82,
0x65,0x81,0x68,0x82,0x65,0x81,0x64,0x82,0x14,0x01,0x66,0x82,0x3A,0x97,0x2B,0x06,
0x19,0xCA,0x19,0xED,0xE6,0x40,0xA6,0x81,0x84,0x01,0x31,0x3D,0x00,0xFD,0xFE,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};


// define      BLOADER_EE		720
define      BLOADER_FL		720
define      RAM_BEGIN		0x1000
define      EEPROM_BEGIN		0x000
define      EEPROM_END		0x0FFF
define      FLASH_BEGIN		0x380000
define      FLASH_END		0x400000
define		StartADR	0x50

Proc Connect
{
    var Value,Temp,Data0B,DataF1,Ret;
	Run(AVRreset);
	Value = USB;
	Ret=0;
	if(Value != 0x00) { print("   Adapter not found. ");Ret=0xEE;return(Ret); }
	Run(CheckAdapter);
	Value = USB;
	if(Value != 0x05) { print("   Adapter not found. ");Ret=0xEE;return(Ret); }
	if(aCrystal=1){Ret=aCalcBRR();}
	if(aCrystal!=1){Ret=CalcBRR();}
	return(Ret);
}


Proc Read 
{
    var Value,Counter,CounterH,Ret,Temp,Address,Data;


	Ret=Connect();
	if(Ret=0xEC){ print("   SEC is active! "); return;}
	if(Ret=0xEE){ print("   wrong CLK! "); return;}	
	print("   BDM is open! ");
//...............
if(ActiveBuffer = 0)
{
	Run(LoadADR);
	Value = RAM_BEGIN>>8; USB = Value;
	Value = RAM_BEGIN; USB = Value;
	Value = EEPROM_BEGIN>>24; USB = Value;
	Value = EEPROM_BEGIN>>16; USB = Value;
	Value = EEPROM_BEGIN>>8; USB = Value;
	Value = EEPROM_BEGIN; USB = Value;
	Value = USB;
	if(Value != 0x00) { print("   disconnect 0 "); return; }
//.................................
	Address=720;
	Counter=0;
	Run(LoadBoot);
	Value=Address>>8;USB=Value;
	USB=Address;
	Data = Calc();
	Data=Data*2;
	while(Counter!=720)
	{
	Value=Boot_EE[Counter];
	if(Counter=2){Value=Data;}
	if(Counter=3){Value=0x20;}
	USB=Value;
	Counter++;
	}
	Value = USB;
	if(Value != 0x00) { print("   disconnect 0_1 "); return; }
	USB=StartADR;
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 1 "); return; }	
	print("   Read EEPROM...");
	CounterH = EEPROM_END + 1;
	CounterH = CounterH-EEPROM_BEGIN;
	PBPos = 0;PBMax = CounterH;Address=0;
	while(Address!=CounterH)
	{
	Run(RDHeader);
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 2 "); return; }	
	Counter=0;
	Run(ReadEEPROM);	
	while(Counter!=0x40)
	{
	Value = USB;
	if(Value = 0x8000) { print("   disconnect 3 "); break;}
	FBUF[Address] = Value;
	Counter++;PBPos++;Address++;		
	}
	}
}
else
{
	Run(LoadADR);
	Value = RAM_BEGIN>>8; USB = Value;
	Value = RAM_BEGIN; USB = Value;
	Address=FLASH_BEGIN+0x80000000;
	Value = Address>>24; USB = Value;
	Value = Address>>16; USB = Value;
	Value = Address>>8; USB = Value;
	Value = Address; USB = Value;
	Value = USB;
	if(Value != 0x00) { print("   disconnect 4 "); return; }
//..............................
	Address=BLOADER_FL;
	Counter=0;
	Run(LoadBoot);
	Value=Address>>8;USB=Value;
	USB=Address;
	Data = Calc();
	Data=Data*2;
	while(Counter!=BLOADER_FL)
	{
	Value=Boot_FL[Counter];
	if(Counter=2){Value=Data;}
	if(Counter=3){Value=0x20;}
	USB=Value;
	Counter++;
	}
	Value = USB;
	if(Value != 0x00) { print("   disconnect 0_1 "); return; }
	USB=StartADR;
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 5 "); return; }	
	print("   Read FLASH...");
	CounterH = FLASH_END-FLASH_BEGIN;
	PBPos = 0;PBMax = CounterH;Address=0;
	while(Address!=CounterH)
	{
	Run(RDHeader);
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 6 "); return; }	
	Counter=0;
	Run(ReadEEPROM);	
	while(Counter!=0x40)
	{
	Value = USB;
	if(Value = 0x8000) { print("   disconnect 7 "); break;}
	EBUF[Address] = Value;
	Counter++;PBPos++;Address++;		
	}
	}
}
	if(ForceCloseAfterRead != 0) { return(0x7FFFFFFF);}
	print("\; Success");
}


proc Compare
{
    var Value,Temp,Data0B,DataF1,Mismatch,Active,Ret;
	Run(AVRreset);
	Value = USB;
	if(Value != 0x00) { print("   Adapter not found. ");return; }
	Run(CheckAdapter);
	Value = USB;
	if(Value != 0x05) { print("   Adapter not found. ");return; }

	Ret=Connect();
	if(Ret=0xEC){ print("   SEC is active! "); return;}
	if(Ret=0xEE){ print("   wrong CLK! "); return;}	
	print("   BDM is open! ");
	Active=1;
	Mismatch=0;
	if(ActiveBuffer = 0)
	{
		Mismatch=CompareEE(Active);
	}
	else
	{
		Mismatch=CompareFL(Active);
	}
	if(Mismatch = 0)
	{
		if(ForceCloseAfterRead != 0) { return(0x7FFFFFFF);}
	}
	print("\; Done. Number of mismatch: %i",Mismatch);
}

proc Erase
{
    var Value,Temp,Mismatch,Active,Ret;
	Run(AVRreset);
	Value = USB;
	if(Value != 0x00) { print("   Adapter not found. ");return; }
	Run(CheckAdapter);
	Value = USB;
	if(Value != 0x05) { print("   Adapter not found. ");return; }
//...........................................
	if(aCrystal=1){Ret=aCalcBRR();}
	if(aCrystal!=1){Ret=CalcBRR();}
	if(Ret=0xEC){ print("   SEC is active! "); return;}
	if(Ret=0xEE){ print("   wrong CLK! "); return;}	
	print("   BDM is open! ");
	Active=1;
	if(ActiveBuffer = 0)
	{
		Mismatch=Erase_EEP(Active);
	}
	else
	{
		Mismatch=Erase_FLASH(Active);
	}
	print("\; Done.");
}


Proc CompareEE(Active)
{
    var Value,Counter,CounterH,Ret,Temp,Mismatch,Address,Data;

if(Active=0)
	{
	Ret=Connect();
	if(Ret=0xEC){ print("   SEC is active! "); return;}
	if(Ret=0xEE){ print("   wrong CLK! "); return;}	
	print("   BDM is open! ");
	}
//..........................
	Mismatch=0;
//..........................
	Run(LoadADR);
	Value = RAM_BEGIN>>8; USB = Value;
	Value = RAM_BEGIN; USB = Value;
	Value = EEPROM_BEGIN>>24; USB = Value;
	Value = EEPROM_BEGIN>>16; USB = Value;
	Value = EEPROM_BEGIN>>8; USB = Value;
	Value = EEPROM_BEGIN; USB = Value;
	Value = USB;
	if(Value != 0x00) { print("   disconnect 10 "); return; }
//.................................
	Address=720;
	Counter=0;
	Run(LoadBoot);
	Value=Address>>8;USB=Value;
	USB=Address;
	Data = Calc();
	Data=Data*2;
	while(Counter!=720)
	{
	Value=Boot_EE[Counter];
	if(Counter=2){Value=Data;}
	if(Counter=3){Value=0x20;}
	USB=Value;
	Counter++;
	}
	Value = USB;
	if(Value != 0x00) { print("   disconnect 0_1 "); return; }
	USB=StartADR;
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 11 "); return; }	
//..............................
	print("   Compare EEPROM...");
	CounterH = EEPROM_END + 1;
	CounterH = CounterH-EEPROM_BEGIN;
	PBPos = 0;PBMax = CounterH;Address=0;
	while(Address!=CounterH)
	{
	Run(RDHeader);
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 12 "); return; }	
	Counter=0;
	Run(ReadEEPROM);	
	while(Counter!=0x40)
	{
	Value = USB;
	if(Value = 0x8000) { print("   disconnect 13 "); break;}
	Temp=FBUF[Address];
        if(Value != Temp) { Mismatch++;FSEL[Address] = 0;}
        	else { FSEL[Address] = 1;}
	Counter++;PBPos++;Address++;		
	}
	}
	return(Mismatch);
}


Proc CompareFL(Active)
{
    var Value,Counter,CounterH,Ret,Temp,Mismatch,Address,Data;

if(Active=0)
	{
	Ret=Connect();
	if(Ret=0xEC){ print("   SEC is active! "); return;}
	if(Ret=0xEE){ print("   wrong CLK! "); return;}	
	print("   BDM is open! ");
	}
//..........................
	Mismatch=0;
//..........................
	Run(LoadADR);
	Value = RAM_BEGIN>>8; USB = Value;
	Value = RAM_BEGIN; USB = Value;
	Address=FLASH_BEGIN+0x80000000;
	Value = Address>>24; USB = Value;
	Value = Address>>16; USB = Value;
	Value = Address>>8; USB = Value;
	Value = Address; USB = Value;
	Value = USB;
	if(Value != 0x00) { print("   disconnect 14 "); return; }
//...........................
	Address=BLOADER_FL;
	Counter=0;
	Run(LoadBoot);
	Value=Address>>8;USB=Value;
	USB=Address;
	Data = Calc();
	Data=Data*2;
	while(Counter!=BLOADER_FL)
	{
	Value=Boot_FL[Counter];
	if(Counter=2){Value=Data;}
	if(Counter=3){Value=0x20;}
	USB=Value;
	Counter++;
	}
	Value = USB;
	if(Value != 0x00) { print("   disconnect 0_1 "); return; }
	USB=StartADR;
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 15 "); return; }	
	print("   Compare FLASH...");
	CounterH = FLASH_END-FLASH_BEGIN;
	PBPos = 0;PBMax = CounterH;Address=0;
	while(Address!=CounterH)
	{
	Run(RDHeader);
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 16 "); return; }	
	Counter=0;
	Run(ReadEEPROM);	
	while(Counter!=0x40)
	{
	Value = USB;
	if(Value = 0x8000) { print("   disconnect 17 "); break;}
	Temp=EBUF[Address];
        if(Value != Temp) { Mismatch++;ESEL[Address] = 0;}
            else { ESEL[Address] = 1;}
	Counter++;PBPos++;Address++;		
	}
	}
	return(Mismatch);
}


Proc Erase_EEP(Active) 
{
    var Value,Counter,CounterH,Ret,Temp,Address,Data;

if(Active=0)
	{
	Ret=Connect();
	if(Ret=0xEC){ print("   SEC is active! "); return;}
	if(Ret=0xEE){ print("   wrong CLK! "); return;}	
	print("   BDM is open! ");
	}
/////////////////////////////////////
	Run(LoadADR);
	Value = RAM_BEGIN>>8; USB = Value;
	Value = RAM_BEGIN; USB = Value;
	Value = EEPROM_BEGIN>>24; USB = Value;
	Value = EEPROM_BEGIN>>16; USB = Value;
	Value = EEPROM_BEGIN>>8; USB = Value;
	Value = EEPROM_BEGIN; USB = Value;
	Value = USB;
	if(Value != 0x00) { print("   disconnect 18 "); return(0xEE); }
//.........................
	Address=720;
	Counter=0;
	Run(LoadBoot);
	Value=Address>>8;USB=Value;
	USB=Address;
	Data = Calc();
	Data=Data*2;
	while(Counter!=720)
	{
	Value=Boot_EE[Counter];
	if(Counter=2){Value=Data;}
	if(Counter=3){Value=0x30;}
	USB=Value;
	Counter++;
	}
	Value = USB;
	if(Value != 0x00) { print("   disconnect 0_1 "); return; }
	USB=StartADR;
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 19 "); return(0xEE); }	
	print("   ERASE EEPROM...");
	Run(ERHeader);
	Value=USB;
	if(Value != 0xFF) { print("   disconnect 20 "); return(0xEE); }	
	return(0x00);
}


Proc Erase_FLASH(Active)
{
    var Value,Counter,CounterH,Ret,Temp,Address,Data;

if(Active=0)
	{
	Ret=Connect();
	if(Ret=0xEC){ print("   SEC is active! "); return;}
	if(Ret=0xEE){ print("   wrong CLK! "); return;}	
	print("   BDM is open! ");
	}
//................................
	Run(LoadADR);
	Value = RAM_BEGIN>>8; USB = Value;
	Value = RAM_BEGIN; USB = Value;
	Address=FLASH_BEGIN+0x80000000;
	Value = Address>>24; USB = Value;
	Value = Address>>16; USB = Value;
	Value = Address>>8; USB = Value;
	Value = Address; USB = Value;
	Value = USB;
	if(Value != 0x00) { print("   disconnect 21 "); return(0xEE); }
//..............................
	Address=BLOADER_FL;
	Counter=0;
	Run(LoadBoot);
	Value=Address>>8;USB=Value;
	USB=Address;
	Data = Calc();
	Data=Data*2;
	while(Counter!=BLOADER_FL)
	{
	Value=Boot_FL[Counter];
	if(Counter=2){Value=Data;}
	if(Counter=3){Value=0x30;}
	USB=Value;
	Counter++;
	}
	Value = USB;
	if(Value != 0x00) { print("   disconnect 0_1 "); return; }
	USB=StartADR;
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 22 "); return(0xEE); }	
	print("   ERASE FLASH...");
	Run(ERHeader);
	Value=USB;
	if(Value != 0xFF) { print("   disconnect 23 "); return(0xEE); }	
	return(0x00);
}



Proc Write
{
    var Value,Counter,CounterH,Ret,Temp,Address,Mismatch,Data,Active;


///////////////////////////////
Active=0;
if(ActiveBuffer = 0)
{
	if(Preerase=1)
	{
	Ret=Erase_EEP();
	if(Ret!=0x00){ print("   Not connected. "); return;}	
	}
	else
	{
	Ret=Connect();
	if(Ret=0xEC){ print("   SEC is active! "); return;}
	if(Ret=0xEE){ print("   wrong CLK! "); return;}	
	print("   BDM is open! ");
	}
//...........................................................
	Run(LoadADR);
	Value = RAM_BEGIN>>8; USB = Value;
	Value = RAM_BEGIN; USB = Value;
	Value = EEPROM_BEGIN>>24; USB = Value;
	Value = EEPROM_BEGIN>>16; USB = Value;
	Value = EEPROM_BEGIN>>8; USB = Value;
	Value = EEPROM_BEGIN; USB = Value;
	Value = USB;
	if(Value != 0x00) { print("   disconnect 24 "); return; }
//.......................
	Address=720;
	Counter=0;
	Run(LoadBoot);
	Value=Address>>8;USB=Value;
	USB=Address;
	Data = Calc();
	Data=Data*2;
	while(Counter!=720)
	{
	Value=Boot_EE[Counter];
	if(Counter=2){Value=Data;}
	if(Counter=3){Value=0x40;}
	USB=Value;
	Counter++;
	}
	Value = USB;
	if(Value != 0x00) { print("   disconnect 0_1 "); return; }
	USB=StartADR;
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 25 "); return; }	
	print("   Wirte EEPROM...");
	CounterH = EEPROM_END + 1;
	CounterH = CounterH-EEPROM_BEGIN;
	PBPos = 0;PBMax = CounterH;Address=0;
	while(Address!=CounterH)
	{
	Run(WRHeader);
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 26 "); return; }	
	Counter=0;
	Run(WriteEEPROM);	
	while(Counter!=0x40)
	{
	Value=FBUF[Address];
	USB=Value;
	Counter++;PBPos++;Address++;		
	}
	Value = USB;
	if(Value != 0x00) { print("   disconnect 27 "); return; }
	Run(WRWait);
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 28 "); return;}
	}

	Mismatch=0;
	Active=0;
	Mismatch=CompareEE(Active);
	if(Mismatch = 0)
	{
		if(ForceCloseAfterWrite != 0) { return(0x7FFFFFFF);}
	}
	print("\; Done. Number of mismatch: %i",Mismatch);
}
else
{
	if(Preerase=1)
	{
	Ret=Erase_FLASH(Active);
	if(Ret!=0x00){ print("   Not connected. "); return;}	
	}
	else
	{
	Ret=Connect();
	if(Ret=0xEC){ print("   SEC is active! "); return;}
	if(Ret=0xEE){ print("   wrong CLK! "); return;}	
	print("   BDM is open! ");
	}
//...............................
	Run(LoadADR);
	Value = RAM_BEGIN>>8; USB = Value;
	Value = RAM_BEGIN; USB = Value;
	Address=FLASH_BEGIN+0x80000000;
	Value = Address>>24; USB = Value;
	Value = Address>>16; USB = Value;
	Value = Address>>8; USB = Value;
	Value = Address; USB = Value;
	Value = USB;
	if(Value != 0x00) { print("   disconnect 29 ");  return; }
//..............................
	Address=BLOADER_FL;
	Counter=0;
	Run(LoadBoot);
	Value=Address>>8;USB=Value;
	USB=Address;
	Data = Calc();
	Data=Data*2;
	while(Counter!=BLOADER_FL)
	{
	Value=Boot_FL[Counter];
	if(Counter=2){Value=Data;}
	if(Counter=3){Value=0x40;}
	USB=Value;
	Counter++;
	}
	Value = USB;
	if(Value != 0x00) { print("   disconnect 0_1 "); return; }
	USB=StartADR;
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 30 ");  return; }	
	print("   Write FLASH...");
	CounterH = FLASH_END-FLASH_BEGIN;
	PBPos = 0;PBMax = CounterH;Address=0;
	while(Address!=CounterH)
	{
	Run(WRHeader);
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 31 ");  return; }	
	Counter=0;
	Run(WriteEEPROM);	
	while(Counter!=0x40)
	{
	Value=EBUF[Address];
	USB=Value;
	Counter++;PBPos++;Address++;		
	}
	Value = USB;
	if(Value != 0x00) { print("   disconnect 32 ");  return; }
	Run(WRWait);
	Value=USB;
	if(Value != 0xAA) { print("   disconnect 33 ");  return;}
	}
	Mismatch=0;
	Active=0;
	Mismatch=CompareFL(Active);
	if(Mismatch = 0)
	{
		if(ForceCloseAfterWrite != 0) { return(0x7FFFFFFF);}
	}
	print("\; Done. Number of mismatch: %i",Mismatch);

}
	print("\; Success");
}



/////////////////////////////////////////////////////////////////////////

Proc aCalcBRR
{
var	Value,Temp,Data1,Data2,Ret;

	Ret=0xEE;
	Crystal=0;
	while
	{
	Value=Calc();
	Run(Reboot);
	USB = Value;
	Value = USB;
	if(Value != 0xAA) { print("   BDM not open!  ");Ret=0xEE;return(Ret); }
//...........................................
	Temp=USB;
	Data1=Temp<<8;
	Temp=USB;
	Data1=Data1|Temp;
	Temp=USB;
	Data2=Temp<<8;
	Temp=USB;
	Data2=Data2|Temp;	
	if(Data1!=0xFFFF){Ret=0;break;}
	if(Data2!=0xFFFF){Ret=0;break;}
	Crystal++;
	if(Crystal=4){break;}
	}
	Data1=Data1|Data2;
	if(Ret=0)
		{if(Data1=0x0000){Ret=0xEC;}}
	return(Ret);
}

Proc CalcBRR
{
var	Value,Temp,Data1,Data2,Ret;
	Ret=0xEE;
	Value=Calc();
	Run(Reboot);
	USB = Value;
	Value = USB;
	if(Value != 0xAA) { print("   BDM not open!  ");Ret=0xEE;return(Ret); }
//...........................................
	Temp=USB;
	Data1=Temp<<8;
	Temp=USB;
	Data1=Data1|Temp; 
//	print("Data1: %h",Data1);
	Temp=USB;
	Data2=Temp<<8;
	Temp=USB;
	Data2=Data2|Temp;
//	print("Data2: %h",Data2);	
	if(Data1!=0xFFFF){Ret=0;}
	if(Data2!=0xFFFF){Ret=0;}
	Data1=Data1|Data2;
	if(Ret=0)
		{if(Data1=0x0000){Ret=0xEC;}}
	Data1=Data1&Data2;
	if(Data1=0xFFFF){Ret=0xEE;}
	return(Ret);
}

Proc Calc
{
	var BootBRR;
if(Crystal=3){BootBRR=16;}
if(Crystal=2){BootBRR=8;}
if(Crystal=1){BootBRR=4;}
if(Crystal=0){BootBRR=2;}
    return(BootBRR);
}
//..............................


Proc Info
{
  print("");
  print("  Module for programming Motorola MCU type MC9S12XHZ512.");
  print("	Maskset 0M80F");
  print("  Next functions are support:");
  print("");
  print("     EEPROM read/write/verify.");
  print("     FLASH read/write/verify.");
  print("-------------------------------------------------------");
  print("  Note: special adapter are required !");
  print("-------------------------------------------------------");
  print("  Copyright (C) 2008 iProg Group.");
}


[Device]

areg	DR,0
areg	RDY,1
areg	BRR,1
areg	START_BOOT,2
areg	ADR_MCU,2
areg	BLOAD,3
areg	RD_HEAD,3
areg	WR_HEAD,4
areg	ER_HEAD,5
areg	START_ADR,5
areg	WR_WAIT,6
areg	VER,7
areg	IO,4
areg	IORD,4

define	RST		EP.5

var Value,Counter,BtH,BtL,Temp,ByteH,ByteL,AH,AL;

Proc AVRreset
{
	RST = 1;
	Delay(10000);
	RST = 0;
	Delay(10000);
	USB = 0x00;
}

Proc CheckAdapter
{
	Delay(10000);
    	Value = VER;
    	if(Value != 1)
    	{
        Value = VER;
    	}
	VER = 5;
    	Value = VER;
    	USB = Value;
}
/////////////////////////////////////////

Proc Reboot
{
	Value = USB;BRR = Value;
	IO = 0; Delay(5000);		// Reset = 0
	IO = 3; Delay(5000);		// Reset = 1
	Counter = 0;
	while(Counter!=5)
	{
	Value = RDY;
	USB = Value;
	Counter++;
	}
}

Proc LoadADR
{
	Counter = 0;
	while(Counter!=6)
	{
	Value = USB;
	ADR_MCU = Value;
	Counter++;
	}
	USB=0;
}


Proc LoadBoot
{
	Value=0;
	Value=USB;
	Counter=Value<<8;
	Value=0;
	Value=USB;
	Counter=Counter|Value;
	while(Counter!=0)
	{
	Value=USB;
	BLOAD=Value;
	Counter--;
	}
	USB=0;
	Value=USB;
	START_ADR=Value;
	Value=START_BOOT;
	USB=Value;
}

Proc RDHeader
{
	Value=RD_HEAD;
	USB=Value;
}

Proc WRHeader
{
	Value=WR_HEAD;
	USB=Value;
}

Proc WRWait
{
	Value=WR_WAIT;
	USB=Value;
}

Proc ERHeader
{
	Value=ER_HEAD;
	USB=Value;
}

Proc ReadEEPROM
{
	Counter=0;
    	while(Counter!=0x40)
    	{
	Value=DR; 
	USB = Value;
      	Counter++;
    	}
}

Proc WriteEEPROM
{
	Counter = 0;
	while(Counter!= 0x40)
    	{
	Value = USB;
	DR=Value;
	Counter++;
	}
	USB=0;
	
}
