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.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Need guidance with nes to snes.

Post by dougeff »

You are correct, 94143. I guess what I wrote was way off. I ran some tests, just to confirm.

Once you enable HDMA, it runs every frame and resets the table automatically, just before drawing the first scanline.

The first value in the table is transferred before the wait (not after), and affects even the top scanline.

So you wouldn't need to manually write the y scroll register during NMI, just modify the first values in the HDMA table and it will affect the top of the screen.

And I forgot that the max for the scanline wait was 127 (the upper bit is for repeats).

I guess the table should be 10 bytes long.

if wait for split screen is > 127

1, # lines to wait (127)
2,3, y scroll for top
4, # lines to wait (total - 127)
5,6, y scroll for top
7, any number (1-127), doesn't matter
8,9 y scroll for bottom
10 zero (end of table)

if wait for split screen <= 127

1, # lines to wait (1-127)
2,3, y scroll for top
4, any number (1-127), doesn't matter
5,6, y scroll for bottom
7, zero (end of table)

And, like he said, you shouldn't be adjusting the table midscreen. Either change it during NMI or double buffer.

If I'm wrong, let me know. Thanks.
nesdoug.com -- blog/tutorial on programming for the NES
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

dougeff wrote: Sun Jun 20, 2021 6:31 am You are correct, 94143. I guess what I wrote was way off. I ran some tests, just to confirm.

Once you enable HDMA, it runs every frame and resets the table automatically, just before drawing the first scanline.

The first value in the table is transferred before the wait (not after), and affects even the top scanline.

So you wouldn't need to manually write the y scroll register during NMI, just modify the first values in the HDMA table and it will affect the top of the screen.

And I forgot that the max for the scanline wait was 127 (the upper bit is for repeats).

I guess the table should be 10 bytes long.

if wait for split screen is > 127

1, # lines to wait (127)
2,3, y scroll for top
4, # lines to wait (total - 127)
5,6, y scroll for top
7, any number (1-127), doesn't matter
8,9 y scroll for bottom
10 zero (end of table)

if wait for split screen <= 127

1, # lines to wait (1-127)
2,3, y scroll for top
4, any number (1-127), doesn't matter
5,6, y scroll for bottom
7, zero (end of table)

And, like he said, you shouldn't be adjusting the table midscreen. Either change it during NMI or double buffer.

If I'm wrong, let me know. Thanks.
I appreciate all the info here. It's very wonky for me trying to figure this out. Right now I'm simply pausing each time the hdma is initiated, so I can see how the hdma table is working for me. The first 3 bytes, I can only see changes when using the first 2 of them. The first bite I set to 7F, and take me to the middle of the screen, the second byte I alter, shows me the vertical portion move up or down. The 3rd byte however does absolutely nothing, I get no changes. My issue is, when scrolling to an above screen, I have the 16 pixel depth gap that appears as the screen scrolls down, but I have no way of covering that 16 pixel depth gap, I need to get the gfx above that 16 pixel depth gap, to connect past it to look seamless, but I am unable to do so.

update oooooh, im getting somewhere. :)

I've been manually editing the hdma table in ram, with bsnes on pause and then i advance each frame to watch the changes. I finally got a formula that works, but then it craps out once my first byte in the hdma table passes 7F.

So right now what i have is

Code: Select all

;load table into hdma, this is for vertical scroll, 
;when character touches the top of the screen

LDX #$05
LDA $9370,x
;01EE00 7FFE00 = table to load into wram 
STA $7E8000,x
DEX
BPL ;back to LDA $9370,x 

;update hdma table before hdma init
LDA $7E8000
CLC
ADC #$02 
STA $7E8000 
LDA $7E8001
SEC
SBC #$02 
STA $7E8001 
LDA $7E8004
SEC
SBC #$02 
STA $7E8004 
RTS
So what i do, is increase the first byte by 02, that amount of scanlines to wait counter, then i take the second byte and decrease that by 02 bytes which is the vertical byte, the 3rd byte does nothing for me so it's always 00, the 4th byte I always have set as 7F, the 5th byte I decrease by 02 bytes, which deals with the vertical byte as well.

