#!/usr/bin/perl
# -*- mode:perl; tab-width:4; c-basic-offset:4; c-indent-level:4; indent-tabs-mode:nil;  -*-
# Copyright (C) 2009, Bret McDanel <trixter AT 0xdecafbad.com>
#
# Version: MPL 1.1 
#
# The contents of this file are subject to the Mozilla Public License Version 
# 1.1 (the "License"); you may not use this file except in compliance with 
# the License. You may obtain a copy of the License at 
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
# for the specific language governing rights and limitations under the 
# License.
#
# The Original Code is Yaesu CAT EEPROM dumper
#
# The Initial Developer of the Original Code is 
# Bret McDanel <trixter AT 0xdecafbad.com>
# Portions created by the Initial Developer are Copyright (C)
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Bret McDanel <trixter AT 0xdecafbad.com>

use Getopt::Std;


my $serial_port = undef;
my $baud_rate = 38400;
my $outline="";
my $ascii="";
my %options;


sub usage()
{
    print "Usage: $0 [-b baud] [-d device]\n";
    print "example: $0 -b 38400 -d /dev/ttyS0\n";
    exit;
}
$OS_win = ($^O eq "MSWin32") ? 1 : 0;

if ($OS_win) {
    eval "use Win32::SerialPort";
    die "Must have Win32::SerialPort correctly installed: $@\n" if ($@);
} else {
    eval "use Device::SerialPort";
    die "Must have Device::SerialPort correctly installed: $@\n" if ($@);
}



getopts("b:d:h",\%options);
usage() if defined $options{h};
$serial_port = $options{d} if defined $options{d};
$baud_rate = $options{b} if defined $options{b};
usage()  if ! defined $serial_port;

my $port = ( $OS_win ?
             (new Win32::SerialPort ($serial_port)) :
             (new Device::SerialPort ($serial_port)) )
    || die "Can't open $serial_port: $!\n";
$port->databits(8);
$port->baudrate($baud_rate); # menu item 19
$port->parity("none");
$port->stopbits(2);
$port->read_char_time(0);     # don't wait for each character
$port->read_const_time(1000); # 1 second per unfulfilled "read" call



for(my $msb=0;$msb<255;$msb++) {
    for(my $lsb=0,my $offset=0;$lsb<=255;$lsb+=2) {
        my $count_out = $port->write(chr($msb).chr($lsb).chr(0).chr(0).chr(0xBB));
        die "write failed\n"      unless ($count_out);
        die "write incomplete\n"  if ( $count_out != 5 );

        my ($count_in, $string_in) = $port->read(2);
        exit if $count_in ne 2;
        $outline .= sprintf "%s ",unpack("H*", $string_in) if defined $string_in;
        
        if(ord(substr($string_in,0,1)) >= 32 && ord(substr($string_in,0,1)) <= 127) {
            $ascii.=substr($string_in,0,1);
        } else {
            $ascii.=".";
        }
        if(ord(substr($string_in,1,1)) >= 32 && ord(substr($string_in,1,1)) <= 127) {
            $ascii.=substr($string_in,1,1);
        } else {
            $ascii.=".";
        }
        
        if(($lsb+2) % 16 eq 0) {
            printf "%02x:%02x %s\t%s\n",$msb,$offset,$outline,$ascii;
            $outline="";
            $ascii="";
            $offset+=16;
        } elsif(($lsb+2) % 8 eq 0) {
            $outline.="\t";
            $ascii.=" ";
        }
    }
}

if($outline!="") {
    printf "%02x:%02x %s\t%s\n",$msb,$offset,$outline,$ascii;
}

