aboutsummaryrefslogtreecommitdiffstats
path: root/data/bacldr2.asm
diff options
context:
space:
mode:
Diffstat (limited to 'data/bacldr2.asm')
-rw-r--r--data/bacldr2.asm65
1 files changed, 65 insertions, 0 deletions
diff --git a/data/bacldr2.asm b/data/bacldr2.asm
new file mode 100644
index 0000000..ae9c381
--- /dev/null
+++ b/data/bacldr2.asm
@@ -0,0 +1,65 @@
+ ;; Load an assembly program at BOFA and handle relocations
+ ;; Relocations are a list of 16-bit addresses at the end of
+ ;; the image, processed in reverse order, terminated with
+ ;; an FFFFh sentinel.
+
+ org 0 ; This code must be position-independent
+
+BOFA: equ 65052
+offset: equ 0xeeee ; Length of the BASIC prefix
+ENTRY: equ 0xbbbb
+
+ ld hl,(BOFA)
+ push hl
+ ld e,l
+ ld d,h
+ ld bc,offset ; Offset < 256 so B = 0
+ add hl,bc
+
+ ; Get data block length
+loop:
+ ld a,-8
+ add (hl)
+ jr nc,reloc ; END is a shorter line than any data line
+
+ ; Skip length byte + line number (2 bytes) + string opcode (3 bytes)
+ ld c,6
+ add hl,bc
+
+ ; Copy remaining data
+ ld c,a
+ ldir
+
+ ; Skip return + CR
+ inc hl
+ inc hl
+ jr loop
+
+ ;; Process relocations. At this point DE points beyond
+ ;; the end of the contiguous image.
+reloc:
+ pop bc ; BC <- BOFA
+reloc_loop:
+ ex de,hl
+ dec hl
+ ld d,(hl)
+ dec hl
+ ld e,(hl)
+ ld a,e
+ and d
+ inc a ; A = FFh only if BC = FFFFh
+ jr z,reloc_done
+ ex de,hl
+ add hl,bc
+ ld a,(hl)
+ add c
+ ld (hl),a
+ inc hl
+ ld a,(hl)
+ adc a,b
+ ld (hl),a
+ jr reloc_loop
+reloc_done:
+ ld hl,ENTRY
+ add hl,bc
+ jp (hl)