/***********************************************************************
	idblock_report.c


	Reports system ID Block information.

 ***********************************************************************


 Instructions:

 1. Compile the program to the target and run it.  The contents of the
    system ID block will be printed (or any errors reported) to stdio.


 ***********************************************************************


 Version History:

 1.00 - Initial version, based on write_idblock.c.


 **********************************************************************/


#class auto


#define VERSION "1.00"
#define PROGRAM_NAME "idblock_report.c"


// check for undefined board types
//  (new since 7.04P2)


#ifndef BL2000
	#define BL2000		0x0800
#endif
#ifndef BL2010
	#define BL2010		0x0801
#endif
#ifndef BL2010B
	#define BL2010B	0x0805
#endif
#ifndef BL2020
	#define BL2020		0x0802
#endif
#ifndef BL2030
	#define BL2030		0x0803
#endif
#ifndef BL2040
	#define BL2040		0x0804
#endif
#ifndef BL2100
	#define BL2100		0x0B00
#endif
#ifndef BL2101
	#define BL2101		0x0B06
#endif
#ifndef BL2105
	#define BL2105		0x0B04
#endif
#ifndef BL2110
	#define BL2110		0x0B01
#endif
#ifndef BL2111
	#define BL2111		0x0B08
#endif
#ifndef BL2115
	#define BL2115		0x0B05
#endif
#ifndef BL2120
	#define BL2120		0x0B02
#endif
#ifndef BL2121
	#define BL2121		0x0B07
#endif
#ifndef BL2130
	#define BL2130		0x0B03
#endif
#ifndef BL2500A
	#define BL2500A	0x1500
#endif
#ifndef BL2500B
	#define BL2500B	0x1502
#endif
#ifndef BL2500C
	#define BL2500C	0x1504
#endif
#ifndef BL2510A
	#define BL2510A	0x1501
#endif
#ifndef BL2510B
	#define BL2510B	0x1503
#endif
#ifndef EG2110A
	#define EG2110A	0x0603
#endif
#ifndef LP3500
	#define LP3500		0x1200
#endif
#ifndef LP3510
	#define LP3510		0x1201
#endif
#ifndef OP6600
	#define OP6600		0x0300
#endif
#ifndef OP6700
	#define OP6700		0x0302
#endif
#ifndef OP6800
	#define OP6800		0x0D00
#endif
#ifndef OP6805
	#define OP6805		0x0D02
#endif
#ifndef OP6810
	#define OP6810		0x0D01
#endif
#ifndef OP7200
	#define OP7200		0x1100
#endif
#ifndef OP7200B
	#define OP7200B	0x1102
#endif
#ifndef OP7210
	#define OP7210		0x1101
#endif
#ifndef OP7210B
	#define OP7210B	0x1103
#endif
#ifndef RABLINK
	#define RABLINK	0x0601
#endif
#ifndef RCM2100
	#define RCM2100	0x0700
#endif
#ifndef RCM2110
	#define RCM2110	0x0701
#endif
#ifndef RCM2115
	#define RCM2115	0x0704
#endif
#ifndef RCM2120
	#define RCM2120	0x0702
#endif
#ifndef RCM2130
	#define RCM2130	0x0703
#endif
#ifndef RCM2200
	#define RCM2200	0x0900
#endif
#ifndef RCM2210
	#define RCM2210	RCM2200
#endif
#ifndef RCM2250
	#define RCM2250	0x0E00
#endif
#ifndef RCM3000
	#define RCM3000	0x0F00
#endif
#ifndef RCM3010
	#define RCM3010	0x0F01
#endif
#ifndef RCM3100
	#define RCM3100	0x1000
#endif
#ifndef RCM3110
	#define RCM3110	0x1001
#endif
#ifndef RCM3200
	#define RCM3200	0x1300
#endif
#ifndef RCM3300A
	#define RCM3300A	0x1400
#endif
#ifndef RCM3400A
	#define RCM3400A	0x1600
