#!/usr/bin/perl
# jtag_state_table.pl: generates jtag_state_table.c source file, containing
#    full tables of TAP state transitions and their associated path costs.
# Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>
# Released under the GNU GPL v2 (or later).

use JTAG;

my $paths = tap_path_table();
my $costs = tap_path_costs();

my $tablefile = "jtag_state_table.c";
open FILE, ">$tablefile" or die "unable to open: $tablefile\n";

print FILE <<HEAD;
#include "jtag.h"
#include <assert.h>

u8 jtag_state_paths[16][16] = {
HEAD

for my $start_state ( 0 .. 15 )
{
	my $start = get_state_name($start_state);
	print FILE "\t\t{ ";
	for my $final_state ( 0 .. 15 )
	{
		print FILE ", " if $final_state;
		print FILE "\n\t\t  " unless $final_state  % 4;
		my $final = get_state_name($final_state);
		my $path = $paths->{$start}->{$final};
		my $path_length = length($path);
		my $path_cost = $costs->{$start}->{$final};
		# verify the JTAG algorithms work (TODO: unit tests)
		die "$start -> $final:\n" .
				"\tpath and cost do not match: " .
				"$path_length != $path_cost\n" .
				"\tpath = $path"
			unless $path_length  == $path_cost;
		printf FILE "%12s", "B8(" . reverse($path) . ")";
	}
	print FILE "\n\t\t},\n";
}

print FILE <<MIDDLE;
	};

u8 jtag_get_tms_path(tap_state_t start, tap_state_t final)
{
	return jtag_state_paths[start][final];
}


static u8 jtag_path_costs[16][16] = {
MIDDLE

for my $start_state ( 0 .. 15 )
{
	my $start = get_state_name($start_state);
	print FILE "\t\t{ ";
	for my $final_state ( 0 .. 15 )
	{
		print FILE ", " if $final_state;
		my $final = get_state_name($final_state);
		my $cost = $costs->{$start}->{$final};
		print FILE $cost;
	}
	print FILE " },\n";
}

print FILE <<FOOT;
	};

u8 jtag_get_tms_path_len(tap_state_t start, tap_state_t final)
{
	return jtag_path_costs[start][final];
}
FOOT
close FILE;
