It is currently Sun Dec 17, 2017 9:00 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 1389 posts ]  Go to page Previous  1 ... 5, 6, 7, 8, 9, 10, 11 ... 93  Next
Author Message
 Post subject:
PostPosted: Mon Jun 06, 2011 2:14 pm 
Offline
User avatar

Joined: Wed Oct 15, 2008 11:50 am
Posts: 939
Local variables in C and C++ are allocated on the stack (a sliding window of RAM used just for locals and function parameters). On a 6502 you don't have such a thing.

In 6502 ASM a "local" variable is one that is only used by one particular subroutine. Assemblers that support scoping can make this easier by making access to labels from the outside harder. This does not support recursion, so if your subroutine calls itself it will stomp on the local variables, unlike C and C++.

What Tokumaru was describing was something different. I will try to explain in more round terms:

Hypothetical Man wrote:
I have a routine that handles the title screen. It needs 500 bytes of RAM, which I allocate starting at $0300.

I have another routine that implements my game. It needs 1500 bytes of RAM. Because I know that the game and the title screen will never be running at the same time, I also start allocating RAM at $0300.

So now I have two routines that use the same memory locations for variables, but because they never run at the same time (and do not care what is in RAM when they start) they do not step on each other's toes.


I think this approach is fine when you are dealing with distinct modes of operation, like our title screen / game example. If your game is a series of mini games (like Pirates!), each mini-game might reuse the same area of RAM for variables, and then you might have a small protected segment to keep game state variables.

Personally I do not like doing this within a game mode. It's true, my sprite generator never runs at the same time as my object updates, but this type of data interleaving over-complicates your code. Only if I were very desperate for RAM would this be an option for me.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 06, 2011 2:22 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10169
Location: Rio de Janeiro - Brazil
unregistered wrote:
So that means we could declare a variable... and then, later on, since the previous variable was local... and we are in a different area of code, we could declare another variable in the same spot!?

That's the idea. Since not all variables must exist at all times, many variables can share memory locations, and the code I wrote before is the most organized way I can think of doing that.

Quote:
Just like local variables in C++?

Kinda... In the sample code I wrote they aren't exactly local, because technically you could still use them anywhere in the program (i.e. the labels are global). Of course you wouldn't want to use one module's variables in another module, because that would crash the program. You could probably use ASM6's local labels (they start with a period, I think) though, and they would be more like local variables. Something like this:

Code:
SomeFunction:

   .enum LocalVariables3

.LocalVariable1 .dsb 1
.LocalVariable2 .dsb 1
.LocalPointer .dsb 2

   .ende

   ;the variables declared above can only be seen here

   ;return
   rts


Quote:
If all of the files combine in to one single .asm file then how does this work when there is just one file?

There's really no difference between 1 file vs. multiple files... When you include a file, it's the same as if you were copying and pasting its contents directly into the first file. The only reason to separate the source into multiple files and use includes is organization. Scrolling through a 20,000 line program looking for a piece of code is hell.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 06, 2011 2:31 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10169
Location: Rio de Janeiro - Brazil
qbradq wrote:
Personally I do not like doing this within a game mode. It's true, my sprite generator never runs at the same time as my object updates, but this type of data interleaving over-complicates your code. Only if I were very desperate for RAM would this be an option for me.

I wouldn't be able to make my game without this. The main engine uses every last byte of RAM, so I can't afford to have memory allocated for a bunch of stuff that just isn't running during gameplay (title screen, menus, bonus stages, etc). The main systems, like the ones dealing with music, sprites, etc. use global variables, because those are used by all program modes. It's not a difficult thing to manage at all: whatever is used by multiple program modes is global.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 06, 2011 2:48 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 807
Location: cypress, texas
qbradq and tokumaru, thanks so much for helping me through this! :D I understand everything yall said now! :D

tokumaru, thank you also for telling us about your best way to make variables! :D


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 09, 2011 12:20 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 807
Location: cypress, texas
Shiru, in famitone's readme.txt, wrote:
Warning: don't forget that active DMC conflicts with $2002 and controllers polling, read docs to learn how to avoid it (generally don't use $2002 polling and poll controllers three times in a row, then use matching result).

