From 75342f5a49bd373898353145d101b57a9dfb133d Mon Sep 17 00:00:00 2001 From: Jorj Bauer Date: Tue, 12 Feb 2019 21:24:40 -0500 Subject: [PATCH] added script to side-load a binary right in to a running SDL build via the debugger --- util/debug-bin.pl | 122 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100755 util/debug-bin.pl diff --git a/util/debug-bin.pl b/util/debug-bin.pl new file mode 100755 index 0000000..5565209 --- /dev/null +++ b/util/debug-bin.pl @@ -0,0 +1,122 @@ +#!/usr/bin/perl + +# Reads a compiled binary (ProDOS header) and loads it via the debugger. +# +# Binary should be created and loaded something like +# +# cc65 -t apple2enh -O testbin.c +# ca65 -t apple2enh testbin.s +# ld65 -t apple2enh -o testbin testbin.o --lib apple2enh.lib +# ./debug-bin.pl testbin + +use strict; +use warnings; +use IO::Socket; + +$| = 1; + +my $filename = shift || die "No file provided"; + +my $fh; +open($fh, $filename) || die "Unable to open file: $!"; + +my $data; +die unless (read($fh, $data, 26) == 26); +my $pos = 26; + +my ($magic, $version, $volume, $numEntries) = unpack("H8H8H32H4", $data); +die "Bad magic [$magic]" unless ($magic eq "00051600"); +$numEntries = int($numEntries); + +print "Entries: " . $numEntries . "\n"; + +my ($dataoffset, $datalength, $infoOffset, $infoLength, $entryPoint); +while ($numEntries) { + die unless (read($fh, $data, 12) == 12); + $pos += 12; + my ($entryID, $entryOffset, $entryLength) = unpack("H8H8H8", $data); + if (hex($entryID) == 11) { + print "ProDOS chunk found at offset 0x$entryOffset length 0x$entryLength\n"; + $infoOffset = hex($entryOffset); + $infoLength = hex($entryLength); + } + if (hex($entryID) == 1) { + print "Data found at offset 0x$entryOffset length 0x$entryLength\n"; + $dataoffset = hex($entryOffset); + $datalength = hex($entryLength); + } + $numEntries--; +} +die "Failed to find info chunk" + unless ($infoOffset || $infoLength); +die "Failed to find data chunk" + unless ($dataoffset || $datalength); + +die "Haven't figured out how to read in this order" + unless ($infoOffset < $dataoffset); + +while ($pos < $infoOffset) { + die unless (read($fh, $data, 1) == 1); + $pos++; +} +die "Failed to read info chunk" unless (read($fh, $data, $infoLength) == $infoLength); +$pos += $infoLength; + +my $unpacked = unpack('H*', $data); +my @hex = ($unpacked =~ /(..)/g); +my @bytes = map { hex($_) } @hex; +$entryPoint=($bytes[6] << 8) |$bytes[7]; + +while ($pos < $dataoffset) { + die unless (read($fh, $data, 1) == 1); + $pos++; +} + +die "Failed to read data chunk" unless (read($fh, $data, $datalength) == $datalength); +$unpacked = unpack('H*', $data); +@hex = ($unpacked =~ /(..)/g); +@bytes = map { hex($_) } @hex; + +my $socket = new IO::Socket::INET (PeerHost => '127.0.0.1', + PeerPort => '12345', + Proto => 'tcp', + ) or die "ERROR in Socket Creation : $!\n"; +print $socket sprintf("L 0x%X\n", $entryPoint); +my $count = 0; +foreach my $i (@bytes) { + print $socket sprintf("%.2X", $i); + print sprintf("%.2X ", $i); + $count++; + if ($count >= 16) { + print $socket "\n"; + print "\n"; + $count = 0; + } +} +print $socket "\n"; # End data entry mode + +# Goto new code +print $socket sprintf("G 0x%X\n\n", $entryPoint); +<$socket>; +#sleep(5); +print sprintf("EntryPoint: 0x%X\n", $entryPoint); +exit(0); + +__END__ +Each entry: + Entry ID (4 bytes): 00 00 00 01 = data form + Entry Offset (4 bytes): 00 00 00 3a = 0x3a + Entry Length: 4 bytes: 00 00 18 40 = 0x1840 bytes +--- + 00 00 00 0B = ProDOS file info + 00 00 00 32 = offset + 00 00 00 08 = length +--- + +Header w/ size of $3A bytes; then file data + +Offset $24/$25 are length (big endian) +$35 -> file type ($06: BIN; $FF: SYS) +$38/$39: aux type for bin (big endian) + +$33: ProDOS Access Byte %11000011 (enable access, destroy, rename, write, read)