Skip navigation
NintendoAge
Welcome, Guest! Please Login or Join
Loading...

Nerdy Nights week 5 multiple sprites, reading controllers, more instructions

Apr 23, 2014 at 4:19:30 PM
Mega Mario Man (63)
avatar
(Tim ) < Ridley Wrangler >
Posts: 2743 - Joined: 02/13/2014
Nebraska
Profile
Originally posted by: Dread

Originally posted by: KHAN Games

up/down for sprite 0, yes.



So then just add all other positions for sprites 1,2,3?

Sounds to me that you are on the right path.


-------------------------
Current Project
Isometric Survival Horror

Older Projects
Tailgate Party, Power Pad Demo, Happy Hour

Links
Store, Facebook, Twitter

Apr 23, 2014 at 11:03:48 PM
Dreadmoc (18)
avatar
(Iron Worker) < Eggplant Wizard >
Posts: 314 - Joined: 03/02/2013
Colorado
Profile
Okay, I got him moving good. Little Mario moves in all eight directions using the arrow keys.

I forgot a dollar on 0208 for down and one his little legs fell off. I felt bad so I added it and it's working great. Kinda creepy to watch some of him move, like just his head flying off his body!

Thanks for the help guys.

-------------------------

            

Apr 24, 2014 at 12:14:28 AM
Mega Mario Man (63)
avatar
(Tim ) < Ridley Wrangler >
Posts: 2743 - Joined: 02/13/2014
Nebraska
Profile
Glad you got him working! Small victories are what keep you moving forward.

-------------------------
Current Project
Isometric Survival Horror

Older Projects
Tailgate Party, Power Pad Demo, Happy Hour

Links
Store, Facebook, Twitter

Sep 4, 2014 at 3:07:07 AM
Baka94 (0)
avatar
< Little Mac >
Posts: 73 - Joined: 02/27/2014
Finland
Profile
I guess it's time to see if I understand how the controller reading works. Each time you read a controller the NES cycles through the buttons (since it only uses bit 0 for this) and I need to store each button state to separate memory slot where the game itself reads the buttons. Is this correct?

BTW, do I need to write the 0 and 1 to the $4017 if I want to use controller 2 too, or does writing to $4016 set up both controllers?


Edited: 09/04/2014 at 03:08 AM by Baka94

Jan 3, 2015 at 10:31:06 PM
Dredster (0)
avatar
(Dred ) < Tourian Tourist >
Posts: 24 - Joined: 03/05/2013
Arkansas
Profile
How do the controller ports recognize different buttons for different functions ? I don't understand how the bit is set for on/off is set for all the buttons. It would seem that they have to be set to different adresses.

-------------------------
Sorry guys, but I think I got the last copy of Buzz and Waldog from Retrozone.


Edited: 01/04/2015 at 06:56 PM by Dredster

Jan 4, 2015 at 12:10:18 PM
user (6)

< El Ripper >
Posts: 1462 - Joined: 05/30/2014
Profile
Originally posted by: Baka94

I guess it's time to see if I understand how the controller reading works. Each time you read a controller the NES cycles through the buttons (since it only uses bit 0 for this) and I need to store each button state to separate memory slot where the game itself reads the buttons. Is this correct?

BTW, do I need to write the 0 and 1 to the $4017 if I want to use controller 2 too, or does writing to $4016 set up both controllers?

If only one input each NMI is needed, and the priority order is: A, B, Se, St, DPad, then:
ldx #$09
LOOP:
  dex
  beq DONE
  lda $4016
  and #$01
  beq LOOP
DONE:
  ...           ; if x ==... 8=A 7=B 6=Se 5=St 4=U 3=D 2=L 1=R 0=None
would (likely be faster and) work too I guess!

Just an alternative idea, I don't mean to teach anything.

Cheers!

- user

Edit: changed 00000001 to #$01, it is the same thing, but probably better understandable this way.


Edited: 01/04/2015 at 12:15 PM by user