What is active DMC? I know $2002 is in the first group of I/O registers... I guess it allows interaction with the controllers. In my code I'm using $4016 to read the controller... $4016 is from the second and last group of I/O registers. When I read the controller from $4016 is that called 'polling' too? :?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 09, 2011 12:46 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3969
Any reading that has side effects may screw up, because DMC adds one extra read. Examples of reads with side effects include reading the controller or reading bytes from PPU Data. Reading PPU status is okay, since one extra read won't hurt anything.

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


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 10, 2011 1:59 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 807
Location: cypress, texas
Dwedit wrote:
Any reading that has side effects may screw up... Examples of reads with side effects include reading the controller
Yes, I agree, now (after reading some more about reading). : ) My song wont play for me. :( And so I'm wondering if it has something to do with the way I've worked the callling code into the controller reading part. Here is what i've got (the famitone code is between the ---\/-- and the ---^---):
Code:
react_to_input:
        lda #$01        ; strobe joypad
        sta $4016
        lda #$00
        sta $4016

        lda $4016        ; Is the A button down?
        and #1
      beq @not_a
      ldx aHasbeenpressed
      bne @b
      sta aHasbeenpressed
      inc aFrame        ;run only once per press.
        jmp @b      
@not_a:      sta aHasbeenpressed
@b:      lda $4016      ;Is the B button down?
      and #1
      beq @select
      lda #0
      sta aFrame
      jsr low_c          ;low_c is just small code that plays a note

;-----------------------\/------------------------------------------      
@select lda $4016  ; Select does something(music no working)
      and #1
      beq @start
      ldx <musicA_module ;also songA
      ldy >musicA_module      
      jsr FamiToneMusicStart      
@start   lda $4016  ; Start does nothing
      and #1
      beq @up
      jsr FamiToneMusicStop
;-----------------------^-------------------------------------------      
@up      lda $4016   ;Is Up  down?
      and #1
      beq @down
      dec oY
@down   lda $4016  ;is Down down?
      and #1
      beq @left
      inc oY
@left   lda $4016  ;is Left down?
      and #1
      beq @right
      dec oX
@right  lda $4016  ;Is Right down?
        and #1
      beq not_dn
      inc oX
not_dn:   rts 

Thank you for spending time reading that big amount of code. Sorry, though, I hope there is something wrong there. :|


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 10, 2011 6:43 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 807
Location: cypress, texas
Dwedit wrote:
Any reading that has side effects may screw up, because DMC adds one extra read.


DMC is delta modulation channel. That is the fifth APU channel right? My song doesn't have anything in that channel... so that means there is one less read... and then the side effects don't happen? :?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 10, 2011 8:03 pm 
Offline
Formerly 65024U

Joined: Sat Mar 27, 2010 12:57 pm
Posts: 2257
First off, you need to read the controller and store it into a variable. Doing it right off of the read is a terrible way to make an engine. Do a LSR and ROL it into a variable, then use that variable to see what needs to happen.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 11, 2011 1:35 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 807
Location: cypress, texas
Thanks for your suggestion! :) Here's my code now... does nothing... maybe i need to separate the reading code from the controller check code?? :? :)

Code:
react_to_input:
        lda #$01        ; strobe joypad
        sta $4016
        lda #$00
        sta $4016

;*****************Read Entire Controller*
        lda #0
      sta controller1
      ldx #8
      
-read:   lda $4016
      ora controller1
      lsr   ;shift right one bit
      ror ;rotate one bit right
      sta controller1
      dex
      bne -read
;*******************************************

        lda controller1    ; Is the A button down?
        and #1
      beq @not_a
      ldx aHasbeenpressed
      bne @b
      sta aHasbeenpressed
      inc aFrame        ;run only once per press.
        jmp @b      
@not_a:      sta aHasbeenpressed
@b:      lda controller1      ;Is the B button down?
      and #00000010b
      beq @select
      lda #0
      sta aFrame
      jsr low_c          ;low_c is just small code that plays a note
   
;-----------------------\/------------------------------------------ 
   
