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.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

Hi everyone, been very busy making sure all aspects of the game function properly, before I go onto the vertical scroll engine the game has.

As of right now, I've got every stage that I start on working correctly before their vertical scroll portions.

Starting tomorrow I'll get to work on that. First thing will be for me to watch the original rom in FCEUX'S debugger, and see how it performs the routine. I'll keep you updated.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

Update: I've got the games vertical scroll functioning, not perfect, but it's a start. The physical properties and BG tiles all match, which is good. However, when it comes time to resume horizontal scrolling, I'll get the vertical drawing appearing towards the right end of my screen. I need to update my tile attribute routine, cause I'm getting the incorrect palettes for my tiles.

Now the big issue, when scrolling you definitely see the 16 pixel height gap between the screen transitions. Tiles are drawn from ppu2000-ppu23BF, and ppu23C0-23FF are left blank, since the NES doesnt draw tiles there, only attribute data. Im saving this dead last to tackle, since the current state of the vertical scroll isn't stable.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

Update: got the vertical scroll working. The next thing I have to figure out is using HDMA to combine the two screens, since I now have a gap between the two tilemaps.

Right now I'm working on one of the games irq routines, having issues where I get a millisecond glitch of the incorrect tilemap appearing on my split.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

Update 1: I've finally gotten around to properly getting my stack pushed/pulled from properly, when the NMI fires up in the middle of a 16-bit instruction. My issue was, the game deliberately hard codes the sound engine handler address within the stack, and I needed to adjust the addresses within the sound engine handler, that restore the NMI handler. So for the first time today, I finally had the game boot up, and the sound engine play, all without crashing. I haven't put it through its paces yet, but the fact that it all booted up is very promising, thank you to everyone here that helped me out with trying to get 16-bit push/pull working!

Update 2: Port is coming along nicely, aside from vertical screens not drawing together due to lack of HDMA, I'm able to complete a stage from start to finish! This port has been a major pain, working on an mmc3 title with 8kb swappable banks at $8000 & $A000, I've been doing alot of indirect loadings. And I hate, hate, HATE, the DB register. There was a point where I figured I could so an indirect long, where I have 3 registers set aside in my DP, for my lo/hi address, and the other for the prg bank, but I kept forgetting I need to have the the DB set to the proper bank that I'm trying to load from. It's tough when you're the only one working on a port, and being my first time with the snes, man its driving me crazy, lol!

However, I'm getting the itch to port an MMC1 title, since alot of those simply swap out 16kb banks in $8000-$BFFF. :-)
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Need guidance with nes to snes.

Post by dougeff »

If you are using 239 pixel high screens, I think the HDMA would work like this. You will be hdma-ing to $210e, an 8 bit, write twice register.

You set the HDMA to point to a 4 byte table:
1=# of lines to wait
2,3= y scroll values
4= 0 (end of table)

so, during NMI, you will set the y scroll for the top of the screen, 2 writes to 210e (should be the same as the NES uses). Then you set up the HDMA to transfer mode 2 (1 register / 2 writes), B bus destination to $0e (register $210e), direct mode. Point it to your 4 byte table. Enable HDMA with $420c.

Then you adjust the HDMA table every frame.
# of lines to wait, something like
#=240 - y scroll low byte

new y scroll value = top screen y scroll value + 16, if >= $1f0 (bottom of 2nd map), then subtract $1f0, so it wraps back around to the top of the first screen.

These might be off by 1, I didn't test it. It will be something like this.


Edit, this isn't right.
Last edited by dougeff on Sun Jun 20, 2021 6:32 am, edited 1 time in total.
nesdoug.com -- blog/tutorial on programming for the NES
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Need guidance with nes to snes.

Post by 93143 »

It's a bit more complicated than that. First, an HDMA channel will always write something on line 0 (unless it's started during the active frame, which is a bit fiddly); the line count in the table is the number of lines to wait after doing the transfer, even though it comes before the data in the table. In practice, all this means is that you don't have to manually reset vertical scroll to the top-of-screen value during VBlank - you can have the HDMA do it.

Second, you can't wait longer than 127 lines in an HDMA table, because the top bit of the line counter is the Repeat flag. If you want your split lower than that, you may have to write the upper scroll value a second time to bridge the gap.

https://wiki.superfamicom.org/dma-and-hdma

You could also forget about using HDMA and just use an IRQ, making sure you're in HBlank before changing the scroll value. But you're already using an IRQ for something else, and I'm not sure if there could be clashes, or how definite the relationship is between the desired trigger locations - you can reset the H/V trigger point inside the IRQ, and redirect to different code using a trampoline, but this gets complicated if you can't guarantee that the desired IRQ routines always line up in a particular order, or if they have to happen so close together that they'd overlap. HDMA might be easier if you can get it working consistently, as you don't need to worry about any of that.
Last edited by 93143 on Sat Jun 19, 2021 12:18 pm, edited 1 time in total.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

