Some tidbits about the Cx4 (attn: byuu, nocash)

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Optiroc
Posts: 129
Joined: Thu Feb 07, 2013 1:15 am
Location: Sweden

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by Optiroc »

Ikari: Do you plan to implement any way of loading custom Cx4 code with SD2SNES? For example by using the format byuu proposed here.
AWJ
Posts: 433
Joined: Mon Nov 10, 2008 3:09 pm

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by AWJ »

The Cx4 "firmware" is nothing but trig and reciprocal lookup tables. The actual program is entirely in the external ROM. I suspect you could construct lookup tables programmatically at startup (or even at compile time with what modern C++ allows in a constexpr) that exactly match the internal ROM's; you would just have to be careful about rounding.
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by Near »

The Cx4 is unique in that it's the only SNES cartridge firmware that we could legally distribute with emulators, since you can't copyright math constants.

The one advantage of allowing the firmware to be separate would be if you wanted to use your own data ROM instead. As it's ROM data, there's no reason it couldn't be changed at manufacturing time ala the NEC uPD DSPs, but it would certainly be much less important since it's only the dat ROM.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by nocash »

Good findings! Including some really unexpected low-level stuff... how did you figure out the "cache page lock" and "Suspend Cx4 for NN cycles" features - just by examining cpu's code execution timings?

Are port 7F40h and up R/W? Most of the 7F4xh registers are only known to be writeable, but reading might work as well?

Or better, what about the whole 6C00h..7FFFh area? Is there anything read-able in there, mirrors or so?

What happens on reading unused bits (eg. 2 unused bits in the waitstate register, etc.)? Do they always return zero or so? And did you test if they ignore attempts to write different values to them?