And to my amazement, every fram when this code is accessed, it works, the gap is gone, looks seamless! But, once my first byte reaches past 7F, it craps out. I know everyone here explained 8# is the repeat bit, so i'm wondering how to continue for this to be seamless till the end?
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Need guidance with nes to snes.

Post by dougeff »

Make the table longer, if > 127

You mentioned the scroll high byte is always zero?

I'm wondering, if the original game is vertically scrolling, isn't it 2 screens tall? In that case the SNES version should also be 2 screens tall, and the high byte of the vertical scroll should some times be 1.
nesdoug.com -- blog/tutorial on programming for the NES
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

this nes game has the screens side by side when accessing a vertical porition of the stage.

You say make the table bigger, but i'm confused as to how i'm supposed to keep doing what i'm doing, once i reach 7F in my first byte? I've been altering bytes on the fly to try to see a difference but i cant nail the formula yet.

The last non glitched numbers for me midway through my scroll in the hdma table, are 7F7000 7F8000, after that the hdma gets screwy
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Need guidance with nes to snes.

Post by 93143 »

infidelity wrote: Sun Jun 20, 2021 5:17 amEverything honestly.
Can you describe in your own words what you think HDMA is?
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

Can edit specific registers during h-blank
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Need guidance with nes to snes.

Post by 93143 »

Yeah, that's the concept. You can poke locations on the B bus in between scanlines. This may be why the DMA unit has 8 channels, because it means you can poke up to 8 different locations. It's mostly a way to automate raster effects, although it's flexible enough that homebrewers have even used it to stream audio (the I/O ports are on the B bus)...

I suspect it's just the practicalities of the implementation that are causing you problems.

