The way the format works is like this. Say you have these bytes:
Code: Select all
00 ff 00 00 ff ff 00 00 00 00 00 00 ff ff ff ff ff ffAn FF is appended at the end to mark where the routine should stop copying, so the output would be:
Code: Select all
01 00 01 ff 02 00 02 ff 06 00 06 ff ffCode: Select all
#!/usr/bin/env python3
# basic rle compression program
# by nicklausw
# this format works as follows.
# one byte is read, and that is
# how many of the next byte to copy over. repeat.
# when the first byte is $ff, the copy is done.
import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("in_file", help="the chr data to be rle'd")
parser.add_argument("out_file", help="the rle'd output")
args = parser.parse_args()
f_in = open(args.in_file, 'rb')
f_out = open(args.out_file, 'wb')
# python doesn't need variable initialization i think,
# but for clarity's sake.
byte_n = 0 # byte
byte_c = 1 # byte count
for c in f_in.read():
if c != byte_n or byte_c == 0xFE:
f_out.write(bytes([byte_c]))
f_out.write(bytes([byte_n]))
byte_c = 1
byte_n = c
else:
byte_c += 1
# now catch the last time around
f_out.write(bytes([byte_c]))
f_out.write(bytes([byte_n]))
# the end mark
f_out.write(bytes([0xFF]))
f_in.close()
f_out.close()
Code: Select all
.proc rle_copy_ppu
setxy16
seta8
ldy #$00
loop:
seta8
lda (rle_cp_ram), y
cpa #$ff
beq done
seta16
and #$ff
tax
iny
seta8
lda (rle_cp_ram),y
jsr rle_loop
iny
jmp loop
done:
rts
rle_loop:
seta16
;and #$ff
loop2:
sta PPUDATA
dex
bne loop2
rts
.endprocCode: Select all
; copy font
setaxy16
stz PPUADDR ; we will start video memory at $0000
lda #font
sta rle_cp_ram
jsr rle_copy_ppu
And this is the actual output:

I'll give more info on my code if need be, but can anyone see anything wrong that might cause an error in things being copied over?