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/nes/flush_attributes.s

      1     .include    "global.s"
      2 
      3     .area   GBDKOVR (PAG, OVR)
      4     .x_save:                    .ds 1
      5     .y_save:                    .ds 1
      6     .attribute_row_dirty:       .ds 1
      7     .attribute_column_dirty:    .ds 1
      8 
      9     .area   _HOME
     10 
     11 .macro LOAD_ROW_DIRTY ?lbl, ?lbl2
     12 .ifdef NES_WINDOW_LAYER
     13     bit *__current_vram_cfg_write
     14     bpl lbl
     15     lda *_attribute_row_dirty_win,x
     16     jmp lbl2
     17 .endif
     18 lbl:
     19     lda *_attribute_row_dirty,x
     20 lbl2:
     21 .endm
     22 
     23 .macro LOAD_COLUMN_DIRTY ?lbl, ?lbl2
     24 .ifdef NES_WINDOW_LAYER
     25     bit *__current_vram_cfg_write
     26     bpl lbl
     27     lda *_attribute_column_dirty_win,x
     28     jmp lbl2
     29 .endif
     30 lbl:
     31     lda *_attribute_column_dirty,x
     32 lbl2:
     33 .endm
     34 
     35 .macro LOAD_ROW_ATTRIBUTE ?lbl, ?lbl2
     36 .ifdef NES_WINDOW_LAYER
     37     bit *__current_vram_cfg_write
     38     bpl lbl
     39     lda *_attribute_row_dirty_win,x
     40     jmp lbl2
     41 .endif
     42 lbl:
     43     lda *_attribute_row_dirty,x
     44 lbl2:
     45 .endm
     46 
     47 .macro CLEAR_ATTRIBUTE_DIRTY ?lbl, ?lbl2
     48     lda #0
     49 .ifdef NES_WINDOW_LAYER
     50     bit *__current_vram_cfg_write
     51     bpl lbl
     52     sta _attribute_row_dirty_win,x
     53     sta _attribute_column_dirty_win,x
     54     jmp lbl2
     55 .endif
     56 lbl:
     57     sta _attribute_row_dirty,x
     58     sta _attribute_column_dirty,x
     59 lbl2:
     60 .endm
     61 
     62 _flush_shadow_attributes::
     63 .ifdef NES_WINDOW_LAYER
     64     ; First process window layer
     65     lda *__current_vram_cfg_write
     66     pha
     67     ora #PPUHI_WIN
     68     sta *__current_vram_cfg_write
     69     jsr _flush_shadow_attributes_impl
     70     ; ...then background layer
     71     lda *__current_vram_cfg_write
     72     and #~PPUHI_WIN
     73     sta *__current_vram_cfg_write
     74     jsr _flush_shadow_attributes_impl
     75     pla
     76     sta *__current_vram_cfg_write
     77     rts
     78 _flush_shadow_attributes_impl::
     79 .endif
     80     ldx #0
     81 .ifndef NES_TILEMAP_S
     82 1$:
     83 .endif
     84     stx *.x_save
     85     LOAD_ROW_DIRTY
     86     beq 2$
     87     sta *.attribute_row_dirty
     88     ldy .xy_shift_tab,x
     89     jsr _flush_shadow_attributes_rows
     90     ldx *.x_save
     91 2$:
     92     LOAD_COLUMN_DIRTY
     93     beq 3$
     94     sta *.attribute_column_dirty
     95     ldy .xy_shift_tab,x
     96     jsr _flush_shadow_attributes_columns
     97 3$:
     98     ldx *.x_save
     99     CLEAR_ATTRIBUTE_DIRTY
    100 .ifndef NES_TILEMAP_S
    101     inx
    102     cpx #NUM_NT
    103     bne 1$
    104 .endif
    105     rts
    106 
    107 ;
    108 ; Writes every row of attributes from _shadow_attributes that's been marked
    109 ; as dirty in the _attribute_row_dirty byte to PPU memory.
    110 ;
    111 _flush_shadow_attributes_rows:
    112     lda #<PPU_AT0
    113     sta *.tmp
    114     lda .ppu_hi_tab,x
    115 .ifdef NES_WINDOW_LAYER
    116     bit *__current_vram_cfg_write
    117     bpl 0$
    118     ora #PPUHI_WIN
    119 0$:
    120 .endif
    121     sta *.tmp+1
    122 _flush_shadow_attributes_row_loop:
    123     lsr *.attribute_row_dirty
    124     bcc 1$
    125     jmp _flush_shadow_attributes_update_row
    126 1$:
    127     beq _flush_shadow_attributes_end
    128 _flush_shadow_attributes_next_row:
    129     ; Y += AT_SHADOW_WIDTH
    130     tya
    131     clc
    132     adc #AT_SHADOW_WIDTH
    133     tay
    134     ; .tmp += ATTRIBUTE_PACKED_WIDTH
    135     lda *.tmp
    136     adc #ATTRIBUTE_PACKED_WIDTH
    137     sta *.tmp
    138     jmp _flush_shadow_attributes_row_loop
    139 _flush_shadow_attributes_end:
    140     rts
    141 
    142 ;
    143 ; Flushes all dirty rows of _attribute_shadow by writing them to PPU memory
    144 ;
    145 _flush_shadow_attributes_update_row:
    146     stx *REGTEMP+3
    147     ; Update all 8 bytes of row for now, as each row in _attribute_row_dirty only stores 1 bit
    148     ; TODO: Could store 8 bytes and update range, at expense of 7 more bytes.
    149     lda *.tmp+1
    150     tax
    151     lda *.tmp
    152     jsr .ppu_stripe_begin_horizontal
    153     ; Write 8 bytes
    154 .ifdef NES_WINDOW_LAYER
    155     bit *__current_vram_cfg_write
    156     bpl 1$
    157     i = 0
    158     .rept ATTRIBUTE_PACKED_WIDTH
    159     lda _attribute_shadow_win+i,y
    160     jsr .ppu_stripe_write_byte
    161     i = i + 1
    162     .endm
    163     jmp 2$
    164 1$:
    165 .endif
    166     i = 0
    167     .rept ATTRIBUTE_PACKED_WIDTH
    168     lda _attribute_shadow+i,y
    169     jsr .ppu_stripe_write_byte
    170     i = i + 1
    171     .endm
    172 2$:
    173     jsr .ppu_stripe_end
    174     ldx *REGTEMP+3
    175     jmp _flush_shadow_attributes_next_row
    176 
    177 ;
    178 ; Writes every column of attributes from _shadow_attributes that's been marked
    179 ; as dirty in the _attribute_column_dirty byte to PPU memory.
    180 ;
    181 ;
    182 _flush_shadow_attributes_columns:
    183     lda #<PPU_AT0
    184     sta *.tmp
    185     lda .ppu_hi_tab,x
    186 .ifdef NES_WINDOW_LAYER
    187     bit *__current_vram_cfg_write
    188     bpl 0$
    189     ora #PPUHI_WIN
    190 0$:
    191 .endif
    192     sta *.tmp+1
    193 _flush_shadow_attributes_columns_loop:
    194     lsr *.attribute_column_dirty
    195     bcc 1$
    196     jmp _flush_shadow_attributes_update_column
    197 1$:
    198     beq _flush_shadow_attributes_columns_end
    199 _flush_shadow_attributes_columns_next_column:
    200     ; Y += 1
    201     iny
    202     ; .tmp += 1
    203     inc *.tmp
    204     jmp _flush_shadow_attributes_columns_loop
    205 _flush_shadow_attributes_columns_end:
    206     rts
    207 
    208 _write_vert:
    209     lda *.tmp+1
    210     tax
    211     lda *.tmp
    212     jsr .ppu_stripe_begin_vertical
    213     lda _attribute_shadow,y
    214     jsr .ppu_stripe_write_byte
    215     lda _attribute_shadow+(AT_SHADOW_WIDTH*4),y
    216     jsr .ppu_stripe_write_byte
    217     jsr .ppu_stripe_end
    218     ; inc src index
    219     tya
    220     clc
    221     adc #AT_SHADOW_WIDTH
    222     tay
    223     ; inc ppu addr
    224     lda *.tmp
    225     adc #ATTRIBUTE_PACKED_WIDTH
    226     sta *.tmp
    227     rts
    228 
    229 ;
    230 ; Flushes all dirty rows of _attribute_shadow by writing them to PPU memory
    231 ;
    232 _flush_shadow_attributes_update_column:
    233     stx *REGTEMP+3
    234     sty *.y_save
    235     lda *.tmp
    236     pha
    237     ; Update all 8 bytes of column for now, as each column in _attribute_column_dirty only stores 1 bit
    238     ; As PPU has no increment-by-8 feature, split writes into 4 separate stripes 2 bytes each
    239     ; TODO: Could make a dedicated unrolled transfer routine in nmi handler that writes all 8 bytes as one stripe.
    240     .rept 4
    241     jsr _write_vert
    242     .endm
    243     pla
    244     sta *.tmp
    245     ldy *.y_save
    246     ldx *REGTEMP+3
    247     jmp _flush_shadow_attributes_columns_next_column
    248 
    249 ; Shift MSB of attribute X / Y (attribute table index) from bits 1 and 0 to 7 and 3
    250 .ifdef NES_TILEMAP_F
    251 .xy_shift_tab:
    252 .db 0b00000000
    253 .db 0b00001000
    254 .db 0b10000000
    255 .db 0b10001000
    256 .endif
    257 .ifdef NES_TILEMAP_S
    258 .xy_shift_tab:
    259 .db 0b00000000
    260 .db 0b00000000
    261 .db 0b00000000
    262 .db 0b00000000
    263 .endif
    264 .ifdef NES_TILEMAP_H
    265 .xy_shift_tab:
    266 .db 0b00000000
    267 .db 0b00001000
    268 .endif
    269 .ifdef NES_TILEMAP_V
    270 .xy_shift_tab:
    271 .db 0b00000000
    272 .db 0b01000000
    273 .endif
    274 
    275 ; Get hi address of attribute table index
    276 .ifdef NES_TILEMAP_F
    277 .ppu_hi_tab:
    278 .db >PPU_AT0
    279 .db >PPU_AT1
    280 .db >PPU_AT2
    281 .db >PPU_AT3
    282 .endif
    283 .ifdef NES_TILEMAP_S
    284 .ppu_hi_tab:
    285 .db >PPU_AT0
    286 .db >PPU_AT0
    287 .db >PPU_AT0
    288 .db >PPU_AT0
    289 .endif
    290 .ifdef NES_TILEMAP_H
    291 .ppu_hi_tab:
    292 .db >PPU_AT0
    293 .db >PPU_AT1
    294 .endif
    295 .ifdef NES_TILEMAP_V
    296 .ppu_hi_tab:
    297 .db >PPU_AT0
    298 .db >PPU_AT2
    299 .endif

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.