Jan 9, 2015 at 10:06:15 PM
Dredster (0)
avatar
(Dred ) < Tourian Tourist >
Posts: 24 - Joined: 03/05/2013
Arkansas
Profile
I am at a loss; how do I get the sprite to move up and down I tried adding ReadUp:
LDA $4016
AND #%00000001
BEQ ReadUpDone

LDA $0200
SEC
SBC #$01
STA $0200
ReadUpDone:


ReadDown:
LDA $4016
AND #%00000001
BEQ ReadDownDone

LDA $0200
CLC
ADC #$01
STA $0200
ReadDownDone:
, but that does not work is there another directive I need to add or change. Could someone point me in the right direction or tell me ?

-------------------------
Sorry guys, but I think I got the last copy of Buzz and Waldog from Retrozone.

Jan 9, 2015 at 10:22:56 PM
user (6)

< El Ripper >
Posts: 1462 - Joined: 05/30/2014
Profile
Originally posted by: Dredster

I am at a loss; how do I get the sprite to move up and down I tried adding ReadUp:
LDA $4016
AND #%00000001
BEQ ReadUpDone

LDA $0200
SEC
SBC #$01
STA $0200
ReadUpDone:


ReadDown:
LDA $4016
AND #%00000001
BEQ ReadDownDone

LDA $0200
CLC
ADC #$01
STA $0200
ReadDownDone:
, but that does not work is there another directive I need to add or change. Could someone point me in the right direction or tell me ?

1. Did you put this before?
  LDA #$01
  STA $4016
  LDA #$00
  STA $4016     ; tell both the controllers to latch buttons

2. Try pushing A and B buttons.

I hope this helps.



Jan 9, 2015 at 10:39:29 PM
Dredster (0)
avatar
(Dred ) < Tourian Tourist >
Posts: 24 - Joined: 03/05/2013
Arkansas
Profile
Yeah, I just added the code that I thought would move the sprite up and down based on what someone else posted. Everything is in place as normal. I push the A and B buttons but they just move it left to right. I'm trying to figure out how to get the sprite to move up and down using the up and down buttons. I assumed the $0200 was to set for the Y movements and $203 was for the X coordinates. I am also not getting how to move multiple sprites. I tried setting it to the 8x16 byte in $2000, but the sprite is scrabbled and the sprite is still in the same position as before.

-------------------------
Sorry guys, but I think I got the last copy of Buzz and Waldog from Retrozone.


Edited: 01/09/2015 at 10:41 PM by Dredster

Jan 9, 2015 at 10:58:30 PM
user (6)

< El Ripper >
Posts: 1462 - Joined: 05/30/2014
Profile
Originally posted by: Dredster

Yeah, I just added the code that I thought would move the sprite up and down based on what someone else posted. Everything is in place as normal. I push the A and B buttons but they just move it left to right. I'm trying to figure out how to get the sprite to move up and down using the up and down buttons. I assumed the $0200 was to set for the Y movements and $203 was for the X coordinates. I am also not getting how to move multiple sprites. I tried setting it to the 8x16 byte in $2000, but the sprite is scrabbled and the sprite is still in the same position as before.

Sequence:

LDA $4016
AND #%00000001 ; A button

LDA $4016
AND #%00000001 ; B button

LDA $4016
AND #%00000001 ; Select

LDA $4016
AND #%00000001 ; Start

5th and 6th time you do so...

LDA $4016
AND #%00000001 ; Up

LDA $4016
AND #%00000001 ; Down

7th and 8th time you do so...

LDA $4016
AND #%00000001 ; Left

LDA $4016
AND #%00000001 ; Right

But you obviously use a loop to make things more rational to read, and save space in the ROM.

Hope this helps!

Edit: I messed up U/D/L/R


Edited: 01/09/2015 at 11:03 PM by user