An HDMA table can be thought of as a list of data shots (or addresses to obtain data from, in Indirect mode, but never mind that now). Each shot (1, 2, or 4 bytes) is preceded by the number of lines to wait after the shot before doing the next one. The format (assuming two-byte shots, which should be what you're doing) could be expressed as:

N1 L1 H1
N2 L2 H2
N3 L3 H3
0

With this table, the DMA unit will activate on line 0, load N1, and write the two bytes L1 and H1 to the target location specified in $43x1, in the pattern specified in $43x0. It will then wait N1 lines, load N2, and write L2 and H2 to the specified location. Then it will wait N2 lines, load N3, and write L3 and H3 to the specified location. Then it will wait N3 lines, load 0, and quit.

That's not exactly how it works internally, but that's what it boils down to as far as the programmer cares, as long as you aren't fiddling with the active table too close to the read times. I'd have had it wait Nn lines before the data shot, but I'm no chip engineer...

The catch you're running into is that if Nn is higher than 127, the top bit gets set, and the top bit tells the DMA unit to keep reading bytes off the table every scanline and writing them to the target register(s) until (Nn-128) lines have passed. This means that for sparse HDMA effects like what you're attempting, the practical maximum value of Nn is 127 (that is, $7F).

To solve this problem, keep in mind that mid-screen writes to the scroll registers on SNES don't have any weird quirks - they just change the scroll value. In other words, it doesn't matter how many times you write the same value to the scroll registers; it will do nothing. It has to be a different value to have an effect.

In other words, you don't have to go from the top of the screen to the split in one leap - you can wait some number of lines less than 128, write the same top-of-screen scroll value over again (which does nothing to the display), and then wait the rest of the interval and write the split value. It extends the table in the middle, meaning you have to rewrite a bunch of it rather than just changing a byte here and there, but that shouldn't be a huge issue.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

93143 wrote: Sun Jun 20, 2021 4:11 pmyou don't have to go from the top of the screen to the split in one leap - you can wait some number of lines less than 128, write the same top-of-screen scroll value over again (which does nothing to the display), and then wait the rest of the interval and write the split value. It extends the table in the middle, meaning you have to rewrite a bunch of it rather than just changing a byte here and there, but that shouldn't be a huge issue.
Came back to say that I got it working seamlessly going upwards, and then I saw this response. I did a cmp of 7E:8000 to check when it reaches 7F, once it reaches that, I redo the table a small bit.

$7E:8000 I set as 01
$7E:8001 I dec value by 01
$7E:8002 stays 00

$7E:8003 stays as 7F
$7E:8004 is a copy of $7E:8001
$7E:8005 stays 00

$7E:8006 is now 7F
$7E:8007 is a copy of $7E:8004, but Inc'd by 10
$7E:8008 is 00

$7E:8009 is 00, end of table

With all that done, I get a seamless transition going upward! Now I gotta work going down, but I'm waiting till tomorrow to do that. But after months of developing this port, to see a transition without that gap, I'm very happy/excited!
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Need guidance with nes to snes.

Post by 93143 »

Excellent!

I figured there was probably some way to rig the table to get away with a minimum of rewriting, but I decided not to complicate things... anyway, it's good to hear you got it working.

One question - why does the initial scroll value ($7E:8001) get decremented? Is that just the normal scroll procedure?
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

93143 wrote: Sun Jun 20, 2021 5:21 pm Excellent!

I figured there was probably some way to rig the table to get away with a minimum of rewriting, but I decided not to complicate things... anyway, it's good to hear you got it working.

One question - why does the initial scroll value ($7E:8001) get decremented? Is that just the normal scroll procedure?
Thank you!

For some reason when I tried to align the screens together after I've reached 7F in $8000, i couldn't get the screens to perfectly align afterwards. The top portion would be off 1 scanline, so I had to decrement $8001 by 1, do my modifications to the rest of the table, and then I was able to continue on with the seamless scroll.
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Need guidance with nes to snes.

Post by 93143 »

Are you sure it was the top portion that was off? That seems very weird.

Keep in mind that "neutral" vscroll on SNES is -1 because of the blank line 0.
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

93143 wrote: Sun Jun 20, 2021 9:11 pm Are you sure it was the top portion that was off? That seems very weird.

Keep in mind that "neutral" vscroll on SNES is -1 because of the blank line 0.
From my observation yes, it was the top that was the issue when I came to needing to alter the table, after 7F has been read for # of scanlines.

When I proceeded with the continuation of the code, I couldn't get the two screens to stay together perfectly, I kept adjusting the value for the lower y scroll, but the more I screwed with that, the more it kept the bottom layer stationary, it even move upward. The values for the upper and lower are always a 10 byte difference between the upper and lower screen. I wasted hours fiddling with the lower value. So I decided to screw with the upper value, and when I shifted the byte by -1 scanline, the upper & lower layer were perfectly aligned.

My concern, since I was modifying the table on the tkt frame by frame, waa that there might me a noticeable slowdown with the scroll screen transition, since 1 frame I've shifted back 1 scanline, but when watching the transition in real time, it is undetectable! All smooth and perfect pixels!
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Need guidance with nes to snes.

Post by dougeff »

is scanline zero always blank? I don't remember reading that anywhere.
nesdoug.com -- blog/tutorial on programming for the NES
infidelity
Posts: 490
Joined: Fri Mar 01, 2013 4:46 am

Re: Need guidance with nes to snes.

Post by infidelity »

Idk.

However, I've now just figured out the equations for going down! :-D just finished tightening up the code. I'm at work now, but will write out exactly what it all is. :-)

update when an irq split screen is activated that moves up & down, the gap between screens is still present, will need to figure that out. But right now I'm checking every stage to view the vertical transitions, so far all are 100%

update 2 so now that I'm working on the hdma/irq splits, I'm now able to alter that 3rd byte in my hdma table, to determine which tile map to show.
creaothceann
Posts: 611
Joined: Mon Jan 23, 2006 7:47 am
Location: Germany
Contact:

Re: Need guidance with nes to snes.

Post by creaothceann »

dougeff wrote: Mon Jun 21, 2021 5:42 am is scanline zero always blank?
Yes.

IIRC background tiles are loaded several pixels in advance, but the sprites to be displayed on scanline x need to be determined at scanline x-1. As a result for scanline 0 there would be invalid data in the sprite buffers, so scanline 0 is just automatically blanked.
My current setup:
Super Famicom ("2/1/3" SNS-CPU-GPM-02) → SCART → OSSC → StarTech USB3HDCAP → AmaRecTV 3.10
Post Reply