upernes

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Patrick FR
Posts: 78
Joined: Tue Jan 19, 2010 10:35 am
Location: Lyon

Re: upernes

Post by Patrick FR »

By the way, you need to add a ton of indirect addresses to the 'super mario'.txt file containing the indirect jumps:
Here is my file (the crc is used to assert that we are using the same ROM dump):

crc32: $F2DB8422

IndirectJump: $06
addr: $8231
addr: $8FCF
addr: $8567
addr: $858B
addr: $859B
addr: $8652
addr: $865A
addr: $8693
addr: $86A8
addr: $86E6
addr: $93FC
addr: $88AE
addr: $92DB
addr: $9B0E
addr: $9A2E
addr: $85BF
addr: $85E3
addr: $8643
addr: $86FF
addr: $8732
addr: $8749
addr: $9061
addr: $8245
addr: $9131
addr: $B069
addr: $B0E9
addr: $B35A
addr: $AEDC
addr: $8FE4
addr: $889D
addr: $9071
addr: $AEEA
addr: $B376
addr: $C2F1
addr: $C8E0
addr: $CA77
addr: $98E5
addr: $B36D
addr: $BDD2
addr: $BC85
addr: $B233
addr: $9B01
addr: $BB38
addr: $B269
addr: $9B41
addr: $91CD
addr: $B245
addr: $9B14

If not the same rom, add the unknown address given by the converted rom and convert it again until it works.
Patrick FR
Posts: 78
Joined: Tue Jan 19, 2010 10:35 am
Location: Lyon

Re: upernes

Post by Patrick FR »

Improving the speed of the nametable writes:

Updating vram by column:
We update columns of tiles. 8 colums, they can be updated by DMA using a 32 words increment.

Updating vram by Line case:
We e update lines. Same thing but one by one increment, 30 lines.

This can be made through DMA (10 times faster than a loop).
However, the line or column must be identified. The background mirroring bit can help.
2 columns or line will be updated at each NMI, not overloading the console. It can be done by DMA or by HDMA.
Bit masks can determine what to update.

However I checked if it was really the BG update who were slowing down the program. I removed it from the NMI routine and it changes nothing to the speed, maybe it's the sprite zero emulation? Balloon Fight is always fluid, it does not use it.

Edit:
Btw the Sprite0 emulation does not work well on the test rom, something is wrong with it or when writing in the scrolling registers while rendering. Sometimes it works, sometimes it stays at (0, 0). That's why the screen is shaking so much.
Maybe the scrolling values should be always written using the HDMA.
Last edited by Patrick FR on Sun Jun 04, 2017 7:44 am, edited 1 time in total.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: upernes

Post by tepples »

What do you update if the game changes an attribute byte and nothing else?

It's straightforward for a game to squeeze in full screen updates to the attribute tables of both nametables. I can make an attribute update torture test ROM if you want.
Patrick FR
Posts: 78
Joined: Tue Jan 19, 2010 10:35 am
Location: Lyon

Re: upernes

Post by Patrick FR »

Every name value must be changed when attributes are changed. Because of the background tile format, otherwise it would use only one palette for the tiles instead of 4.
However the full bank copy to VRAM seems to be fast enough. I assumed it was not and I was wrong, "assume nothing" when optimising. According to the documentation, the DMA can copy up to 6KB during vblank.

The Sprite0 flag and change the scroll registers during rendering seems to be the main problem.
Patrick FR
Posts: 78
Joined: Tue Jan 19, 2010 10:35 am
Location: Lyon

Re: upernes

Post by Patrick FR »

I checked the conversion of my sprite0 test rom (t9_sprite0.sh) and it shows the same problem. Scrolling during rendering seems to work, but it is like it misses sprite zero hits.
And by stopping the program randomly it shows that it updates the sprite CHR data in VRAM all the time.
I will fix this :)
Patrick FR
Posts: 78
Joined: Tue Jan 19, 2010 10:35 am
Location: Lyon

Re: upernes

Post by Patrick FR »

Sprite0 emulation looks fine, it's something with the ppu control register, it takes too long to call it and it misses frames when looking for the sprite zero hit and vblank.
I tried the test rom ont the console and the picture is fine, and it is fast. While it flickers on bsnes plus.
On the other side it flickers on smb on the real hardware like on the emulator. And seems slow.
The title screen of SMB does not show, I read that it could be because of some missing delay in PPU reads.

Here are the reads performed by SMB:
.DW rlda_2002
.DW rldx_2002
.DW rlda_2007 <- it works, the latching was tested

The mirroring must be emulated by making a copy of the nametables bank 1 after bank 2.
Nametables bank 2 is not very clean, the lower part is missing.

