aboutsummaryrefslogtreecommitdiffstats
path: root/data/bacldrr.asm
blob: 0944c0e335d5e88b28c964411d16e7efc197d1a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
	org 0			; This code must be position-independent

	defc END=00C9h		; END routine in BASIC ROM
	defc BOFA=65052
	defc DATALEN=0DDDDh	; Placeholder: length of data, sans relocations
	defc DENTRY=0BBBBh	; Placeholder: entrypoint vs final addr ptr
	

	ld bc,END		; END entry point in BASIC (B = 0!)
	push bc			; Save as return address
	ld hl,(BOFA)		; BOFA = start of data
	push hl			; Save for reloc routine
	ld e,l
	ld d,h
	ld c,(hl)		; First BASIC line = BASIC prefix
	add hl,bc		; Skip prefix

	;; Copy the data into place
copy_loop:
	ld a,(hl)		; BASIC line length
	sub 8			; 6 byte header, 2 byte trailer
	jr c,reloc		; END is shorter than any data line

	ld c,6			; BC <- 6 (header length)
	add hl,bc		; Skip header

	; Copy payload data
	ld c,a			; BC <- len since B = 0
	ldir

	; Skip trailer (2 bytes)
	inc hl
	inc hl

	jr copy_loop

	;;  Process relocation
	;;  HL -> data
	;;  DE -> relocations

reloc:
	ld hl,DATALEN		; Length of data sans relocations
	pop de			; BOFA
	add hl,de
	ex de,hl
reloc_loop:
	ld a,(de)
	inc de
	cp 7fh			; JR doesn't support testing the sign bit
	jr c,reloc_large
	ld c,a
	ld b,0

	; Apply relocation: HL += BC, (HL) += HL, HL += 2
reloc_apply:
	add hl,bc
	ld a,l
	add (hl)
	ld (hl),a
	ld a,h
	inc hl
	adc (hl)
	ld (hl),a
	inc hl
	jr reloc_loop

	; Large jump (> 127 bytes) or end
	; 80h = END, 81-FFh are large jump biased by 8100h in *bigendian* order
reloc_large:
	sub 81h
	jr c,reloc_done
	ld b,a
	ld a,(de)
	inc de
	ld c,a
	jr reloc_apply

	; All done, jump to entry point
	; Note: top of stack is 00C9h -> END, so a RET from the
	; target routine if the same as END.
reloc_done:
	ld bc,DENTRY		; Offset from final address ptr to entry point
	add hl,bc
	jp (hl)