aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2018-09-10 08:09:03 -0700
committerH. Peter Anvin <hpa@zytor.com>2018-09-10 08:09:03 -0700
commit5f7fee08686acdb4d726018afd914ec2b6797375 (patch)
tree91828c8a02bdd8c384d73502c7939e9ec0422001
parent8e5bfce70b8af0b2481de4c9c342556c8fb7c110 (diff)
downloadabc80-5f7fee08686acdb4d726018afd914ec2b6797375.tar.gz
abc80-5f7fee08686acdb4d726018afd914ec2b6797375.tar.xz
abc80-5f7fee08686acdb4d726018afd914ec2b6797375.zip
bin2bac: use GOSUB as a much cleaner way to hijack BASICHEADde1
Instead of doing self-modifying BASIC code, use a GOSUB statement to push the BASIC instruction pointer onto the stack, where it can be modified if the user so wishes. See updated bye800.asm for how to use it. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--data/bac800.asm20
-rwxr-xr-xdata/bin2bac.pl12
-rw-r--r--data/bye800.asm14
3 files changed, 20 insertions, 26 deletions
diff --git a/data/bac800.asm b/data/bac800.asm
index 42c0f1f..7b0190f 100644
--- a/data/bac800.asm
+++ b/data/bac800.asm
@@ -30,8 +30,14 @@ COMSZ: defw 0 ; COMMON area size (memory reserved @ BOTM)
defw 0 ; Address for the first DEF statement
defw 0 ; Address for the first DATA statement
- ;; BASIC bytecode to invoke _start
+ ;; BASIC bytecode to invoke _start The GOSUB allows the
+ ;; assembly program to hijack the BASIC flow of control if it
+ ;; would want to; the BASIC return instruction pointer is
+ ;; found at offset +4 of the value in SPSAV = FF45h
_basic:
+ defb 130 ; GOSUB
+ defw 1+1 ; Skip 1 byte
+ defb 146 ; END
defb 221 + 11 ; PUSH int 11
defb 209 ; Function call, 1 parameter
defb 25 ; SYS() SYS(11) = BOFA
@@ -40,10 +46,7 @@ _basic:
defb 209 ; Function call, 1 parameter
defb 23 ; CALL()
defb 184 ; POP int (end expression)
- defb 128 ; GOTO
-gotooffs:
- defw 1 ; Skip nothing
- defb 146 ; END
+ defb 160 ; RETURN
;; Relocator code. In order to support saving and re-loading
;; programs, this must handle being restarted at either the
@@ -55,7 +58,6 @@ _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
@@ -113,11 +115,7 @@ reloc_large:
; All done, jump to entry point. A RET will return to BASIC
; which will execute an END statement.
done:
- pop hl ; -> _start
- ld de,gotooffs - _start
- add hl,de ; -> GOTO offset (to override END)
-jpentry:
- defc REL2=jpentry+1 ; Relocation here
+ defc REL2=done+1 ; Relocation here
jp ENTRY ; Entry relative to start of program
; Relocation data follows immediately afterwards
diff --git a/data/bin2bac.pl b/data/bin2bac.pl
index 76904b8..ac02303 100755
--- a/data/bin2bac.pl
+++ b/data/bin2bac.pl
@@ -191,16 +191,16 @@ sub makebac800($$$$) {
my $bhdr;
# See bac800.asm
$bhdr = "\x8f\x00\x01\x00";
- $bhdr .= pack("v", 0x63 + length($relocs) + length($data));
+ $bhdr .= pack("v", 0x5e + length($relocs) + length($data));
$bhdr .= pack("v*", 0, 0, 0, $reserve, 0, 0, 0);
- $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 .= "\x82\x02\x00\x92\xe8\xd1\x19\xfe\x9c\xd1\x17\xb8\xa0";
+ $bhdr .= "\x01" . pack("v", 0xffca - length($relocs));
+ $bhdr .= "\x7d\x91\x4f\x7c\x98\x47\xb1\x28\x25\xe5\x11\x34\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\x06";
- $bhdr .= "\x23\x82\x57\x7e\x18\xe6\xe1\x11\xfd\xff\x19";
+ $bhdr .= "\x23\x82\x57\x7e\x18\xe6";
$bhdr .= "\xc3" . pack("v", $entry);
- $bhdr .= "\x01\x35";
+ $bhdr .= "\x01\x2f";
$data = $bhdr . $relocs . $data;
diff --git a/data/bye800.asm b/data/bye800.asm
index 4b7325b..5add19e 100644
--- a/data/bye800.asm
+++ b/data/bye800.asm
@@ -3,18 +3,14 @@
;;
defc CONWRITE=000Bh
- defc IPSAV=65338
+ defc SPSAV=0FF45h
_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 ix,(SPSAV)
+ ld de,chain_nul
+ ld (ix+4),e
+ ld (ix+5),d
ld hl,hello
ld c,hello_len