Help with SA-1 demo

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.
Molive
Posts: 50
Joined: Sat Apr 07, 2018 7:39 pm
Location: EN

Re: Help with SA-1 demo

Post by Molive » Sat Apr 13, 2019 2:29 pm

So I've done another test where the SA-1 sends an interrupt as soon as it is turned on, and in software this interrupt fires but on hardware there is no such interrupt.
This confirms that the SA-1 is not even starting, which means it's nothing to do with IRQs or DMA or bus conflicts or anything like that.
This is so weird.
SNES demos are great

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

Re: Help with SA-1 demo

Post by nocash » Sat Apr 13, 2019 4:35 pm

This is in the registers (so SNES-CPU uses ROM-vectors, and SA-1 uses the custom I/O vectors).

Code: Select all

SA-1 Registers (W)
 2200 00 80 A0 00 80 07 80 07 80 00 00 F0 00 00 00 00
 2210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 2220 80 81 82 83 00 00 80 80 04 FF FF 00 00 00 00 00
 2230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 2240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 2250 00 00 00 00 00 00 00 00 8A EE 6C FB 00 00 00 00

SA-1 Registers (R)
 2300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SNES-IRQ vector destroys A register (and doesn't push/pop anything that might be changed when using another RAM vector).
The SNES and SA-1 handlers for IRQ don't seem to acknowledge IRQs to the SA-1 hardware (only to the GPU).
But the code that I am looking at seems to have IRQs disabled anyways.

For cases where IRQs should fire, did you make sure that everything is enabled (in SA-1 hardware, and also in CPU's I-flag), and old IRQs were acknowledged before enabling them? And of course, don't forget to acknowledge them before trying to return from the interrupt handler.

The APU streaming code looks as if it's all properly sync'ed to the APU speed, that should work (as long as the APU isn't faster than your SNES/SA-1 code, I haven't counted clock cycles for checking if the timings are too tight).

Other thing: 420Dh is set to Fast ROM? I don't think that SA-1 boards are supporting that.
But it shouldn't matter as long as SNES CPU leaves bank 80-FF unused (and it shouldn't affect any banks on SA-1 CPU).

If you have problems firing an IRQ: Fire a flag in I-RAM/BW-RAM instead. Maybe it will turn out that the SA-1 is running, and it's just the IRQ code that isn't working.
As byuu has said, CIC issues might also trigger some kind of copy protection (if you have a CIC-disable switch in the console, set that to CIC-enabled, at least if cart+console are for same region).

EDIT: To trigger the SA-1 entrypoint/reset vector, one should normally set CCNT bit5 for a moment.
Though the bit may be set automatically at power-up, so maybe you won't need to set it manually in that case.

Molive
Posts: 50
Joined: Sat Apr 07, 2018 7:39 pm
Location: EN

Re: Help with SA-1 demo

Post by Molive » Sun Apr 14, 2019 5:15 am

So, in short: it now works. kinda.

In long:
The issue was in the SA-1 boot. When booting, I leave emulation mode, jump to the correct bank, set up dpage and stack and then jump to a subroutine to set up the rest of the registers. This seems fine at first, until you include register 222Ah - IRAM write enable.
IRAM, by default, starts with no write capabilities. I turn it on in the subroutine where I set the rest of the registers, and I thought I didn't write to IRAM until I did that - except I did, by accident.
When jumping into the subroutine the SA-1 writes a return address to the stack - which is in IRAM. Because write enable is still off, this return address never gets written, and so when returning it jumps to whatever uninitialized memory is in the stack at power on - and crashes. The fix is simple, before jumping into the subroutine enable IRAM writes (I'm actually doing it before leaving emulation mode, because I was getting annoyed.)

I would've come across this earlier - except BSNES let the write go through. In fact, I removed the code that enabled IRAM writes altogether and it ran fine. I assume that it's just entirely ignoring this register.
The SD2SNES' implementation also must not account for the stack writing to disabled IRAM, as that worked also.

I said earlier that it kinda worked: All of the VBP tests fail, and it just produces nonsense. I will look into this further and relay results in another post to this thread.
Thanks for all your help. :)
~Molive
SNES demos are great

Pokun
Posts: 1235
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Help with SA-1 demo

Post by Pokun » Sun Apr 14, 2019 7:19 am

So a write protected stack. I guess for emulators, protecting memory from stray writes isn't necessary, and if it's like the MMC1 for NES which there are several versions of with some that do not feature write protection and some that do, and since the header do not specify the version of MMC1 the game is designed for, ignoring the write protection feature is a way to make all games work.

But I guess emulating the write protection is useful for development (to discover bugs like this), or just for accuracy. There could, in theory, be a game that relies on the write protection to work.

Molive
Posts: 50
Joined: Sat Apr 07, 2018 7:39 pm
Location: EN

Re: Help with SA-1 demo

Post by Molive » Sun Apr 14, 2019 12:37 pm

Apparently my SA-1's version code is 23h.
SNES demos are great

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

Re: Help with SA-1 demo

Post by nocash » Sun Apr 14, 2019 1:35 pm

Good to know. I'll add the 23h in fullsnes... until/unless somebody discovers chips or boards with other values.
Hmmm, 23h might come from the RF5A123 chip name. The next byte doesn't happen to return A1h, or does it? But theoretically the register should be only 8bit, not 16bit.
Or 23h could be an open-bus effect from reading 230Eh? But that shouldn't happen, at least not when reading the register from SNES-CPU side.

Stack with disabled write access is really nasty. I had looked if your code had initialized stack, and if it had enabled write access, but I didn't thought about checking if that was both done before the first stack write.

Emulating that kind of stuff is uncomfortable... it's rarely needed, and hurts performance... in this case one could probably implement two memory write functions; fast "memory write" code used when all ram is unlocked, and a slower "I/O callback" function used when the ram (or parts of it) are locked.

Did you get the variable-bit-length reads working? And are you stlll UV-erasing after each test? I guess a flash chip would make everything easier, even if it's too small to hold the whole demo. But flash chips with 16bit databus are probably even harder to get than those with 8bit databus... at least in traditional DIP package with 5V supply : /

One distracting thing about the variable-bit feature is that writing to VBD is said to trigger a manual-increment (which wouldn't be desired when using the auto-increment mode) (though that effect wouldn't hurt when re-iniatilizing the address register after the VBD write).

The specs are sounding as if variable-bit ROM address starts at 00:0000 (?) rather than at C0:0000. In that case your code might bug when using address FB:xxxx instead of 33:xxxx (bit23 is probably ignored, but bit22 would be part of the supported 8Mbyte ROM space). Some carts access the upper 4Mbyte via A22=1 (which may be ignored by smaller chips), and some via a separate /CS chipselect signal (which won't work unless you do have two ROM chips). I am not sure how to select 1 or 2 chip mode - there seems to be no I/O bit for that - best guess would be that it's selected by wiring SA-1 pin85 to GND or VCC.
On the other hand, if above is wrong, then 33:xxxx would be probably seen as a LoROM address (so that might make things worse).

EDIT: Just wondering if variable-bit ROM reads are done with 16bit databus... if yes, then the address would be needed to be word-aligned.
EDIT: Looking at Jumpin Derby, that uses D7:xxxx as variable-bit address, so the address isn't a zero-based ROM offset in that game (but that might be a bug in the game).

byuu
Posts: 1537
Joined: Mon Mar 27, 2006 5:23 pm

Re: Help with SA-1 demo

Post by byuu » Sun Apr 14, 2019 2:21 pm

I would've come across this earlier - except BSNES let the write go through.
When I enabled the write protection bits, some games stopped running. There are games that never clear it after boot.
Apparently my SA-1's version code is 23h.
It's open bus. If you read from $230e you get $23. If you read from $80230e you get $80.
Vitor ran into that with his speed test: https://github.com/VitorVilela7/SnesSpeedTest

You raise an interesting point though, is it one CPU's open bus, or does it depend on which CPU reads it? Can one CPU see the others' open bus value?

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

Re: Help with SA-1 demo

Post by nocash » Sun Apr 14, 2019 7:12 pm

Going by the specs, the version can be read from SNES-CPU side only. Molive, where did you read it from?

Byuu, do you remember which SA-1 games don't initialize the write-protect bits, and for which memory... I-RAM or BW-RAM?
Just to be sure: Unlocking is done by setting the write-enable bits (not by clearing them).

Or did you mean GSU games? Those do have a write-protect function for "Backup RAM", but none of the existing boards is having that kind of memory installed, so the protect feature is having no function (most or all GSU boards do have normal "Game Pak RAM", but that isn't affected by the "Backup RAM" write protection).

Molive
Posts: 50
Joined: Sat Apr 07, 2018 7:39 pm
Location: EN

Re: Help with SA-1 demo

Post by Molive » Mon Apr 15, 2019 1:30 am

nocash wrote:Did you get the variable-bit-length reads working? And are you still UV-erasing after each test?
No, Yes. I have a few chips and I can erase 5 at a time, but it takes like 30mins to erase and 10 to flash.

I'm doing some more VBP testing, and it seems something along the lines of "Writing to VDA clears the lowest four bits of VBD" happens:

a = 8, i = 16
lda #%10001010
sta VBD ;VBD is now 8A
lda ...
ldx ...
stx VDAL
sta VDAH ;VBD is now 80
lda VDP ;Now barrelshifted 16bits a time.

You'd need to specifically set VDA first, and then set VBD. This matches the flow diagram in the manual.
I can't confirm this is true behaviour, only that something like this happens, and that swapping them gave me different results on hardware.
Unfortunately, I have no idea what it now means, it almost looks like it's reading from random nearby memory positions. I might just switch to fixed-mode.
nocash wrote:Molive, where did you read it from?
It was CPU side. When running the test in BSNES it returns "1".
EDIT: https://github.com/VitorVilela7/SnesSpeedTest also seems to have it as 1 in BSNES and 23h on console, based on the screenshots.
SNES demos are great

byuu
Posts: 1537
Joined: Mon Mar 27, 2006 5:23 pm

Re: Help with SA-1 demo

Post by byuu » Mon Apr 15, 2019 3:36 am

It was CPU side. When running the test in BSNES it returns "1".
EDIT: https://github.com/VitorVilela7/SnesSpeedTest also seems to have it as 1 in BSNES and 23h on console, based on the screenshots.
Read it again CPU side with lda $bf230e.

Also, the SA1 is definitely a case where using forks of my code from 8+ years ago isn't the best idea.
Unlike the people who forked Nestopia et al, my project's very much still active so they are missing out on improvements.
https://gitlab.com/higan/higan/blob/mas ... io.cpp#L17

My current SA1 code emulates bus conflict timings, open bus for $230e, and does its best to support CPU vs SA1 only registers.
It should be available in bsnes v107.1 if you're not fond of higan.
Byuu, do you remember which SA-1 games don't initialize the write-protect bits, and for which memory... I-RAM or BW-RAM?
Just to be sure: Unlocking is done by setting the write-enable bits (not by clearing them).
Unfortunately not, this was back in 2008 or so. I can re-enable the write protection, but I don't have testers to go through all the SA1 games anymore.
Or did you mean GSU games? Those do have a write-protect function for "Backup RAM", but none of the existing boards is having that kind of memory installed, so the protect feature is having no function (most or all GSU boards do have normal "Game Pak RAM", but that isn't affected by the "Backup RAM" write protection).
You know honestly, it may be the case that I got bitten by the GSU and then decided to remove it from the SA1 as well. Seems unlikely but I can't say for certain.

That's a really good point about the write-protect, thank you for that! I could enable write protection conditionally based on the PCB IDs of SuperFX games.

Molive
Posts: 50
Joined: Sat Apr 07, 2018 7:39 pm
Location: EN

Re: Help with SA-1 demo

Post by Molive » Mon Apr 15, 2019 6:13 am

byuu wrote:Read it again CPU side with lda $bf230e.
Unsurprisingly, it's now BFh. Can the version code even be read?

In other news, it now works. I switched to using fixed-mode, which solved most of it, but then I made all the VBP sections word aligned (like nocash suggested) and that fixed the rest.
I thank you all for your help.
:)
SNES demos are great

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

Re: Help with SA-1 demo

Post by nocash » Mon Apr 15, 2019 9:49 am

Molive wrote:I'm doing some more VBP testing, and it seems something along the lines of "Writing to VDA clears the lowest four bits of VBD" happens:
a = 8, i = 16
lda #%10001010
sta VBD ;VBD is now 8A
lda ...
ldx ...
stx VDAL
sta VDAH ;VBD is now 80
lda VDP ;Now barrelshifted 16bits a time.
Okay, that's unexpected.
But it might somewhat make sense technically: The first word is pre-loaded at time when writing Address MSB, and that pre-loaded value shouldn't be affected by the shift-amount... so the hardware might intentionally force the shift-amount to be zero to "disable" the shifting on pre-load (or to shift-in the initial 16bits, as shift value "0" is treated as "16").
In manual mode, something similar might happen: Eg. when setting VBD=0Ah and then writing the address, then VBD might change to 00h or 80h (if it's 80h then you would see auto-increments to happen when repeatedly reading Data, despite of initially having disabled auto-increment by the VBD=0Ah setting).
Molive wrote:You'd need to specifically set VDA first, and then set VBD. This matches the flow diagram in the manual.
Yeah, looks like so. Then writing VBD with bit7=1 apparently does NOT trigger any unwanted manual increments (I don't remember exactly where that theory came from... probably from snes9x's sa1.cpp source code).
byuu wrote:
Molive wrote:
nocash wrote:Molive, where did you read it from?
It was CPU side.
Read it again CPU side with lda $bf230e.
Er, yes, sure, but which one, the SNES-CPU in the console, or the SA-1-CPU in the cartridge?

Interpreting the screenshots at https://github.com/VitorVilela7/SnesSpeedTest isn't so easy.
The first screenshot (with "----" shown as SA-1 version) seems to be from the current source code version, showing [230e] read from both CPU's, and "--" and "--" meaning that both are open-bus (although the open-bus check on SA-1 side looks a bit quirky).
All other screenshots (with a single 2-digit hex value shown as SA-1 version) seem to be from older source code versions, and they are apparently showing [230e] from one CPU only (as for which one: one could probably find out by going through the older source code version).
byuu wrote:thank you for that! I could enable write protection conditionally based on the PCB IDs of SuperFX games.
What condition? The write-protect register does exist on all GSU boards, but the corresponding "Back-up RAM" memory chip doesn't exist on any boards.
Searching for write protect posts... here: http://www.smwcentral.net/?p=viewthread ... 54#p579554 you seem to have actually tried to emulate the GSU's "BRAMR" register and breaking various games with it - despite of no single game ever having used "Back-up RAM" chips : )

byuu
Posts: 1537
Joined: Mon Mar 27, 2006 5:23 pm

Re: Help with SA-1 demo

Post by byuu » Mon Apr 15, 2019 3:02 pm

> What condition?

You mentioned it was two different types of RAM. SA1 has 1L0NxS and 1LxB boards. I presume you mean only one of them have the RAM type that can be protected.

> you seem to have actually tried to emulate the GSU's "BRAMR" register and breaking various games with it - despite of no single game ever having used "Back-up RAM" chips : )

Oh, I see. Well that rules out the SuperFX, but I also had trouble with SA1 games back then.

byuu
Posts: 1537
Joined: Mon Mar 27, 2006 5:23 pm

Re: Help with SA-1 demo

Post by byuu » Sun Apr 21, 2019 1:13 am

Okay I emulated SueprFX backup RAM with BRAMR write protection (pointless, but whatever) and SA-1 SWBE + BWPA + SIWP + CIWP write protection.

Kirby's Dream Land 3 fails to run when emulating CWBE.
The SNES CPU sets BWPA = 02 (to protect 400000-4003ff), and then the SA1 CPU sets CWBE = 00 (to disable writes to the protected area.) The SA1 CPU then starts writing to 4001ax and 40032x addresses. Per the documentation, these writes should fail, and yet they must not fail in order for the game to run.

So for now, CWBE isn't emulated.

Post Reply