gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/libc/targets/sm83/font.s
1 ; font.ms
2 ;
3 ; Michael Hope, 1999
4 ; michaelh@earthling.net
5 ;
6 .include "global.s"
7
8 .globl .cr_curs
9 .globl .adv_curs
10 .globl .cury, .curx
11 .globl .display_off
12 .globl .drawing_lcd
13
14 ; Structure offsets
15 sfont_handle_sizeof = 3
16 sfont_handle_font = 1
17 sfont_handle_first_tile = 0
18
19 ; Encoding types - lower 2 bits of font
20 FONT_256ENCODING = 0
21 FONT_128ENCODING = 1
22 FONT_NOENCODING = 2
23
24 ; Other bits
25 FONT_BCOMPRESSED = 2
26
27 .CR = 0x0A ; Unix
28 .SPACE = 0x00
29
30 ; Maximum number of fonts
31 .MAX_FONTS = 6
32
33 .area _FONT_HEADER (ABS)
34
35 .org .MODE_TABLE+4*.T_MODE
36 JP .tmode
37
38 .module font.ms
39
40 .globl .fg_colour, .bg_colour
41
42 .globl .remove_VBL, .remove_LCD
43 .globl _set_bkg_1bpp_data, _set_bkg_data
44
45 .area _INITIALIZED
46 .curx:: ; Cursor position
47 .ds 0x01
48 .cury::
49 .ds 0x01
50
51 .area _INITIALIZER
52 .db 0x00 ; .curx
53 .db 0x00 ; .cury
54
55 .area _DATA
56 ; The current font
57
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 ld hl,#_font_ibm
71 call font_load
72 ret
73
74 ; Load the font HL
75 font_load::
76 call .display_off
77 push hl
78
79 ; Find the first free font entry
80 ld hl,#font_table+sfont_handle_font
81 ld b,#.MAX_FONTS
82 font_load_find_slot:
83 ld a,(hl) ; Check to see if this entry is free
84 inc hl ; Free is 0000 for the font pointer
85 or (hl)
86 cp #0
87 jr z,font_load_found
88
89 inc hl
90 inc hl
91 dec b
92 jr nz,font_load_find_slot
93 pop hl
94 ld hl,#0
95 jr font_load_exit ; Couldn't find a free space
96 font_load_found:
97 ; HL points to the end of the free font table entry
98 pop de
99 ld (hl),d ; Copy across the font struct pointer
100 dec hl
101 ld (hl),e
102
103 ld a,(font_first_free_tile)
104 dec hl
105 ld (hl),a
106
107 push hl
108 call font_set ; Set this new font to be the default
109
110 ; Only copy the tiles in if were in text mode
111 ld a,(.mode)
112 and #.T_MODE
113
114 call nz,font_copy_current
115
116 ; Increase the 'first free tile' counter
117 ld hl,#font_current+sfont_handle_font
118 ld a,(hl+)
119 ld h,(hl)
120 ld l,a
121
122 inc hl ; Number of tiles used
123 ld a,(font_first_free_tile)
124 add a,(hl)
125 ld (font_first_free_tile),a
126
127 pop hl ; Return font setup in HL
128 font_load_exit:
129 ;; Turn the screen on
130 LDH A,(.LCDC)
131 OR #(LCDCF_ON | LCDCF_BGON)
132 AND #~(LCDCF_BG9C00 | LCDCF_BG8000)
133 LDH (.LCDC),A
134
135 RET
136
137 ; Copy the tiles from the current font into VRAM
138 font_copy_current::
139 ; Find the current font data
140 ld hl,#font_current+sfont_handle_font
141 ld a,(hl+)
142 ld h,(hl)
143 ld l,a
144
145 ld a, (hl+)
146 ld e, a
147 ld a, (hl+)
148 ld d, a
149
150 ld a, e
151 ld c, #128
152 and #3
153 cp #FONT_128ENCODING
154 jr z, 1$
155 cp #FONT_NOENCODING
156 jr z, 2$
157 inc h
158 jr 2$
159 1$:
160 ld a, c
161 add l
162 ld l, a
163 adc h
164 sub l
165 ld h, a
166 2$:
167 push hl
168 ld c, e
169 ld a, (font_current+sfont_handle_first_tile)
170 ld e, a
171 push de
172 bit FONT_BCOMPRESSED, c
173 jr nz, 3$
174 call _set_bkg_data
175 jr 4$
176 3$:
177 call _set_bkg_1bpp_data
178 4$:
179 add sp, #4
180 ret
181
182 ; Set the current font to HL
183 font_set::
184 ld a,(hl+)
185 ld (font_current),a
186 ld a,(hl+)
187 ld (font_current+1),a
188 ld a,(hl+)
189 ld (font_current+2),a
190 ret
191
192 ;; Print a character with interpretation
193 .put_char::
194 ; See if it's a special char
195 cp #.CR
196 jr nz,1$
197
198 ; Now see if were checking special chars
199 push af
200 ld a,(.mode)
201 and #.M_NO_INTERP
202 jr nz,2$
203 call .cr_curs
204 pop af
205 ret
206 2$:
207 pop af
208 1$:
209 call .set_char
210 jp .adv_curs
211
212 ;; Print a character without interpretation
213 .out_char::
214 call .set_char
215 jp .adv_curs
216
217 ;; Delete a character
218 .del_char::
219 call .rew_curs
220 ld a,#.SPACE
221 jp .set_char
222
223 ;; Print the character in A
224 .set_char:
225 push af
226 ld a,(font_current+2)
227 ; Must be non-zero if the font system is setup (cant have a font in page zero)
228 or a
229 jr nz,3$
230
231 ; Font system is not yet setup - init it and copy in the ibm font
232 ; Kind of a compatibility mode
233 call _font_init
234
235 ; Need all of the tiles
236 xor a
237 ld (font_first_free_tile),a
238
239 call _font_load_ibm
240 3$:
241 pop af
242 push bc
243 push de
244 push hl
245 ; Compute which tile maps to this character
246 ld e,a
247 ld hl,#font_current+sfont_handle_font
248 ld a,(hl+)
249 ld h,(hl)
250 ld l,a
251 ld a,(hl+)
252 and #3
253 cp #FONT_NOENCODING
254 jr z,set_char_no_encoding
255 inc hl
256 ; Now at the base of the encoding table
257 ; E is set above
258 ld d,#0
259 add hl,de
260 ld e,(hl) ; That's the tile!
261 set_char_no_encoding:
262 ld a,(font_current+0)
263 add a,e
264 ld e,a
265
266 LD A,(.cury) ; Y coordinate
267 LD L,A
268 LD H,#0x00
269 ADD HL,HL
270 ADD HL,HL
271 ADD HL,HL
272 ADD HL,HL
273 ADD HL,HL
274 LD A,(.curx) ; X coordinate
275 LD C,A
276 LD B,#0x00
277 ADD HL,BC
278 LD BC,#0x9800
279 ADD HL,BC
280
281 WAIT_STAT
282
283 LD (HL),E
284 POP HL
285 POP DE
286 POP BC
287 RET
288
289 _putchar::
290 PUSH BC
291 LDA HL,4(SP) ; Skip return address
292 LD A,(HL) ; A = c
293 CALL .put_char
294 POP BC
295 RET
296
297 _setchar::
298 PUSH BC
299 LDA HL,4(SP) ; Skip return address
300 LD A,(HL) ; A = c
301 CALL .set_char
302 POP BC
303 RET
304
305 _font_load::
306 push bc
307 LDA HL,4(SP) ; Skip return address and bc
308 LD A,(HL) ; A = c
309 inc hl
310 ld h,(hl)
311 ld l,a
312 call font_load
313 push hl
314 pop de ; Return in DE
315 pop bc
316 ret
317
318 _font_set::
319 push bc
320 LDA HL,4(SP) ; Skip return address
321 LD A,(HL) ; A = c
322 inc hl
323 ld h,(hl)
324 ld l,a
325 call font_set
326 pop bc
327 ld de,#0 ; Always good...
328 ret
329
330 _font_init::
331 push bc
332 .globl .tmode
333
334 call .tmode
335
336 xor a
337 ld (font_first_free_tile),a
338
339 ; Clear the font table
340 ld hl,#font_table
341 ld b,#sfont_handle_sizeof*.MAX_FONTS
342 1$:
343 ld (hl+),a
344 dec b
345 jr nz,1$
346 ld a,#3
347 ld (.fg_colour),a
348 xor a
349 ld (.bg_colour),a
350
351 call .cls_no_reset_pos
352 pop bc
353 ret
354
355 _cls::
356 .cls::
357 XOR A
358 LD (.curx), A
359 LD (.cury), A
360 .cls_no_reset_pos:
361 PUSH DE
362 PUSH HL
363 LD HL,#0x9800
364 LD E,#0x20 ; E = height
365 1$:
366 LD D,#0x20 ; D = width
367 2$:
368 WAIT_STAT
369
370 LD (HL),#.SPACE ; Always clear
371 INC HL
372 DEC D
373 JR NZ,2$
374 DEC E
375 JR NZ,1$
376 POP HL
377 POP DE
378 RET
379
380 ; Support routines
381 _gotoxy::
382 lda hl,2(sp)
383 ld a,(hl+)
384 ld (.curx),a
385 ld a,(hl)
386 ld (.cury),a
387 ret
388
389 _posx::
390 LD A,(.mode)
391 AND #.T_MODE
392 JR NZ,1$
393 PUSH BC
394 CALL .tmode
395 POP BC
396 1$:
397 LD A,(.curx)
398 LD E,A
399 RET
400
401 _posy::
402 LD A,(.mode)
403 AND #.T_MODE
404 JR NZ,1$
405 PUSH BC
406 CALL .tmode
407 POP BC
408 1$:
409 LD A,(.cury)
410 LD E,A
411 RET
412
413 ;; Rewind the cursor
414 .rew_curs:
415 PUSH HL
416 LD HL,#.curx ; X coordinate
417 XOR A
418 CP (HL)
419 JR Z,1$
420 DEC (HL)
421 JR 99$
422 1$:
423 LD (HL),#.MAXCURSPOSX
424 LD HL,#.cury ; Y coordinate
425 XOR A
426 CP (HL)
427 JR Z,99$
428 DEC (HL)
429 99$:
430 POP HL
431 RET
432
433 .cr_curs::
434 PUSH HL
435 XOR A
436 LD (.curx),A
437 LD HL,#.cury ; Y coordinate
438 LD A,#.MAXCURSPOSY
439 CP (HL)
440 JR Z,2$
441 INC (HL)
442 JR 99$
443 2$:
444 CALL .scroll
445 99$:
446 POP HL
447 RET
448
449 .adv_curs::
450 PUSH HL
451 LD HL,#.curx ; X coordinate
452 LD A,#.MAXCURSPOSX
453 CP (HL)
454 JR Z,1$
455 INC (HL)
456 JR 99$
457 1$:
458 LD (HL),#0x00
459 LD HL,#.cury ; Y coordinate
460 LD A,#.MAXCURSPOSY
461 CP (HL)
462 JR Z,2$
463 INC (HL)
464 JR 99$
465 2$:
466 ;; See if scrolling is disabled
467 LD A,(.mode)
468 AND #.M_NO_SCROLL
469 JR Z,3$
470 ;; Nope - reset the cursor to (0,0)
471 XOR A
472 LD (.cury),A
473 LD (.curx),A
474 JR 99$
475 3$:
476 CALL .scroll
477 99$:
478 POP HL
479 RET
480
481 ;; Scroll the whole screen
482 .scroll:
483 PUSH BC
484 PUSH DE
485 PUSH HL
486 LD HL,#0x9800
487 LD BC,#0x9800+0x20 ; BC = next line
488 LD E,#0x20-0x01 ; E = height - 1
489 1$:
490 LD D,#0x20 ; D = width
491 2$:
492 WAIT_STAT
493 LD A,(BC)
494 LD (HL+),A
495 INC BC
496
497 DEC D
498 JR NZ,2$
499 DEC E
500 JR NZ,1$
501
502 LD D,#0x20
503 3$:
504 WAIT_STAT
505 LD A,#.SPACE
506 LD (HL+),A
507 DEC D
508 JR NZ,3$
509
510 POP HL
511 POP DE
512 POP BC
513 RET
514
515 ;; Enter text mode
516 .tmode::
517 DI ; Disable interrupts
518
519 ;; Turn the screen off
520 LDH A,(.LCDC)
521 AND #LCDCF_ON
522 JR Z,1$
523
524 ;; Turn the screen off
525 CALL .display_off
526
527 ;; Remove any interrupts setup by the drawing routine
528 LD DE,#.drawing_lcd
529 CALL .remove_LCD
530 1$:
531
532 CALL .tmode_out
533
534 ;; Turn the screen on
535 LDH A,(.LCDC)
536 OR #(LCDCF_ON | LCDCF_BGON)
537 AND #~(LCDCF_BG9C00 | LCDCF_BG8000)
538 LDH (.LCDC),A
539
540 EI ; Enable interrupts
541
542 RET
543
544 ;; Text mode (out only)
545 .tmode_out::
546 ;; Clear screen
547 CALL .cls_no_reset_pos
548
549 LD A,#.T_MODE
550 LD (.mode),A
551
552 RET
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.