Jan 10, 2015 at 2:13:38 AM
Dredster (0)
avatar
(Dred ) < Tourian Tourist >
Posts: 24 - Joined: 03/05/2013
Arkansas
Profile
I see that it's latched by
LatchController:
LDA #$01
STA $4016
LDA #$00
STA $4016
Which is the same as writing it out like that. I understand how it cycles through the buttons. I just want to be able to make the sprite go up and down. It only goes left and right using B. BunnyBoy says to try to figure out how to move multiple sprites,figure out how to make the sprites move up and down and go left and right using the D-Pad buttons. I am not able to figure out how to do those things.

-------------------------
Sorry guys, but I think I got the last copy of Buzz and Waldog from Retrozone.

Jan 10, 2015 at 4:25:27 AM
MadnessVX (1)
avatar
< Tourian Tourist >
Posts: 40 - Joined: 07/12/2013
Texas
Profile
After the latch, you want your controller reading code to do something when it sees that a button is pushed. Each time you read $4016, it will be for a different button as User stated above. So if you want to read that up or down was pressed, you must have a total of 8 reads. (Technically 5 or 6, but its best to read the whole controller! ) You cannot simply have two reads from $4016, and call them up and down.

Some pseudoish-code:

Latch_Controller:  ;Controller gets latched here
  lda #$01
  sta $4016
  lda #$00
  sta $4016

Read_Control:  ;Here is where we actually read the controller

  lda $4016              ;First read from 4016. This is the A button.
  and #%00000001
  cmp $%01               ;compare the value you just loaded into the accumulator with #%00000001. (Same as #$01)
  bne .not a             ;if they are not equal, skip the code for A
       <---------------  ;Code for the A button will go here
.not a:
  Read the controller again to see if B was pressed
  More code

.not b:
  More code
  etc...

You keep making reads until you have read them all. (8 times) You want to put your increments or decrements where the up or down reads are.

 I hope this makes sense. For you veterans if I have said anything wrong, please publicly humiliate me!


Edited: 01/10/2015 at 04:28 AM by MadnessVX

Jan 10, 2015 at 10:22:01 AM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
That's basically what I was going to ask... if he had all the routine going through all 8 button latches. Hard to tell with only a small code snippet.

-------------------------

gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin


Jan 10, 2015 at 11:59:01 AM
user (6)

< El Ripper >
Posts: 1462 - Joined: 05/30/2014
Profile
Originally posted by: Dredster

I see that it's latched by
LatchController:
LDA #$01
STA $4016
LDA #$00
STA $4016
Which is the same as writing it out like that. I understand how it cycles through the buttons. I just want to be able to make the sprite go up and down. It only goes left and right using B. BunnyBoy says to try to figure out how to move multiple sprites,figure out how to make the sprites move up and down and go left and right using the D-Pad buttons. I am not able to figure out how to do those things.
Controller Ports

The controllers are accessed through memory port addresses $4016 and $4017.  First you have to write the value $01 then the value $00 to port $4016.  This tells the controllers to latch the current button positions.  Then you read from $4016 for first player or $4017 for second player.  The buttons are sent  one at a time, in bit 0.  If bit 0 is 0, the button is not pressed.  If bit 0 is 1, the button is pressed.

Button status for each controller is returned in the following order: A, B, Select, Start, Up, Down, Left, Right.

  LDA #$01
  STA $4016

  LDA #$00
  STA $4016     ; tell both the controllers to latch buttons

  LDA $4016     ; player 1 - A
  LDA $4016     ; player 1 - B
  LDA $4016     ; player 1 - Select
  LDA $4016     ; player 1 - Start
  LDA $4016     ; player 1 - Up
  LDA $4016     ; player 1 - Down
  LDA $4016     ; player 1 - Left
  LDA $4016     ; player 1 - Right

AND Instruction

Button information is only sent in bit 0, so we want to erase all the other bits.  This can be done with the AND instruction.  Each of the 8 bits is ANDed with the bits from another value.  If the bit from both the first AND second value is 1, then the result is 1.  Otherwise the result is 0.


