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/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.