[Description]

Location = "Motorola\MC9S12A128";

Info = " Module for programming EEPROMs memory of MC9S12A128,DT128,DG128,DJ128,DB128.",
	" Maskset",
	" Manufacturer: Motorola.",
    " -----------------------------------------------------------",
    " Supported functions:",
    "    EEPROM read/write/verify",
    "    FLASH read",
    " -----------------------------------------------------------",
    " NOTE: SPECIAL ADAPTER ARE REQUIRED! ",
    " ",
    " Author: VKProg (C) 2008";

Picture = "MC9S12A128.bmp";
Buffer1 = "EEPROM",0x800;
Buffer2 = "FLASH",0x20000;
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        = "-";
//InitBoot    = "&Init bootloader",ChipInfoButton,"Init bootloader",F9;
//Div4        = "-";
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, 0x10, 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, 0x01, 0x6E, 0x18, 0x0B, 0xFF, 0x01, 0x14, 0x18, 0x0B, 0x41, 0x00, 0x12, 0xEC, 0xF9, 
0xA9, 0x27, 0xFB, 0xDC, 0x1A, 0x81, 0x01, 0x26, 0x22, 0xEC, 0xF9, 0x96, 0x15, 0xF8, 0x2F, 0x8C, 
0x00, 0x20, 0x18, 0x27, 0x00, 0x64, 0x8C, 0x00, 0x30, 0x18, 0x27, 0x00, 0xFC, 0x8C, 0x00, 0x40, 
0x18, 0x27, 0x00, 0x90, 0x8C, 0x00, 0x50, 0x18, 0x27, 0x00, 0x69, 0xCC, 0x00, 0x80, 0x20, 0x03, 
0xCC, 0x00, 0x00, 0x6C, 0xF9, 0x78, 0xCC, 0x00, 0x00, 0x6C, 0xF9, 0x6E, 0x20, 0xC0, 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, 0xEC, 0xF9, 0x29, 0xC3, 0x40, 0x00, 
0xB7, 0x46, 0xE6, 0xF9, 0x24, 0x1A, 0xF9, 0x28, 0xA6, 0x70, 0x6A, 0x30, 0x04, 0x31, 0xF9, 0x6D, 
0xF9, 0x14, 0x20, 0x9C, 0xCD, 0x40, 0x00, 0xCE, 0x08, 0x00, 0x86, 0xFF, 0x07, 0x0C, 0x41, 0x18, 
0x27, 0xFF, 0x8D, 0xCC, 0x00, 0xFD, 0x18, 0x20, 0xFF, 0x89, 0x34, 0x35, 0xA4, 0x70, 0x04, 0x35, 
0xFB, 0x31, 0x30, 0x3D, 0x1A, 0xFA, 0xFE, 0xF8, 0xEC, 0xFA, 0xFE, 0xEA, 0xC3, 0x40, 0x00, 0xB7, 
0x46, 0xE6, 0xFA, 0xFE, 0xE4, 0x54, 0x37, 0x25, 0x41, 0x0E, 0xFA, 0xFE, 0xD8, 0x01, 0x3B, 0x1F, 
0x01, 0x15, 0x40, 0xFB, 0xEC, 0x40, 0xAC, 0x00, 0x27, 0x1F, 0x8C, 0xFF, 0xFF, 0x26, 0x30, 0x18, 
0x02, 0x00, 0x40, 0x18, 0x0B, 0x20, 0x01, 0x16, 0x18, 0x0B, 0x80, 0x01, 0x15, 0xB6, 0x01, 0x15, 
0x84, 0x30, 0x26, 0x20, 0x1F, 0x01, 0x15, 0x80, 0xFB, 0x08, 0x08, 0x02, 0x02, 0x63, 0x80, 0x26, 
0xCE, 0xCC, 0x00, 0x00, 0x1B, 0x81, 0x18, 0x20, 0xFF, 0x29, 0xCC, 0x00, 0xFC, 0x20, 0xF5, 0xCC, 
0x00, 0xFD, 0x20, 0xF0, 0xCC, 0x00, 0xFF, 0x20, 0xEB, 0x18, 0x0B, 0x30, 0x01, 0x15, 0x7C, 0x40, 
0x00, 0x18, 0x0B, 0x41, 0x01, 0x16, 0x18, 0x0B, 0x80, 0x01, 0x15, 0xB6, 0x01, 0x15, 0x84, 0x30, 
0x26, 0x09, 0x1F, 0x01, 0x15, 0x40, 0xFB, 0x18, 0x20, 0xFE, 0xF5, 0xCC, 0x00, 0xFF, 0x18, 0x20, 
0xFE, 0xF1, 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, 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, 0x7B, 0x18, 0x0B, 0x10, 0x01, 0x02, 0x18, 0x0B, 0xFF, 0x01, 0x04, 0x79, 0x01, 
0x02, 0xEC, 0xF9, 0xA6, 0x27, 0xFB, 0xDC, 0x1A, 0x81, 0x01, 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, 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, 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, 0x96, 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, 
0x38, 0x5B, 0x30, 0x07, 0x20, 0x52, 0xC1, 0x3F, 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, 0x2E, 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, 0x3F, 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, 
0x01, 0x7B, 0x01, 0x03, 0x1F, 0x01, 0x05, 0x40, 0xFB, 0x53, 0x2A, 0xF5, 0x07, 0x5D, 0xCC, 0xFF, 
0xFE, 0x07, 0x6F, 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, 0x38, 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, 0x51, 0xC4, 0x01, 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, 0x3D, 0x3E, 0x38, 0x3F, 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};


define      BLOADER_EE		450
define      BLOADER_FL		720
define      RAM_BEGIN		0x1000
define      EEPROM_BEGIN	0x000
define      EEPROM_END		0x07FF
define      FLASH_BEGIN		0x0E0000
define      FLASH_END		0x100000
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=BLOADER_EE;
	Counter=0;
	Run(LoadBoot);
	Value=Address>>8;USB=Value;
	USB=Address;
	Data = Calc();
	Data=Data*2;
	while(Counter!=BLOADER_EE)
	{
	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=BLOADER_EE;
	Counter=0;
	Run(LoadBoot);
	Value=Address>>8;USB=Value;
	USB=Address;
	Data = Calc();
	Data=Data*2;
	while(Counter!=BLOADER_EE)
	{
	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=BLOADER_EE;
	Counter=0;
	Run(LoadBoot);
	Value=Address>>8;USB=Value;
	USB=Address;
	Data = Calc();
	Data=Data*2;
	while(Counter!=BLOADER_EE)
	{
	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=BLOADER_EE;
	Counter=0;
	Run(LoadBoot);
	Value=Address>>8;USB=Value;
	USB=Address;
	Data = Calc();
	Data=Data*2;
	while(Counter!=BLOADER_EE)
	{
	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 of MC9S12A128,DT128,DG128,DJ128,DB128.");
  print("	Maskset");
  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 VKProg.");
}


[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;
	
}