Did you check if 7F60h and up can change expception vectors other than NMI/IRQ? Might also support COP/BRK, and possibly also exception vectors in 6502-emulation mode.
And when are those vectors mapped to FFExh, is there an enable bit for that? Or they just mapped anytime when the CX4 is busy (and unmapped when it's ready)?

For Port "$7f53: READ (mirrors: $7f54-$7f57, $7f59, $7f5b-$7f5f)", the official address should be 7F5Eh (the games are using that address to test the busy flag in bit6), ie. 7F53h should be treated as "mirror" of 7F5Eh. (That of course, for READing only) (the 7F53h WRITE description should be kept as is).
NB. the games are testing 7F5Eh.bit6 not only for "CPU running", but also for "DMA running" or "Cache load running", so it seems to be a more general busy flag, not solely for CPU code execution.

Having the 7F52h ROM config description is nice (there has been a bunch of conflicting info whether one should write 00h or 01h to 7F48h or 7F52h for mapping two ROMs), but it's much clearer. Oh, only, the notation in your txt is slightly confusing for that port, everywhere else "0: and 1:" are used for "bit0 and bit1," but I guess here they do mean "set bit0 to 0 or 1", right?
For 2x16Mbit ROM, did you also tested if A23 toggles between /CE1 and /CE2 in LoROM mode? Aside from A22, that would be the other possible address line for mapping more than 2Mbyte LoROM.

---

And, for the CPU operands...

"PC of current instruction + 1" is that the 8bit program counter, or the whole 24bit address? In the cx4-style NNNN:NN notation (rather than SNES-style NN:NNNN notation)?
And then, "+1" means plus one 16bit word, ie +2 bytes, right?

"$28: ??? (always seems to return $2e)" that's (as known so far) unrelated to operand number 2Eh? And just returns a (seemingly) constant value of 00002Eh? Might be some internal status value. Btw. if there's a way to read PC, did you check if one could read SP for call/ret stack, too?
User avatar
ikari_01
Posts: 141
Joined: Sat Jul 04, 2009 2:28 pm
Location: Wunstorf, Germany

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by ikari_01 »

nocash wrote:Good findings! Including some really unexpected low-level stuff... how did you figure out the "cache page lock" and "Suspend Cx4 for NN cycles" features - just by examining cpu's code execution timings?
I actually figured out cache page lock when first doing the Cx4 core for the sd2snes. It kept working improperly and the game made use of $7f4c in the corresponding places... I was like "hm, this could only work if the cache behaved something like this..." and at one point it became clear.

The suspend feature was found by accident shortly before posting my notes when messing around with the DMA feature. Before finding out that $7f47 is actually just the destination bank number instead of some mode setting register I wondered why it locked up for certain values. One idea was that it might be used to "DMA" values poked by the S-CPU to a specific register so I started poking some registers during lockup and found that for $7f56-$7f5c the SNES address appeared on the ROM data bus instead of the Cx4 bus address for a number of different durations. This also conveniently explained the bit 0 flag in $7f5e getting set not only for $7f55 writes but also $7f56-7f5c.
nocash wrote:Are port 7F40h and up R/W? Most of the 7F4xh registers are only known to be writeable, but reading might work as well?
Or better, what about the whole 6C00h..7FFFh area? Is there anything read-able in there, mirrors or so?
What happens on reading unused bits (eg. 2 unused bits in the waitstate register, etc.)? Do they always return zero or so? And did you test if they ignore attempts to write different values to them?
$6000-$6bff is fully r/w (3kB RAM)
$6c00-$6fff returns random values with a bit of noise.
$7000-$7bff is fully r/w (mirror of $6000-$6bff)
$7c00-$7f3f returns the same kind of garbage as above.
$7f40-$7f52 reflect the values written but only for the bits actually used. All other bits are read as 0. (e.g. writing $ff to $7f52 will result in $7f52 reading $01.)
$7f60-$7f7f is fully r/w. (vector area)
$7f80-$7faf is fully r/w. (16x24bit registers)
$7fb0-$7fbf is always 0.
$7fc0-$7fef is fully r/w. (mirror of $7f80-$7faf)
$7ff0-$7fff is always 0. (mirror of $7fb0-$7fbf)

The "random" pattern for the unmapped work RAM areas ($6c00-$6fff, $7c00-$7fff) is a bit strange, it is a 32 byte pattern repeating itself.
nocash wrote:Did you check if 7F60h and up can change expception vectors other than NMI/IRQ? Might also support COP/BRK, and possibly also exception vectors in 6502-emulation mode.
And when are those vectors mapped to FFExh, is there an enable bit for that? Or they just mapped anytime when the CX4 is busy (and unmapped when it's ready)?
$7f60-$7f7f is always mapped to $ffe0-$ffff while the Cx4 is busy and always unmapped when it is idle. All 32 bytes can be used. There is no separate enable flag.
Also $7f40-$7f5f is always mapped to $ffc0-$ffdf while the Cx4 is running, whatever that may be good for :)
nocash wrote:For Port "$7f53: READ (mirrors: $7f54-$7f57, $7f59, $7f5b-$7f5f)", the official address should be 7F5Eh (the games are using that address to test the busy flag in bit6), ie. 7F53h should be treated as "mirror" of 7F5Eh. (That of course, for READing only) (the 7F53h WRITE description should be kept as is).
I wonder. I think I've seen MMX2 poll $7f56 in one occasion, might have been the Cx4 tests though.
nocash wrote:NB. the games are testing 7F5Eh.bit6 not only for "CPU running", but also for "DMA running" or "Cache load running", so it seems to be a more general busy flag, not solely for CPU code execution.
True, and these other actions also affect the IRQ flag.
nocash wrote:[$7f52]Oh, only, the notation in your txt is slightly confusing for that port, everywhere else "0: and 1:" are used for "bit0 and bit1," but I guess here they do mean "set bit0 to 0 or 1", right?
For 2x16Mbit ROM, did you also tested if A23 toggles between /CE1 and /CE2 in LoROM mode? Aside from A22, that would be the other possible address line for mapping more than 2Mbyte LoROM.
Oops, yes, it's the value 0 or 1 for bit 0. Going to correct that too.
A23 does nothing unfortunately so it really seems the cap for LoROM is 16Mbits.
nocash wrote:"PC of current instruction + 1" is that the 8bit program counter, or the whole 24bit address? In the cx4-style NNNN:NN notation (rather than SNES-style NN:NNNN notation)?
And then, "+1" means plus one 16bit word, ie +2 bytes, right?
It is the 8-bit program counter within the cache page, so it reads 0000NN. I don't know yet what happens when reading the register at PC=$ff. "+1" means one instruction so one 16-bit word :)
nocash wrote:"$28: ??? (always seems to return $2e)" that's (as known so far) unrelated to operand number 2Eh? And just returns a (seemingly) constant value of 00002Eh? Might be some internal status value. Btw. if there's a way to read PC, did you check if one could read SP for call/ret stack, too?
I see no obvious connection to operand $2e, though I haven't tried writing to $28 yet. Regarding the stack pointer, all other operands in the 00-ff range, save for the constants and other documented ones, have read 000000. I shall try manipulating the stack (e.g. call) and do another readout some time.
User avatar
ikari_01
Posts: 141
Joined: Sat Jul 04, 2009 2:28 pm
Location: Wunstorf, Germany

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by ikari_01 »

Also, while the Cx4 is busy, from the SNES's perspective:

- when Cx4 CPU is running or DMA to internal RAM in progress, $6000-$7f3f return $ff
- when Cx4 CPU is running (but not when DMA takes place) $7f80-$7faf and $7fc0-$7fef return various things, sometimes R0 is repeated throughout, sometimes it changes wildly. Could be the current contents of the CPU's IDB.
- when Cx4 is accessing the bus (in any way), ROM/cartRAM reads return $00.
qwertymodo
Posts: 775
Joined: Mon Jul 02, 2012 7:46 am

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by qwertymodo »

In LoROM, you could probably get 24 MBit ROM with a 16MBit ROM1 and 8MBit ROM2 and "bank switching" the second half of ROM1 and all of ROM2 in the upper half of the ROM address space (I forget which register that is, but there's the one that switches between 1x16 and 2x8).
User avatar
ikari_01
Posts: 141
Joined: Sat Jul 04, 2009 2:28 pm
Location: Wunstorf, Germany

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by ikari_01 »

That should actually work. Crafty!
qwertymodo
Posts: 775
Joined: Mon Jul 02, 2012 7:46 am

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by qwertymodo »

Good luck deciding how to map the resulting ROM file for emulation though ;)
Last edited by qwertymodo on Sun Aug 14, 2016 11:41 pm, edited 1 time in total.
User avatar
ikari_01
Posts: 141
Joined: Sat Jul 04, 2009 2:28 pm
Location: Wunstorf, Germany

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by ikari_01 »

And another one: $7f58 and $7f5a always read as $00.
Revenant
Posts: 462
Joined: Sat Apr 25, 2015 1:47 pm
Location: FL

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by Revenant »

Some things I'm curious/unclear about after reading these notes:

- Does reading registers $2e/$2f using other register read instructions (i.e. $602e instead of $612e) still get meaningful data from the bus somehow (after waitstates)?
- Does writing $2f using a register write instruction allow writing to the bus from e.g. the A register instead of ext_dta?
- Does reading/writing other registers using $61xx/e1xx still use/change the value of ext_dta?
Revenant
Posts: 462
Joined: Sat Apr 25, 2015 1:47 pm
Location: FL

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by Revenant »

Anyway, I've started implementing these timing notes in bsnes-plus. Program page caching (and preloading), wait states, the RAM/ROM ports, and various other register and memory changes are in so far.

Here's the current state of the MMX2 attract demo:
https://www.youtube.com/watch?v=sYyPDf49JAQ

Definitely an improvement, although it still seems a little wonky. I don't have a real cartridge for comparison, so I can't tell how much of the things happening in the video are timing mistakes on my part or just normal gameplay mistakes.
User avatar
FitzRoy
Posts: 144
Joined: Wed Oct 22, 2008 9:27 pm
Contact:

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by FitzRoy »

Revenant wrote:Definitely an improvement, although it still seems a little wonky. I don't have a real cartridge for comparison, so I can't tell how much of the things happening in the video are timing mistakes on my part or just normal gameplay mistakes.
I dunno, my first impression is.. that could be perfect. Mega Man survives the whole ordeal and the scene ends with him about to deliver a killing blow. Need someone with the cart to do a recording.
fred
Posts: 67
Joined: Fri Dec 30, 2011 7:15 am
Location: Sweden

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by fred »

Got a friend with a rockman X2 cart who did a quick recording: https://youtu.be/F_P7I3dqj30
For some reason the capture occasionally drops to 30 fps recording, but i hope it's servicable still.
Revenant
Posts: 462
Joined: Sat Apr 25, 2015 1:47 pm
Location: FL

Re: Some tidbits about the Cx4 (attn: byuu, nocash)

Post by Revenant »

Thanks for the recording! I didn't compare frame-by-frame or anything but I'm surprised to see that my attempt so far seems to be pretty much right on target.

I guess tonight I'll push the current WIP branch to github tonight after I finish tweaking a couple of other things. There's still some other stuff (mostly w/r/t memory mapping details) from the notes in this thread that I haven't implemented yet but I guess the majority of the crucial stuff is there now.

(edit: https://github.com/devinacker/bsnes-plus/tree/cx4)

Big thanks to ikari for researching and documenting all this stuff, too.
Post Reply