nesdev.com
http://forums.nesdev.com/

Pallete affects scroll value
http://forums.nesdev.com/viewtopic.php?f=2&t=16221
Page 2 of 6

Author:  Pokun [ Mon Jul 24, 2017 10:28 pm ]
Post subject:  Re: Pallete affects scroll value

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.

Author:  IMAGICA [ Wed Aug 02, 2017 1:51 pm ]
Post subject:  Re: Pallete affects scroll value

Can you confirm if I'm reading bit 1?
Code:
 LDA #$01
  STA $4016
  LDA #$01
  STA $4016
  LDX #$08

Author:  Pokun [ Wed Aug 02, 2017 3:58 pm ]
Post subject:  Re: Pallete affects scroll value

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:
  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:
  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.

Author:  IMAGICA [ Wed Aug 02, 2017 5:01 pm ]
Post subject:  Re: Pallete affects scroll value

Thanks by the way what is the advantage of 8x16 sprites are? I willing to remake my sprites if it has advantages I need.

Author:  rainwarrior [ Wed Aug 02, 2017 6:15 pm ]
Post subject:  Re: Pallete affects scroll value

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).

Author:  IMAGICA [ Sun Aug 20, 2017 9:35 pm ]
Post subject:  Re: Pallete affects scroll value

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 28 times

Author:  Pokun [ Mon Aug 21, 2017 3:28 am ]
Post subject:  Re: Pallete affects scroll value

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:
  lda #%00000001
  sta $4017 ;enable Square 1

I guess you meant $4015 here, that's where you enable/diable APU sound channels.

Code:
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:
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:
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:
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.

Author:  IMAGICA [ Sat Sep 02, 2017 1:27 pm ]
Post subject:  Re: Pallete affects scroll value

Pokun wrote:
Code:
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:
 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.

Author:  tepples [ Sat Sep 02, 2017 2:44 pm ]
Post subject:  Re: Pallete affects scroll value

The NMI handler interrupts the loop and sets the flag to a nonzero value.

Author:  dougeff [ Sat Sep 02, 2017 7:20 pm ]
Post subject:  Re: Pallete affects scroll value

Quote:
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.

Author:  IMAGICA [ Mon Sep 04, 2017 7:03 pm ]
Post subject:  Re: Pallete affects scroll value

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?

Author:  dougeff [ Mon Sep 04, 2017 7:39 pm ]
Post subject:  Re: Pallete affects scroll value

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.

Author:  IMAGICA [ Tue Sep 19, 2017 9:31 am ]
Post subject:  Re: Pallete affects scroll value

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 13 times

Author:  dougeff [ Tue Sep 19, 2017 10:13 am ]
Post subject:  Re: Pallete affects scroll value

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

Author:  tokumaru [ Wed Sep 20, 2017 10:44 am ]
Post subject:  Re: Pallete affects scroll value

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.

Page 2 of 6 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/