Need guidance with nes to snes. UPDATE: Port Complete of Mega Man IV + MSU-1

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.
Dartan
Posts: 8
Joined: Sat Apr 10, 2021 9:55 pm
Location: Germany

Re: Need guidance with nes to snes.

Post by Dartan »

By the way, do you use 16bit registers (M-flag=0 and/or X-flag=0) anywhere in you code? Because I don't think your IRQ routine considers these flags correctly and unexpected, bad things will happen if the IRQ fires while the M or X flag is cleared.

(More experienced developers who have actually written code for this CPU, please correct me if I'm wrong here.)
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: Need guidance with nes to snes.

Post by dougeff »

For both NMI and IRQ, assume the size of AXY is unknown, and you should explicitly set register size before pushing and popping to the stack. This example if you want 16 bit mode.

REP #$30
PHA
PHX
PHY

...
PLY
PLX
PLA
RTI

note, you might also push/pop the data bank register, if that is changed in the IRQ code

PHB
REP #$30
PHA
PHX
PHY

PHK ;zero
PLB ;change data bank to zero
...
PLY
PLX
PLA
PLB
RTI

Edit...If, however, you only ever use the A register, and only ever in 8 bit (during the IRQ) you could get away with.

PHB
SEP #$20 ;A= 8 bit
PHA

PHK
PLB
...
PLA
PLB
RTI
nesdoug.com -- blog/tutorial on programming for the NES
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: Need guidance with nes to snes.

Post by Oziphantom »

You should always set the sizes to 16 bits before pushing and then again before pulling. Since they have to move the DP for this to fix things, it means they are changing it in their code and need to save and restore it.
See https://www.youtube.com/watch?v=rPcwGeX_hLs&t=530s for a full walk through on each of the possible outcomes and traps. For this case you don't want to worry about the NMIReadyFlag and the ACK is not $4210, but my walk through on how to save and why to save and what else you need to do applies.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

After almost 2 days, and almost giving up, I just got the games first irq working! The bottom stays still to display text, while the upper half speeds across the screen from left to right. But boy oh boy, it's scrolling lightning fast, way faster than originally performed! Not sure why, I think I may have to add an AND operand to slow it down, but I shouldn't have to since I havent messed with the original games scrolling.

The issue I was having with the irq not working properly, and this is credit to the properties viewer in the bsnes debugger, was a combination of my irq enable fluctuating on and off, and writes to $4200 were not truly being written to the snes $4200. Turns out from when I first started, I had my irq's turning on and off from the TSB/TRB tables I did 2 months ago, so I removed the bits from those routines, and simply turned on HV IRQ within my snesinit code. As for the writes to $4200, I made it so it happens in DB 00.

But still, not sure why the crazy blazing scroll speed? I even ran the port on no$nes, and it's the same crazy speed.
creaothceann
Posts: 610
Joined: Mon Jan 23, 2006 7:47 am
Location: Germany
Contact:

Re: Need guidance with nes to snes.

Post by creaothceann »

Does the scrolling speed depend on the CPU speed? Because the NES and the SNES have the same field-/framerates, but the SNES runs at up to ~3.58 MHz, depending on which area the CPU is accessing.
My current setup:
Super Famicom ("2/1/3" SNS-CPU-GPM-02) → SCART → OSSC → StarTech USB3HDCAP → AmaRecTV 3.10
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: Need guidance with nes to snes.

Post by Oziphantom »

something will be updating that scroller value, make sure that is actually only running as fast as you think it is running. I.e once per frame.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

Ok, I ran the original rom and checked against the frame counter, the game increases the scroll every #$10 per frame.

I ran my port, it does the exact same thing. So it's working correctly. I think what's throwing me off, is the more vibrant colors the snes produces, cause these colors look so much more vibrant and fuller, compared to what you see on the NES. I ran my port and the nes rom at the same time and everything matched, just the snes colors really pop.

I was successful in altering another irq that is used in the game, however this one actually needed its split value altered, it wasnt matching in the snes.

update - I'm right on the doorstep of the title screen. Once I get the initiated, I'm going to stop going forward until I can get the 2A03 sound emulator into the APU. I need to tackle that soon.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

Ok, I'm having another issue with my irq vector arriving at an inappropriate time.

There's a point in my port where I need to set my A,X,Y to 16-bit. Just before my next command is to reset A,X,Y back to 8-bit, my irq vector fires up, and screws up the stack now that it's in 16-bit mode.

I was thinking I could easily set a register someplace, when I initiate 16-bit mode, so that when my irq vector fires up, i can have a check for it and simply RTL out of there.

But then I'm thinking, who's to say the timing wont screw that up at some point too?

Is there a command to read the P flag? I cant find documentation if that's possible. Because what i want to do is, at the start of my irq vector, check against the flags for A/X&Y being in 16bit mode, and if any is true, to RTL outta there.

Any help/suggestions would be great, thanks!

update - hmm, thinking my idea should be to set a flag register before I switch to 16-bit, cause I tried checking the processor status, (just figured out I could push the processor and pull it) but it came up as a 16 bit value.
creaothceann
Posts: 610
Joined: Mon Jan 23, 2006 7:47 am
Location: Germany
Contact:

Re: Need guidance with nes to snes.

Post by creaothceann »

Interrupts push the status register to the stack, so in your interrupt handler(s) you could just clear the 16-bit mode bits with SEP #$30. (%00110000)
My current setup:
Super Famicom ("2/1/3" SNS-CPU-GPM-02) → SCART → OSSC → StarTech USB3HDCAP → AmaRecTV 3.10
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: Need guidance with nes to snes.

Post by dougeff »

AND, you need to exit the interrupt with RTI to restore the Status Flags (P).
nesdoug.com -- blog/tutorial on programming for the NES
Dartan
Posts: 8
Joined: Sat Apr 10, 2021 9:55 pm
Location: Germany

Re: Need guidance with nes to snes.

Post by Dartan »

creaothceann wrote: Sun Apr 18, 2021 9:18 am Interrupts push the status register to the stack, so in your interrupt handler(s) you could just clear the 16-bit mode bits with SEP #$30. (%00110000)
But if you just clear the 16-bit mode, saving the original values of A,X,Y is problematic. If you clear the 16-bit mode before pushing the registers to the stack, only the lower 8 bits of the registers will be saved. If you clear the mode after pushing to the stack, you will have to somehow restore the previous mode before the corresponding pull instructions.

To my understanding the typical way to write a save IRQ handler is to first enable the 16-bit mode, then push the registers, then set the mode to whatever your code wants it to be, then - after the actual handler code - set the mode back to 16-bit, pull back the previous register values and then RTI:

Code: Select all

IRQ:
	REP #$30
	PHA
	PHX
	PHY
	SEP #$30 ; if your handler expects 8-bit mode

	...

	REP #$30
	PLY
	PLX
	PLA
	RTI
(basically what dougeff posted a few posts above)

If your handler codes modifies any other CPU registers (DBR!), be sure to also save and restore them!

(If your code adheres to some very strict restrictions, you might be able to simplify some things and save a few CPU cycles. But unless you *really* know what you're doing and have serious performance issues, I just wouldn't bother.)
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

dougeff wrote: Sun Apr 18, 2021 9:22 am AND, you need to exit the interrupt with RTI to restore the Status Flags (P).
Dartan wrote: Sun Apr 18, 2021 10:20 am
creaothceann wrote: Sun Apr 18, 2021 9:18 am Interrupts push the status register to the stack, so in your interrupt handler(s) you could just clear the 16-bit mode bits with SEP #$30. (%00110000)
But if you just clear the 16-bit mode, saving the original values of A,X,Y is problematic. If you clear the 16-bit mode before pushing the registers to the stack, only the lower 8 bits of the registers will be saved. If you clear the mode after pushing to the stack, you will have to somehow restore the previous mode before the corresponding pull instructions.

To my understanding the typical way to write a save IRQ handler is to first enable the 16-bit mode, then push the registers, then set the mode to whatever your code wants it to be, then - after the actual handler code - set the mode back to 16-bit, pull back the previous register values and then RTI:

Code: Select all

IRQ:
	REP #$30
	PHA
	PHX
	PHY
	SEP #$30 ; if your handler expects 8-bit mode

	...

	REP #$30
	PLY
	PLX
	PLA
	RTI
(basically what dougeff posted a few posts above)

If your handler codes modifies any other CPU registers (DBR!), be sure to also save and restore them!

(If your code adheres to some very strict restrictions, you might be able to simplify some things and save a few CPU cycles. But unless you *really* know what you're doing and have serious performance issues, I just wouldn't bother.)
creaothceann wrote: Sun Apr 18, 2021 9:18 am Interrupts push the status register to the stack, so in your interrupt handler(s) you could just clear the 16-bit mode bits with SEP #$30. (%00110000)
I want to thank the three of you for all that valuable info. I tried doing everything the three of you suggested, but for some bizarre reason I kept getting strange crashes.

The only thing that has made my rom crash no more was adding

Code: Select all

LDA $4212
BPL $E237 ;back to LDA $4212
This was the only thing that has allowed my intro and title screen to consistently loop with no more crashes. Everything is working 100% correctly, I even let the sequence play out for an hour, just to make sure the crasb wouldn't happen again. Very bizzare.
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: Need guidance with nes to snes.

Post by Oziphantom »

Where are you doing that loop? Checking to make sure you are in VBlank with a loop like that suggest something is very wrong.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

Oziphantom wrote: Tue Apr 20, 2021 12:10 am Where are you doing that loop? Checking to make sure you are in VBlank with a loop like that suggest something is very wrong.
I need to explain. During bootup, the game has it's copyright screen, then developer screen, then it begins the story to the game, which has 5 different scenes before it reaches the title screen. Everything works and looks perfect leading up to the title screen. When start has not been pressed by certain amount of time, the game loops back to the story portion of the game. When I would reach my 5th scene of the story, before the text fades in for the story, the game would crash. I traced the crash all the way to the point where I was performing my stack change. The original rom has 3 stack locations for various functions. The irq vector for me, kept firing while I was in the middle of my stack transfer. The stack transfer/modification I do, uses 16-bit A,X,Y. The irq would fire BEFORE I was able to set my processor back to 8-bit mode. The suggestions that were given to me a few days ago, worked for a little while in that scene, but towards the end of that scene, I'd get another crash. I dont know if there is a timing issue, since I'm not running a sound engine right now, not sure if that has anything to do with the timing? I've tried various other methods to make it so the irq vector would not fire during that stack transfer. After literally a day of going back and forth over this, I tried using SNES's $4212 right before my stack routine, and it is the only thing that is keeping my game from crashing at that point. Everything works 100%, I've even been able to progress further into the port, getting other screens and game functions to operate. Again I'm not sure if it's because the port is missing a chunk of code, due to me not running the sound engine.
Last edited by infidelity on Tue Apr 20, 2021 5:14 am, edited 1 time in total.
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: Need guidance with nes to snes.

Post by Oziphantom »

you IRQ and NMI should not have any issues with dealing with interrupting something that is 16bits not 8. As in the IRQ you should set the size you want.

Moving the stack can be an issue. It depends on how you are moving it and where you are moving it too.
As an interrupt will use the stack and place 4 bytes, and then you code will place 6 for the A,X,Y, 1 for PBR, 1 for DP so 12 bytes are pushed to the stack, and then pulled from the stack.
So if you stack is somewhere that is not RAM, it will fail and crash. If your stack is pointing to data that you need to keep and you are doing it for fast PLA to read data, then it will trash the data.
Post Reply