git.y1.nz

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.