Pallete affects scroll value

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

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

Re: Pallete affects scroll value

Post by Pokun »

Yes and if it's a one player game you read bit 0 and bit 1 of $4016 as controller 1 data so that either standard or expansion controller can be used. If it's a two player game you also read bit 0 and bit 1 of $4017 as controller 2 data. This is what (most) commercial games do.
Only if you have a three or four player game you would treat bit 0 of $4016 and $4017 as separate data (as controller 1 and 2) from bit 1 (as controller 3 and 4). In that case you would also want to support the four score.
IMAGICA wrote:I need to learn buffering first
The Nerdy Nights sound tutorial actually has a (graphic) buffering system that is worth studying.
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

Can you confirm if I'm reading bit 1?

Code: Select all

 LDA #$01
  STA $4016
  LDA #$01
  STA $4016
  LDX #$08
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Pallete affects scroll value

Post by Pokun »

Not there. There you are writing to the $4016 output port, which is used by the controller as a command that it's time to send its current button data to the NES. It's called a latch or strobe for the controllers, and it gets you all controllers including the expansion port controllers.


Here is where you don't read bit 1:

Code: Select all

  LDX #$08
ReadController1Loop:
  LDA $4016
  LSR A            ; bit0 -> Carry
  ROL buttons     ; bit0 <- Carry
  DEX
  BNE ReadController1Loop
 
  RTS
You shift bit 0 of $4016 into Carry (using LSR) and then rotate it out of Carry and into the RAM register "buttons" (using ROL). But you never touch bit 1 of $4016.

A simple way is to just add another set of LSR and ROL to get bit 1 into a temporary variable. Then you merge the two variables using OR.

Code: Select all

  LDX #$08
ReadController1Loop:
  LDA $4016            ;get button data from bit 0 (con I) and bit 1 (con III)
  LSR A                ;shift button data from bit 0 into carry
  ROL buttons          ;rotate carry into a RAM register (con I buttons)
  LSR A                ;shift button data from bit 1 into carry
  ROL temp             ;rotate carry into a RAM register (con III buttons)
  DEX
  BNE ReadController1Loop

MergeControllers:
  LDA temp
  ORA buttons            ;OR con III with con I to merge them
  STA buttons

  RTS
And if your game is using two controllers you just repeat this code but use $4017 instead to get controller II and IV, and then merge them with each other the same way.



Edit: The easiest way to test if expansion port controllers (AKA controller III and IV) are working, is to test the game in an emulator like FCEUX and enable "Famicom 4-player Adapter" or similar. Then you just enable controller III in the emulator and see if it works with your game the same as controller I.
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

Thanks by the way what is the advantage of 8x16 sprites are? I willing to remake my sprites if it has advantages I need.
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Pallete affects scroll value

Post by rainwarrior »

IMAGICA wrote:Thanks by the way what is the advantage of 8x16 sprites are? I willing to remake my sprites if it has advantages I need.
We had a recent thread on that topic:
https://forums.nesdev.com/viewtopic.php?f=2&t=16235

The advantage is really just that they're bigger. You can cover more screen with them, and use all 8K of the CHR tables rather than just one 4K side.

Conversely, the disadvantage is also that they're bigger. You'll end up with more wasted space at edges, and probably more overlap problems (i.e. 8 sprites per scanline issues).
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

I'm Still here. I'm now fixing the vblank issue of the game.
I'm also goin to post the code for anyone to find pout the v blank issue that Pokun gave the answer to.
Pokun wrote:
IMAGICA wrote: 2. I Don't want the All nmi approach. I want some of the rendering to go Outside Like text, boss AI and other stuff. I heard that It boggles down speed if your not careful.
Then just move out all your logic from the NMI and put it in your forever loop. Only keep the graphic updates (OAM, VRAM, $2000, $2001 and $2005 writes) in the NMI.
IMAGICA wrote: 3. It's a one player game. However, If I get to demaking smash bros., I'll need that info
You misunderstand me. If it's a one player game, you need to read both bit 0 and bit 1 of $4016 to your controller 1 data so that people can use both standard controllers and Famicom expansion port controllers. Nerdy Nights doesn't teach this but it's good practice to do it. Else people might not be able to use their arcade sticks and other controllers with your game.
IMAGICA wrote: 4. I found an article on stacks pha and pla. I just need to figure out where my buffer's going to go.
Your buffers goes into RAM wherever there is space. You are already buffering OAM and scroll in RAM. I like to keep my OAM buffer on RAM page 2 ($0200~$02FF), BG and palette buffers in page 3, and scroll and $2000/$2001 buffers in the zero page. The BG buffer can't be too big (there's not enough vblank time to draw the whole nametable), so you could also keep BG and palette buffers at the beginning of page 1. The stack starts in the other end of page 1 so unless you use a lot of stack there's no risk they will collide.
Attachments
Kitsunetales.asm
(26.46 KiB) Downloaded 102 times
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Pallete affects scroll value

Post by Pokun »

The https://wiki.nesdev.com/w/index.php/The_frame_and_NMIs explains how you can structure your code to keep graphic updates and game logic separate.

A few problems:

Code: Select all

  lda #%00000001
  sta $4017 ;enable Square 1
I guess you meant $4015 here, that's where you enable/diable APU sound channels.

Code: Select all

clrmem:
  LDA #$00
  STA $0000, x
  STA $0100, x
  STA $0200, x
  STA $0400, x
  STA $0500, x
  STA $0600, x
  STA $0700, x
  LDA #$FE
  STA $0300, x
  INX
  BNE clrmem