@select lda controller1  ; Select does something(music no working)
      and #00000100b
      beq @start
      ldx <musicA_module ;also songA
      ldy >musicA_module      
      jsr FamiToneMusicStart
      
@start   lda controller1  ; Start does nothing
      and #00001000b
      beq @up
      jsr FamiToneMusicStop
;-----------------------^-------------------------------------------   

@up      lda controller1   ;Is Up  down?
      and #00010000b
      beq @down
      dec oY
@down   lda controller1  ;is Down down?
      and #00100000b
      beq @left
      inc oY
@left   lda controller1  ;is Left down?
      and #01000000b
      beq @right
      dec oX
@right  lda controller1  ;Is Right down?
        and #10000000b
      beq not_dn
      inc oX
not_dn:   rts 


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 11, 2011 3:06 pm 
Offline
Formerly 65024U

Joined: Sat Mar 27, 2010 12:57 pm
Posts: 2257
That's not right. This is what you need:

.rsset $300
ControllerButtons: .rs 1

LDX #$01
STA $4016
DEX
STX $4016
LDX #$08
Loop:
LDA $4016
LSR A
ROL ControllerButtons
DEX
BNE Loop
RTS ;Controller value in the variable ControllerButtons.

Maybe look into more 6502. Seems you don't have a good enough understanding of it or the hardware.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 15, 2011 5:31 pm 
Offline
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 807
Location: cypress, texas
3gengames, I relpaced my code with your code and put this right after it
Code:
jsr high_c
      .if ControllerButtons != 0
      .error "need help"
      .endif

And while running my program it never ever stops and says need help no matther what I'm pressing on the controller. The controller works fine in other programs. It is continuealy reaching this code cause I can hear a high pitch C noise over and over.

In your code you've got
Code:
Loop:
LDA $4016
LSR A
ROL ControllerButtons
DEX
BNE Loop

That lsr a writes its answer back into the accumulator right? And rol ControllerButtons writes its answer back into ControllerButtons right? So how is ControllerButtons updated? (These questions are for yall too.)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 15, 2011 6:00 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10169
Location: Rio de Janeiro - Brazil
"LDA $4016" puts the state of the current button into the accumulator; "LSR A" (or simply "LSR", depending on the assembler) shifts the bit out of the accumulator and into the carry flag; "ROL ControllerButtons" shifts the carry flag into ControllerButtons. Do this 8 times in a row and each bit of "ControllerButtons" will indicate the state of a buttom.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 15, 2011 6:05 pm 
Offline
Formerly 65024U

Joined: Sat Mar 27, 2010 12:57 pm
Posts: 2257
the .rsset and Controller variable is any piece of RAM you want to point it at, here's a commented and better version:

Code:
LDX #$01 ;X=1
STX $4016 ;Write high latch value to controller port.
DEX ;X=0
STX $4016 ;4016=0 now, can be read back.
LDX #$08 ;X=8
Loop: LDA $4016; Put the player 1 controller value into the accumulator. This will hold the value of ONE button.
LSR A ;Put DataLine1 [Controller] onto the Carry.
ROL ControllerButtons ;Shift ControllerButtons RAM one bit left with the carry. When done 8 times, will be updated with button statuses for each button. One bit will represent one button. The MSB will be first read, LSB last read. 1=Pressed, 0=Not pressed.
DEX ;X=X-1
BNE Loop;If X!=0 then loop.
RTS ;Return from subroutine. New controller status for Player 1 will be in the RAM byte ControllerButtons.


Does this make sense on how it works? Any qustions just ask. This program should work.

ETA: NINJA'D!


Last edited by 3gengames on Thu Jun 16, 2011 12:19 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 15, 2011 6:25 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10169
Location: Rio de Janeiro - Brazil
3gengames wrote:
[code]LSR $4016; Put the player 1 controller value into the CARRY bit.

Does this really work? I mean, LSR absolute is a read-modify-write instruction, so you're effectively writing something back to $4016... Doesn't this interfere with the reading process?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1389 posts ]  Go to page Previous  1 ... 5, 6, 7, 8, 9, 10, 11 ... 93  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 guests


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:  
Powered by phpBB® Forum Software © phpBB Group