Ok so my guess is, do I have hdma going at the start of my NMI, when the game is in vertical scroll mode?
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Need guidance with nes to snes.

Post by 93143 »

HDMA stays on indefinitely once you set $420C. It just takes over the bus briefly every now and then to do its thing; it's very low-overhead. You should be able to turn it on once at the beginning of the game mode that uses it, and just adjust the table every frame to keep pace with the scroll seam. Double-buffering the table is probably a good idea if you're writing to it during active display, so you'd also have to rewrite $43x2-x3.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

Very complicated. Tried watching a video on it. I've actually got my table loaded in rom, but I have no clue what I'm doing, I'm just blindly editing my table on the fly to watch the different actions. Right now I have it so $420C is only active during a vertical scroll (aka, $FA not equal)

update going to set aside ram to be the table, instead of rom.

update 2 No luck, outta my league with this one. I even tried messing with irq's.

My hdma code. I'm using $14A-$14D in ram for the hdmi table. $14D is always 00, to indicate end of table. When the game vertical register $FA is equal, I have $14A-$14D cleared.

Code: Select all

LDA $FA ;games vertical counter
BNE ;to LDA $FA, sorry, I code in hex

;clear hdma table
STZ $14A
STZ $14B
STZ $14C
STZ $14D

JMP $ED10 ;start of game code after NMI pushes

;modify hdma table in ram
LDA $FA
STA $14A
INC $14B

;prep hdma addresses
LDA #$02
STA $4330
LDA #$0E
STA $4331
LDA #$7E ;wram
STA $4334
LDA #$4A ;wram lo
STA $4332
LDA #$01 ;wram hi
STA $4333
LDA #$08
STA $420C ;hdmi init

JMP $ED10 ;start of game code after NMI pushes
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Need guidance with nes to snes.

Post by 93143 »

You didn't read my post. You can't use just four bytes for the table.

The first byte is the number of lines to wait (up to 127) after the first data shot before doing the second data shot. The next thing in the table is that first data shot, which happens on line 0. If that's the only thing in your table (other than the zero terminator), the data in that shot will apply to the whole screen.

What you want is to write the scroll value for the upper part of the screen either once or twice, depending on whether the distance to the split is greater than 127, and make sure the sum of the line count values for those two shots is the distance to the split. Then write the scroll value for the lower part of the screen, with whatever line count value you want, and turn off the channel with zero.

If you try to use a number greater than 127 for the line count, it will go into Repeat mode, transferring two bytes every scanline until it reaches (n-128) lines. You do not want this.

...

Also, why are you loading a value and branching on it, only to load it again at the branch target? Can't you assume that you arrive at LDA $FA with the value already in the accumulator?
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

93143 wrote: Sat Jun 19, 2021 2:49 pm Also, why are you loading a value and branching on it, only to load it again at the branch target? Can't you assume that you arrive at LDA $FA with the value already in the accumulator?
I'm just testing, trying different things, this wont be in the final code I use. So should I stick with using rom for my hdma table?
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Need guidance with nes to snes.

Post by 93143 »

Don't you have to modify the line count and scroll values in the table? You can't use ROM for that unless you (a) use indirect mode and have the addresses in the table point to RAM, or (b) waste a bunch of ROM on a couple hundred tables, one for each possible position of the split.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

I'm sorry I'm new to hdma and its just confusing to me. I'm going to hold off and move on with the port.
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Need guidance with nes to snes.

Post by 93143 »

Are you having trouble with the concept, or the details?
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

Everything honestly. The only thing I have working, is the prep work for the hdma in regards to where to load the hdma table. Im going to have my table located at 7E:8000. I dont know how big the table is supposed to be either. I work better with visual aids, step by step. I've tried searching the internet for hdma examples with my situation, but I just find the traditional examples of window masking/color math manipulation. Its just complicated for me to process.

my current code at the start of my nmi

Code: Select all

;$FA is the y scroll, when character touches the top of the screen, 
;$FA starts with a write of 00, then FE, then EE, 
;then after that it decrements by 02 till $FA reaches 00, 
;when character touches the bottom of the screen, 
;$FA starts with a write of 00, then increments by 02 until 
;$FA reaches F0, then after that $FA finishes with a write of 00.

lda $fa			;y counter
bne			;to lda #$02

stz $420c		;turn off hdma	
jmp $ed10		;resume nmi

lda #$02		;hdma mode 2
sta $4330
lda #$0e		;hdma $210E bg1 y scroll
sta $4331
lda #$7e		;hdma bank id
sta $4334
lda #$80		;hdma hi byte bank
sta $4333
stz $4332		;hdma lo byte bank
lda #$08		;inititiate hdma channel 3 transfer
sta $420c
jmp $ed10		;resume nmi
Post Reply