If all this BunnyBoy wrote is undestood, try looking at the following (really bad, good-coding wise) example, hoping that you can find out what your code is missing. Think this way if this helps: when you ask about inputs, you get always _8_ answers, yes or no (1 or 0), one for each possible input (A,B,Sel,Start,U,D,L,R), which are in bit 0 of a read to $4016, forcefully in that specific order.

  LDA #$01
  STA $4016
  LDA #$00
  STA $4016     ; tell both the controllers to latch buttons

LDA $4016 ; player 1 - A, you don't care about the answer LDA $4016 ; player 1 - B, you don't care about the answer LDA $4016 ; player 1 - Select, you don't care about the answer LDA $4016 ; player 1 - Start, you don't care about the answer

LDA $4016 ; player 1 - Up, NOW you DO care about the answer AND #%00000001 ; you want to keep only bit0 BEQ SKIPUP ; Up was NOT pressed, so skip the next instructions

LDA $0200 ; sprite y position SEC ; set carry SBC #$01 ; subtract 1 STA $0200 ; sprite NEW y position JMP SKIPDOWN ; it is either Up or Down, so if Up is pressed you skip the next check

SKIPUP: LDA $4016 ; player 1 - Down, NOW you DO care about the answer AND #%00000001 ; you want to keep only bit0 BEQ SKIPDOWN ; Down was NOT pressed, so skip the next instructions LDA $0200 ; sprite y position CLC ; clear carry ADC #$01 ; add 1 STA $0200 ; sprite NEW y position

SKIPDOWN: ; ... ; the program continues here
It is ugly coding wise, but it works.

Check the attachments (rename controller.txt to .asm).

I hope this helps!

- user

Jan 10, 2015 at 1:04:47 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
If you read $4016 directly from the controller, you're doing it 100% wrong. Please don't advocate doing it that way. I'm not going to argue with people again (Main reason I left for so long) how it's okay to do it how they want. It's not, it's the shittiest code you could ever write. Put it into variables, add button press variables, and stop doing it 10000% wrong.

Set 3 variables in RAM: ControllerData, ControllerDataOld (For figuring button presses), and then set ControllerOutput to $4016. Jump to this routine, then do a LDA-BIT/LDA-AND combo to test. 100% less crappy.

ReadController:
  LDA ControllerData
  STA ControllerDataOld ;Store old key presses.
  LDY #$01
  STY ControllerOutput ;Set to $4016
  STY ControllerData
  DEY
  STY ControllerOutput
.ReadControllers
  LDA $4016
  LSR A
  ROL ControllerData
  BCC .ReadControllers
  LDA ControllerDataOld
  EOR #$FF ;Reverse keys not pressed last time.
  AND ControllerData ;Test with new keys.
  STA ControllerDataNewlyPressed ;Store buttons that were just pressed.
  RTS
 



Edited: 01/10/2015 at 01:14 PM by removed04092017

Jan 10, 2015 at 1:20:59 PM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
The way 3Gen is describing is definitely the better way of doing it (and way less code), but the way user described it also works fine for getting started and learning how things work. Bunnyboy switches to the better method in a later Nerdy Nights tutorial.

-------------------------

gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin


Jan 10, 2015 at 2:03:10 PM
user (6)

< El Ripper >
Posts: 1462 - Joined: 05/30/2014
Profile
Original post deleted by the author.

The post of bunnyboy here below expresses the same concept more technically and in a more correct English.

- user


Edited: 02/16/2015 at 02:49 AM by user

Jan 10, 2015 at 3:57:16 PM
bunnyboy (81)
avatar
(Funktastic B) < Master Higgins >
Posts: 7704 - Joined: 02/28/2007
California
Profile
Originally posted by: 3GenGames

