It is currently Sun Dec 16, 2018 2:36 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 29 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Tue Sep 18, 2018 10:37 am 
Offline

Joined: Sat Aug 25, 2018 7:21 am
Posts: 29
Hi.
I made my journey through the PPU wiki, but everything is a little bit messy in my head. So I'm here to ask you for advice on how to start... basically. Any clue will be welcome. My CPU is fully working (maybe NMI and IRQ interrupts are a proper starting point?), but now I don't know what to do first (assume I understand the contents displayed on the wiki more or less). I don't want you to trace a route map for me, just some advice to start.

I think I could try to write my own PPU Viewer so it helps me out with the memory structure of the PPU. What do you think of this? However, I feel like I don't really understand the "working cycle" of the PPU: it draws 256 scanlines plus the hidden ones [post-render?] and after that VBLANK takes place, during which PPU "calculates" the next frame (sprite 0 hit, nametable switching [if it's set], etc). That's a summary of what I understand.


Last edited by HastatusXXI on Mon Sep 24, 2018 8:10 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 12:17 pm 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11013
Location: Rio de Janeiro - Brazil
A common first step in PPU emulation is to code an "instantaneous" PPU, which draws an entire frame all at once every frame, sampling the PPU settings (scroll, palettes, etc.) from a specific time in the frame.

This is horribly inaccurate, and anything that requires any sort of CPU-PPU synchronization will fail, but a few games should be playable this way.

This will help you familiarize yourself with the formats of the pattern, name and attribute tables, as well as various other settings and components that impact the way the image is rendered.

Once you understand how the data is used to form a picture, you can increase the parallelism and simulate the PPU alongside the CPU, doing all the memory fetches and logic that the actual PPU does.


Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 1:22 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3726
Location: Mountain View, CA
Do what tokumaru says. Additional points alongside his:

