SPC7110 Decompression

Strictly for discussing ZSNES development and for submitting code. You can also join us on IRC at irc.libera.chat in #zsnes.
Please, no requests here.

Moderator: ZSNES Mods

Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

neviksti wrote:
Nach wrote:Is the return value the correct values to write to ($4809/A) ?
You don't need to write anything to those registers.
Well, "need" is a matter of how important accuracy is.
neviksti wrote: EDIT: Wait, did you mean for the emulator? The hardware can't tell how long the compressed data is. It doesn't write any compressed data length to those registers.
FEoEZ is reading from those registers and changing the next decompression request based on what is written there from the previous one.

I don't know if the documentation is correct that compressed length is written there, but something is, and we need to know what if we want accuracy.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

Another thing I need verified.

Does reading from $480B write to $4805/6?
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
byuu

Post by byuu »

$4809/a is most likely writing the decompressed data length. Makes it easier to set a loop that reads from $4800 until $4809/a = 0 or $ffff or whatever.
neviksti
Lurker
Posts: 122
Joined: Thu Jul 29, 2004 6:15 am

Post by neviksti »

Nach wrote:Another thing I need verified.

Does reading from $480B write to $4805/6?
My memory viewer, when looking at the registers, was constantly reading them. This would affect the values of $4811/12/13 and $4809/0A (well and $4800/$4810), but nothing else.

If I didn't access $4810, it looked like $4809/0A was decremented once for every byte read from $4800. You can write whatever you want to $4809/0A from SNES software, and that value doesn't appear to ever be "reset" or anything by hardware... the only changes are the decrementing.

Of course, I was not focussing on that at the time, so double checks would be useful. I am out of town for a wedding at the moment and can't run tests, so you will have to wait. Byuu made a mod that should also allow him to do tests if he feels comfortable with that (I don't think it will hurt your copier, but I can understand the reservations of risking it).
neviksti
Lurker
Posts: 122
Joined: Thu Jul 29, 2004 6:15 am

Post by neviksti »

Here's the remaining utilities:

Mode 1 is "meant" for 2 bitplane SNES graphics
Mode 0 is "meant" for word oriented data (say, tilemaps, or not considering correlations between bitplanes in graphics so it is only "single" bitplane)

win32 exe's
http://neviksti.com/SPC7110/CompMode0.exe
http://neviksti.com/SPC7110/CompMode1.exe
http://neviksti.com/SPC7110/DecompMode0.exe
http://neviksti.com/SPC7110/DecompMode1.exe

source
http://neviksti.com/SPC7110/CompMode0.c
http://neviksti.com/SPC7110/CompMode1.c
http://neviksti.com/SPC7110/DecompMode0.c
http://neviksti.com/SPC7110/DecompMode1.c


I didn't test these as much as the mode 2. But testing by compressing then decompressing datasets with random data it seems okay.
caitsith2
New Member
Posts: 8
Joined: Tue Aug 03, 2004 9:27 am

Post by caitsith2 »

Compressor code is completely BIT-PERFECT.
neviksti
Lurker
Posts: 122
Joined: Thu Jul 29, 2004 6:15 am

Post by neviksti »

caitsith2 wrote:Compressor code is completely BIT-PERFECT.
Awesome! Thanks for the testing.
Nightcrawler wrote:
Nach wrote:We do need compressors, so we can have the translation groups put in new locale/language graphics where appropriate.
Yes, that would be very helpful. I previously looked into doing the translation outside of the compressed graphics (before the chip was cracked) and space was certainly at a premium. I thought it should be possible to do, but difficult to say the least and some corners might need to be cut. It should be much more feasible with a working compressor and being able to utilize much of the same space the compressed graphics use already.
Nightcrawler,
I hope those utilities are acceptable. Good luck with your projects.

Should I upload these programs/code to romhacking.net? I never know what kind of stuff is reasonable for there. This is a very specific set of utilities.
I.S.T.
Zealot
Posts: 1325
Joined: Tue Nov 27, 2007 7:03 am

Post by I.S.T. »

Game specific utilities are allowed at RHDN.
Nightcrawler
Romhacking God
Posts: 922
Joined: Wed Jul 28, 2004 11:27 pm
Contact:

Post by Nightcrawler »

neviksti wrote: Nightcrawler,
I hope those utilities are acceptable. Good luck with your projects.

Should I upload these programs/code to romhacking.net? I never know what kind of stuff is reasonable for there. This is a very specific set of utilities.
Yeah, they look OK. I'm sorry I didn't get to test them (thankfully caitsith2 came through). I have closing for my house next week. It's practically been a second job to take care of that stuff.

Anyway, They're bit perfect, the code looks pretty readable, and that's all that really matters. Anything else would be minor.

Kammedo is supposed to be working on this translation, so hopefully I won't have to. It takes me so long to finish large projects anymore.

As for RHDN, I'd say almost anything you're involved with is reasonable! RHDN has many hardware docs, some homebrew material, and source code for things like this. Certainly submit whatever you have to RHDN. I'd recommend the same for SPC7110 documents. Anything on RHDN will be easily searchable and available to anyone who needs it. It will also be archived and preserved for the foreseeable future.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
Lord Nightmare
Rookie
Posts: 14
Joined: Fri Nov 26, 2004 7:50 pm
Location: PA, USA
Contact:

