I finally came up with a decompression routine in 6502 for my C++ program RLE. I've tested things, and Tepples' PackBits is more efficient than my byte-for-byte compression, but I thought I would post this anyway, just in case it might help others in their endeavors.
First, I'll explain my C++ RLE prog. It's VERY basic in how it's implemented. It's just a program that takes the bytes in a file, and adds the count of each byte in front of the bytes that repeat; this is the most basic RLE that I know of, and probably is. Example:
$00,$00,$00,$00,$17,$11,$ad,$ad,$ad,$00,$00,$00,$00,$00,$00,$00
Compressed with the most simple of RLE would be:
$04,$00,$01,$17,$01,$11,$03,$ad,$07,$00
This is exactly what my C++ prog does. Anyway, Wikipedia offers a VERY easy to understand definition of run-length encoding, so check this out (this is for any newer folk that haven't learned any compression yet) This will explain what I posted above in much better wording:
http://en.wikipedia.org/wiki/Run-length_encoding
It doesn't look like much for compression, but if you have many repeating tiles, it can be useful. Anyway, it took me a while to come up with a decent decompression scheme, mainly because I overlooked one stupid flaw that I was doing in it. Here is how I handle decompressing this in 6502:
Like the name of the topic, I haven't pushed this past being more than 256 bytes. Sue me, I'm new to compression haha
I think this SHOULD be readable, and I hope it is since it's such basic structure, but if anyone is confused, let me know and I will try to comment it further. Basically, you load a byte, check to see if it's the amount of times you put a tile down, or if it's the tile number, and repeat. I have been told that this code looks convoluted though, so I may just be jaded because I've looked at it alot : P
Also, it uses all 3 registers, so if anyone here has anything they'd like to add to the algorithm that could speed it up and preserve one of them, please do!
First, I'll explain my C++ RLE prog. It's VERY basic in how it's implemented. It's just a program that takes the bytes in a file, and adds the count of each byte in front of the bytes that repeat; this is the most basic RLE that I know of, and probably is. Example:
$00,$00,$00,$00,$17,$11,$ad,$ad,$ad,$00,$00,$00,$00,$00,$00,$00
Compressed with the most simple of RLE would be:
$04,$00,$01,$17,$01,$11,$03,$ad,$07,$00
This is exactly what my C++ prog does. Anyway, Wikipedia offers a VERY easy to understand definition of run-length encoding, so check this out (this is for any newer folk that haven't learned any compression yet) This will explain what I posted above in much better wording:
http://en.wikipedia.org/wiki/Run-length_encoding
It doesn't look like much for compression, but if you have many repeating tiles, it can be useful. Anyway, it took me a while to come up with a decent decompression scheme, mainly because I overlooked one stupid flaw that I was doing in it. Here is how I handle decompressing this in 6502:
Code:
lda #$20
sta $2006
ldx #$00
stx $2006
stx odd_even
compressed_screen:
lda compressed_nametable,x ; Grab the first byte from the
tay ; nametable indexed by X, then
lda odd_even ; stick that in Y. Test if odd_even
bne tile_number ; is 0 or 1. If it's 0, keep going
; and stick Y in 'number_of_tiles',
sty number_of_tiles ; increment odd_even to 1 so on
inc odd_even ; the next pass it will skip this
inx ; portion of code, and increment
jmp compressed_screen ; X. Jump back to compressed_screen
; if you got to that point.
tile_number: ; If odd_even was 1, stick Y in
sty the_tiles ; 'the_tiles'. This is the actual place
ldy number_of_tiles ; you find the tiles in your chr. Load
: lda the_tiles ; Y with how many tiles there are
sta $2007 ; and stick all of them in $2007
dey ; until Y is expired. Decrement
bne :- ; odd_even to put it back to 0,
dec odd_even ; increment X for the overall file read
inx
cpx #$60 ; and test for the size of the compressed file
bne compressed_screen ; if it doesn't pass the test, go back
; to the beginning and keep reading
sta $2006
ldx #$00
stx $2006
stx odd_even
compressed_screen:
lda compressed_nametable,x ; Grab the first byte from the
tay ; nametable indexed by X, then
lda odd_even ; stick that in Y. Test if odd_even
bne tile_number ; is 0 or 1. If it's 0, keep going
; and stick Y in 'number_of_tiles',
sty number_of_tiles ; increment odd_even to 1 so on
inc odd_even ; the next pass it will skip this
inx ; portion of code, and increment
jmp compressed_screen ; X. Jump back to compressed_screen
; if you got to that point.
tile_number: ; If odd_even was 1, stick Y in
sty the_tiles ; 'the_tiles'. This is the actual place
ldy number_of_tiles ; you find the tiles in your chr. Load
: lda the_tiles ; Y with how many tiles there are
sta $2007 ; and stick all of them in $2007
dey ; until Y is expired. Decrement
bne :- ; odd_even to put it back to 0,
dec odd_even ; increment X for the overall file read
inx
cpx #$60 ; and test for the size of the compressed file
bne compressed_screen ; if it doesn't pass the test, go back
; to the beginning and keep reading
Quote:
; This represents the size of the compressed file
Like the name of the topic, I haven't pushed this past being more than 256 bytes. Sue me, I'm new to compression haha
I think this SHOULD be readable, and I hope it is since it's such basic structure, but if anyone is confused, let me know and I will try to comment it further. Basically, you load a byte, check to see if it's the amount of times you put a tile down, or if it's the tile number, and repeat. I have been told that this code looks convoluted though, so I may just be jaded because I've looked at it alot : P
Also, it uses all 3 registers, so if anyone here has anything they'd like to add to the algorithm that could speed it up and preserve one of them, please do!