#endif
#ifndef RCM3410A
	#define RCM3410A	0x1601
#endif
#ifndef RTDK
	#define RTDK		0x0301
#endif
#ifndef SR9100
	#define SR9100		0x0502
#endif
#ifndef SR9150
	#define SR9150		0x0C00
#endif
#ifndef SR9160
	#define SR9160		0x0C01
#endif


// local function prototypes


int GetFlashID(void);
void PrintFlashDescription(char *which, int FlashID);
void PrintProductDescription(int ProductID);
void PrintSysIDBlockInfo(void);


/********************************************************************/


void main(void)
{
	printf("%s, version %s.\n", PROGRAM_NAME, VERSION);

	PrintSysIDBlockInfo();
	PrintProductDescription(SysIDBlock.productID);
	PrintFlashDescription("Flash ID", (int) SysIDBlock.flashID);
	PrintFlashDescription("Flash2 ID", (int) SysIDBlock.flash2ID);
#if FLASH_COMPILE || FAST_RAM_COMPILE
	PrintFlashDescription("GetFlashID() result", GetFlashID());
#endif
}

#if FLASH_COMPILE || FAST_RAM_COMPILE
int GetFlashID(void)
{
	static int id;

#asm
#if __SEPARATE_INST_DATA__ && FLASH_COMPILE
	; Only if separate I&D space is enabled AND the program runs in
	;  flash do we need to call the run-in-data-RAM function this way.
	ld		hl, _GetFlashID
	lcall	_CallRAMFunction
#else
	call	_GetFlashID
#endif
	ld		(id), hl
#endasm
	return(id);
}
#endif

const char *FlashDescription[] = {
	"?\n  If valid and supported, a description should be added to the Flash array",
	" is small, uniform sectors; byte write",
	" is small, uniform sectors; sector write",
	" is large, nonuniform sectors (128/96/8/8/16); byte write",
	" is large, nonuniform sectors (16/8/8/96/128); byte write",
	" is large, nonuniform sectors (16*7/4/4/8); byte write",
	" is large, nonuniform sectors (8/4/4/16*7); byte write",
	" is large, nonuniform sectors (64*3/32/8/8/16); byte write",
	" is large, nonuniform sectors (16/8/8/32/64*3); byte write",
	" is large, nonuniform sectors (64*7/32/8/8/16); byte write",
	" is large, nonuniform sectors (16/8/8/32/64*7); byte write",
	" is large, uniform sectors (64*8); byte write",
	" is large, uniform sectors (64*8); byte write",
	" is large, uniform sectors (64*4); byte write",
	" is large, uniform sectors (64*4); byte write",
	" is large, nonuniform sectors (128/96/8/8); byte write",
	" is large, uniform sectors (32*8); byte write",
	" is large, nonuniform sectors (8/4/4/16*7); byte write"
};

struct _Flash {
	int fID;
	int fType;
	char *name;
};

