/* This simple utility takes address (ram or flash) as the only argument
 * and returns equivalent addres in ram/flash.
 * Transform matrix is taken from disassembly of HD200_UPG.SYS ver 1.30.5
 * 
 * author: Marcin Bukat
 * e-mail: marcin.bukat@gmail.com
 */

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

struct transform{
		uint32_t f_base;
		uint32_t f_end;
		uint32_t d_base;
		uint32_t d_end;
		};

int main(int argc, char *argv[])
{
	uint32_t address;
	uint8_t i;

	if ( argc < 2 )
	{
		printf("Usage: %s ADDRESS\n",argv[0]);
		return -1;
	}

	address = strtol(argv[1],NULL,0);
	
	struct transform transform_matrix[] = { 
	{0xb0a,0xf09,0x10000000,0x100003FF},
	{0xf0a,0x16a1,0x10000400,0x10000b97},
	{0x16a2,0x1b6b,0x10000ba0,0x10001069},
	{0x1b6c,0x1fcf,0x100010f0,0x10001553},
	{0x1fd0,0x6b9b,0x100066e0,0x1000b2ab},
	{0x6b9c,0xa6d3,0x1000b2ac,0x1000ede3},
	{0xa6d4,0xc3eb,0x30BE3C20,0x30BE5937},
	{0xC3EC,0x4b1f7,0x30BE5938,0x30c24743},
	{0x4B1F8,0x6c6e3,0x30C24744,0x30C45c2f},
	{0x6C6E4,0x6d503,0x30C45C30,0x30C46a4f},
	{0x6D504,0x6f01b,0x30C46A50,0x30c48567},
	{0x6f01c,0x72561,0x30c48a70,0x30c4bfb5},
	{0x72562,0x7a0dc,0x30c4e361,0x30c55eda},
	{0x7a0dd,0x7af14,0x30c55ee0,0x30c56d17},
	{0x7af15,0x7bc78,0x30c56d20,0x30c57a83},
	{0x7bc79,0x7e78a,0x30c57a90,0x30c5a5a1},
	{0x7e78b,0x807e2,0x30c5a5b0,0x30c5c607},
	{0x807e3,0x81bfa,0x30c5c610,0x30c5da27},
	{0x81bfb,0x82d3e,0x30c5da30,0x30c5eb73},
	{0x82d3f,0x86c3e,0x30c5eb80,0x30c62a7f},
	{0x86c3f,0x93ace,0x30c62a80,0x30c6e40f},
	{0x92e33,0xb1d20,0x30c6e410,0x30c70afd},
	{0x95921,0x963f4,0x30c70b00,0x30c715d3},
	{0x95ff5,0x9a002,0x100066e0,0x1000a6ed},
	{0x9a003,0x9b0da,0x1000f60c,0x100106e3},
	{0x980db,0xaf016,0x30c75b80,0x30c8cabb},
	{0xb2017,0xb25e2,0x30c8cac0,0x30c8d08b}};

	printf("Address: 0x%08x\n",address);
	for (i=0;i<27;i++)
	{
		if ( address >= transform_matrix[i].f_base && 
		     address <= transform_matrix[i].f_end )
		{
			printf("%d: 0x%08x\n",i,address + transform_matrix[i].d_base - transform_matrix[i].f_base);
		}
		else if ( address >= transform_matrix[i].d_base &&
			  address <= transform_matrix[i].d_end )
		{
			printf("%d: 0x%08x\n",i,address - transform_matrix[i].d_base + transform_matrix[i].f_base);
		}
	}
return 0;
}

