#!/usr/bin/perl

my $state = 'begin';

my $trk = 0;
my $sec = 0;

my @sectorData = ();

my $reLDA_C08C = qr/LDA\s+\$C08C,X\t0x([8-9A-Fa-f][0-9A-Fa-f])/;
my $reLDY_C08C = qr/LDY\s+\$C08C,X\t0x([0-9A-Fa-f]{2})\t0x([0-9A-Fa-f]{2})\t0x([8-9A-Fa-f][0-9A-F])/;

my $reSTA_0300 = qr/STA\s+\$0300,Y\t0x([0-9A-F]{2})\t0x([0-9A-F]{2})\t0x([0-9A-F]{2})/;
my $reSTA_26Y  = qr/STA\s+\(\$26\),Y\t0x([0-9A-F]{2})\t0x([0-9A-F]{2})\t0x([0-9A-F]{2})/;


sub hexdump {
    my ($arr) = @_;

    for($i = 0; $i < scalar(@{$arr}); $i++) {
        if ( $i % 16 == 0 ) {
            printf("\n%04X: ", $i);
        }
        printf("%02X ", @{$arr}[$i]);
    }
    
    print "\n";
}


while (<>) {

    chomp;
    s/[\n\r]+//;

    print;

    { # for the redo to avoid print input twice 

        if ( $state eq 'begin' ) {
            if ( /LDA\s+\$C08C,X\t0xD5/ ) {
                print "\t marker D5";
                $state = 'loaded_D5';
            }
        }
        elsif ( $state eq 'loaded_D5' ) {
            if ( /LDA\s+\$C08C,X\t0xAA/ ) {
                print "\t marker AA";
                $state = 'loaded_AA';
            }
            elsif ( /$reLDA_C08C/ ) {
                $state = 'begin';
                redo;
            }
        }
        elsif ( $state eq 'loaded_AA' ) {
            if ( /LDA\s+\$C08C,X\t0x96/ ) {
                print "\t marker 96";
                $state = 'loaded_96';
                print "\t; sector marker";
            }
            elsif ( /$reLDA_C08C/ ) {
                $state = 'begin';
                redo;
            }
        }
        elsif ( $state eq 'loaded_96' ) {
            if ( /$reLDA_C08C/ ) {
                print "\t marker v1";
                $state = 'loaded_v1';
            }
        }
        elsif ( $state eq 'loaded_v1' ) {
            if ( /$reLDA_C08C/ ) {
                print "\t marker v2";
                $state = 'loaded_v2';
            }
        }
        elsif ( $state eq 'loaded_v2' ) {
            if ( /$reLDA_C08C/ ) {
                print "\t marker t1:$1";
                $trk = hex($1) << 1;
                $trk |= 1;
                $state = 'loaded_t1';
            }
        }
        elsif ( $state eq 'loaded_t1' ) {
            if ( /$reLDA_C08C/ ) {
                print "\t marker t2:$1";
                $trk &= hex($1);
                print "\t; trk:$trk";
                $state = 'loaded_t2';
            }
        }
        elsif ( $state eq 'loaded_t2' ) {
            if ( /$reLDA_C08C/ ) {
                print "\t marker s1:$1";
                $sec = hex($1) << 1;
                $sec |= 1;
                $state = 'loaded_s1';
            }
        }
        elsif ( $state eq 'loaded_s1' ) {
            if ( /$reLDA_C08C/ ) {
                print "\t marker s2:$1";
                $sec &= hex($1);
                print "\t; sec:$sec";
                $state = 'loaded_s2';
            }
        }

        elsif ( $state eq 'loaded_s2' ) {
            if ( /LDA\s+\$C08C,X\t0xD5/ ) {
                print "\t marker D5";
                $state = 'waitingfor_AA';
            }
            elsif ( /EOR\s+#\$D5/ ) {
                $state = 'begin';
                redo;
            }
        }

        elsif ( $state eq 'waitingfor_AA' ) {
            if ( /LDA\s+\$C08C,X\t0xAA/ ) {
                print "\t marker AA 2";
                $state = 'waitingfor_AD';
            }
            elsif ( /$reLDA_C08C/ ) {
                $state = 'begin';
                redo;
            }
        }

        elsif ( $state eq 'waitingfor_AD' ) {
            if ( /LDA\s+\$C08C,X\t0xAD/ ) {
                print "\t marker AD";
                $state = 'loaded_AD';
                print "\t; sector data marker";
            }
            elsif ( /EOR\s+#\$D5/ ) {
                $state = 'begin';
                redo;
            }
        }

        elsif ( $state eq 'loaded_AD' ) {
            if ( /$reLDY_C08C/ ) {
                print "\t byte read: $3 (t:$trk s:$sec)";
            }
            elsif ( /$reSTA_0300/ ) {
                printf( "\t byte to mem: \$%04X:$1\n", 0x300 + hex($3) );
            }
            elsif ( /$reSTA_26Y/ ) {
               my  $y = hex($3);
                printf( "\t byte to mem ind: (\$26)+\$%02X:$1\n", $y );
                if ($y >= 255) {
                    $state = 'sector_decode';
                }
            }
        }

        elsif ( $state eq 'sector_decode' ) {
            if ( /$reSTA_26Y/ ) {
                $i = hex($1);
                $y = hex($3);
                printf( "\t byte to mem ind: (\$26)+\$%02X:$1\n", $y );
                $sectorData[$y] = $i;
                if ($y >= 255) {
                    $state = 'sector_decode';
                    print "\nHEXDUMP track: $trk  sector: $sec\n";
                    hexdump(\@sectorData);
                }
            }
            elsif ( /$reLDA_C08C/ ) {
                $state = 'begin';
                redo;
            }
        }

    } # for the redo to avoid print input twice 

    print "\n";

}