const struct _Flash Flash[] = {
	{0x0134, 0x16, "AMD AM29F002B"},
	{0x0140, 0x15, "AMD AM29LV002BT"},
	{0x016D, 0x1F, "AMD AM29LV001B"},
	{0x0177, 0x17, "AMD AM29F004B"},
	{0x017B, 0x18, "AMD AM29F004B"},
	{0x01B0, 0x15, "AMD AM29F002B"},
	{0x01B5, 0x17, "AMD AM29LV004BT"},
	{0x01B6, 0x18, "AMD AM29LV004BB"},
	{0x01C2, 0x16, "AMD AM29LV002BB"},
	{0x01ED, 0x13, "AMD AM29LV001B"},

	{0x0434, 0x16, "Fujitsu MBM29F002BC"},
	{0x04B0, 0x15, "Fujitsu MBM29F002TC"},

	{0x1F07, 0x12, "Atmel AT49F002"},
	{0x1F08, 0x11, "Atmel AT49F002T"},
	{0x1F25, 2, "Atmel AT29C1024"},
	{0x1F26, 2, "Atmel AT29LV1024"},
	{0x1F35, 2, "Atmel AT29LV010 / AT29BV010A"},
	{0x1FA4, 2, "Atmel AT29C040"},
	{0x1FBA, 2, "Atmel AT29LV020 / AT29BV020"},
	{0x1FC4, 2, "Atmel AT29LV040 / AT29BV040"},
	{0x1FD5, 2, "Atmel AT29C010"},
	{0x1FDA, 2, "Atmel AT29C020"},

	{0x20E2, 0x1A, "STMicroelectronics M29F040B"},
	{0x20E3, 0x1A, "STMicroelectronics M29W040B"},

	{0x4001, 1, "Mosel/Vitelic V29C51001T"},
	{0x4002, 1, "Mosel/Vitelic V29C51002T"},
	{0x4003, 1, "Mosel/Vitelic V29C51004T"},
	{0x4060, 1, "Mosel/Vitelic V29LC51001"},
	{0x4063, 1, "Mosel/Vitelic V29C31004T"},
	{0x4073, 1, "Mosel/Vitelic V29C31004B"},
	{0x4082, 1, "Mosel/Vitelic V29LC51002"},
	{0x40A1, 1, "Mosel/Vitelic V29C51001B"},
	{0x40A2, 1, "Mosel/Vitelic V29C51002B"},
	{0x40A3, 1, "Mosel/Vitelic V29C51004B"},

	{0xAD34, 0x16, "Hyundai HY29F002B"},
	{0xADB0, 0x15, "Hynix/Hyundai HY29F002T"},

	{0xBF07, 2, "SST SST29EE010"},
	{0xBF08, 2, "SST SST29LE010 / SST29VE010"},
	{0xBF10, 2, "SST SST29EE020"},
	{0xBF12, 2, "SST SST29LE020 / SST29VE020"},
	{0xBF13, 1, "SST SST29SF040"},
	{0xBF14, 1, "SST SST29VF040"},
	{0xBF20, 1, "SST SST29SF512"},
	{0xBF21, 1, "SST SST29VF512"},
	{0xBF22, 1, "SST SST29SF010"},
	{0xBF23, 1, "SST SST29VF010"},
	{0xBF24, 1, "SST SST29SF020"},
	{0xBF25, 1, "SST SST29VF020"},
	{0xBF3D, 2, "SST SST29LE512 / SST29VE512"},
	{0xBF5D, 2, "SST SST29EE512"},
	{0xBFB4, 1, "SST SST39SF512"},
	{0xBFB5, 1, "SST SST39SF010"},
	{0xBFB6, 1, "SST SST39SF020"},
	{0xBFB7, 1, "SST SST39SF040"},
	{0xBFD4, 1, "SST SST39LF512 / SST39VF512"},
	{0xBFD5, 1, "SST SST39LF010 / SST39VF010"},
	{0xBFD6, 1, "SST SST39LF020 / SST39VF020"},
	{0xBFD7, 1, "SST SST39LF040 / SST39VF040"},

	{0xC234, 0x16, "Macronix MX29F002B"},
	{0xC2B0, 0x15, "Macronix MX29F02T"},

	{0xDA45, 2, "Winbond W29C020CT"},
	{0xDA46, 2, "Winbond W29C040"},
	{0xDAB5, 0x1C, "Winbond W39L020"},
	{0xDAC1, 2, "Winbond W29EE011"},

	{0, 0x00, "unlisted type"}
};

void PrintFlashDescription(char *which, int FlashID)
{
	int i;

	i = 0;
	while (Flash[i].fID) {
		if (FlashID == Flash[i].fID) {
			break;
		}
		i++;
	}
	printf("\n\n%s 0x%04X is a(n) %s:\n\n  Type 0x%04X",
	       which, FlashID, Flash[i].name, Flash[i].fType);

	if ((Flash[i].fType > 0) && (Flash[i].fType < 3)) {
		i = Flash[i].fType;
	} else if ((Flash[i].fType > 0x10) && (Flash[i].fType < 0x20)) {
		i = Flash[i].fType - 0x0E;
	} else {
		i = 0;
	}
	printf("%s.\n", FlashDescription[i]);
}