If you read $4016 directly from the controller, you're doing it 100% wrong. Please don't advocate doing it that way. I'm not going to argue with people again (Main reason I left for so long) how it's okay to do it how they want. It's not, it's the shittiest code you could ever write. Put it into variables, add button press variables, and stop doing it 10000% wrong.
Your example is more correct (start a new thread if you want it ripped apart) for a final product, but far more complicated for an intro lesson.  Now you need to first explain jsr/rts, variables vs constants vs addresses, naming conventions, shifting, and bcc.  How are those tutorials you were writing going?  

Sep 9, 2015 at 5:07:28 PM
Cockroachcharlie (0)
avatar
< Cherub >
Posts: 19 - Joined: 09/05/2015
Pennsylvania
Profile
Originally posted by: bunnyboy
 
Originally posted by: 3GenGames

If you read $4016 directly from the controller, you're doing it 100% wrong. Please don't advocate doing it that way. I'm not going to argue with people again (Main reason I left for so long) how it's okay to do it how they want. It's not, it's the shittiest code you could ever write. Put it into variables, add button press variables, and stop doing it 10000% wrong.
Your example is more correct (start a new thread if you want it ripped apart) for a final product, but far more complicated for an intro lesson.  Now you need to first explain jsr/rts, variables vs constants vs addresses, naming conventions, shifting, and bcc.  How are those tutorials you were writing going?  

WAAAH!  I actually understood what you were talking about until you mentioned those parts I underlined in the quote!  I was soooo close!  [retreats to corner to sulk].
 

Sep 9, 2015 at 6:46:00 PM
Mega Mario Man (63)
avatar
(Tim ) < Ridley Wrangler >
Posts: 2743 - Joined: 02/13/2014
Nebraska
Profile
Originally posted by: Cockroachcharlie
 
Originally posted by: bunnyboy
 
Originally posted by: 3GenGames

If you read $4016 directly from the controller, you're doing it 100% wrong. Please don't advocate doing it that way. I'm not going to argue with people again (Main reason I left for so long) how it's okay to do it how they want. It's not, it's the shittiest code you could ever write. Put it into variables, add button press variables, and stop doing it 10000% wrong.
Your example is more correct (start a new thread if you want it ripped apart) for a final product, but far more complicated for an intro lesson.  Now you need to first explain jsr/rts, variables vs constants vs addresses, naming conventions, shifting, and bcc.  How are those tutorials you were writing going?  

WAAAH!  I actually understood what you were talking about until you mentioned those parts I underlined in the quote!  I was soooo close!  [retreats to corner to sulk].
 
It's not too bad. You'll be fine. These tutorials are fantastic and guide you through perfectly.

 

-------------------------
Current Project
Isometric Survival Horror

Older Projects
Tailgate Party, Power Pad Demo, Happy Hour

Links
Store, Facebook, Twitter

Sep 9, 2015 at 9:14:00 PM
Cockroachcharlie (0)
avatar
< Cherub >
Posts: 19 - Joined: 09/05/2015
Pennsylvania
Profile
Originally posted by: Mega Mario Man
 
Originally posted by: Cockroachcharlie
 
Originally posted by: bunnyboy
 
Originally posted by: 3GenGames

If you read $4016 directly from the controller, you're doing it 100% wrong. Please don't advocate doing it that way. I'm not going to argue with people again (Main reason I left for so long) how it's okay to do it how they want. It's not, it's the shittiest code you could ever write. Put it into variables, add button press variables, and stop doing it 10000% wrong.
Your example is more correct (start a new thread if you want it ripped apart) for a final product, but far more complicated for an intro lesson.  Now you need to first explain jsr/rts, variables vs constants vs addresses, naming conventions, shifting, and bcc.  How are those tutorials you were writing going?  

WAAAH!  I actually understood what you were talking about until you mentioned those parts I underlined in the quote!  I was soooo close!  [retreats to corner to sulk].
 
