1; Prints values in various ways to output,
2; including numbers and strings.
3
4newline = 10
5
6zp_byte print_temp_
7
8; Prints indicated register to console as two hex
9; chars and space
10; Preserved: A, X, Y, flags
11print_a:
12	php
13	pha
14print_reg_:
15	jsr print_hex
16	lda #' '
17	jsr print_char_
18	pla
19	plp
20	rts
21
22print_x:
23	php
24	pha
25	txa
26	jmp print_reg_
27
28print_y:
29	php
30	pha
31	tya
32	jmp print_reg_
33
34print_p:
35	php
36	pha
37	php
38	pla
39	jmp print_reg_
40
41print_s:
42	php
43	pha
44	txa
45	tsx
46	inx
47	inx
48	inx
49	inx
50	jsr print_x
51	tax
52	pla
53	plp
54	rts
55
56
57; Prints A as two hex characters, NO space after
58; Preserved: A, X, Y
59print_hex:
60	jsr update_crc
61
62	pha
63	lsr a
64	lsr a
65	lsr a
66	lsr a
67	jsr print_nibble_
68	pla
69
70	pha
71	and #$0F
72	jsr print_nibble_
73	pla
74	rts
75
76print_nibble_:
77	cmp #10
78	blt @digit
79	adc #6;+1 since carry is set
80@digit: adc #'0'
81	jmp print_char_
82
83
84; Prints low 4 bits of A as single hex character
85; Preserved: A, X, Y
86print_nibble:
87	pha
88	and #$0F
89	jsr update_crc
90	jsr print_nibble_
91	pla
92	rts
93
94
95; Prints character and updates checksum UNLESS
96; it's a newline.
97; Preserved: A, X, Y
98print_char:
99	cmp #newline
100	beq :+
101	jsr update_crc
102:       pha
103	jsr print_char_
104	pla
105	rts
106
107
108; Prints space. Does NOT update checksum.
109; Preserved: A, X, Y
110print_space:
111	pha
112	lda #' '
113	jsr print_char_
114	pla
115	rts
116
117
118; Advances to next line. Does NOT update checksum.
119; Preserved: A, X, Y
120print_newline:
121	pha
122	lda #newline
123	jsr print_char_
124	pla
125	rts
126
127
128; Prints string
129; Preserved: A, X, Y
130.macro print_str str,str2
131	jsr print_str_
132	.byte str
133	.ifnblank str2
134		.byte str2
135	.endif
136	.byte 0
137.endmacro
138
139
140print_str_:
141	sta print_temp_
142
143	pla
144	sta addr
145	pla
146	sta addr+1
147
148	jsr inc_addr
149	jsr print_str_addr
150
151	lda print_temp_
152	jmp (addr)
153
154
155; Prints string at addr and leaves addr pointing to
156; byte AFTER zero terminator.
157; Preserved: A, X, Y
158print_str_addr:
159	pha
160	tya
161	pha
162
163	ldy #0
164	beq :+ ; always taken
165@loop:  jsr print_char
166	jsr inc_addr
167:       lda (addr),y
168	bne @loop
169
170	pla
171	tay
172	pla
173	; FALL THROUGH
174
175; Increments 16-bit value in addr.
176; Preserved: A, X, Y
177inc_addr:
178	inc addr
179	bne :+
180	inc addr+1
181:       rts
182
183
184; Prints A as 1-3 digit decimal.
185; In: A = MSB
186; Preserved: A, X, Y
187print_dec:
188	sta print_temp_
189	pha
190	txa
191	pha
192	tya
193	pha
194	ldy print_temp_
195	lda #0
196	sta print_temp_
197	tya
198	jmp :+
199
200
201; Prints 16-bit AY as 1-5 digit decimal.
202; Preserved: A, X, Y
203print_ay_dec:
204	jsr update_crc
205	sta print_temp_
206	pha
207	txa
208	pha
209	tya
210	pha
211:       jsr update_crc
212
213	; Strip leading zeroes
214	ldx #6
215:       dex
216	cmp @lsb-1,x
217	lda print_temp_
218	sbc @msb-1,x
219	tya
220	bcc :-
221	bcs @non_zero
222
223	; Print remaining digits
224
225@more:  ; Commit subtraction
226	iny
227	sta print_temp_
228	pla
229
230	; Subtract
231@digit: sbc @lsb,x
232	pha
233	lda print_temp_
234	sbc @msb,x
235	bcs @more
236
237	; Print digit and undo subtraction
238	tya
239	jsr print_char_
240	pla
241	clc
242	adc @lsb,x
243@non_zero:
244	sec
245	ldy #'0'
246	dex
247	bne @digit
248
249	ora #'0'
250	jsr print_char_
251
252	pla
253	tay
254	pla
255	tax
256	pla
257	rts
258
259@lsb:   .byte 0,<10,<100,<1000,<10000
260@msb:   .byte 0,>10,>100,>1000,>10000
261
262
263; Prints one of two characters based on condition.
264; SEC; print_cc bcs,'C','-' prints 'C'.
265; Preserved: A, X, Y, flags
266.macro print_cc cond,yes,no
267	; Avoids labels since they're not local
268	; to macros in ca65.
269	php
270	pha
271	cond *+6
272	lda #no
273	bne *+4
274	lda #yes
275	jsr print_char
276	pla
277	plp
278.endmacro
279