Posted September 19, 2022 by nesrocks
New in version 0.106:
RLE decompression code is provided in neslib, but Tepples made an improvement that is described here. Basically it removes a restriction in the original format, at a small ROM/CPU cost: https://forums.nesdev.org/viewtopic.php?t=17747
After the edits, this is how it goes:
; Used to unpack NESST rle packed nametables. Those are packed horizontally so not very ; much use for a side scroller game's stages, but still very useful for its static screens. ; Includes Tepples improvement ; Util constants _RLE_LOW = temp _RLE_HIGH = temp+1 _RLE_TAG = temp+2 ; this value marks the end of the sequence _RLE_BYTE = temp+3 ; Decompresses a stream compressed with Shiru RLE to video memory. ; The first byte in the stream is the run marker. ; After that, any byte other than the run marker is copied literally to the output. ; A run marker followed by 0 ends the stream. ; a run marker followed by 1 means itself (uncompressed); ; A run marker followed by a byte with value 2-255 writes ; that many copies of the most recently written byte to the stream. ; @param XA pointer to start of stream load_nam_rle: ; Set up tay stx <_RLE_HIGH lda #0 sta <_RLE_LOW ; Read byte that does not appear in data, used to signal a run lda (_RLE_LOW),y sta <_RLE_TAG iny bne @tag_nowrap inc <_RLE_HIGH @tag_nowrap: @decodeloop: ; Read a byte from the stream lda (_RLE_LOW),y iny bne @main_nowrap inc <_RLE_HIGH @main_nowrap: ; If it doesn't match the run marker, output it cmp <_RLE_TAG beq @is_rle @is_literal: sta _PPUDATA_2007 sta <_RLE_BYTE bne @decodeloop @is_rle: ; We just saw a run marker. Load the length, stopping if zero lda (_RLE_LOW),y beq @done iny bne @len_nowrap inc <_RLE_HIGH @len_nowrap: ; The run marker followed by $01 means itself cmp #$01 bcs @is_run lda <_RLE_TAG bcc @is_literal @is_run: tax ; X = length of run ; Output the most recent byte X times lda <_RLE_BYTE @runloop: sta _PPUDATA_2007 dex bne @runloop beq @decodeloop @done: rts