-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
init.asm
160 lines (142 loc) · 4.11 KB
/
init.asm
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
;
; Title: BBC Basic ADL for AGON - Initialisation Code
; Initialisation Code
; Author: Dean Belfield
; Created: 12/05/2023
; Last Updated: 26/11/2023
;
; Modinfo:
; 11/07/2023: Fixed *BYE for ADL mode
; 26/11/2023: Moved the ram clear routine into here
SEGMENT CODE
XDEF _end
XREF _main ; In main.asm
XREF RAM_START ; In ram.asm
XREF RAM_END
.ASSUME ADL = 1
INCLUDE "equs.inc"
argv_ptrs_max: EQU 16 ; Maximum number of arguments allowed in argv
;
; Start in ADL mode
;
JP _start ; Jump to start
;
; The header stuff is from byte 64 onwards
;
_exec_name: DB "BBCBASIC.BIN", 0 ; The executable name, only used in argv
ALIGN 64
DB "MOS" ; Flag for MOS - to confirm this is a valid MOS command
DB 00h ; MOS header version 0
DB 01h ; Flag for run mode (0: Z80, 1: ADL)
;
; And the code follows on immediately after the header
;
_start: PUSH AF ; Preserve the rest of the registers
PUSH BC
PUSH DE
PUSH IX
PUSH IY
LD (_sps), SP ; Preserve the 24-bit stack pointer (SPS)
LD IX, _argv_ptrs ; The argv array pointer address
PUSH IX
CALL _parse_params ; Parse the parameters
POP IX ; IX: argv
LD B, 0 ; C: argc
CALL _clear_ram
JP _main ; Start user code
;
; This bit of code is called from STAR_BYE and returns us safely to MOS
;
_end: LD SP, (_sps) ; Restore the stack pointer
POP IY ; Restore the registers
POP IX
POP DE
POP BC
POP AF
RET ; Return to MOS
;Clear the application memory
;
_clear_ram: PUSH BC
LD HL, RAM_START
LD DE, RAM_START + 1
LD BC, RAM_END - RAM_START - 1
XOR A
LD (HL), A
LDIR
POP BC
RET
; Parse the parameter string into a C array
; Parameters
; - HL: Address of parameter string
; - IX: Address for array pointer storage
; Returns:
; - C: Number of parameters parsed
;
_parse_params: LD BC, _exec_name
LD (IX+0), BC ; ARGV[0] = the executable name
INC IX
INC IX
INC IX
CALL _skip_spaces ; Skip HL past any leading spaces
;
LD BC, 1 ; C: ARGC = 1 - also clears out top 16 bits of BCU
LD B, argv_ptrs_max - 1 ; B: Maximum number of argv_ptrs
;
_parse_params_1:
PUSH BC ; Stack ARGC
PUSH HL ; Stack start address of token
CALL _get_token ; Get the next token
LD A, C ; A: Length of the token in characters
POP DE ; Start address of token (was in HL)
POP BC ; ARGC
OR A ; Check for A=0 (no token found) OR at end of string
RET Z
;
LD (IX+0), DE ; Store the pointer to the token
PUSH HL ; DE=HL
POP DE
CALL _skip_spaces ; And skip HL past any spaces onto the next character
XOR A
LD (DE), A ; Zero-terminate the token
INC IX
INC IX
INC IX ; Advance to next pointer position
INC C ; Increment ARGC
LD A, C ; Check for C >= A
CP B
JR C, _parse_params_1 ; And loop
RET
; Get the next token
; Parameters:
; - HL: Address of parameter string
; Returns:
; - HL: Address of first character after token
; - C: Length of token (in characters)
;
_get_token: LD C, 0 ; Initialise length
$$: LD A, (HL) ; Get the character from the parameter string
OR A ; Exit if 0 (end of parameter string in MOS)
RET Z
CP 13 ; Exit if CR (end of parameter string in BBC BASIC)
RET Z
CP ' ' ; Exit if space (end of token)
RET Z
INC HL ; Advance to next character
INC C ; Increment length
JR $B
; Skip spaces in the parameter string
; Parameters:
; - HL: Address of parameter string
; Returns:
; - HL: Address of next none-space character
; F: Z if at end of string, otherwise NZ if there are more tokens to be parsed
;
_skip_spaces: LD A, (HL) ; Get the character from the parameter string
CP ' ' ; Exit if not space
RET NZ
INC HL ; Advance to next character
JR _skip_spaces ; Increment length
; Storage
;
_sps: DS 3 ; Storage for the stack pointer
_argv_ptrs: BLKP argv_ptrs_max, 0 ; Storage for the argv array pointers