aboutsummaryrefslogtreecommitdiffstats
path: root/data/bacldr2.asm
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2014-06-17 08:50:17 -0700
committerH. Peter Anvin <hpa@zytor.com>2014-06-17 08:50:17 -0700
commitc2b2d4556275fad0360a98128bb62436134e2065 (patch)
treeeb50c22ab3044b72e74ccf326d522535dfd61cf3 /data/bacldr2.asm
parenta6a1600daa977d4f97f7e02a7499e1236afe54e9 (diff)
downloadabc80-c2b2d4556275fad0360a98128bb62436134e2065.tar.gz
abc80-c2b2d4556275fad0360a98128bb62436134e2065.tar.xz
abc80-c2b2d4556275fad0360a98128bb62436134e2065.zip
bacldr: Add loader variant that supports relocatable code
Add a version of the loader which supports relocatable code to be loaded at BOFA. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
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)