aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2025-04-26 05:41:50 -0400
committerB. Watson <urchlay@slackware.uk>2025-04-26 05:41:50 -0400
commitc3133bb6cde23877c38659820a410dd7688cf813 (patch)
treed15430bf5a7c7387bf89a863f066c2d671ce1014
parent291f6ba7b54fb01053c8927d526bec5b3a1a111f (diff)
downloadatari8-self-relocator-c3133bb6cde23877c38659820a410dd7688cf813.tar.gz
switch to bitmap approach.
-rw-r--r--Makefile2
-rw-r--r--autorun.sysbin1113 -> 1151 bytes
-rwxr-xr-xmkrelocxex.pl44
-rw-r--r--reloc.s79
4 files changed, 67 insertions, 58 deletions
diff --git a/Makefile b/Makefile
index 412c0ab..6e1a27f 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ reloc.atr: reloc.xex hello40.xex hello41.xex mkrelocxex.pl autorun.sys
autorun.sys: reloc.xex hello40.xex hello41.xex
./mkrelocxex.pl hello40.xex hello41.xex autorun.sys
-reloc.xex: reloc.s
+reloc.xex: reloc.s mkrelocxex.pl
cl65 -t none -o reloc.xex reloc.s
hello40.xex: hello.s
diff --git a/autorun.sys b/autorun.sys
index 8aedd8b..65b4c28 100644
--- a/autorun.sys
+++ b/autorun.sys
Binary files differ
diff --git a/mkrelocxex.pl b/mkrelocxex.pl
index a871cd5..a46360b 100755
--- a/mkrelocxex.pl
+++ b/mkrelocxex.pl
@@ -2,6 +2,7 @@
# mkrelocxex prototype in perl (will rewrite in C).
# this version only supports init addresses, not run addresses.
+# *very* ugly code, sorry about that.
use bytes;
@@ -45,17 +46,6 @@ sub read_seg {
return @bytes;
}
-sub print_table {
- my ($name, $t) = @_;
- print "\n$name byte table:\n";
- my $i = 0;
- for(@$t) {
- printf "\$%04x ", $_;
- print "\n" if $i && ($i & 10 == 0);
- }
- print "\n";
-}
-
($start, $end) = read_header($lo);
($hi_start, $hi_end) = read_header($hi);
@@ -77,20 +67,33 @@ if(($hi_start != ($start + 0x0100)) || ($hi_end != ($end + 0x0100))) {
@bytes = read_seg($lo, $start, $end);
@hi_bytes = read_seg($hi, $hi_start, $hi_end);
+@bit_table = ();
for($i = 0; $i < @bytes; $i++) {
my ($a, $b) = ($bytes[$i], $hi_bytes[$i]);
- next if $a == $b;
- if($b == ($a + 1)) {
- push @hi_table, ($i + $start);
+ my $bit;
+
+ if($a == $b) {
+ $bit = 0;
+ } elsif($b == ($a + 1)) {
+ $bit = 1;
} else {
die "invalid difference (not 0 or 1)\n";
}
+
+ my $table_idx = int($i / 8);
+ my $pos = 7 - $i % 8;
+ #warn "$i $table_idx $pos\n";
+ $bit_table[$table_idx] |= ($bit * (1 << $pos));
}
-push(@hi_table, 0);
+$offset = $start;
-print_table("hi", \@hi_table);
-print "table size: " . @hi_table . " bytes\n\n";
+if(0) {
+ for(@bit_table) {
+ printf("\$%04x: %08b \$%04x\n", $offset, $_, $_);
+ $offset += 8;
+ }
+}
($istart, $iend) = read_header($lo);
@@ -127,9 +130,12 @@ $rcode .= chr(0);
$rcode .= chr($init & 0xff);
$rcode .= chr($init >> 8);
-for(@hi_table) {
+printf "bitmap table starts at \$%04x\n", ($rstart + length($rcode));
+
+for(@bit_table) {
+ die "bad relocation" if $_ > 0xff;
$rcode .= chr($_ & 0xff);
- $rcode .= chr($_ >> 8);
+ #$rcode .= chr($_ >> 8);
}
$rend = $rstart + length($rcode) - 1;
diff --git a/reloc.s b/reloc.s
index 5e06056..ec608c3 100644
--- a/reloc.s
+++ b/reloc.s
@@ -18,8 +18,10 @@
zp_addr = FR0
offset_pages = zp_addr ; 1 byte
table_ptr = zp_addr+1 ; 2 bytes
- dest_ptr = table_ptr ; alias
- code_ptr = zp_addr+3 ; 2 bytes
+ dest_ptr = zp_addr+3 ; 2 bytes
+ code_ptr = zp_addr+5 ; 2 bytes
+ shfreg = zp_addr+7 ; 1 byte
+ pagecount = zp_addr+8 ; 1 byte
.org start_addr - 6
.word $ffff
@@ -41,7 +43,7 @@ memlo_00:
sbc MEMLO+1
sta offset_pages
- bcs memlo_ok
+ bcs relocate_code
.ifdef verbose_memlo_check
; whoops, MEMLO is too high, print message and wait for keystroke
@@ -72,74 +74,75 @@ exitwait:
freeze: bne freeze ; wait for the user to press Reset.
.endif
-memlo_ok:
- ; adjust addresses before moving the code.
+relocate_code:
+ ; adjust addresses while moving the code.
; point to the relocation table...
lda #<table
sta table_ptr
lda #>table
sta table_ptr+1
-fixup_addrs:
- ; walk the reloc table
- ldy #1
- lda (table_ptr),y
- sta code_ptr+1
- dey
- lda (table_ptr),y
- sta code_ptr
-
- ; point to next table entry
- inc table_ptr
- bne tp1ok
- inc table_ptr+1
-tp1ok:
- inc table_ptr
- bne tp2ok
- inc table_ptr+1
-tp2ok:
-
- ora code_ptr+1 ; A still has code_ptr, quit if we hit $0000 in the table
- beq fixup_done
- lda (code_ptr),y ; Y still 0
- sec
- sbc offset_pages
- sta (code_ptr),y
- sec ; *should* already be set...
- bcs fixup_addrs
-fixup_done:
-
- ; absolute addresses are fixed up, now move the code.
+ ; ...and to the code we're moving...
lda code_start
sta code_ptr
lda code_start+1
sta code_ptr+1
+
+ ; ...and to the destination we're moving to.
lda MEMLO
sta dest_ptr
lda MEMLO+1
sta dest_ptr+1
- ; x = (code_end >> 8) - (code_start >> 8) + 2
+ ; pagecount = (code_end >> 8) - (code_start >> 8) + 2
lda code_end+1
sec
sbc code_start+1
tax
inx
inx
- ldy #0
+ stx pagecount
+
+ ldx #0
+ lda (table_ptr,x)
+ sta shfreg
; this moves a page at a time, meaning if code_end isn't
; on an even page boundary, we move a little more than
; needed. it won't hurt anything, and it follows the
; KISS principle.
+ ldy #0
move_loop:
lda (code_ptr),y
+ pha
+ cpx #8
+ bne shiftit
+
+ ; bump bitmap pointer
+ inc table_ptr
+ bne tpok
+ inc table_ptr+1
+
+tpok:
+ ; get next byte of bitmap
+ ldx #0
+ lda (table_ptr,x)
+ sta shfreg
+
+shiftit:
+ inx
+ pla
+ asl shfreg
+ bcc dontadj
+ sbc offset_pages
+
+dontadj:
sta (dest_ptr),y
iny
bne move_loop
inc code_ptr+1
inc dest_ptr+1
- dex
+ dec pagecount
bne move_loop
; bump MEMLO to point one byte past the end of the moved code.