It is currently Fri Oct 19, 2018 1:20 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 23 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Thu Dec 21, 2017 8:29 pm 
Online

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7668
Location: Seattle
Assuming the VRC4 is like most other mappers, the contents of its generated address bus (A13 and up) don't care about the value of A15 from the NES's CPU. So this vaguely insinuates that at the moment that the CPU is accessing the stack (and A14,A13 = b'00'), then at that moment, either bank 0xC000 or 0x1C000 is presented to the ROM. Doesn't really matter; it's just a little obfuscatory.

So, yes, I'm pretty certain that the sequences of 0xC1FF 0xC1FE are in fact actually $01FF and $01FE for the stack, writing values to RAM as it JSRs somewhere. (Why? Because if I look at PRG offset 0x1FA17, I see the instruction JSR $FC56) Other reasons: Second address is lower than first, stack is a decreasing kind, so something pushed 2 bytes to the stack; the only thing that can push exactly two bytes to the stack on subsequent cycles is JSR.)

https://nesdev.com/6502_cpu.txt gives lots of details about the cycle-by-cycle timing that we can see here.


Top
 Profile  
 
PostPosted: Fri Dec 22, 2017 12:21 pm 
Offline
User avatar

Joined: Tue Mar 22, 2016 8:27 pm
Posts: 85
Location: Minnesota
I think I tracked it down. It looks like I found a spot where it tries to write to $A000 (VRC4 PRG Select 1 register) and in fact it accidentally writes to $E000 instead (VRC4 CHR select register). There is an extra-long delay on A14, shown in the attachment. Since it had not changed the PRG page as intended, it returned to the wrong location from an RTS shortly thereafter. Stepping in FCEUx, I found that it was supposed to return to location $8003, data A9, 00, A8, 99, and it in fact returned to location $C003, cross-referenced between analyzer and ROM file with data 6A, CC, 0C, EE.

So, it looks like everything stems from whatever this delay is on A14 when writing to $A000. I think we get inconsistent behavior (tap reset, etc) because the timing is right on the very edge where we don't know whether it is writing to $A000 or $E000. Any little thing, probably even including initial VRC4 states that would not normally matter, might slightly bump this timing one way or the other.

Now we get to consider why this delay exists and what could be done about it. I will try making it take longer between writing to $8000 and writing to $A000. I am thinking, write $1C to $8000 like normal, then JSR somewhere else in that same page, write $1D to $A000 there and RTS back. I will try that tonight and see what happens.

Edit:
I guess on second thought, the VRC4 would care what is on the CPU bus and not the PRG bus (as shown on the analyzer) when writing to PRG Select 1... But anyway this is strange looking and it crashes right after this by returning to the wrong page, so I think we are on the right track here.


Attachments:
debugger.png
debugger.png [ 41.45 KiB | Viewed 740 times ]
Analyzer Part 1.png
Analyzer Part 1.png [ 38.35 KiB | Viewed 740 times ]
Analyzer Part 2.png
Analyzer Part 2.png [ 38.62 KiB | Viewed 740 times ]
Top
 Profile  
 
PostPosted: Fri Dec 22, 2017 1:58 pm 
Online

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7668
Location: Seattle
Oops indeed.

Without any better guesses, I'd hope there's some extra load on A14 (but what??) that's slowing it down.

It looks like your mixed-signal analyzer supports 16 digital and four analog signals; could you do the capture again looking at CPUA14 and CPUA13 on two of the analog inputs?


Top
 Profile  
 
PostPosted: Fri Dec 22, 2017 7:13 pm 
Offline
User avatar

Joined: Tue Mar 22, 2016 8:27 pm
Posts: 85
Location: Minnesota
I changed it to this and it made no apparent difference.

Code:
 07:FD3D:20 50 FF  JSR $FF50


 07:FF50:AC 00 80  LDY $8000
 07:FF53:8C EE 07  STY $07EE
 07:FF56:AC FF BF  LDY $BFFF
 07:FF59:8C EF 07  STY $07EF
 07:FF5C:A0 1C     LDY #$1C
 07:FF5E:8C 00 80  STY $8000
 07:FF61:C8        INY
 07:FF62:EA        NOP
 07:FF63:EA        NOP
 07:FF64:EA        NOP
 07:FF65:EA        NOP
 07:FF66:EA        NOP
 07:FF67:EA        NOP
 07:FF68:EA        NOP
 07:FF69:EA        NOP
 07:FF6A:8C 00 A0  STY $A000
 07:FF6D:8C 00 A0  STY $A000
 07:FF70:8C 00 A0  STY $A000
 07:FF73:60        RTS -----------------------------------------


Emulator still runs it normally. Famicom still crashes but can run like before when I put the counter back in and tap reset. Verified this behavior on the Famicom and a USA Front-load NES.

I was not able to analyze with this code. (The MSO4054B I used has been an after-work activity.) When I get back in January, I will look at CPU_A14 and CPU_A13 on analog channels. I may as well throw PRG_A13 onto an analog channel too I guess.

Edit:
MDO4054C


Last edited by Ben Boldt on Sat Dec 23, 2017 4:44 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Sat Dec 23, 2017 4:42 pm 
Offline
User avatar

Joined: Tue Mar 22, 2016 8:27 pm
Posts: 85
Location: Minnesota
I went ahead and went in to work on this. ;)

I think the PRG-A14 changing mid-cycle is correct as an effect of the page swap register write. We would want A14 to be set up correctly before the next cycle so that you can immediately continue to access/execute from that page. I got a similar scope shot when writing to $8000 where the PRG address bus changed mid-cycle, and you can see that the CPU address bus did not have this effect.