Post by Lord Nightmare »

neviksti: can you do some tests on the cart of what the result is of writes to those two registers nach mentioned are? I believe they might be important.

LN
"When life gives you zombies... *CHA-CHIK* ...you make zombie-ade!"
neviksti
Lurker
Posts: 122
Joined: Thu Jul 29, 2004 6:15 am

Post by neviksti »

Lord Nightmare wrote:neviksti: can you do some tests on the cart of what the result is of writes to those two registers nach mentioned are? I believe they might be important.

LN
I can run some tests if needed.
Can you be more specific though?

The only thing I saw about Nach asking what happens when you write to some registers is here:
Nach wrote:When writing to $4806 I need to verify some of what happens.
Is decompression done to $50:0000, $50:($4805,6), or $50:($4805,6)<<mode?
At this point is ($4805,6)<<mode written back to ($4805,6)?
What happens if the previous decompression wasn't fully processed and this is written to again?
I've had long discussions with Kammedo on this. Some keep referring to bank $50 as if the decompression results are stored there. I don't agree with that, and I have seen no reason to believe that bank $50 is anything more than just another access to reg $4800 (with the possible exception that it may need to be "enabled").

The notion of "decompression wasn't fully processed" goes along with that. The length of the decompression cannot be determined by the hardware ... it just responds byte by byte. It is not loaded somewhere which can be accessed randomly. (EDIT: Although I guess there could be issues while the hardware is trying to seek forward a fixed offset into the decomp data, and you go to start another decomp while it is in the middle of this. Since resetting should be an unconditional thing, I doubt it causes any problems... but I have not checked either though.)

Maybe someone has found something that I didn't, but that is how I understand it. Also, the cost of implementing the RAM for that feature, which doesn't have much use, would be wasteful so I really doubt there is anything more than something that lets you read out the decompressed stream byte by byte.

I think Nach already knows all this now, so maybe you are referring to something else?

This also refers to the results of writing some regs:
Nach wrote:How does $480C work? When is the bit there set and cleared?
Is the bit set when there is a write to $4806, and then cleared when there is a read, or perhaps a full read from $4800? Reading from $480C sets ($4809,A) immediately after a write to $4806 or only after the decompression is finished?
I believe this works exactly as the docs suggest. A new decompression is setup after writing to $4806. After the hardware FIFO or buffer or whatnot (the internal details don't matter here) has enough of the requested data that it is ready for the software to start pulling decomp data from it, it sets the bit in $480C. The bit is clear until then. This much I have tested.

My recollection is (don't consider this verified):
It is cleared after being read once while set. TheDumper and DarkForce mentioned similarly.

What I don't know is:
Is this bit cleared by anything else? (starting a new decomp, or reading from $4800)
Is that what you want? The doc already explains more than I've tested myself on that.


The quickest way for me to do tests, is give me a list of reg reads / writes you want me to do and I'll tell you the results. Otherwise I may misunderstand what you want.
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

After playing with things almost every which way I could think of, I do understand how things work much better now. But some of the docs don't seem to be correct or are too ambiguous, we need it tested.

When is $480C set? Some time after $4806 is written to? Does $480C have to be read before it's written? (that's how emulators seem to do it today). Do larger values in $4805/6 make it take longer for it to set $480C?

What happens when reading from $4800 and $4806 was never written to? Or what if it was written to but $480C wasn't set yet?

Can one write to $4800? Does it do anything?

What effect does the values written to $480B have on the other registers listed above?

Is $4809/A even written to decompression side aside from the constant subtraction? Does writing to $4806 or reading $480C affect it in anyway?
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
byuu

Post by byuu »

Do larger values in $4805/6 make it take longer for it to set $480C?
I would truly be shocked if that were not the case. There's absolutely no way in hell it can either skip ahead in the compressed input or decompress up to 64kbytes immediately.

The bad news is this puts us in the same situation as the DSP-1. To emulate that properly (counting $480c reads is cheap and dangerous), we'd have to give the SPC7110 its own clock. And that's going to be painful.
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

byuu wrote:
Do larger values in $4805/6 make it take longer for it to set $480C?
I would truly be shocked if that were not the case. There's absolutely no way in hell it can either skip ahead in the compressed input or decompress up to 64kbytes immediately.
I also would be surprised, but the time it takes may relate to the compression ratio of the bytes in question, and not the amount of bytes to skip.
byuu wrote: The bad news is this puts us in the same situation as the DSP-1. To emulate that properly (counting $480c reads is cheap and dangerous), we'd have to give the SPC7110 its own clock. And that's going to be painful.
Not necessarily. If the only clock involved is the amount of time from $4806 write to $480C being able to return a ready bit, and output skip time to SNES clock ratio was a constant, then we can emulate it the output very simply.

Code: Select all

$4806w:
...
skip_amount = 16($4805);
start_clock = snes.clock;

$480Cr:
...
diff_clock = snes.clock - start_clock;
bit = diff_clock >= skip_amount/snes_clock_ratio;
If it's not a constant skip amount to SNES clock, which is more likely, and tied to the compression ratio, we'd have to modify the decompressor to keep track of how many bits/bytes it pulled in so far, get the compression ratio, and change the ratio to SNES clock based on that.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
Post Reply