struct _Product {
	int pID;
	char *name;
	char *description;
};

const struct _Product Product[] = {
//*** RabbitCore Modules ***//

	{RCM2000, "RCM2000", "25MHz R2000, 256K flash, 512k SRAM"},
	{RCM2010, "RCM2010", "25MHz R2000, 256K flash, 128k SRAM"},
	{RCM2020, "RCM2020", "18MHz R2000, 256K flash, 128K SRAM"},

	{RCM2100, "RCM2100", "22MHz R2000, 2x256K flash, 512K SRAM, ethernet"},
	{RCM2110, "RCM2110", "22MHz R2000, 256K flash, 128K SRAM, ethernet"},
	{RCM2115, "RCM2115", "22MHz R2000, 256K flash, 128K SRAM, ethernet (no RJ45)"},
	{RCM2120, "RCM2120", "22MHz R2000, 2x256K flash, 512K SRAM"},
	{RCM2130, "RCM2130", "22MHz R2000, 256K flash, 128K SRAM"},

	{RCM2200, "RCM2200", "22MHz R2000, 256K flash, 128K SRAM, ethernet"},
	{RCM2210, "RCM2210", "22MHz R2000, 256K flash, 128K SRAM, ethernet (no RJ45)"},
	{RCM2250, "RCM2250", "22MHz R2000, 2x256K flash, 512K SRAM, ethernet"},

	{RCM2300, "RCM2300", "22MHz R2000, 256K flash, 128K SRAM"},

	{RCM3000, "RCM3000", "29MHz R3000, 2x256K flash, 512K SRAM, ethernet"},
	{RCM3010, "RCM3010", "29MHz R3000, 256K flash, 128K SRAM, ethernet"},

	{RCM3100, "RCM3100", "29MHz R3000, 2x256K flash, 512K SRAM"},
	{RCM3110, "RCM3110", "29MHz R3000, 256K flash, 128K SRAM"},

	{RCM3200, "RCM3200", "44MHz R3000, 512K flash, 256K+512K SRAM, ethernet"},

	{RCM3400A, "RCM3400A", "29MHz R3000, 512K flash, 512K SRAM, ethernet on PB, analog"},
	{RCM3410A, "RCM3410A", "29MHz R3000, 256K flash, 256K SRAM, ethernet on PB, analog"},


//*** Single Board Computers ***//

//Jackrabbit
	{BL1800, "BL1800", "29MHz R2000, 256K flash, 128K SRAM, RS485, battery"},
	{BL1805, "BL1805", "29MHz R2000, 256K flash, 512K SRAM, RS485, battery"},
	{BL1810, "BL1810", "14MHz R2000, 128K flash, 128K SRAM, RS485, battery"},
	{BL1820, "BL1820", "14MHz R2000, 128K flash, 128k SRAM"},

//Wildcat
	{BL2000, "BL2000", "22MHz R2000, 256K flash, 128K SRAM, ethernet, high-quality analog"},
	{BL2010, "BL2010", "22MHz R2000, 256K flash, 128K SRAM, ethernet, analog"},
	{BL2010B, "BL2010B", "22MHz R2000, 256K flash, 512K SRAM, ethernet, analog"},
	{BL2020, "BL2020", "22MHz R2000, 256K flash, 128K SRAM, high-quality analog"},
	{BL2030, "BL2030", "22MHz R2000, 256K flash, 128K SRAM, analog"},
	{BL2040, "BL2040", "22MHz R2000, 256K flash, 128K SRAM"},

//Smart Cat
	{BL2100, "BL2100", "22MHz RCM2200, 256K flash, 128K SRAM, ethernet, analog"},
	{BL2101, "BL2101", "22MHz RCM2200, 256K flash, 128K SRAM, ethernet, 10V analog"},
	{BL2105, "BL2105", "22MHz RCM2250, 2x256K flash, 512K SRAM, ethernet, analog"},
	{BL2110, "BL2110", "22MHz RCM2200, 256K flash, 128K SRAM, ethernet"},
	{BL2111, "BL2111", "22MHz RCM2250, 2x256K flash, 512K SRAM, ethernet, 10V analog"},
	{BL2115, "BL2115", "22MHz RCM2250, 2x256K flash, 512K SRAM, ethernet"},
	{BL2120, "BL2120", "22MHz RCM2300, 256K flash, 128K SRAM, analog"},
	{BL2121, "BL2121", "22MHz RCM2300, 256K flash, 128K SRAM, 10V analog"},
	{BL2130, "BL2130", "22MHz RCM2300, 256K flash, 128K SRAM"},

//RabbitNet
	{BL2500A, "BL2500A", "29MHz RCM3010, 256K flash, 128K SRAM, ethernet"},
	{BL2500B, "BL2500B", "29MHz RCM3000, 2x256K flash, 512K SRAM, ethernet"},
	{BL2500C, "BL2500C", "44MHz RCM3200, 512K flash, 256K+512K SRAM, ethernet"},
	{BL2510A, "BL2510A", "29MHz RCM3110, 256K flash, 128K SRAM"},
	{BL2510B, "BL2510B", "29MHz RCM3100, 2x256K flash, 512K SRAM"},

//Fox Low-Power Controller
	{LP3500, "LP3500", "7MHz R3000, 2x256K flash, 512K SRAM, analog, relay"},
	{LP3510, "LP3510", "7MHz R3000, 256K flash, 128K SRAM"},


//*** Embedded Control Systems ***//

//SmartStar
	{SR9100, "SR9100", "29MHz R2000, 2x256K flash, 128K SRAM"},

//MiniStar
	{SR9150, "SR9150", "22MHz R2000, 2x256K flash, 128K SRAM, ethernet"},
	{SR9160, "SR9160", "22MHz R2000, 2x256K flash, 128K SRAM"},

//*** Operator Interfaces ***//

//Intellicom
	{OP6600, "OP6600", "18MHz R2000, 256K flash, 128K SRAM"},
	{OP6700, "OP6700", "18MHz R2000, 2x256K flash, 256K SRAM, ethernet"},

//Minicom
	{OP6800, "OP6800", "22MHz RCM2200, 256K flash, 128K SRAM, ethernet"},
	{OP6805, "OP6805", "22MHz RCM2250, 2x256K flash, 512K SRAM, ethernet"},
	{OP6810, "OP6810", "22MHz RCM2300, 256K flash, 128K SRAM"},

//eDisplay
	{OP7200, "OP7200", "22MHz RCM2200, 256K flash, 128K SRAM, ethernet, analog, touchscreen"},
	{OP7200B, "OP7200B", "22MHZ RCM2250, 2x256K flash, 512K SRAM, ethernet, analog, touchscreen"},
	{OP7210, "OP7210", "22MHz RCM2300, 256K flash, 128K SRAM"},
	{OP7210B, "OP7210B", "22MHz RCM2250, 2x256K flash, 512K SRAM, ethernet"},


//*** Other Products ***//

//RabbitLink
	{EG2110A, "EG2110A", "22MHz R2000, 2x256K flash, 128K SRAM, ethernet, 3V"},
	{RABLINK, "RABLINK", "22MHz R2000, 2x256K flash, 128K SRAM, ethernet"},

//TCP/IP Development Kit
	{RTDK, "RTDK", "18MHz R2000, 2x256K flash, 128K SRAM, ethernet"},
	{0, "unlisted type", "If valid, a description should be added to the Product array"}
};

