diff options
author | H. Peter Anvin <hpa@zytor.com> | 2018-09-10 08:09:03 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2018-09-10 08:09:03 -0700 |
commit | 5f7fee08686acdb4d726018afd914ec2b6797375 (patch) | |
tree | 91828c8a02bdd8c384d73502c7939e9ec0422001 | |
parent | 8e5bfce70b8af0b2481de4c9c342556c8fb7c110 (diff) | |
download | abc80-de1.tar.gz abc80-de1.tar.xz abc80-de1.zip |
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.asm | 20 | ||||
-rwxr-xr-x | data/bin2bac.pl | 12 | ||||
-rw-r--r-- | data/bye800.asm | 14 |
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 |