Screen Split (No mapper)

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
UsernameInUse
Posts: 2
Joined: Fri Dec 11, 2020 12:57 pm

Screen Split (No mapper)

Post by UsernameInUse » Fri Dec 11, 2020 1:09 pm

Hi!

I'm making a vertical scrolling game on a basic (32K PRG 8K CHR) cartridge. I understand how nametables and basic scrolling works.
For now, my goal is to make a status bar at the top of the screen (32x3 tiles). I checked some Sprite 0 Hit threads but I don't quite understand how it works. Please, show a simple code for basic vertical scrolling splitting.

I also have more questions.
1. How to detect the current PPU scanline?
2. How to force load a scroll position?

Thanks in advance.

Best regards,
Tom.

tepples
Posts: 22288
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Screen Split (No mapper)

Post by tepples » Fri Dec 11, 2020 1:22 pm

What the PPU does:
One scanline before a frame starts, $2002 bit 6 ($40 place value) becomes 0.
When an opaque pixel of sprite 0 and an opaque pixel of the background are drawn at the same position, $2002 bit 6 becomes 1. This event during the frame is called the "sprite 0 hit", as described in NESdev Wiki article "PPU OAM" section "Sprite zero hits".

What a program on the CPU does with it:
This is seen, for example, with the bottom of the coin in the status bar in the first Super Mario Bros.
Every vblank, the program sets the scroll position for the status bar, spins in a loop waiting for $2002 bit 6 to become 0 and then become 1, and then changes the scroll position for the playfield.

Now you have three smaller problems:
  1. How to line up sprite 0 with the bottom of the status bar to arrange for a sprite 0 hit to happen. The best way to arrange for this depends on a mock screenshot of what you want the top status bar and playfield to look like.
  2. How to wait for the sprite 0 hit. The simplest way that could possibly work is this:

    Code: Select all

    : 
      bit $2002
      bvs :-
      bit $2002
      bvc :-
    
  3. How to change the scroll position mid-frame, which is trickier than setting scroll at the top of the screen especially if scrolling vertically. You'll probably need a sequence of writes to $2006, $2005, $2005, and $2006, as described in NESdev Wiki article "PPU scrolling" section "Split X/Y scroll". See tokumaru's code example in the topic "Screen split and vertical scrolling in the bottom half".

lidnariq
Posts: 10273
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Screen Split (No mapper)

Post by lidnariq » Fri Dec 11, 2020 1:24 pm

UsernameInUse wrote:
Fri Dec 11, 2020 1:09 pm
1. How to detect the current PPU scanline?
You can't. Not directly, anyway. Without a mapper, there are five options:
1- Wait for the sprite 0 hit flag to become true
2- Wait for the "9 sprites on a scanline" flag to become true
3- Count cycles
4- Magic with OAM evaluation
5- Magic with the DPCM IRQ

Pokun
Posts: 1760
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Screen Split (No mapper)

Post by Pokun » Fri Dec 11, 2020 2:11 pm

Nerdy Nights also got sprite 0 hit covered.

User avatar
dougeff
Posts: 2825
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Screen Split (No mapper)

Post by dougeff » Fri Dec 11, 2020 4:00 pm

Does it need to be NROM?

You could use a mapper with single screen mirroring, such as AxROM or MMC1. You would use mapper registers to swap nametables. The main screen on one nametable, the HUD on another nametable.

Example, Cobra Triangle.

I can't remember what it uses to time the split, but sprite zero hit would be the easiest.
nesdoug.com -- blog/tutorial on programming for the NES

Post Reply