1; Prints values in various ways to output, including numbers and strings.
2
3newline = 10
4
5; Prints indicated register to console as two hex chars and space
6; Preserved: A, X, Y, P
7print_a:
8	php
9	pha
10print_reg_:
11	jsr print_hex
12	lda #' '
13	jsr print_char_
14	pla
15	plp
16	rts
17
18print_x:
19	php
20	pha
21	txa
22	jmp print_reg_
23
24print_y:
25	php
26	pha
27	tya
28	jmp print_reg_
29
30print_p:
31	php
32	pha
33	php
34	pla
35	jmp print_reg_
36
37print_s:
38	php
39	pha
40	txa
41	tsx
42	pha
43	inx
44	inx
45	inx
46	inx
47	jsr print_x
48	pla
49	tax
50	pla
51	plp
52	rts
53
54
55; Prints A as two hex characters, NO space after
56; Preserved: X, Y
57print_hex:
58	; Update checksum
59	pha
60	jsr update_crc
61	pla
62
63	; Print high nibble
64	pha
65	lsr a
66	lsr a
67	lsr a
68	lsr a
69	jsr @nibble
70	jsr print_char_
71	pla
72
73	; Print low nibble
74	and #$0F
75	jsr @nibble
76	jmp print_char_
77
78@nibble:
79	cmp #10
80	blt @digit
81	adc #6;+1 since carry is set
82@digit:	adc #$30
83	rts
84
85
86; Prints character and updates checksum UNLESS it's a newline.
87; Preserved: X, Y
88print_char:
89	cmp #newline
90	beq :+
91	pha
92	jsr update_crc
93	pla
94:	jmp print_char_
95
96
97; Prints space. Doesn't affect checksum.
98; Preserved: A, X, Y
99print_space:
100	pha
101	lda #' '
102	bne print_char_pla_rts	; always branches
103
104
105; Advances to next line. Doesn't affect checksum.
106; Preserved: A, X, Y
107print_newline:
108	pha
109	lda #newline
110print_char_pla_rts:
111	jsr print_char_
112	pla
113	rts
114
115
116; Prints zero-terminated string after JSR that called this routine.
117; Preserved: A, X, X
118print_str:
119	sta temp
120
121	; Get addr of string
122	pla
123	sta addr
124	pla
125	sta addr+1
126	jsr inc_addr
127
128	lda temp
129
130	jsr print_str_addr
131	jmp (addr)
132
133
134; Prints string
135; Preserved: A, X, Y
136.macro print_str str
137	jsr print_str
138	.byte str,0
139.endmacro
140
141
142; Prints string at addr and leaves addr pointing to
143; byte AFTER zero terminator.
144; Preserved: A, X, Y
145print_str_addr:
146	pha
147	tya
148	pha
149
150	ldy #0
151	beq :+ ; always taken
152@loop:	jsr print_char
153	jsr inc_addr
154:	lda (addr),y
155	bne @loop
156
157	pla
158	tay
159	pla
160	; FALL THROUGH
161
162; Increments 16-bit value in addr.
163; Preserved: A, X, Y
164inc_addr:
165	inc addr
166	beq :+
167	rts
168:	inc addr+1
169	rts
170
171
172; Prints A as 1-3 digit decimal value, NO space after.
173; Preserved: Y
174print_dec:
175	cmp #100
176	blt @tens
177	ldx #'0'
178:	sbc #100
179	inx
180	cmp #100
181	bge :-
182	jsr @digit
183@tens:	cmp #10
184	blt @ones
185	ldx #'0'
186:	sbc #10
187	inx
188	cmp #10
189	bge :-
190	jsr @digit
191@ones:	clc
192	adc #'0'
193	jmp print_char
194
195@digit:	pha
196	txa
197	jsr print_char
198	pla
199	rts
200
201
202; Reports value of A via low/high beeps.
203; Preserved: X, Y
204beep_bits:
205	; Make reference low beep
206	clc
207	jsr @beep
208
209	; End marker
210	sec
211
212	; Remove high zero bits
213:	rol a
214	beq @zero
215	bcc :-
216
217	; Play remaining bits
218@loop:	php
219	jsr @beep
220	plp
221	asl a
222	bne @loop
223@zero:	rts
224
225@beep:	pha
226
227	; Set LSB of pitch based on carry
228	lda #0
229	adc #$FF
230	sta $4002
231
232	; Set up square
233	lda #1
234	sta SNDCHN
235	sta $4003
236	sta $4001
237
238	; Fade volume
239	lda #15
240:	pha
241	eor #$30
242	sta $4000
243	delay_msec 8
244	pla
245	clc
246	adc #-1
247	bne :-
248
249	; Silence
250	sta SNDCHN
251	delay_msec 120
252
253	pla
254	rts
255
256
257; Reports internal error and exits program
258internal_error:
259	print_str "Internal error"
260	lda #1
261	jmp exit
262