53 Frames a second!
I have my new one byte encoder/decoder and am now pushing 53 frames a second with vsync off.
It has Run Length, Differential and Tri Pixel Encoding.
With Vsync the video plays almost perfectly in sync down to the second.
The one byte encoder has the average bytes per frame down to 402 from 472.
20:1 compression ratio.
I am not using any kind of read buffer. I still stream off the SD card with just a VIA.
So one benefit of this encoding scheme is that since SD cards stream the bits highest to lowest I get to do this:
Code: Select all
; Load Control Bit 1
lda VIA_PORTA; Read bit 8 of byte from SD card.
bne .SkipRun ; If 1 Skip Pixels
; Load Control Bit 2
lda VIA_PORTA ; Else check bit 7
bne .RLE ; If 1 Repeat Pixels
jmp .TriPixel ; Else TriPixel
.SkipRun: ;Just add this amount to the screen pointer
; Load 7 bits for a skip value up to 127
This is neat because now I don't have shift these control bits like this:
That makes the decoder routine up there just about the fastest thing I can figure out to do.
I need some way to keep track of bytes because SD cards have 10 CRC bytes every 512 bytes.
I don't want to waste decode time counting bits, so I compromised and kept everything encoded with 8 bits.
For skips I get to use 7 bits and skip up to 127. Skip is used a lot and can span lines.
I already only need 6 bits to encode the 64 lookup values for the 'TriPixel' runs of 3 pixels so good there.
That means that a repeat can only be 6 bits and a max of 64 also. Less than ideal.
But, since the screen is only 100 pixels wide and the end of every line has a minimum of 28 pixels to skip, IE a full black or white fill will have a skip byte at the end of all 64 lines, you are at worst using two bytes to fill the line.
The old two byte routine was already using two bytes to do that and since the end of every line has a skip you were never filling more than 100 pixels with a 2 byte update anyway.
Add to that the fact that usually you are not filling more than half the screen with any given color and that 64 repeat is not so limiting.
With this simple routine I got down to 2,569 KB from 50MB of uncompressed frames. This shaved around 500KB from my previous best. It also added almost 7 frames per second to the average framerate for the faster decode and reduced bit reads.
Even better is that it lowered the number of frames that missed vsync by quite a lot. There is almost no visible 'rubber banding' and the only way to tell it happens at all is to play it side by side with a mp4 on my PC.
So now I think I have just about the fastest SD card read possible with a plain VIA, and I think I have just about the fastest possible greyscale decoder for a 6502+Worlds Worst Video card. ( prove me wrong

)
And while I really would love any tips or hints for improvements, I think I am about done with this portion.
I was afraid that the buffer would be too small given the overhead of writing to the buffer and then pulling from it and that it would end up slowing it down in problem areas and not helping anywhere else.
But now that I have lowered the bytes per frame and increased the decode speed that 7.5KB of ram I have available (if I put the decoder in ROM) might be enough to actually improve the 30 FPS lock.
I still need to finish up VIA square wave music as well for a proper demo as well, but the heavy lift of this encoder/decoder seems to be done.
https://github.com/Fifty1Ford/Ben-Eater ... 1Byte7.asm
https://github.com/Fifty1Ford/Ben-Eater ... w1Byte7.py