It seems like the page swap may have worked but yet it still jumped to the wrong location. And this happened relatively soon after the program started. I got to thinking, maybe the swap mode is wrong. That could potentially have this effect.

I did a little experiment with setting a breakpoint on writes to the Swap Mode control register at $9008/900C (also $9002/9003 in case I had not converted them to VRC4e properly). I tripped no breakpoints on this register at all. So, I tweaked the code to initialize $9008 and $900C to the value $02 and the game crashed in the emulator similar to what we are seeing on the Famcom (tries executing data until it locks up on a bad op-code). Initializing to $00, the game runs normally in the emulator.

Here is the code that breaks it:
Code:
 07:FF50:A9 02     LDA #$02
 07:FF52:8D 08 90  STA $9008
 07:FF55:8D 0C 90  STA $900C
 07:FF58:4C 03 FA  JMP $FA03

(and change reset vector to $FF50)


I really believe that this proves that Gradius II relies on the power-on state of the VRC4 swap mode register, or else this would have had no effect. I will bring this home tonight and reflash it with the code above modified to LDA #$00 and see what happens. I am not sure what else it can be at this point, so I'll try it and let you know.


Attachments:
logic analyzer.jpg
logic analyzer.jpg [ 219.12 KiB | Viewed 677 times ]
Write to $8000.png
Write to $8000.png [ 33.96 KiB | Viewed 677 times ]
Top
 Profile  
 
PostPosted: Sat Dec 23, 2017 6:25 pm 
Offline
User avatar

Joined: Tue Mar 22, 2016 8:27 pm
Posts: 85
Location: Minnesota
After having come home and tried the swap mode initialization, I have results I never would have expected.

It still crashes and will run with reset tapping like before. It did not fix that problem. HOWEVER, now it ALWAYS comes up with wrong CHR on the splash screen, and when you play the game, you die right away until game over. So that whole business is happening every time now, no longer a rare occasion. Just from writing to $9008 and $900C. FCEUx does not have a problem when doing this.

Here is a video showing some things I've talked about:
  • Reset button cycles through the 5 games
  • Tap reset to get Gradius II to run
  • Bad CHR on splash screen

I really don't know where to go next with this! It is very unexpected that $9008/900C had any effect on CHR. What can this mean?


Top
 Profile  
 
PostPosted: Sat Dec 23, 2017 9:15 pm 
Online

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7668
Location: Seattle
Ben Boldt wrote:
I will bring this home tonight and reflash it with the code above modified to LDA #$00 and see what happens. I am not sure what else it can be at this point, so I'll try it and let you know.
I believe this to be correct.

Ben Boldt wrote:
HOWEVER, now it ALWAYS comes up with wrong CHR on the splash screen, and when you play the game, you die right away until game over.
[...] It is very unexpected that $9008/900C had any effect on CHR. What can this mean?
I have to assume that some initialization code is being skipped. But ... I admit I'm not certain how. It should be possible to look at the Gradius CHR and figure out what banks you're getting instead.

Have you explicitly disabled the VRC4's IRQ in your replacement VRC2 initialization?


Top
 Profile  
 
PostPosted: Sun Dec 24, 2017 12:33 am 
Offline
User avatar

Joined: Tue Mar 22, 2016 8:27 pm
Posts: 85
Location: Minnesota
lidnariq wrote:
Have you explicitly disabled the VRC4's IRQ in your replacement VRC2 initialization?

Are you talking about Ganbare Goemon 2 VRC2 initialization? I actually did not ever add any extra code for that game. I only modified VRC control register write addresses. Unfortunately, I am not able to find any obvious free space in PRG-ROM; it seems to have all been used up to 100% by the English translation patch that I applied... I have not had a problem since I got rid of the $6000 / $6100 business.

I see what you mean though -- if the interrupt got left enabled from the previous game, I can see how that might be a problem when there's presumably nothing to acknowledge / clear the VRC4 interrupt flag. I have actually tested this game pretty thoroughly. I played it quite a few times. It is a hilarious, not so politically correct game and it keeps bringing me back. I have attached an IPS file with my changes.

Edit:
Actually I did change up how it wrote to the 4 $B00x registers at ROM file address $1D806. They were doing something stupid with indirect addressing that did not allow me to just easily remap them to the non-sequential VRC4e values. But I found a way to write over their code without needing additional space.

Edit 2:
Well, maybe I'm the one who did something stupid, because it seems this same code is used to write to B00x and C00x, and my modification would make it always write to B00x... Looks like I have more work to do on this one.

Edit 3:
Adding attachment: now also writing to C00x registers as intended.


Attachments:
File comment: Now writing to $C00x registers as intended. Apply this on top of the original English Translation (see bottom attachment)
Ganbare Goemon 2 (J) [!] T-English VRC4e no6000 update.ips [134 Bytes]
Downloaded 22 times
File comment: Changed register writes for VRC4e, Removing reads from $6000 / $6100. Apply this on top of the English Translation (see bottom attachment) Note: This is the one containing an error where it does not write to $C00x.
Ganbare Goemon 2 (J) [!] T-English VRC4e no6000.ips [107 Bytes]
Downloaded 24 times
File comment: Ganbare Goemon 2 English Translation v1.02 by The Stardust Crusaders, downloaded from RHDN (Apply to original (J) [!] version of the ROM.)
ganbaregoemon2.zip [8.61 KiB]
Downloaded 24 times
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 23 posts ]  Go to page Previous  1, 2

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group