void PrintProductDescription(int ProductID)
{
	int i;

	i = 0;
	while (Product[i].pID) {
		if (ProductID == Product[i].pID) {
			break;
		}
		i++;
	}
	printf("\n\nProduct ID 0x%04X is a(n) %s:\n\n", ProductID, Product[i].name);
	printf("  %s.\n", Product[i].description);
}

void PrintSysIDBlockInfo(void)
{
	printf("\n\nSystem ID Block content:\n\n");
	printf("  tableVersion =  %d\n", SysIDBlock.tableVersion);
	printf("  productID =     0x%04X\n", SysIDBlock.productID);
	printf("  vendorID =      %d\n", SysIDBlock.vendorID);
	printf("  timestamp =     %02d/%02d/%02d%02d  %02d:%02d:%02d\n\n",
		SysIDBlock.timestamp[2], SysIDBlock.timestamp[3],
		SysIDBlock.timestamp[0], SysIDBlock.timestamp[1],
			SysIDBlock.timestamp[4], SysIDBlock.timestamp[5],
			SysIDBlock.timestamp[6]);

	printf("  flashID =       0x%08LX\n", SysIDBlock.flashID);
	printf("  flashType =     0x%04X\n", SysIDBlock.flashType);
	printf("  flashSize =     %d Kbytes\n", SysIDBlock.flashSize * 4);
	printf("  sectorSize =    %d bytes\n", SysIDBlock.sectorSize);
	printf("  numSectors =    %d\n", SysIDBlock.numSectors);
	printf("  flashSpeed =    %d nS\n\n", SysIDBlock.flashSpeed);

	printf("  flash2ID =      0x%08LX\n", SysIDBlock.flash2ID);
	printf("  flash2Type =    0x%04X\n", SysIDBlock.flash2Type);
	printf("  flash2Size =    %d Kbytes\n", SysIDBlock.flash2Size * 4);
	printf("  sector2Size =   %d bytes\n", SysIDBlock.sector2Size);
	printf("  num2Sectors =   %d\n", SysIDBlock.num2Sectors);
	printf("  flash2Speed =   %d nS\n\n", SysIDBlock.flash2Speed);

	printf("  ramID =         0x%08LX\n", SysIDBlock.ramID);
	printf("  ramSize =       %d Kbytes\n", SysIDBlock.ramSize * 4);
	printf("  ramSpeed =      %d nS\n\n", SysIDBlock.ramSpeed);

	printf("  cpuID =         R%u (rev. %u)\n",
	       ((SysIDBlock.cpuID >> 8) & 0xFF) * 1000 + 2000,
	       SysIDBlock.cpuID & 0xFF);
	printf("  crystalFreq =   %.4f MHz\n\n", SysIDBlock.crystalFreq * 1.0e-6);

	printf("  macAddr =       %02X:%02X:%02X:%02X:%02X:%02X\n",
	       SysIDBlock.macAddr[0], SysIDBlock.macAddr[1], SysIDBlock.macAddr[2],
	       SysIDBlock.macAddr[3], SysIDBlock.macAddr[4], SysIDBlock.macAddr[5]);
	printf("  serialNumber =  '%s'\n", SysIDBlock.serialNumber);
	printf("  productName =   '%s'\n\n", SysIDBlock.productName);

	printf("  reserved =      0x%02X\n\n", SysIDBlock.reserved[0]);

	printf("  idBlockSize =   0x%08LX bytes\n", SysIDBlock.idBlockSize);
	printf("  userBlockSize = 0x%04X\n", SysIDBlock.userBlockSize);
	printf("  userBlockLoc =  0x%04X\n\n", SysIDBlock.userBlockLoc);

  	printf("  idBlockCRC =    0x%04X\n", SysIDBlock.idBlockCRC);
	printf("  marker =        %02X %02X %02X %02X %02X %02X\n",
	       SysIDBlock.marker[0], SysIDBlock.marker[1], SysIDBlock.marker[2],
	       SysIDBlock.marker[3], SysIDBlock.marker[4], SysIDBlock.marker[5]);
}