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

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
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 » Sun Sep 09, 2018 6:18 pm

Wow, some interesting questions here. I'm going to answer part of it for now, can't tackle all at once :)

First of all, WS1+WS2 should probably be referred to as just "waitstates" or "extra clocks per cycle". The two games set these to 4, and as a result the Cx4 accesses ROM at 4MHz. (20MHz / 5).
The power-on default is 3 for both, thus it would access ROM and RAM at 5MHz. I can take logic analyzer traces of all that if required (which is what I did in the first place to determine waitstates, measure instruction times, etc... but I did not save the traces so I'd need to record them again.)


The DMA transfers work as described by nocash (simultaneous for independent buses, sequential for same bus).
DMA would usually take place between cartridge ROM and internal RAM, or internal RAM and cartridge RAM.

Small discourse that might deserve a thread on its own:
SNES DMA actually also works the way nocash described :)
Source and destination addresses are put on their respective buses simultaneously and RD+PAWR or PARD+WR are asserted depending on DMA direction.

For a memory write cycle, data usually only has to be valid a short period of time before and during the rising edge (i.e. end) of the write strobe (like 30ns or so). Thus the source has plenty of time during the active period of the cycle to put its data on the bus before it is required at the destination.
There seems to be an extra cycle before every DMA block (usually with a bogus address on the buses, and with no read or write control signals asserted) but I don't know what that's for.

So far I cannot confirm an extra cycle of overhead per HDMA channel, usually I'm just seeing one extra cycle before all HDMA channels fire in a row. Of course it would need to pause to fetch a new pointer from an indirect table, or a new count value, but as long as that isn't happening there don't seem to be any extra cycles.
Then there's the seemingly arbitrary prolongation of the previous CPU cycle, which actually just pads out to the next multiple of 8 master clocks since reset. I overlaid the RGB signal with PAWR so the B bus writes actually became visible, and HDMA is always nicely lined up in a vertical row, surrounded by regular CPU cycles jittering about around it. It recently turned out that it's important to keep phase relationship between DMA access and dot clock but that's a different topic... (maybe anybody saw the Chrono Trigger frog glitch in the demo roll, or flickering pixels around sprites in Star Ocean or Kirby Super Star... https://github.com/RedGuyyyy/sd2snes/issues/6)


Anyway, back to topic:
byuu wrote: Is it confirmed in LoROM mode that the Cx4 bus can't see ROM at $c0-ff:0000-ffff?
Just re-checked, the following regions are open bus:
C0:0000-FF:FFFF
40:0000-6F:FFFF
70:8000-77:FFFF (70:0000-77:7FFF is cartridge RAM)
78:0000-7D:FFFF

byuu wrote: Does writing to $7f53 get the Cx4 out of a lockup from a bad DMA transfer as well?
A bad DMA transfer just seems to keep the CPU stalled in memory access ($7f53 bits 7 and 6 are set). Writing to $7f53 clears those bits and you can talk to the Cx4 again.
byuu wrote: What happens if I start a DMA or cache page operation while the Cx4 is active? Will it take priority over the Cx4 instruction processing, stay pending until the Cx4 instructions are halted, or just do nothing?
It simply ignores DMA or cache page triggers as long as $7f53.6 is set. It does not execute them afterwards. It does accept all the register values though, so you could prepare everything, then just trigger DMA or cache page as soon as the Cx4 becomes idle.

Gotta catch some sleep now ;)

nocash
Posts: 1211
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

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

Post by nocash » Wed Sep 12, 2018 3:15 pm

I am still wondering if one can use operand=00h to access "Register A" or not. The question (and answer) affects many opcodes, almost everything that doesn't use immediates as parameter. At the moment, my emulation is allowing operand=00h for A, if that's wrong then I could change that, but it would be nice if somebody could confirm if it's really wrong.

And, I am wondering about CartROM vs CartRAM... especially about three different cases:

For DMA one does simply specify different src/dst addresses to select between CartROM/CartRAM (eg. without needing to set a SoureType=CartRAM flag or so), right?

For Program Code/cache loading, does that work, too? Allowing to execute code that comes from CartRAM? Would be interesting to know, and if it's working then it might be a bit easier to test custom code on the CX4 (provided one has a way to run SNES code in WRAM, which could then relocate CX4 code to CartRAM) (installing CartRAM would be probably easier than installing (writeable) CartROM).

For CX4 data reads from CartROM/CartRAM - if DMA (and maybe also cache loading) works just by using different addresses - then I am wondering why one needs to use different opcodes (612Eh/612Fh) for reading CartROM/CartRAM. Or could it be possible to use either opcode for either CartROM/CartRAM? If so, maybe the opcodes differ only by using different waitstates, WS1/WS2?

Overload
Posts: 47
Joined: Mon May 30, 2011 4:38 pm
Location: Australia
Contact:

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

Post by Overload » Fri Nov 22, 2019 11:17 pm

If this information is already known, disregard. I haven't been here in a while.
byuu wrote: What exactly happens on MOV MBR,reg[00-5f]? Does it get loaded with zero?
In my tests zero was returned.
byuu wrote: Implementing this breaks sprites in Rockman X2's opening sequence, the 2 on the X2 title screen, and I stopped looking after that.

Allowing it to access 00-7f makes the game work again.

The instruction being executed is $612e, which is of course the first of the three-opcode sequence for reading from the bus.
I couldn't get bus reads to work. I did all my tests using a MashMods Flash Programmer. This needs to be tested on a SNES.
nocash wrote: I am still wondering if one can use operand=00h to access "Register A" or not. The question (and answer) affects many opcodes, almost everything that doesn't use immediates as parameter. At the moment, my emulation is allowing operand=00h for A, if that's wrong then I could change that, but it would be nice if somebody could confirm if it's really wrong.
As far as I can remember there is nothing mapped at 00H, it just returns 0.

Post Reply