aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2014-06-10 20:38:12 -0700
committerH. Peter Anvin <hpa@zytor.com>2014-06-10 20:38:12 -0700
commit2c1f0999e6b0d8dde47da6d110bab6ae64ea2411 (patch)
tree90c6db48f26990685a053eb1bf156ee9d0e42caa
parenta86afc2b242239466520211a35b70df770159850 (diff)
downloadabc80-2c1f0999e6b0d8dde47da6d110bab6ae64ea2411.tar.gz
abc80-2c1f0999e6b0d8dde47da6d110bab6ae64ea2411.tar.xz
abc80-2c1f0999e6b0d8dde47da6d110bab6ae64ea2411.zip
bin2bac: Simplify by requiring the whole data block to be contiguous
Instead of storing a new address for each statement, just encode it once in the loader. This gets the overhead down a fair bit. Also, simplify some of the generated bytecode. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--abc80.qsf3
-rw-r--r--data/bacldr.asm23
-rwxr-xr-xdata/bin2bac.pl77
3 files changed, 38 insertions, 65 deletions
diff --git a/abc80.qsf b/abc80.qsf
index 3eb15c6..a2ecb87 100644
--- a/abc80.qsf
+++ b/abc80.qsf
@@ -34,7 +34,7 @@
set_global_assignment -name SMART_RECOMPILE ON
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 2.2
set_global_assignment -name PROJECT_CREATION_TIME_DATE "23:24:24 AUGUST 26, 2004"
-set_global_assignment -name LAST_QUARTUS_VERSION 11.0
+set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1"
# Pin & Location Assignments
# ==========================
@@ -541,7 +541,6 @@ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name USE_SIGNALTAP_FILE stp6.stp
-set_global_assignment -name USE_TIMEQUEST_TIMING_ANALYZER ON
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR"
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON
diff --git a/data/bacldr.asm b/data/bacldr.asm
index 2d0e43b..2ff4044 100644
--- a/data/bacldr.asm
+++ b/data/bacldr.asm
@@ -2,29 +2,26 @@
BOFA: equ 65052
offset: equ 0xeeee ; Length of the BASIC prefix
+LOAD: equ 0xdddd ; Load address
+ENTRY: equ 0xbbbb
ld hl,(BOFA)
ld de,offset
add hl,de
+ ld de,LOAD
ld b,0
; Get data block length
loop:
- ld a,-10
+ ld a,-8
add (hl)
- jr nc,run ; End of file marked by an empty REM
+ jp nc,ENTRY ; End of file marked by an empty REM
; Skip length byte + line number (2 bytes) + string opcode (3 bytes)
ld c,6
add hl,bc
- ; Load address
- ld e,(hl)
- inc hl
- ld d,(hl)
- inc hl
-
; Copy remaining data
ld c,a
ldir
@@ -33,13 +30,3 @@ loop:
inc hl
inc hl
jr loop
-
-run:
-; jp 0x1234 ; Replace with RET if no entry point
- ret
- nop
- nop
-
-endbyte:
- defb 13
-data:
diff --git a/data/bin2bac.pl b/data/bin2bac.pl
index 4ef7eef..51f470a 100755
--- a/data/bin2bac.pl
+++ b/data/bin2bac.pl
@@ -5,8 +5,6 @@ use bytes;
sub genpad($$) {
my($left, $final) = @_;
- printf STDERR "Padding %d bytes\n", $$left;
-
my $o = ($final ? "\x01" : "\x00") . ("\x00" x $$left);
$$left = 252; # Bytes left in block minus end marker
@@ -18,8 +16,6 @@ sub bacstmt($$$) {
my $l = length($data) + 4;
my $d = pack("Cv", $l, $line) . $data . "\x0d";
- printf STDERR "bacstmt: l = %d, left = %d\n", $l, $$left;
-
if ($l > $$left) {
$d = genpad($left,0).$d;
}
@@ -28,63 +24,54 @@ sub bacstmt($$$) {
return $pad.$d;
}
-sub makebac($$) {
- my($segdata, $entrypt) = @_;
+sub makebac($$$) {
+ my($data, $addr, $entrypt) = @_;
# <bacldr.asm code>
my $bld1 = "\x2a\x1c\xfe\x11";
# 16-bit offset from BOFA to first data line between $bld1 and $bld2
- my $bld2 = "\x19\x06\x00\x3e\xf6\x86\x30\x0e\x0e\x06";
- $bld2 .= "\x09\x5e\x23\x56\x23\x4f\xed\xb0\x23\x23\x18\xed";
- # C3 = JP, 00C9 is the address for END in all ABC80 BASIC interpreters
- $bld2 .= pack("Cv", 0xc3, defined($entrypt) ? $entrypt : 0x00c9);
-
- # +2 for the offset, +2 for the final 0xbb + CR
- my $bldlen = length($bld1) + length($bld2) + 2 + 2;
- print STDERR "bldlen = ", $bldlen, "\n";
+ my $bld2 = "\x19\x11";
+ # 16-bit load address between $bld2 and $bld3
+ my $bld3 = "\x06\x00\x3e\xf8\x86\xd2";
+ # 16-bit entr point between $bld3 and $bld4
+ my $bld4 = "\x0e\x06\x09\x4f\xed\xb0\x23\x23\x18\xf0";
+ # 0x00C9 is the address for END in all ABC80 BASIC interpreters
+ $entrypt = 0x00c9 unless(defined($entrypt));
+
+ # +2 for the final 0xbb + CR
+ my $bldlen = length($bld1) + 2 + length($bld2) + 2 + length($bld3) + 2 +
+ length($bld4) + 2;
my $q = "\x82"; # Output (program start marker)
my $left = 251; # Bytes left in block
my $r = 0; # Last emitted line number
- # 1 E%=PEEK(65054%)+SWAP%(PEEK(65055%)) [EOFA]
- $q .= bacstmt(++$r, \$left,
- "\x83\xc1\xf1\x45\x37\x80\xc7\x1e\xfe\xce\x36\xc7".
- "\x1f\xfe\xce\x36\xce\x34\xf5\xb7");
- # 2 Z%=CALL(E%-<loader offset>)
+ # Address 65054 is EOFA
+ # 1 Z%=CALL(PEEK(65054%)+SWAP%(PEEK(65055%)-<loader offset>)
$q .= bacstmt(++$r, \$left,
- "\x83\xc1\xf1\x5a\x37\x80\xc1\xf1\x45\xba\x0d\xd5\xc7".
+ "\x83\xc1\xf1\x5a\x00\xbb\xc7\x1e\xfe\xce\x36\xc7".
+ "\x1f\xfe\xce\x36\xce\x34\xf5\xc7".
pack("v",$bldlen)."\xf8\xce\x3a\xb7");
my $pfxlen = length($q) - 1; # The initial 0x82 isn't stored in RAM
- my $bld = $bld1 . pack("v", $pfxlen) . $bld2;
- print STDERR "pfxlen = ", $pfxlen, "\n";
-
- foreach my $sega ( sort(keys(%{$segdata})) ) {
- my $addr = $sega;
- my $data = ${$segdata}{$sega};
-
- my $i = 0;
- my $dl = length($data);
- while ($i < $dl) {
- my $l = $dl - $i;
-
- printf STDERR "left = %d, l = %d\n", $left, $dl;
+ my $bld = $bld1 . pack("v", $pfxlen) . $bld2 . pack("v", $addr) .
+ $bld3 . pack("v", $entrypt) . $bld4;
- # 9 = 3 byte BAC header + 6 byte overhead + CR
- $q .= genpad(\$left,0) if ($left <= 10);
- $l = $left-10 if ($l > $left-10);
+ my $i = 0;
+ my $dl = length($data);
+ while ($i < $dl) {
+ my $l = $dl - $i;
- printf STDERR "Line %d address %04X, %d/%X bytes\n",
- $r+1, $addr, $l, $l;
+ # 8 = 3 byte BAC header + 4 byte overhead + CR
+ $q .= genpad(\$left,0) if ($left <= 8);
+ $l = $left-8 if ($l > $left-8);
- # String expression + address + data + return
- $q .= bacstmt(++$r, \$left, "\xcb\"".pack("C", $l+2).
- pack("v",$addr).substr($data,$i,$l)."\xbb");
+ # String expression + address + data + return
+ $q .= bacstmt(++$r, \$left,
+ "\xcb\"" . pack("C", $l) . substr($data,$i,$l)."\xbb");
- $i += $l;
- $addr += $l;
- }
+ $i += $l;
+ $addr += $l;
}
# Terminal END statement
@@ -107,4 +94,4 @@ close(FILE);
$segs{$org} = $dd;
-print makebac(\%segs, $entry);
+print makebac($dd, $org, $entry);