Post by hydrophilic on Jul 24, 2014 6:14:50 GMT
It looks like you are doing the correct waiting, and I don't think read order is important. So hoepfull this bug is all that needs to be fixed:
which should be
in short, change the last line from STA to STY.
Also, you were storing count-1 into the VDC copy length. This is correct for Fill, but I think the actual value should be used for Copy. I haven't played with this myself, so I pulled out the C128 Programmer's Reference Guide and it says the value -1 must be used for Fill, but it says absolutely nothing about Copy... well in the register description section... further searching found a short paragraph describing block copy and it says the value (not -1) must be used.
At first I thought you were doing your calculations wrong, but on further review they seem correct; I was confused because your code uses the label "destination" to refer to the "source".
Edit
I probably shouldn't say this until the current version is working bug-free, but might as well point it out now before I forget
So this two related ideas; the copy source is probably too limited (can only go back 63 bytes in the general case), and the bit allocation is wasteful.
As I understand your current implementation, it is like this:
%nnnnnn00 = end of file
%nnnnnn01 = raw data
%nnnnnn11 = copy data
%nnnnnn10 = RLE data
You are waisting quite a few bits just to implement end-of-file. I think it would be better to use raw data (%nnnnnn01) with an N value of 0 for end-of-file... of course this means you could not have 256 bytes of raw data. I guess you would need to try compessing several images to see how useful 256 is. Assuming this change is acceptable, then I think a better implementation would be:
%nnnnnn00 = raw data (n=0 end of file)
%nnnnnn10 = RLE data
%nnnnnn01 = short copy (like current)
%dddddd11 = long copy, followed by byte %nnnndddd
The "long copy" would take the next byte of data containing a "high byte" (well bits) for the distance, and a length. This allows a distance upto 1024 bytes backward, but only 0 to 15 (or better 3 to 18) bytes to be copied. I don't know how much difference there is between VDC and VIC-II compression statistics, but for VIC-II, a limit of 63 bytes backward is only occassionaly useful. Only 15 (or 18) bytes might not sound very useful, but most copy lengths in the the many thousands of images I've tested (video, you know) are less than 8 bytes. In other words, the extra byte of "long copy" might be better defined as %nnnddddd which would limit length to 3 + (0 to 7) but allow a range upto 2048 bytes.
Finally, your implementation is not skipping bytes ever. That's okay because its not really important for a single image (very important in a video).
@not1 tax ;copies -x bytes forwords +bytes
bne @not2 ;is it 0
ldy #$01 ;set high byte to 1 if zero
@not2 sta destination ;low byte
sta destination+1 ;high byte
which should be
@not1 tax ;copies -x bytes forwords +bytes
bne @not2 ;is it 0
ldy #$01 ;set high byte to 1 if zero
@not2 sta destination ;low byte
sty destination+1 ;high byte
in short, change the last line from STA to STY.
Also, you were storing count-1 into the VDC copy length. This is correct for Fill, but I think the actual value should be used for Copy. I haven't played with this myself, so I pulled out the C128 Programmer's Reference Guide and it says the value -1 must be used for Fill, but it says absolutely nothing about Copy... well in the register description section... further searching found a short paragraph describing block copy and it says the value (not -1) must be used.
At first I thought you were doing your calculations wrong, but on further review they seem correct; I was confused because your code uses the label "destination" to refer to the "source".
Edit
I probably shouldn't say this until the current version is working bug-free, but might as well point it out now before I forget
So this two related ideas; the copy source is probably too limited (can only go back 63 bytes in the general case), and the bit allocation is wasteful.
As I understand your current implementation, it is like this:
%nnnnnn00 = end of file
%nnnnnn01 = raw data
%nnnnnn11 = copy data
%nnnnnn10 = RLE data
You are waisting quite a few bits just to implement end-of-file. I think it would be better to use raw data (%nnnnnn01) with an N value of 0 for end-of-file... of course this means you could not have 256 bytes of raw data. I guess you would need to try compessing several images to see how useful 256 is. Assuming this change is acceptable, then I think a better implementation would be:
%nnnnnn00 = raw data (n=0 end of file)
%nnnnnn10 = RLE data
%nnnnnn01 = short copy (like current)
%dddddd11 = long copy, followed by byte %nnnndddd
The "long copy" would take the next byte of data containing a "high byte" (well bits) for the distance, and a length. This allows a distance upto 1024 bytes backward, but only 0 to 15 (or better 3 to 18) bytes to be copied. I don't know how much difference there is between VDC and VIC-II compression statistics, but for VIC-II, a limit of 63 bytes backward is only occassionaly useful. Only 15 (or 18) bytes might not sound very useful, but most copy lengths in the the many thousands of images I've tested (video, you know) are less than 8 bytes. In other words, the extra byte of "long copy" might be better defined as %nnnddddd which would limit length to 3 + (0 to 7) but allow a range upto 2048 bytes.
Finally, your implementation is not skipping bytes ever. That's okay because its not really important for a single image (very important in a video).