summaryrefslogtreecommitdiff
path: root/programs/sub-suite/subasm.s
blob: 56d13c2357a099f631314759282b681f466d412f (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
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
; SuBAsm
; The Sux Bootstrapped Assembler.
;
; by mr b0nk 500 <b0nk@b0nk.xyz>

;subasm:
;	ldb #0		; Set the first pointer
;	lda.q cmd_buf	; to the command buffer.
;	jsr set_ptr	;
;	tba		; Reset A.
;	tax		; Reset X.
;	jsr chk_shcmd	; Did we get a shortend command?
;	bne @cmd	; Yes, so skip everything else.
;	jsr chk_cmd	; No, but did we get a full command?
;	bne @cmd	; Yes, so skip everything else.
;	jsr lex		; No, so start lexing this line.
;	bra @end	; We are done.
;@cmd:
;	lda regf	; Get the command ID.
;	cmp #8		; Is the command ID greater than the command count?
;	bcs @end	; Yes, so we're done.
;	lsl #1		; No, so multiply the command ID by two.
;	phx.q		; Preserve X.
;	tax             ; Set the index to the offset that we just calculated.
;	lea.w (cmd_srt, x); Get the pointer, from the command subroutine table.
;	plx.q		; Restore X.
;	and #0		; Reset A.
;	tab		; Reset B.
;	jsr (e)		; Run the command's subroutine.
;@end:
;	and #0		; Reset A.
;	jsr update_ptr	; Get the screen buffer index.
;	tay		; Save it in Y.
;	and #0		; Reset A.
;	rts		; End of subasm.
;
;chk_shcmd:
;	and #0		; Reset A.
;	tab		; Reset B.
;;	inb		; Set the second pointer
;;	lda.w #sh_cmds	; to the shortend command table.
;;	jsr set_ptr	;
;;	deb		; Reset B.
;;	tba		; Reset A.
;	lea sh_cmds	; Get the address of the short command table.
;	phy.w		; Preserve the screen buffer position.
;	txy		; Set our index to zero.
;	lda (ptr), y	; Is there nothing in the command buffer?
;	beq @false	; Yes, so return that we failed.
;	cmp #' '	; No, but is this character, a space?
;	beq @false	; Yes, so return that we failed.
;	jsr tolower	; No, so convert it to lowercase.
;@loop:
;;	ldb (ptr2), y	; Are we at the end of the table?
;	ldb (e)		; Are we at the end of the table?
;	beq @false	; Yes, so return that we failed.
;	cmp b		; No, so did the character match?
;	beq @found	; Yes, so check if there are any arguments.
;	ine		; No, so check the next command.
;	iny		;
;	bra @loop	; Keep looping.
;@found:
;	sty regf	; Save the command ID.
;	lea (ptr)	; Get the address of the next character.
;	ine		;
;;	ldy #1		; Check the next character in the command buffer.
;;	lda (ptr), y	; Is this the end of the buffer?
;	lda (e)		; Is this the end of the buffer?
;	beq @true	; Yes, so return true.
;	cmp #' '	; No, but is this a space?
;	beq @true	; Yes, so return true.
;@false:
;	ldb #0		; Reset B.
;	tba		; Return false.
;	tax		; Reset X.
;	bra @end	; We are done.
;@true:
;	lda #1		; Return true.
;@end:
;	ply.w		; Get back the screen buffer position.
;	rts		; End of chk_shcmd.
;
;
;chk_cmd:
;	and #0		; Reset A.
;	tab		; Reset B.
;	tax		; Reset X.
;	sta.q idx0	; Reset the first index.
;	sta.q idx1	; Reset the second index.
;	mov.q ptr, d	; Set the first pointer to the command buffer.
;@loop:
;	lda.w #cmds	; Get pointer to the start of the command table.
;	add.w idx0	; Offset the pointer, by the length of the previous string.
;	pha.q		; Preserve the command string pointer.
;	jsr strcaseg	; Is the command buffer, the same as the command string?
;	pla.q		; Get the command string pointer back.
;	beq @true	; Yes, so return true.
;	ldb idx1	; No, so Get the command ID.
;	cpb #7		; Have we reached the end of the command table?
;	beq @false	; Yes, so return false.
;	inc idx1	; No, so increment the command ID.
;@getlen:
;	mov d, a	; Get the string.
;	jsr strlen	; Get the string's length.
;	inc		; Add one to the length.
;	add.w idx0, a	; Add the string offset to the current length
;	bra @loop	; Keep looping.
;@true:
;	ldb idx1	; Get the command ID.
;	stb regf	; Return the command ID.
;	ldb #1		; Return true.
;	bra @end	; We are done.
;@false:
;	ldb #0		; Return false.
;@end:
;	rts		; End of chk_cmd.


subasm:
	pha.q			; Preserve A.
	des			; Make room for the command id.
	and #0			; Reset A.
	lea d, (cmd_buf)	; Get the command buffer.
	lea s, (sp+1)		; Get the pointer to the command id.
	jsr chk_shcmd		; Did we get a shortend command?
	bne @cmd		; Yes, so skip everything else.
	jsr chk_cmd		; No, but did we get a full command?
	bne @cmd		; Yes, so skip everything else.
	mov.q ptr, d		;
	psh d			; Preserve D.
	psh s			; Preserve S.
	psh f			; Preserve F.
	jsr lex			; No, so start lexing this line.
	pul d			; Restore D.
	pul s			; Restore S.
	pul f			; Restore F.
	bra @end		; We are done.
@cmd:
	mov s, (s)		; Get the command ID.
	cmp s, #7		; Is the command ID greater than the command count?
	bcs @end		; Yes, so we're done.
	lsl s, #1		; No, so multiply the command ID by two.
	lea.w s, (cmd_srt+s)	; Get the pointer, from the command subroutine table.
	and #0			; Reset A.
	tab			; Reset B.
	jsr s			; Run the command's subroutine.
@end:
	and #0			; Reset A.
	jsr update_ptr		; Get the screen buffer index.
	tay			; Save it in Y.
	ins			; Cleanup the stack frame.
	pla.q			; Restore A.
	rts			; End of subasm.


chk_shcmd:
	phb.q			; Preserve B.
	lea b, sh_cmds		; Get the address of the short command table.
	mov a, (d)		; Is the string empty?
	beq @false		; Yes, so return that we failed.
	cmp #' '		; No, but is this character, a space?
	beq @false		; Yes, so return that we failed.
	jsr tolower		; No, so convert it to lowercase.
@loop:
	cmp (b), #0		; Are we at the end of the table?
	beq @false		; Yes, so return that we failed.
	cmp a, (b)		; No, so did the character match?
	beq @found		; Yes, so check if there are any arguments.
	inb			; No, so check the next command.
	bra @loop		; Keep looping.
@found:
	sub.w b, #sh_cmds	; Get the command ID.
	mov (s), b		; Save the command ID.
	mov a, (d+1)		; Is this the end of the string?
	beq @true		; Yes, so return true.
	cmp #' '		; No, but is this a space?
	beq @true		; Yes, so return true.
@false:
	and #0			; Return false.
	bra @end		; We are done.
@true:
	lda #1			; Return true.
@end:
	plb.q			; Restore B.
	rts			; End of chk_shcmd.


chk_cmd:
	phb.q			; Preserve B.
	phx.q			; Preserve X.
	phy.q			; Preserve Y.
	and #0			; Reset A.
	tab			; Reset B.
	mov x, s		; Preserve the command ID pointer.
	mov y, d		; Preserve the string pointer.
	lea s, cmds		; Get pointer to the start of the command table.
@loop:
	jsr strcasecmp		; Is the command buffer, the same as the command string?
	beq @true		; Yes, so return true.
	inb			; No, so increment the command ID.
	cpb #7			; Have we reached the end of the command table?
	bcs @false		; Yes, so return false.
@getlen:
	mov d, s		; Get the command table string.
	jsr strlen		; Get the string's length.
	mov d, y		; Restore the string pointer.
	inc			; Add one to the length.
	add s, a		; Add the string offset to the current length
	bra @loop		; Keep looping.
@true:
	lda #1			; Return true.
	bra @end		; We are done.
@false:
	lda #0			; Return false.
@end:
	mov s, x		; Restore the command ID pointer.
	mov (s), b		; Save the command ID.
	and a, a		; Set the flags accordingly.
	ply.q			; Restore Y.
	plx.q			; Restore X.
	plb.q			; Restore B.
	rts			; End of chk_cmd.


viewmem:
	pha.q			; Preserve A.
	phb.q			; Preserve B.
	phx.q			; Preserve X.
	sbs #$50		; Make room for the string buffer.
	and #0			; Reset A.
	tab			; Reset B.
	ldx.q prg_cnt		; Get the program counter.
	lda #19			; Move the cursor to the right, by 19 columns.
	sta scr_col		;
	jsr update_pos		;
	jsr print_lo		; Print the low nibble offsets.
@loop:
	lda #'\n'		; Print a newline.
	jsr print_char		;
	lea d, (sp+1)		; Get the address of the string buffer.
	mov s, x		; Get the program counter.
	jsr print_hi		; Print the address to the string buffer.
	mov d, a		; Get the string buffer pointer after the printed address.
	mov s, x		; Get the program counter.
	jsr print_chunk		; Print the next 16 bytes to the string buffer.
	lea d, (sp+1)		; Get the address of the string buffer.
	lea s, (buffer)+y	; Get the address of the screen buffer, at the current cursor position.
;	jsr print_str		; Print the string buffer.
	jsr print_sfast		;
	inb			; Increment the chunk count.
	cpb #$10		; Did we print 16 chunks?
	beq @end		; Yes, so we're done.
	add x, #$10		; No, so add 16 to the address.
	and #0			; Reset A.
	bra @loop		; Keep looping.
@end:
	lda #'\n'		; Print a newline.
	jsr print_char		;
	ads #$50		; Cleanup the stack frame.
	plx.q			; Restore X.
	plb.q			; Restore B.
	pla.q			; Restore A.
	rts			; End of viewmem.


list:
	nop		;
@end:
	rts		; End of list.
asm:
	nop		;
@end:
	rts		; End of asm.
help:
	nop		;
@end:
	rts		; End of help.
instruction:
	nop		;
@end:
	rts		; End of instruction.
run:
	nop		;
@end:
	rts		; End of run.
set_val:
	nop		;
@end:
	rts		; End of set_val.