gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/libc/targets/mos6502/font.s
1 ; font.ms
2 ;
3 ; Michael Hope, 1999
4 ; michaelh@earthling.net
5 ;
6 .include "global.s"
7
8 .area GBDKOVR (PAG, OVR)
9 _temp_word: .ds 2
10
11 .globl .cr_curs
12 .globl .adv_curs
13 .globl .cury, .curx
14 .globl .display_on, .display_off
15
16 ; Structure offsets
17 sfont_handle_sizeof = 3
18 sfont_handle_font = 1
19 sfont_handle_first_tile = 0
20
21 ; Encoding types - lower 2 bits of font
22 FONT_256ENCODING = 0
23 FONT_128ENCODING = 1
24 FONT_NOENCODING = 2
25
26 ; Other bits
27 FONT_COMPRESSED = 4
28 FONT_BCOMPRESSED = 2
29
30 .CR = 0x0A ; Unix
31 .SPACE = 0x00
32
33 ; Maximum number of fonts
34 .MAX_FONTS = 6
35
36 .area _FONT_HEADER (ABS)
37
38 .org .MODE_TABLE+4*.T_MODE
39 jmp .tmode
40
41 .module font.ms
42
43 .globl _set_bkg_1bpp_data, _set_bkg_data
44
45 .area _DATA
46 .curx:: ; Cursor position
47 .ds 0x01
48 .cury::
49 .ds 0x01
50
51 .area _XINIT
52 .db 0x00 ; .curx
53 .db 0x00 ; .cury
54
55 .area _BSS
56 ; The current font
57 font_handle_base:
58 font_current::
59 .ds sfont_handle_sizeof
60 ; Cached copy of the first free tile
61 font_first_free_tile::
62 .ds 1
63 ; Table containing descriptors for all of the fonts
64 font_table::
65 .ds sfont_handle_sizeof*.MAX_FONTS
66
67 .area _HOME
68
69 _font_load_ibm::
70 lda #<_font_ibm
71 ldx #>_font_ibm
72 jmp font_load
73 rts
74
75 ; Load the font HL
76 font_load::
77 sta *_temp_word
78 stx *_temp_word+1
79
80 jsr .display_off
81
82 ; numTiles
83 ldy #1
84 lda [*_temp_word],y
85 tax
86
87 ; Find the first free font entry
88 ldy #sfont_handle_font
89 ldx #.MAX_FONTS
90 font_load_find_slot:
91 lda font_table,y ; Check to see if this entry is free
92 iny
93 ora font_table,y ; Free is 0000 for the font pointer
94 beq font_load_found
95 iny
96 iny
97 dex
98 bne font_load_find_slot
99 jmp font_load_exit ; Couldn't find a free space
100 font_load_found:
101 ; _temp_word points to the end of the free font table entry
102 lda *_temp_word+1
103 sta font_table,y ; Copy across the font struct pointer
104 dey
105 lda *_temp_word
106 sta font_table,y
107
108 lda font_first_free_tile
109 dey
110 sta font_table,y
111 ; Set this new font to be the default
112 jsr font_set
113 tya
114 pha
115 ; Only copy the tiles in if were in text mode
116 lda .mode
117 and #.T_MODE
118 beq font_load_skip_copy_current
119 jsr font_copy_current
120 font_load_skip_copy_current:
121 ; Increase the 'first free tile' counter
122 lda #<font_current+sfont_handle_font
123 sta .tmp
124 lda #>font_current+sfont_handle_font
125 sta .tmp+1
126 ldy #0
127 lda [*.tmp],y
128 iny
129 tax
130 lda [*.tmp],y
131 sta .tmp+1
132 stx .tmp
133 lda font_first_free_tile
134 clc
135 adc [*.tmp],y ; Number of tiles used
136 sta font_first_free_tile
137 font_load_exit:
138 ;; Turn the screen on
139 jsr .display_on
140 pla ; Return font setup in A
141 rts
142
143 ; Copy the tiles from the current font into VRAM
144 font_copy_current::
145 ; Find the current font data
146 lda font_current+sfont_handle_font
147 sta *.tmp
148 lda font_current+sfont_handle_font+1
149 sta *.tmp+1
150 ldy #0
151 lda [*.tmp],y
152 iny
153 pha
154 lda [*.tmp],y
155 iny
156 tax
157 ;
158 pla
159 pha
160 and #3
161 cmp #FONT_128ENCODING
162 beq 1$
163 cmp #FONT_NOENCODING
164 beq 2$
165 ; 256ENCODING - add #256 to .tmp -> inc .tmp+1
166 inc .tmp+1
167 jmp 2$
168 1$:
169 ; 128ENCODING - add #128 to y
170 tya
171 ora #128
172 tay
173 2$:
174 tya
175 clc
176 adc *.tmp
177 sta *_set_bkg_data_PARM_3
178 sta *_set_bkg_1bpp_data_PARM_3
179 lda *.tmp+1
180 adc #0
181 sta *_set_bkg_data_PARM_3+1
182 sta *_set_bkg_1bpp_data_PARM_3+1
183 pla
184 and #FONT_COMPRESSED
185 bne 3$
186 lda font_current+sfont_handle_first_tile
187 jsr _set_bkg_data
188 jsr .display_on
189 rts
190 3$:
191 lda font_current+sfont_handle_first_tile
192 jsr _set_bkg_1bpp_data
193 jsr .display_on
194 rts
195
196 ; Set the current font to Y
197 font_set::
198 lda font_table,y
199 iny
200 sta font_current
201 lda font_table,y
202 iny
203 sta font_current+1
204 lda font_table,y
205 iny
206 sta font_current+2
207 dey
208 dey
209 dey
210 rts
211
212 ;; Print a character with interpretation
213 .put_char::
214 ; See if it's a special char
215 cmp #.CR
216 bne 1$
217
218 ; Now see if were checking special chars
219 lda .mode
220 and #.M_NO_INTERP
221 bne 2$
222 jsr .cr_curs
223 rts
224
225 2$:
226 1$:
227 jsr .set_char
228 jmp .adv_curs
229
230 ;; Print a character without interpretation
231 .out_char::
232 jsr .set_char
233 jmp .adv_curs
234
235 ;; Delete a character
236 .del_char::
237 jsr .rew_curs
238 lda #.SPACE
239 jmp .set_char
240
241 ;; Print the character in A
242 .set_char:
243 pha
244 lda font_current+2
245 ; Must be non-zero if the font system is setup (cant have a font in page zero)
246 bne 3$
247
248 ; Font system is not yet setup - init it and copy in the ibm font
249 ; Kind of a compatibility mode
250 jsr _font_init
251
252 ; Need all of the tiles
253 lda #0
254 sta font_first_free_tile
255 jsr _font_load_ibm
256 3$:
257 ; Compute which tile maps to this character
258 pla
259 pha
260 tax
261 lda font_current+sfont_handle_font
262 sta *.tmp
263 lda font_current+sfont_handle_font+1
264 sta *.tmp+1
265 ldy #0
266 lda [*.tmp],y
267 and #3
268 cmp #FONT_NOENCODING
269 beq set_char_no_encoding
270 iny
271 iny
272 ; Now at the base of the encoding table
273 ; E is set above
274 pla
275 pha
276 clc
277 adc .identity,y
278 tay
279 lda [*.tmp],y ; That's the tile!
280 tax
281 set_char_no_encoding:
282 pla
283 txa
284 clc
285 adc font_current+sfont_handle_first_tile
286 sta _set_bkg_tile_xy_PARM_3
287 lda .curx
288 ldx .cury
289 jsr _set_bkg_tile_xy
290 rts
291
292
293 _putchar::
294 jmp .put_char
295
296 _setchar::
297 jmp .set_char
298
299 _font_load::
300 jmp font_load
301
302 _font_set::
303 tay
304 jmp font_set
305
306 _font_init::
307 .globl .tmode
308 jsr .tmode
309 lda #0
310 sta font_first_free_tile
311 ; Clear the font table
312 ldy #sfont_handle_sizeof*.MAX_FONTS-1
313 1$:
314 sta font_table,y
315 dey
316 bpl 1$
317 lda #3
318 sta .fg_colour
319 lda #0
320 sta .bg_colour
321 jsr .cls_no_reset_pos
322 rts
323
324
325 _cls::
326 .cls::
327 lda #0
328 sta .curx
329 sta .cury
330 .cls_no_reset_pos:
331 ; TODO: Make this clear entire screen to #.SPACE without manual blanking
332 rts
333 ; Support routines
334 _gotoxy::
335 ; TODO: Double-check which is x vs y
336 sta .curx
337 stx .cury
338 rts
339
340 _posx::
341 lda .mode
342 and #.T_MODE
343 bne 1$
344 jsr .tmode
345 1$:
346 lda .curx
347 rts
348
349 _posy::
350 lda .mode
351 and #.T_MODE
352 bne 1$
353 jsr .tmode
354 1$:
355 lda .cury
356 rts
357
358 ;; Rewind the cursor
359 .rew_curs:
360 ldy .cury
361 ldx .curx
362 beq 1$
363 dex
364 jmp 99$
365 1$:
366 cpy #0
367 beq 99$
368 dey
369 99$:
370 stx .curx
371 sty .cury
372 rts
373
374 .cr_curs::
375 lda #0
376 sta .curx
377 lda #.MAXCURSPOSY
378 cmp .cury
379 beq 2$
380 inc .cury
381 jmp 99$
382 2$:
383 jsr .scroll
384 99$:
385 rts
386
387 .adv_curs::
388 lda #.MAXCURSPOSX
389 cmp .curx
390 beq 1$
391 inc .curx
392 jmp 99$
393 1$:
394 lda #0
395 sta .curx
396 lda #.MAXCURSPOSY
397 cmp .cury
398 beq 2$
399 inc .cury
400 jmp 99$
401 2$:
402 ;; See if scrolling is disabled
403 lda .mode
404 and #.M_NO_SCROLL
405 beq 3$
406 ;; Nope - reset the cursor to (0,0)
407 lda #0
408 sta .cury
409 sta .curx
410 jmp 99$
411 3$:
412 jsr .scroll
413 99$:
414 rts
415
416
417 ;; Scroll the whole screen
418 .scroll:
419 ; TODO: Read-Writes on nametable memory is not ideal on the NES for a variety of reasons.
420 ; Even a performant implementation could block for around 15 frames until vblank updates have
421 ; moved all bytes.
422 ; For now, just do nothing and investigate this further.
423 rts
424
425
426 ;; Enter text mode
427 .tmode::
428 ;; Turn the screen off
429 jsr .display_off
430 jsr .tmode_out
431 jsr .display_on
432 rts
433
434 ;; Text mode (out only)
435 .tmode_out::
436 ;; Clear screen
437 jsr .cls_no_reset_pos
438 lda #.T_MODE
439 sta .mode
440 rts
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.