#!/usr/bin/env perl 
use strict;

use IO::Socket::INET;
use Data::Dumper;
#use IO::Socket::Timeout;
#
#

my $prompt= '> ';

sub my_readline_worker($)
{
my $sock=shift;
my $ret="";
my $d="";

while (1) {
return $ret if $sock->read($d,1)!=1;

next if $d eq "\n";

$ret.=$d;

return $ret if $d eq "\r";
return $ret if $ret =~ /> $/;

} 


}

sub my_readline($)
{
my $sock=shift;
my $ret=my_readline_worker($sock);
#print $ret."\n";
return $ret;
}




sub wait_for_prompt($)
{
my $ocd=shift;

1 while (my_readline($ocd) ne $prompt);
}


sub open_ocd($) {
my $addr=shift;
my $sock = IO::Socket::INET->new( $addr);
wait_for_prompt($sock);
return $sock;
}


sub write_reg($$$)
{
my ($ocd,$r,$v)=@_;

$ocd->printf("mww 0x%08x 0x%08x\n",$r,$v);
wait_for_prompt($ocd);
}

sub read_reg($$)
{
my ($ocd,$r)=@_;
my $ret;

$ocd->printf("mdw 0x%08x\n",$r);

$ret=my_readline($ocd);
$ret=my_readline($ocd);

wait_for_prompt($ocd);


$ret =~ s/[\r\n\s]//g;


if ($ret =~ /0x[0-9A-Fa-f]+:([0-9a-fA-F]+)/) {
	return hex($1);
}

return undef;
}


sub dir_get($) {
my $ocd=shift;
return read_reg($ocd,0x50000514);
}


sub dir_set($$) {
my ($ocd,$v)=@_;
write_reg($ocd,0x50000518,$v);
}


sub dir_clr($$) {
my ($ocd,$v)=@_;
write_reg($ocd,0x5000051c,$v);
}

sub io_set($$) {
my ($ocd,$v)=@_;
write_reg($ocd,0x50000508,$v);
}

sub io_clr($$) {
my ($ocd,$v)=@_;
write_reg($ocd,0x5000050c,$v);
}

sub io_get($) {
my $ocd=shift;
return read_reg($ocd,0x50000510);
}

my $ocd=open_ocd('127.0.0.1:4444' );


my $ov=-1;
while (1) {
my $v=io_get($ocd);

next if $v == $ov;

$ov=$v;


printf "%b %b %b %b %04b %04b  %04b %04b  %04b %04b  %04b %04b\n",
	($v >>20) &0x1,
	($v >>19) &0x1,
	($v >>18) &0x1,
	($v >>17) &0x1,

	($v >>24) &0xf,

	($v >>20) &0xf,
	($v >>16) &0xf,

	($v >>12) &0xf,
	($v >>8) &0xf,

	($v >>4) &0xf,
	($v) &0xf;

}