Other tests:
Donkey kong still slow.
Battle city shows something.
Excite bike shows the title screen, need to add more indirect addresses.
Galaga does nothing
Ice climber hangs

So it looks like something is slowing everything down. But it does not show any-more on the Sprite0 test Rom.
Patrick FR
Posts: 78
Joined: Tue Jan 19, 2010 10:35 am
Location: Lyon

Re: upernes

Post by Patrick FR »

I just fixed the nametable mirroring problem and the palette mirroring.
The nametable mirroring is achieved by making a copy of the first bank after the second one. And this is slooow, I must implement the line and column update.
Patrick FR
Posts: 78
Joined: Tue Jan 19, 2010 10:35 am
Location: Lyon

Re: upernes

Post by Patrick FR »

Second correction, I used the proper way of mirroring without adding a copy.
The sprite 0 hit system shakes, it misses vblanks because of the nametables copy at each NMI. I will update the Names only by columns. The direction of mirroring is in the rom file header, therefore it will be vertical/line or horizontal/lines updating.
Enabling the video sync on bsnes plus solves the problem of blinking images on the sprite 0 test ROM.

Another thing to add, is a branch tree for the indirect jumps. There are hundreds of indirect jumps addresses in SMB1 and testing each one slows everything down.
Patrick FR
Posts: 78
Joined: Tue Jan 19, 2010 10:35 am
Location: Lyon

Re: upernes

Post by Patrick FR »

Once a lot of indirect jumps have been detected and every system side of the program is running, it is not needed to check for indirect jump destination @. An option would disconnect the indirect jump check routine and leave the indirect jumps non patched. Like adding IndJumpDisable: 1 in the indirect jump file
And a read of every byte in the program would count probable missing io accesses or missing indirect jumps in order to check for missing patches.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: upernes

Post by tepples »

Patrick FR wrote:I will update the Names only by columns. The direction of mirroring is in the rom file header, therefore it will be vertical/line or horizontal/lines updating.
I could make a torture test ROM for that too.
Patrick FR
Posts: 78
Joined: Tue Jan 19, 2010 10:35 am
Location: Lyon

Re: upernes

Post by Patrick FR »

A torture rom is not mandatory to pass the problem, but it could be fun to try to pass it. Like a rom with vertical scrolling and a rom with horizontal scrolling. And of course attribute table changes.
Patrick FR
Posts: 78
Joined: Tue Jan 19, 2010 10:35 am
Location: Lyon

Re: upernes

Post by Patrick FR »

I tried to reduce the cost of updating the background in vram and the column technique is not that great because it does not use the DMA. A line approach seems better because it uses the DMA.
However, even when reducing the cost of the transfer, the sprite zero emulation glitches. Event without handling the indirect jumps. While it is faster, like on the original but it glitches a lot. It is like it misses the end of the VBlank or the collision. It could also be a bug.
I have to look at it.
Patrick FR
Posts: 78
Joined: Tue Jan 19, 2010 10:35 am
Location: Lyon

Re: upernes

Post by Patrick FR »

I had a problem in PPUSTATUS, I assumed that the Vblank bit was not set when NMI was disabled... :|
I fixed that, but it still glitches.
edit: it seems to be the values written in the register causing problem, once it is like 4 and the other time it is 260 (the correct value). I must find out why incorrect values a written into the PPUSCROLL register. Maybe it is because 260 = $0104 and the highest bit is lost. This bit seems to be changing a lot.

I will try to fix the title screen first. It does not show the "Super Mario Bros." picture, nor 1 or 2 players. Anyone knows what could be the cause? By cause I mean a IO read having a peculiar behaviour.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: upernes

Post by tepples »

The title screen of Super Mario Bros. relies on the ability to read CHR ROM while rendering is off.

When you read video memory using $2007, the PPU returns the last value read from video memory and then reads the next value from VRAM. This means if I set the video memory address to $0F00, I have to read once and throw that value away

Code: Select all

lda #$0F
sta $2006
lda #$00
sta $2006  ; VRAM address = $0F00
lda $2007  ; A := last byte (usually garbage), and last byte := value at $0F00
lda $2007  ; A := last byte (value at $0F00), and last byte := value at $0F01
lda $2007  ; A := last byte (value at $0F01), and last byte := value at $0F02
Because NES and Super NES tiles are in different formats, and because Super NES video memory is word-addressed, literal translation of code that reads CHR ROM will probably fail.
Patrick FR
Posts: 78
Joined: Tue Jan 19, 2010 10:35 am
Location: Lyon

Re: upernes

Post by Patrick FR »

I looked what my code did (I never fully tested that part) and reading from the CHR data was ok but the Acc value was destroyed by the address increment emulation...
I tend to keep the data in nes format, but I am not sure about the CHR data, however it works.

The title screen is all right now. Thanks :)
Post Reply