.code ; Written by Joel Yliluoma in 2012. http://iki.fi/bisqwit/ ; Contains no relocations. ; src_addr and dst_addr must be two zeropage pointers. ppu_send_rleinc: ; Copy stream from CPU memory @ src_addr -> PPU dst_addr ; src_addr need not be aligned in any particular way ; stream is terminated by indication within stream ; Input byte c = 0..3F: ; Put next c+0x01 bytes verbatim, except BACKWARDS ; Input byte c = 40: ; End stream ; Input byte c = 41..7F: ; Read byte b, put byte b ; Put next c-0x40 bytes increasing b by 1 before every write ; Input byte c = 80..FF: ; Read byte b ; Put b, (0x101-c) times ; src_addr is updated to point after the data. ; dst_addr is not modified. bit $2002 ; Load the destination address lda dst_addr+1 sta $2006 lda dst_addr+0 sta $2006 ldy #0 beq @loop @do_rle: ; 80..FF. Carry is set. ror a ; Clears carry. tax dex lda (src_addr),y @rle_loop: sta $2007 inx bne @rle_loop @add2_loop: lda #2 ldy #0 @add_loop: ;clc adc src_addr sta src_addr bcs @src_wrap @loop: lda (src_addr),y iny asl a bcs @do_rle ; bit 7 was set bmi @do_inc ; bit 6 was set (now bit 7) ;@do_lit: lsr a ; clears carry ; 0..3F adc #1 tay ; Y = value+1 tax @lit_loop: ; Literal text is sent BACKWARDS! lda (src_addr),y sta $2007 dey bne @lit_loop ; terminate when Y=0 inx txa ; A = value+2 bne @add_loop @src_wrap: inc src_addr+1 bne @loop @do_inc2: tax ; Get first byte, put it in Y lda (src_addr),y tay @inc_loop: sty $2007 iny dex bpl @inc_loop bmi @add2_loop @do_inc: ; 40..7F. Carry is clear. ror a ; Clears carry. and #$3F bne @do_inc2 inc src_addr+0 bne @ok inc src_addr+1 @ok: rts