-
Notifications
You must be signed in to change notification settings - Fork 0
/
print.asm
260 lines (251 loc) · 4 KB
/
print.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
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
print_word_dec: ; A = ZP address of word
; X,Y = coordinates to print
jsr print_load_addrs
lda (IND_VEC)
sta SB1
lda (IND_VEC),y
sta SB2
stz print_bcd
stz print_bcd+1
stz print_bcd+2
sed
ldx #16
@main_loop:
; shift highest bit to C
asl SB1
rol SB2
ldy #0
; BCD = BCD*2 + C
php
@add_loop:
plp
lda print_bcd,y
adc print_bcd,y
sta print_bcd,y
php
iny
cpy #3
bne @add_loop
plp
dex
bne @main_loop
cld
lda #1
sta print_space
lda print_bcd+2
beq @print_space1
ora #$30
stz print_space
bra @print1
@print_space1:
lda #$20
@print1:
sta VERA_data0
lda print_bcd+1
lsr
lsr
lsr
lsr
beq @print_space2
stz print_space
@num2:
ora #$30
bra @print2
@print_space2:
lda print_space
beq @num2
lda #$20
@print2:
sta VERA_data0
lda print_bcd+1
and #$0F
beq @print_space3
stz print_space
@num3:
ora #$30
bra @print3
@print_space3:
lda print_space
beq @num3
lda #$20
@print3:
sta VERA_data0
lda print_bcd
lsr
lsr
lsr
lsr
beq @print_space4
stz print_space
@num4:
ora #$30
bra @print4
@print_space4:
lda print_space
beq @num4
lda #$20
@print4:
sta VERA_data0
lda print_bcd
and #$0F
ora #$30
sta VERA_data0
rts
print_byte_dec: ; A = byte to print in decimal
; X,Y = coordinates
sta SB1
jsr print_set_vera_addr
stz print_bcd
stz print_bcd+1
sed
ldx #8
@loop:
; shift highest bit to C
asl SB1
; BCD = BCD*2 + C
lda print_bcd
adc print_bcd
sta print_bcd
lda print_bcd+1
adc print_bcd+1
sta print_bcd+1
dex
bne @loop
cld
lda #1
sta print_space
lda print_bcd+1
beq @print_space1
stz print_space
ora #$30
bra @print1
@print_space1:
lda #$20
@print1:
sta VERA_data0
lda print_bcd
lsr
lsr
lsr
lsr
cmp #0
beq @print_space2
@num2:
ora #$30
bra @print2
@print_space2:
lda print_space
beq @num2
lda #$20
@print2:
sta VERA_data0
lda print_bcd
and #$0F
ora #$30
sta VERA_data0
rts
print_set_vera_addr: ; X,Y = coordinates to print
stz VERA_ctrl
lda #$21
sta VERA_addr_bank
tya
clc
adc #$B0
sta VERA_addr_high
txa
asl
sta VERA_addr_low
rts
print_load_addrs: ; Input: A = ZP address of pointer to value; X,Y = coordinates to print
; Output: IND_VEC = de-referenced pointer
sta IND_VEC
stz IND_VEC+1
jsr print_set_vera_addr
lda (IND_VEC)
sta SB1
ldy #1
lda (IND_VEC),y
sta IND_VEC+1
lda SB1
sta IND_VEC
rts
print_vaddr: ; A = ZP address of pointer to 3-byte VRAM address
; X,Y = coordinates to print
jsr print_load_addrs
ldy #2
lda (IND_VEC),y
jsr get_hex_char
sta VERA_data0
dey
lda (IND_VEC),y
jsr _print_hex_byte
lda (IND_VEC)
jmp _print_hex_byte ; tail-optimization
get_hex_char:
cmp #$A
bpl @letter
ora #$30
bra @return
@letter:
clc
adc #$37
@return:
rts
print_byte_hex: ; A = byte value to print in hex; X,Y = coordinates
pha
jsr print_set_vera_addr
pla
_print_hex_byte: ; A = byte value to print in hex
pha
lsr
lsr
lsr
lsr
jsr get_hex_char
sta VERA_data0
pla
and #$0F
jsr get_hex_char
sta VERA_data0
rts
print_string: ; A = ZP address of pointer to null-terminated string (max length = 255)
; X,Y = coordinates to print
phx
phy
jsr print_load_addrs
ldy #0
@loop:
lda (IND_VEC),y
beq @return
sta VERA_data0
iny
bra @loop
@return:
ply
plx
rts
print_char: ; A = screen code to print
; X,Y = coordinates
pha
jsr print_set_vera_addr
pla
sta VERA_data0
rts
ascii_to_screen_code:
cmp #$20
bmi @control
cmp #$60
bmi @return ; no change
cmp #$80
bmi @lowercase
cmp #$A0
bpl @return ; no change
@control: ; make control codes "inverted"
ora #$80
bra @return
@lowercase:
sec
sbc #$60
bra @return
@return:
rts