aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2018-09-10 05:51:48 -0700
committerH. Peter Anvin <hpa@zytor.com>2018-09-10 05:51:48 -0700
commit8e5bfce70b8af0b2481de4c9c342556c8fb7c110 (patch)
tree1a2eb44425f26323a241204b5c3a8f42745b675e
parenta27c0fff19225acde1ef4e7ee15d40e74b25b45c (diff)
downloadabc80-8e5bfce70b8af0b2481de4c9c342556c8fb7c110.tar.gz
abc80-8e5bfce70b8af0b2481de4c9c342556c8fb7c110.tar.xz
abc80-8e5bfce70b8af0b2481de4c9c342556c8fb7c110.zip
bin2bac: for ABC800, allow the assembly program to hijack BASIC
Add a dummy GOTO statement to the assembly prefix. It can be used to redirect to different BASIC bytecode, e.g. to execute a CHAIN statement instead of END. See bye800.asm for how to use. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--data/bac800.asm14
-rwxr-xr-xdata/bin2bac.pl16
-rw-r--r--data/bye800.asm46
-rw-r--r--data/hello800.asm28
4 files changed, 93 insertions, 11 deletions
diff --git a/data/bac800.asm b/data/bac800.asm
index 57456ba..42c0f1f 100644
--- a/data/bac800.asm
+++ b/data/bac800.asm
@@ -39,7 +39,10 @@ _basic:
defb 156 ; + int
defb 209 ; Function call, 1 parameter
defb 23 ; CALL()
- defb 184 ; POP int
+ defb 184 ; POP int (end expression)
+ defb 128 ; GOTO
+gotooffs:
+ defw 1 ; Skip nothing
defb 146 ; END
;; Relocator code. In order to support saving and re-loading
@@ -52,6 +55,7 @@ _start: ; HL points here
;; Subtract the length of the (added) relocations from this value
;; so that 0 offset = start of program
ld bc,_start - _end ; Current base address
+ push hl ; Save pointer to _start
ld a,l
sub c
ld c,a
@@ -109,14 +113,18 @@ reloc_large:
; All done, jump to entry point. A RET will return to BASIC
; which will execute an END statement.
done:
- defc RELENTRY=done+1 ; Relocation here
+ pop hl ; -> _start
+ ld de,gotooffs - _start
+ add hl,de ; -> GOTO offset (to override END)
+jpentry:
+ defc REL2=jpentry+1 ; Relocation here
jp ENTRY ; Entry relative to start of program
; Relocation data follows immediately afterwards
reloc_data:
; Our internal relocations first
defb REL1 - _start
- defb RELENTRY - REL1 - 2
+ defb REL2 - REL1 - 2
_end:
;; The relocation pointer is at _end - 2, so the first
;; relocation must be set to 2 + size of relocation data +
diff --git a/data/bin2bac.pl b/data/bin2bac.pl
index 95bf1f9..76904b8 100755
--- a/data/bin2bac.pl
+++ b/data/bin2bac.pl
@@ -190,17 +190,17 @@ sub makebac800($$$$) {
my $bhdr;
# See bac800.asm
- $bhdr = "\x8f\x00\x21\x00";
- $bhdr .= pack("v", 0x5a + length($relocs) + length($data));
+ $bhdr = "\x8f\x00\x01\x00";
+ $bhdr .= pack("v", 0x63 + length($relocs) + length($data));
$bhdr .= pack("v*", 0, 0, 0, $reserve, 0, 0, 0);
- $bhdr .= "\xe8\xd1\x19\xfa\x9c\xd1\x17\xb8\x92";
- $bhdr .= "\x01" . pack("v", 0xffca - length($relocs));
- $bhdr .= "\x7d\x91\x4f\x7c\x98\x47\xb1\x28\x25\xe5\x11\x34\x00";
+ $bhdr .= "\xe8\xd1\x19\xfd\x9c\xd1\x17\xb8\x80\x01\x00\x92";
+ $bhdr .= "\x01" . pack("v", 0xffc4 - length($relocs));
+ $bhdr .= "\xe5\x7d\x91\x4f\x7c\x98\x47\xb1\x28\x25\xe5\x11\x3a\x00";
$bhdr .= "\x19\xd1\x7e\xfe\x80\x30\x10\x23\x83\x5f\x30\x01\x14";
- $bhdr .= "\x1a\x81\x12\x13\x1a\x88\x12\x13\x18\xeb\xd6\x81\x38";
- $bhdr .= "\x06\x23\x82\x57\x7e\x18\xe6";
+ $bhdr .= "\x1a\x81\x12\x13\x1a\x88\x12\x13\x18\xeb\xd6\x81\x38\x06";
+ $bhdr .= "\x23\x82\x57\x7e\x18\xe6\xe1\x11\xfd\xff\x19";
$bhdr .= "\xc3" . pack("v", $entry);
- $bhdr .= "\x01\x2f";
+ $bhdr .= "\x01\x35";
$data = $bhdr . $relocs . $data;
diff --git a/data/bye800.asm b/data/bye800.asm
new file mode 100644
index 0000000..4b7325b
--- /dev/null
+++ b/data/bye800.asm
@@ -0,0 +1,46 @@
+;;
+;; .bac loader test program
+;;
+
+ defc CONWRITE=000Bh
+ defc IPSAV=65338
+
+_start:
+ ;; After this, do CHAIN "NUL:"
+ ld de,chain_nul-1
+ ld a,e
+ sub l
+ ld (hl),a
+ ld a,d
+ sbc h
+ inc hl
+ ld (hl),a
+
+ ld hl,hello
+ ld c,hello_len
+ ld b,0
+ call CONWRITE
+ ld hl,world
+ ld c,world_len
+ ld b,0
+ call CONWRITE
+
+ ret
+
+hello:
+ defm "Hello, "
+hello_end:
+ defc hello_len=hello_end-hello
+ defm "BAD"
+world:
+ defm "World!\r\n"
+world_end:
+ defc world_len=world_end-world
+ defm "BAD"
+
+ ;; BASIC bytecode for CHAIN "NUL:"
+chain_nul:
+ defb 134, 11 ; CHAIN
+ defb 203, 4 ; String, 4 bytes
+ defm "NUL:"
+ defb 185 ; POP string (end expression)
diff --git a/data/hello800.asm b/data/hello800.asm
new file mode 100644
index 0000000..8545ed7
--- /dev/null
+++ b/data/hello800.asm
@@ -0,0 +1,28 @@
+;;
+;; .bac loader test program
+;;
+
+ defc CONWRITE=000Bh
+ defc IPSAV=65338
+
+_start:
+ ld hl,hello
+ ld c,hello_len
+ ld b,0
+ call CONWRITE
+ ld hl,world
+ ld c,world_len
+ ld b,0
+ call CONWRITE
+ ret
+
+hello:
+ defm "Hello, "
+hello_end:
+ defc hello_len=hello_end-hello
+ defm "BAD"
+world:
+ defm "World!\r\n"
+world_end:
+ defc world_len=world_end-world
+ defm "BAD"