It's not too bad. You'll be fine. These tutorials are fantastic and guide you through perfectly.

 
Actually, the part that made me laugh is that, unless I'm mistaken, he hasn't mentioned subroutines yet in the tutorial, yet I have a pretty firm grounding on those.  Likewise with variables, constants, addresses...and so on.  I was so pleased that I understood things he hadn't even discussed yet, until I got to the underlined point.  :-)

Either way, yeah, these tutorials are a huge help in understanding the differences needed between simply writing in 6502 and writing in 6502 FOR THE NES.  My son and I are working on a game right now and taking the step-by-step approach (step 1; learn 6502, step 2; make our character appear on the screen, step 3; make our character move in some way etc...).  So getting my 15 sprite character to pop up and shift left and right was quite exciting for us.  Still not quite understanding WHY the code caused it to happen, so we are sticking to the design phase while I work on wrapping my head around it, but these tutorials are being an exciting adventure for us.  :-)

edit:  Come to think of it, would it be advisable (and speaking way into the future) to put the movement controls into a subroutine for multi-level games (ala Contra, Super Mario Bros., etc...)?  Or can they be left in the main code block?
 


Edited: 09/09/2015 at 09:33 PM by Cockroachcharlie

Sep 9, 2015 at 11:19:54 PM
Mega Mario Man (63)
avatar
(Tim ) < Ridley Wrangler >
Posts: 2743 - Joined: 02/13/2014
Nebraska
Profile
Originally posted by: Cockroachcharlie

Actually, the part that made me laugh is that, unless I'm mistaken, he hasn't mentioned subroutines yet in the tutorial, yet I have a pretty firm grounding on those.  Likewise with variables, constants, addresses...and so on.  I was so pleased that I understood things he hadn't even discussed yet, until I got to the underlined point.  :-)

Either way, yeah, these tutorials are a huge help in understanding the differences needed between simply writing in 6502 and writing in 6502 FOR THE NES.  My son and I are working on a game right now and taking the step-by-step approach (step 1; learn 6502, step 2; make our character appear on the screen, step 3; make our character move in some way etc...).  So getting my 15 sprite character to pop up and shift left and right was quite exciting for us.  Still not quite understanding WHY the code caused it to happen, so we are sticking to the design phase while I work on wrapping my head around it, but these tutorials are being an exciting adventure for us.  :-)

edit:  Come to think of it, would it be advisable (and speaking way into the future) to put the movement controls into a subroutine for multi-level games (ala Contra, Super Mario Bros., etc...)?  Or can they be left in the main code block?
 

This is the perfect way to do it.

I really don't  have a lot in my main code in the few games I have written. Pretty much, all my main code block does is call subroutines.
 

-------------------------
Current Project
Isometric Survival Horror

Older Projects
Tailgate Party, Power Pad Demo, Happy Hour

Links
Store, Facebook, Twitter

Feb 7, 2016 at 11:34:55 PM
SomeGuy#27 (0)

< Cherub >
Posts: 3 - Joined: 12/01/2015
Profile
Hey, I found this a few months ago when I renewed my previously misguided efforts to learn 6502 a few years ago. It's a good tutorial so far, and thanks for making it!

Mar 3, 2016 at 2:03:41 AM
SomeGuy#27 (0)

< Cherub >
Posts: 3 - Joined: 12/01/2015
Profile
Quick question, is it possible to use comparators with the X and Y registers? Meaning

CMP Y

Or something of that like.

Mar 3, 2016 at 5:13:20 AM
Vectrex28 (130)
avatar
(CD-i Kraid) < Master Higgins >
Posts: 7789 - Joined: 07/28/2012
Switzerland
Profile
Originally posted by: SomeGuy#27

Quick question, is it possible to use comparators with the X and Y registers? Meaning

CMP Y

Or something of that like.

I simply store the Y or X reg in a temporary variable and compare things to that temp variable, something like

  STY maintemp
  CMP maintemp

-------------------------
"Energy Tanks, Missiles, Power Bombs... You want it? It's yours my friend! As long as you have enough credits!"