PPU Emulation - nestest ROM

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
jotac
Posts: 12
Joined: Wed Feb 17, 2021 1:08 pm

PPU Emulation - nestest ROM

Post by jotac » Wed Feb 17, 2021 1:16 pm

Hello,

I have finished a cycle-accurate implementation of the 6502 CPU and tested it with the `nestest.nes` ROM.

I am trying to implement the PPU now. I have loaded and displayed the pattern memory and print it out and checked it is ok. I have displayed the nametables and also verified they are correctly displayed.

However, they certainly are not correctly filled with the `nestest.nes` ROM (and all the other ROMs). Currently, I am not using the color palettes and instead, I use shades of blue, but I have this:

[img][https://drive.google.com/file/d/1OlIDpe ... sp=sharing]

Notice that the line rendered "SELECT: Invalid ops" is the last line of the nestest ROM screen.

So I went on about seeing if the fine_y and coarse_y were incremented. Turns out they were, but after the screen was all already rendered.

By "already rendered" I mean that I can see, byte by byte, the lines being writen onto the nametable, but the following line overwrites the first because coarse_y and fine_y still did not increment. It is only after the last line (the SELECT line) is written, that the coarse and fine ys start incrementing.


I have no clue whatsoever, I leave here my relevant PPU code:
https://gist.github.com/joao-conde/60f6 ... 37b3e49cd2

Any help or debug suggestions appreciated, thanks!

User avatar
Quietust
Posts: 1710
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: PPU Emulation - nestest ROM

Post by Quietust » Wed Feb 17, 2021 4:34 pm

I'm not particularly familiar with Rust, but this code doesn't look right:

Code: Select all

impl From<u16> for VRAMAddress {
    fn from(word: u16) -> VRAMAddress {
        VRAMAddress {
            coarse_x: (word & 0x001F) as u8,
            coarse_y: (word & 0x03E0) as u8,
            nametable_x: (word & 0x0400) as u8,
            nametable_y: (word & 0x0800) as u8,
            fine_y: (word & 0x7000) as u8,
        }
    }
}
Based on the code below it, it seems like it ought to be more like this:

Code: Select all

impl From<u16> for VRAMAddress {
    fn from(word: u16) -> VRAMAddress {
        VRAMAddress {
            coarse_x: (word & 0x001F) as u8,
            coarse_y: ((word & 0x03E0) >> 5) as u8,
            nametable_x: ((word & 0x0400) >> 10) as u8,
            nametable_y: ((word & 0x0800) >> 11) as u8,
            fine_y: ((word & 0x7000) >> 12) as u8,
        }
    }
}
Of course, I'm not sure if that's the only problem, but it certainly seems to be one of them.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

jotac
Posts: 12
Joined: Wed Feb 17, 2021 1:08 pm

Re: PPU Emulation - nestest ROM

Post by jotac » Sun Feb 21, 2021 9:31 am

You are absolutely right @Quietust ! Thanks

Post Reply