aboutsummaryrefslogtreecommitdiffstats
path: root/asmsrc/bac80r.asm
blob: 5d52dc4dcda3a47fb94e21cf77cce5d9ccf44ec9 (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
85
86
87
88
;;
;; Relocating ABC80 .bac loader loading at BOFA
;;
;; To load a device driver, move BOFA to the desired address
;; after initialization, move EOFA to the same address as BOFA
;; and put a 01h byte at the new EOFA (this does a NEW).
;;

	include "setup80.inc"

_start:
	pop hl			; Return address
	pop hl			; P-code position
	inc hl			; Skip end of integer statement
	inc hl			; Skip string constant opcode
	inc hl			; Skip string constant quotation mark
	ld c,(hl)		; String length
	inc hl
	;; HL = string
	;; C = string length
	inc c	; Copy the statement trailer too for simplicity
	inc c
	;; Make space on the stack
	ex de,hl
	xor a
	ld b,a
	ld l,a
	ld h,a
	sbc hl,bc
	add hl,sp
	ld sp,hl		; Make space for chain string on stack
	ex de,hl
	push bc			; String length
	push de			; String address
	push bc			; Bytes occupied on the stack
	ld a,(hl)		; First character in chain string
	ldir
	ld hl,END
	cp a,':'		; Bogus name -> END, not CHAIN ""
	jr z,gotretn
	ld hl,(CHAINPTR)	; Pointer to the CHAIN routine
	inc hl			; Skip RST 56h -> eval expression
gotretn:
	push hl			; Return address

	ld de,(BOFA)		; BOFA = start of data
	push de			; Save for done
	push de			; Save for relocation

	include "copy80.inc"

set_reloc_len:
	defc NEG_RELOC_LEN=set_reloc_len+1
	ld hl,0			; Negative (length of relocation data + 1)
	add hl,de

	;;
	;; Move EOFA to the end of our data
	;; This is probably unnecessary but easy to do
	;; The C code will already have inserted a 01h byte to this address
	;;
	ld (EOFA),hl
	inc hl			; HL -> relocations
	pop de			; DE -> data (= BOFA)

	;; Set a delta if needed.  This loader only supports an
	;; 8-bit delta
	ld a,e
setdelta:
	defc DELTA=setdelta+1
	add a,0
	ld c,a
	ld a,d
	adc a,0
	ld b,a

	include "relocate.inc"

	;; All done, jump to entry point
	;; The stack is all set up for return to CHAIN or END
done:
	defc ENTRY=done+1
	ld bc,0
	pop hl			; HL -> load address (= BOFA)
	add hl,bc
	jp (hl)

	include "end80.inc"