I guess you meant to initialize $0200 to $FF, not $0300, since you are using $0200 as OAM buffer later in your code. You should do it like this:

Code: Select all

clrmem:
  LDA #$00
  STA $0000, x
  STA $0100, x
  STA $0300, x
  STA $0400, x
  STA $0500, x
  STA $0600, x
  STA $0700, x
  LDA #$FE
  STA $0200, x
  INX
  BNE clrmem
This makes sure all sprites are off screen at boot, hiding them.

Code: Select all

Forever:

  JMP Forever     ;jump back to Forever, infinite loop
Here is your main loop, here you can put all logic (except sound which is better off in the NMI to avoid sound lag).

Mine look something like this:

Code: Select all

main:
  jsr con_read       ;read controllers
  jsr logic          ;state machine with all game logic, like: input handlers, moving objects, collisions gravity etc

  lda #$01
  sta draw_flag           ;allow NMI to draw, prevents incomplete buffering
nmi_wait:
  lda nmi_end_flag
  beq nmi_wait            ;wait for NMI to finish, this limits logic to a fixed frame rate
  lda #$00
  sta nmi_end_flag        ;clear NMI completion flag
  jmp main
At the end of the main loop I wait for an NMI to finish. This makes sure there is only one NMI (graphic update) per main loop (game logic). Inside the NMI I only update graphics if the draw flag is set, otherwise I skip it. This prevents the NMI from drawing a frame if the main loop hasn't finished in time for the vblank. Also at the end of the NMI I set the NMI end flag so the main loop knows when it's time to start the next iteration.

In your NMI you first push A, X and Y to the stack so they don't mess with your logic, should an NMI happen in the middle of it. Then check for the draw flag, and skip updates if it's clear, then you fires off your OAM DMA (writing 0 to $2003 and $02 to $4014) to update sprites. After that you should do all your nametable and palette updates ($2006 and $2007) and finally scroll ($2005) and any PPU setting changes ($2000 and $2001).

After that you can do sound and anything else that you want to happen constantly at 60 Hz (or 50 Hz if PAL) without lag, but doesn't need to be in vblank (because vblank time might be up before your NMI handler has finished, that's why we put graphic updates first in the NMI).
And finally last thing before the RTI you have to pull A, X and Y from the stack again (in reverse order from that you pushed them in).

Just ask if there's something not clear enough.
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

Pokun wrote:

Code: Select all

main:
  jsr con_read       ;read controllers
  jsr logic          ;state machine with all game logic, like: input handlers, moving objects, collisions gravity etc

  lda #$01
  sta draw_flag           ;allow NMI to draw, prevents incomplete buffering
nmi_wait:
  lda nmi_end_flag
  beq nmi_wait            ;wait for NMI to finish, this limits logic to a fixed frame rate
  lda #$00
  sta nmi_end_flag        ;clear NMI completion flag
  jmp main
how would

Code: Select all

 lda nmi_end_flag
  beq nmi_wait            

work in this function?

second if I were to modify the mirroring at the end, woulden't I get an error?
Heard that's only possible with mmc3.
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Pallete affects scroll value

Post by tepples »

The NMI handler interrupts the loop and sets the flag to a nonzero value.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Pallete affects scroll value

Post by dougeff »

if I were to modify the mirroring at the end, woulden't I get an error?
Heard that's only possible with mmc3.
PPU Mirroring is hardwired into the PCB (by soldering a spot). It can't be changed except by a special mapper (such as MMC3).

Perhaps there is some other kind of mirroring you are talking about? Many of the CPU RAM addresses are mirrors of other addresses, for example.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

tepples wrote:The NMI handler interrupts the loop and sets the flag to a nonzero value.
How would that happen?

My code is stuck.

I can't just expect it to do it.
what's the "special flag" stack I need to link to it?
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Pallete affects scroll value

Post by dougeff »

If you look at the wiki page on PPU registers...

http://wiki.nesdev.com/w/index.php/PPU_registers

You will see, setting bit 7 on register $2000 will tell the PPU to generate an NMI signal at the end of every frame (at the start of vertical blanking).

With NMIs on, the code will automatically jump to the NMI code (wherever the NMI vector points to), and then once it sees an RTI, will return to the main code.

The NMI code is where you should update sprites, make changes to the background, and call the music subroutine.

Or, you could just flip a NMI_flag on, and immediately RTI. In this scenario, the main code would be looking for changes in the NMI_flag, before it does those things I mentioned (sprites, BG, music)

And read the controllers, maybe.

Edit - on a side note, NMIs are not affected by SEI and CLI, hence the "non maskable" in the name.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

Here's something I've learned:
Never use a NMI that is used to render 8x8 sprites to render 8x16 sprites
Also don't mess with the vblank. I am learning x and y rendering values.


... how do you push x and y?
phx and phy?
Attachments
Kitsunetales.asm
(26.94 KiB) Downloaded 87 times
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Pallete affects scroll value

Post by dougeff »

PHY and PHX don't exist.

PHY = TYA PHA
PHX = TXA PHA

If you need to preserve A, first store A to a temporary variable...

STA temp
TYA
PHA
LDA temp
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Pallete affects scroll value

Post by tokumaru »

dougeff wrote:PHY and PHX don't exist.
They do exist in the 65C02 and 65816, but not in the 6502, which is the core the NES uses.
Post Reply