178 lines
6.6 KiB
Diff
178 lines
6.6 KiB
Diff
diff --git a/README.md b/README.md
|
|
index b9e708c..01aa299 100644
|
|
--- a/README.md
|
|
+++ b/README.md
|
|
@@ -29,10 +29,13 @@ Usage
|
|
-comment Emit comments
|
|
-call Emit callers
|
|
-access Emit accessors
|
|
+ -extern Emit labels for out-of-range addresses
|
|
+ -rangelabels Emit labels for ranges instead of base+offset
|
|
-verbose Print info to STDERR
|
|
-dump Print options in format for -a
|
|
-a FILE Read options from FILE. Lines are: OPTION VALUE
|
|
|
|
+ Addresses may include a range, e.g. table=$300+F
|
|
Addresses may include xex segment number, e.g. 3:1FAE
|
|
|
|
Examples
|
|
diff --git a/dis b/dis
|
|
index 13090f4..83a3be2 100755
|
|
--- a/dis
|
|
+++ b/dis
|
|
@@ -41,7 +41,7 @@ use constant {
|
|
|
|
sub state {
|
|
return {
|
|
- #mem => [map [0], 0 .. 0x10000],
|
|
+ mem => [map [0], 0 .. 0x10000],
|
|
segnum => 0,
|
|
};
|
|
}
|
|
@@ -79,10 +79,10 @@ sub labels {
|
|
(?:\+([0-9a-fA-F]+))? # optional range in hex
|
|
/x;
|
|
$match or die "ERROR: Unrecognized $opt address: $value\n";
|
|
- my $label = $1;
|
|
my $segnum = $2 || 0;
|
|
my $base = hex($3);
|
|
my $range = hex($4||0);
|
|
+ my $label = $1 || sprintf "u%2X", $base;
|
|
for my $off (0 .. $range) {
|
|
my $addr = $base + $off;
|
|
if (($addr & 0xFFFF) != $addr) {
|
|
@@ -92,6 +92,7 @@ sub labels {
|
|
if (defined $state->{$opt}{$segnum}{$addr}) {
|
|
warn sprintf "WARNING: Duplicate $opt: $value: %X\n",
|
|
$addr;
|
|
+ next;
|
|
}
|
|
$state->{$opt}{$segnum}{$addr} =
|
|
$off ? $rangelabels ? sprintf "${label}_%X", $off :
|
|
@@ -194,14 +195,18 @@ sub trace {
|
|
my $targ = rel($i, $i1);
|
|
trace($state, $targ, $byte->[LABEL], $i);
|
|
} elsif ($mode =~ /Ind|Z-Page/) {
|
|
- my $tlabel = $mem->[$i1][LABEL];
|
|
+ my $data = $mem->[$i1];
|
|
+ my $pre = $data->[SEGNUM] ? sprintf "s$data->[SEGNUM]" : "";
|
|
+ my $tlabel = $data->[LABEL] ||= $pre . sprintf "l%02X", $i1;
|
|
push @{$byte->[TARGETS]}, $tlabel if $tlabel;
|
|
- push @{$mem->[$i1][ACCESSORS]}, seglabel($state, $i);
|
|
+ push @{$data->[ACCESSORS]}, seglabel($state, $i);
|
|
} elsif ($mode =~ /Absolute/) {
|
|
my $addr = addr($i1, $i2);
|
|
- my $tlabel = $mem->[$addr][LABEL];
|
|
+ my $data = $mem->[$addr];
|
|
+ my $pre = $data->[SEGNUM] ? sprintf "s$data->[SEGNUM]" : "";
|
|
+ my $tlabel = $data->[LABEL] ||= $pre . sprintf "l%04X", $addr;
|
|
push @{$byte->[TARGETS]}, $tlabel if $tlabel;
|
|
- push @{$mem->[$addr][ACCESSORS]}, seglabel($state, $i);
|
|
+ push @{$data->[ACCESSORS]}, seglabel($state, $i);
|
|
}
|
|
$i += $len[$code];
|
|
}
|
|
@@ -214,23 +219,24 @@ sub extern {
|
|
return if not $opts->{extern};
|
|
return if not $opts->{labels};
|
|
my @labels;
|
|
- for my $opt (qw(code data vector)) {
|
|
- for my $labels (values %{$state->{$opt}||{}}) {
|
|
- for my $addr (sort {$a <=> $b} keys %$labels) {
|
|
- my $label = $labels->{$addr} or next;
|
|
- next if $opts->{labelled}{$label};
|
|
- next if not $opts->{referenced}{$label};
|
|
- next if $label =~ /\+/;
|
|
- my $accessors = $state->{mem}[$addr][ACCESSORS];
|
|
- my $access = "";
|
|
- if ($accessors and $opts->{access}) {
|
|
- $access = "\t\t; " . join " ", "Access:", uniq @$accessors;
|
|
- }
|
|
- push @labels, [$addr,
|
|
- sprintf "$labels->{$addr} equ \$%X$access\n", $addr];
|
|
- }
|
|
+ for (my $addr = 0; $addr < 0x10000; ++$addr) {
|
|
+ my $label = $state->{mem}[$addr][LABEL] or next;
|
|
+ next if $opts->{labelled}{$label};
|
|
+ next if not $opts->{referenced}{$label};
|
|
+ next if $label =~ /\+/;
|
|
+ my $comment = "";
|
|
+ my $accessors = $state->{mem}[$addr][ACCESSORS];
|
|
+ if ($accessors and $opts->{access}) {
|
|
+ $comment .= "\t\t; " . join " ", "Access:", uniq @$accessors;
|
|
}
|
|
+ my $callers = $state->{mem}[$addr][CALLERS];
|
|
+ if ($callers and $opts->{call}) {
|
|
+ $comment .= "\t\t; " . join " ", "Callers:", uniq @$callers;
|
|
+ }
|
|
+ push @labels, [$addr,
|
|
+ sprintf "$label equ \$%X$comment\n", $addr];
|
|
}
|
|
+ print "##EXTERN##\n";
|
|
print map $_->[1], sort { $a->[0] <=> $b->[0] } @labels;
|
|
}
|
|
|
|
@@ -286,8 +292,6 @@ sub dis {
|
|
my $targ = $imm8 = $imm16 = $rel = $targets->[-1];
|
|
$targ =~ s/\+.*//;
|
|
$opts->{referenced}{$targ}++;
|
|
- # Use z: if label is not predeclared in zero-page
|
|
- $imm8 = "z:$imm8" if not defined $mem->[$i1][VALUE];
|
|
} elsif ($mode eq "Immediate" and $state->{constant}{$segnum}{$i1}) {
|
|
$imm8 = $state->{constant}{$segnum}{$i1};
|
|
$opts->{referenced}{$imm8}++;
|
|
@@ -522,7 +526,7 @@ sub raw {
|
|
my ($stream, $opts) = @_;
|
|
my $start = hex($opts->{org}||0);
|
|
my $end = $start + (length $stream) - 1;
|
|
- printf " opt h-\n";
|
|
+ printf " opt h-\n" unless $opts->{headers};
|
|
printf " org \$%04X\n", $start;
|
|
my $state = state();
|
|
layer($state, $start, $end, $stream);
|
|
@@ -616,6 +620,7 @@ sub main {
|
|
call!
|
|
access!
|
|
extern!
|
|
+ headers!
|
|
verbose!
|
|
dump!
|
|
arg|a=s@
|
|
@@ -650,6 +655,13 @@ sub main {
|
|
warn "WARNING: Truncating file at 1M\n";
|
|
}
|
|
|
|
+ if ($opts{extern} and open my $pipe, "-|") {
|
|
+ $_ = do { local $/; <$pipe> };
|
|
+ s/(.*)##EXTERN##\n(.*)/$2$1/s;
|
|
+ print;
|
|
+ exit 0;
|
|
+ }
|
|
+
|
|
if ($opts{type} eq "xex") {
|
|
xex($stream, \%opts);
|
|
} elsif ($opts{type} eq "prg") {
|
|
diff --git a/sid.dop b/sid.dop
|
|
index 0a85ddf..ea19fab 100644
|
|
--- a/sid.dop
|
|
+++ b/sid.dop
|
|
@@ -28,4 +28,4 @@ data SIDPADX=$D419
|
|
data SIDPADY=$D41A
|
|
data SIDOSCIL=$D41B
|
|
data SIDENVEL=$D41C
|
|
-data SID=$D41D+D2
|
|
+data SID=$D41D+E2
|
|
diff --git a/sys.dop b/sys.dop
|
|
index 96c7266..a875e15 100644
|
|
--- a/sys.dop
|
|
+++ b/sys.dop
|
|
@@ -339,7 +339,7 @@ data COLOR2=$2C6
|
|
data COLOR3=$2C7
|
|
data COLOR4=$2C8 ;BACKGROUND
|
|
;($2C9 - $2DF SPARE)
|
|
-data GLBABS=$2E0 ;GLOBAL VARIABLES
|
|
+data GLBABS=$2E0+2 ;GLOBAL VARIABLES
|
|
;($2E0 - $2E3 SPARE)
|
|
data RAMSIZ=$2E4 ;RAM SIZE (HI BYTE ONLY)
|
|
data MEMTOP=$2E5+1 ;TOP OF AVAILABLE MEMORY
|