- Don't worry about mappers. Focus only on first-generation mapper 0 (NROM) games for now
- Use games like Donkey Kong, Mario Bros (NOT Super!), Clu Clu Land, and Pinball as starting games. They make for good test subjects. You *can* get these working with the model/method tokumaru describes
- Yes, you will need NMI, guaranteed. Bit 7 of $2000 will play a critical role in getting things working, along with bit 7 of $2002 (else you'll find game code spinning waiting for that bit)
- You will need to implement some generic joypad methodology for $4016/4017, else some games will spin waiting for certain behaviour
- Don't worry about IRQ for now
- Don't worry about audio for now

Edit: clarification (d7 of $2000 vs. $2002)


Last edited by koitsu on Wed Sep 19, 2018 11:35 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 1:25 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 4108
Surprisingly, Mappers aren't that hard, and games like Mega Man or Mega Man 2 will work fine even with an instantaneous rendering PPU.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Last edited by Dwedit on Wed Sep 19, 2018 6:43 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Wed Sep 19, 2018 4:39 am 
Offline

Joined: Sat Aug 25, 2018 7:21 am
Posts: 29
Yeah, definitely, I'll do what tokumaru suggests. Thank you for your anwers!


Top
 Profile  
 
PostPosted: Wed Sep 19, 2018 1:32 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3155
Location: Brazil
No offense, but I'll say my opinion - do NOT do what he's saying. Reason - you are going to write an inaccurate software and placed down to the others. I experienced this back in 1998. Try to follow what's described in the PPU section (even if it looks crypt) and always have a goal of ACCURACY. Otherwise, as I said, you're producing something NOT interesting, since we have tons of NES emulator projects, but only a few ones made a public release.

The choice is yours now.


Top
 Profile  
 
PostPosted: Wed Sep 19, 2018 4:21 pm 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11013
Location: Rio de Janeiro - Brazil
I certainly didn't suggest releasing an emulator with a crude PPU implementation to the public, but as a private milestone, it makes sense to implement things in the simplest possible way to increase your understanding of that thing.

As long as people are capable of telling apart personal accomplishments from products worth releasing, it's OK to make things that are less than perfect. This is true for emulators, games, or anything really.


Top
 Profile  
 
PostPosted: Wed Sep 19, 2018 4:24 pm 
Online

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20886
Location: NE Indiana, USA (NTSC)
The one wrinkle in that: Certain well-known source code backup services tend to charge more for a private project than a public one.


Top
 Profile  
 
PostPosted: Wed Sep 19, 2018 5:43 pm 
Offline

Joined: Sun Mar 27, 2011 10:49 am
Posts: 266
Location: Seattle
That's only a wrinkle if you choose to make it one and happen to insist on using that particular code hosting service and don't want to or can't pay for a private repo.

And FWIW I don't see anything wrong with "making available publicly because I don't want to or can't pay for a private repo". Especially because, if you aren't going around advertising it, your random repo in a sea of millions will likely go unnoticed anyway.

The only question I have is whether hitching your emulator to a fundamentally inaccurate PPU will add technical debt that'll be a pain to pay off in the future. But I've never written an NES emulator, so I don't have much to add there.


Top
 Profile  
 
PostPosted: Fri Sep 21, 2018 8:01 pm 
Offline

Joined: Sun Mar 27, 2016 7:56 pm
Posts: 181
Just to give you a high-level picture of what's going on, and clear up some misconceptions in your initial post:

The PPU doesn't calculate a whole frame at once (it wouldn't have enough RAM to store all that data!). Rather, it fetches and calculates stuff as the frame is being rendered and displayed on-screen. The CPU is still running as this happens, so a lot of effects like status bars and so on are done by having the CPU change PPU settings in the middle of a frame being rendered. (Though, the programmer has to be careful about what they change and when they change it, so that they don't end up interfering with the PPU and causing graphical glitches.)

Vblank is actually when the PPU is idle. This is why you can access things like PPU memory during vblank, which you aren't really able to do while the frame is rendering, since the PPU is accessing it at the time.

On NTSC systems (like in the US and Japan), there are 262 scanlines total:
  • 0-239 are the visible scanlines, where the PPU is rendering. In other words, the game screen is 240 pixels tall.
  • 240 is the post-render scanline, which could have been the start of Vblank, since the PPU is idle, except... for whatever reason the Vblank flag isn't actually set until the next scanline.
  • 241-260 is Vblank, lasting for 20 scanlines. (On PAL systems, this would be 70 scanlines instead, since games run at 50 FPS instead of 60, so there's more time between frames.)
  • 261 is the last scanline, where the PPU has to fetch some things to prepare for the next frame. You could also think of this as scanline -1.

There's some more detailed information here.


Top
 Profile  
 
PostPosted: Fri Sep 21, 2018 8:15 pm 
Offline
User avatar

Joined: Mon Jul 16, 2018 2:57 pm
Posts: 22
Nicole wrote:
Just to give you a high-level picture of what's going on, and clear up some misconceptions in your initial post:

The PPU doesn't calculate a whole frame at once (it wouldn't have enough RAM to store all that data!). Rather, it fetches and calculates stuff as the frame is being rendered and displayed on-screen. The CPU is still running as this happens, so a lot of effects like status bars and so on are done by having the CPU change PPU settings in the middle of a frame being rendered. (Though, the programmer has to be careful about what they change and when they change it, so that they don't end up interfering with the PPU and causing graphical glitches.)

Vblank is actually when the PPU is idle. This is why you can access things like PPU memory during vblank, which you aren't really able to do while the frame is rendering, since the PPU is accessing it at the time.

On NTSC systems (like in the US and Japan), there are 262 scanlines total:
  • 0-239 are the visible scanlines, where the PPU is rendering. In other words, the game screen is 240 pixels tall.
  • 240 is the post-render scanline, which could have been the start of Vblank, since the PPU is idle, except... for whatever reason the Vblank flag isn't actually set until the next scanline.
  • 241-260 is Vblank, lasting for 20 scanlines. (On PAL systems, this would be 70 scanlines instead, since games run at 50 FPS instead of 60, so there's more time between frames.)
  • 261 is the last scanline, where the PPU has to fetch some things to prepare for the next frame. You could also think of this as scanline -1.

There's some more detailed information here.


Nicole's summary is really great. I know there has been a debate on here recently about what should be on the Wiki. I would argue that a short, concise summary of a topic, in non-technical (but accurate) language, like the one Nicole gave above should be at the top of every Wiki page. It would set the tone of the Wiki as approachable but accurate. Thank you, Nicole!


Top
 Profile  
 
PostPosted: Sat Sep 22, 2018 3:23 am 
Offline

Joined: Sat Aug 25, 2018 7:21 am
Posts: 29
Yeah, thank you Nicole. Your post helped me clarify some misconceptions of mine.

I'm going with tokumaru's approach, Zepper. Of course it's only draft code that I hope will help me understand the PPU as a whole. After it's acomplished its mission, I'll discard it and write proper code with proper synchronization with the CPU, but, at the moment, I don't see the big picture.

About the private hosting inconvenience you mentioned... no worries. I have private backup source code hosting at the moment thanks to my university.


Top
 Profile  
 
PostPosted: Sat Sep 22, 2018 3:42 am 
Offline

Joined: Sat Aug 25, 2018 7:21 am
Posts: 29
I came across something... strange. I started by drawing sprite tiles on screen, but they appear mirrored in X axis. I'm using YYCHR to check my code correctness and everything is drawn right except for this mirroring. I'm using SDL and I know X grows from left to right and Y from up to down, so that's not the cause. And I also know I can invert the tile drawing from right to left, but I'd rather not. What the reason for this mirroring?

Just to clarify, this is the first tile (YYCHR):
Image

This is what my program draws:
Image


Top
 Profile  
 
PostPosted: Sat Sep 22, 2018 7:25 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1441
HastatusXXI wrote:
I came across something... strange. I started by drawing sprite tiles on screen, but they appear mirrored in X axis. I'm using YYCHR to check my code correctness and everything is drawn right except for this mirroring. I'm using SDL and I know X grows from left to right and Y from up to down, so that's not the cause. And I also know I can invert the tile drawing from right to left, but I'd rather not. What the reason for this mirroring?

Just to clarify, this is the first tile (YYCHR):
Image

This is what my program draws:
Image

Not to be blunt, but if your graphics code draws sprites flipped horizontally, then flip them before drawing them so they show up correctly - you're going to have to figure out how to flip sprite tiles anyways (each sprite can be flipped horizontally and/or vertically), so you may as well do it now.

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


Top
 Profile  
 
PostPosted: Sat Sep 22, 2018 8:34 am 
Offline

Joined: Sat Aug 25, 2018 7:21 am
Posts: 29
Quietust wrote:
HastatusXXI wrote:
I came across something... strange. I started by drawing sprite tiles on screen, but they appear mirrored in X axis. I'm using YYCHR to check my code correctness and everything is drawn right except for this mirroring. I'm using SDL and I know X grows from left to right and Y from up to down, so that's not the cause. And I also know I can invert the tile drawing from right to left, but I'd rather not. What the reason for this mirroring?

Just to clarify, this is the first tile (YYCHR):
Image

This is what my program draws:
Image

Not to be blunt, but if your graphics code draws sprites flipped horizontally, then flip them before drawing them so they show up correctly - you're going to have to figure out how to flip sprite tiles anyways (each sprite can be flipped horizontally and/or vertically), so you may as well do it now.


I know how to flip them, it's easy. However, I want to know if this is normal (PPU manages memory in a big-endian fashion, AFAIK), since the wiki states that the colour of a row of 8 pixels in a 8x8 tile is determined by using the corresponding byte of pattern table 0 as 0 bit values and the corresponding byte of pattern table 1 as 1 bit values and this is how I implemented my program. Is YYCHR flipping the sprites prior to drawing them?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 29 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google [Bot] and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group