It is currently Wed Nov 22, 2017 12:35 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 78 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
Author Message
PostPosted: Sun Sep 24, 2017 4:05 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 35
dougeff wrote:
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

preserve A?
What's tat supposed to do?
also rendering the game with 8x16 sprites stops my game from working.


Top
 Profile  
 
PostPosted: Mon Sep 25, 2017 4:23 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1827
Location: DIGDUG
"What's that supposed to do?"
....A:80 X:40
STA temp
....A:80 X:40 temp:80
TXA
....A:40 X:40 temp:80
PHA ;A (40) pushed to stack
LDA temp
....A:80 X:40

Switching to 8x16 sprites shouldn't break your game. Perhaps you misunderstand how 8x16 sprites are organized....or made some other change.

Can you describe how it's "not working", or post a ROM?

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
 Post subject: TYA
PostPosted: Mon Sep 25, 2017 6:53 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 35
dougeff wrote:
"What's that supposed to do?"
....A:80 X:40
STA temp
....A:80 X:40 temp:80
TXA
....A:40 X:40 temp:80
PHA ;A (40) pushed to stack
LDA temp
....A:80 X:40

Switching to 8x16 sprites shouldn't break your game. Perhaps you misunderstand how 8x16 sprites are organized....or made some other change.

Can you describe how it's "not working", or post a ROM?

Now it's not broken.
PHA and graphics are my main concerns now.
So:
PHA as I understand has to be ordered in a certain way.
In the beginning of the NMI, You're supposed to put
Code:
TXA
PHA

TYA
PHA

PHA

in any order
At the end of rendering as I know has to be Backwards of the original PHA Trio.
Code:
PHA

TYA
PHA

TXA
PHA

Now this causes a really bizarre effects on the game. It jitters up and down for a few seconds before locking in a certain position. Now, I know that my game's working. It's just not moving or registering my inputs or can't move the character at all.
Is my PHA example working? If so, Implementing the temp storage to pha will be a breeze.
2nd:
I know now that my graphics need adjustments to a 16 by 16 character. I will be adjusting it to reduce workload on the NES.


Attachments:
Kitsunetales.asm [27.02 KiB]
Downloaded 13 times
KitsuneTales.nes [40.02 KiB]
Downloaded 13 times
Top
 Profile  
 
PostPosted: Mon Sep 25, 2017 7:47 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1035
No, you need to use PLA for the end trio.

And you need to use PHA first before TXA or TYA or else you overwrite the old value of A and can't get it back.

PHA pushes the value in A to the stack.
PLA pulls the last value on the stack and puts it in A.

If you never remove things you push to the stack, your program will very likely break anytime you return (rti or rts) because rti and rts use values from the stack. That's where they get where to return to.
Code:
NMI:
;Information for RTI to work properly is the last thing on the stack.
PHA;The value of A is the last thing on the stack.

TXA;We have overwritten the value of A with the value of X
;But that's okay, because the old value of A is safe on the stack
PHA;Now what was the value of X is the last thing on the stack.

TYA;We have overwritten what was the value of X/A with the value of Y
;But that's okay, because the old value of A and the old value of X are safe on the stack.
PHA;Now what was the value of Y is the last thing on the stack.

;A, X, and Y are now all safely on the stack

;NMI Code here

PLA;The last value on the stack is removed and put into A. (The value for Y in this case)
TAY;We copy that value from A back to Y where it was before the NMI started.
;Because of that PLA now what was the value for X is the last thing on the stack.

PLA;The last value on the stack is removed and put into A. (The value for X in this case)
TAX;We copy that value from A back to X where it was before the NMI started.
;Because of that PLA now what was the value for A is the last thing on the stack.

PLA;Now the value of A is what it was before the NMI started.
;Because of that PLA now the information needed for RTI to work properly is again the last thing on the stack.
;A, X, and Y are now all safely off the stack
RTI;We can safely return now.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Mon Sep 25, 2017 8:11 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 35
Alright! GOT IT TO WORRK. now to the character moving


Top
 Profile  
 
PostPosted: Mon Sep 25, 2017 10:31 pm 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 874
Location: Sweden
It's called the stack because the elements in it are stacked on top of each other. Naturally if you throw a bunch of things in a stack, the last thing you threw will be on top, and when retrieving the things one by one, they will be retrieved in reverse order from the order they where thrown in.

If you always pair every push with a pull before the next RTS or RTI you will never normally have to worry about a stack overflow happening.


Top
 Profile  
 
PostPosted: Tue Sep 26, 2017 8:09 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 35
To reassure, EVERYTIME RTS and ARI comes in, place the PLA Trio THERE?


Top
 Profile  
 
PostPosted: Tue Sep 26, 2017 8:15 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1827
Location: DIGDUG
Quote:
To reassure, EVERYTIME RTS and [RTI] comes in, place the PLA Trio THERE?


Don't worry about standard subroutines (JSR, RTS) needing to preserve A,X,Y values.

Do worry about NMI and IRQ interrupts needing to.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Tue Sep 26, 2017 8:36 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 35
NICE
now my mainproblem is tht the code in the nmi isn't working.


Top
 Profile  
 
PostPosted: Thu Sep 28, 2017 2:23 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 874
Location: Sweden
The reason why you need to backup the registers on the stack in interrupt handlers is that interrupts can potentially interrupt your code at any time. If it would interrupt in the middle of a calculation like:
Code:
  LDA #$05
                          <----NMI happens here
  CLC
  ADC #$03   ;calculate 5+3
The 5+3 calculation will not work if the NMI clobbers A.

For normal subroutines you have full control of when they are supposed to happen so you don't need to backup the registers.


Top
 Profile  
 
PostPosted: Thu Sep 28, 2017 4:25 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1827
Location: DIGDUG
I am often "passing an argument" to a subroutine using A,X,Y registers. And subroutines often "return a value"...usually the A register (sometimes just the zero flag or the carry flag is set or reset).

For example, a subroutine that multiplies, might have the input as A and X, and return A = A * X.

So, the original value in A needs to be overwritten by the subroutine.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Thu Sep 28, 2017 9:58 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 874
Location: Sweden
Me too, but if I need to preserve the registers I would just back them up on the stack or in temporary RAM registers before calling the subroutine or whatever that clobbers them, and retrieve them when I need them again.


Top
 Profile  
 
PostPosted: Wed Oct 11, 2017 7:22 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 35
In a nutshell it looks like this?
Code:
  PHA
  STA temp
  LDA temp
  TXA
  PHA
  STA temp
  LDA temp
  TYA
  pha
  LDA temp


Attachments:
Kitsunetales.asm [26.02 KiB]
Downloaded 9 times
File comment: ghhjk,
KitsuneTales.nes [40.02 KiB]
Downloaded 10 times
Top
 Profile  
 
PostPosted: Thu Oct 12, 2017 1:01 am 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1035
No, it should look exactly like it was in my post.

Code:
NMI:

  PHA
  STA temp;You're storing a new value into temp. (A)
  LDA temp;You're loading the value you just stored from A back into A. Why? The value that's there just came from A.
  TXA;You are putting the value of X into A, so the above line effectively does nothing because you never used the result.
  PHA
  STA temp;You're storing a new value into temp. (A) This effectively makes the first store to temp above do nothing, because its value effectively wasn't used in between being written and being overwritten.
  LDA temp;You're loading the value you just stored from A back into A. Why? That value is already in A.
  TYA;You are putting the value of X into A, so the above line effectively does nothing.
  pha
  LDA temp;This line effectively does nothing
 

NewAttribCheck:
  LDA scroll;Because of this line.


You're loading the value of temp into A, but before it is used, you load the value of scroll into A.

For understanding: The value of A doesn't change after a store, so loading from the exact place you just stored after a load usually does nothing. (Unless you're relying on flag changes, and you are not here.)

Edit: Just as another warning, you should make sure the temp RAM for your NMI isn't used anywhere else. (It's not here, but still.) For a similar reason to why you need to push A, X and Y to the stack. If the NMI interrupts code that expects the temp RAM to be a certain value, and the NMI changes the temp RAM very bad things will probably happen.

You can safely read variables in your NMI, always be careful when something is written.

Another similar piece of code:
Code:
DLs:
  lda columnNumber
  SEC
  SBC  #$01             ; go to next column
  and #%11111111       ; only 256 columns of data, throw away top bit to wrap
  sta columnNumber
  JMP Con;This line effectively does nothing

Con:

You are jumping to Con, but the code could naturally travel there if that line wasn't there.

One of the problems is that you have several RTIs in your code. JSR Updating eventually ends up at some animation labels (FAni, etc) that jumps to done:
Code:
Done:

  lda #$00
  sta NMIB+2
 
 
 
 
 
  PLA
  TAY
 
  PLA
  TAX
 
 
  PLA
 
  rti

Which pulls values off the stack that weren't pushed there (that I can see), and also returns with RTI instead of RTS.
Code:
main:
  JSR updating
  jmp main

updating:
  ;code in between
rts

Anything you JSR to should end in RTS (unless you really know what you're doing.) That is currently not true, at least for updating. One path of updating is updating->aniFrame->Vertical->Direction->DDIR->Gravity->F1->Jump->Delay->AnimationP1->Animation->scrolling->Pa2->Continue->p2->FAniP->FAni->Done->RTI

(That path may not be 100% possible since I didn't learn enough about your game state to be sure what are possible values. Still, you probably get the idea.)

You have another RTI under ReadUpDone that maybe should be an RTS, but I didn't take the time to study how your code gets there. (Or if it gets there.) The reason it's suspicious is because it doesn't pull values from the stack, and the only interrupt start code you have does push.

No matter how complicated the code in between updating: and the RTS is, updating still must end in RTS (unless you really know what you're doing.) This is how you get back to the line beneath way back near the "main:" label. Anytime I create a new subroutine, I make a habit of typing its name, then the RTS underneath it, both before even adding the JSR to its name to my code. Then I write the code in between and will be safe. If I want to create another subroutine the subroutine I just created goes to, same process. label, rts, then jsr, then code under label.

I'd maybe recommend starting completely over rather than trying to band aid this code. It probably sounds scary, but I think with what you've learned you'll actually spend less time rewriting than you will chasing problems in this and you'll end up with better code as a result. I recommend writing code in smaller parts. It helps me read, but it also helps you read.

I had to do a lot of work to find out what happened to updating. It could look something like this:

Code:
main:
  jsr waitVblank
  jsr updating
  jmp main

waitVblank:
;Code to wait for the frame start here
  rts

updating:
  jsr readbuttons
  jsr updateplayer
  rts

readbuttons:
  ;code to read buttons
  rts

updateplayer:
  jsr updateplayerstate
  jsr updateplayeranimations
  rts

updateplayerstate:
  rts
updateplayeranimations:
  rts

Basically, the more code you have in between the start of a subroutine's label and the RTS, the more paths you have to follow to find out what it's really doing. Dividing things allows you to create code you can verify all paths of without even scrolling in your text editor. Things get way less dense when you know the problem is in the 40 line updateplayeranimations rather than somewhere in 400 line updating.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Thu Oct 12, 2017 5:38 am 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 35
May need another Thread: Ok, Doing that in mind, and I know it's way off topic. For This game play, Should the sprites be bigger because you'll be flying via mid air dashing, shooting projectiles and wall jumping? I may need more ram than MMC3 chip for ai and other stuff. Maybe I need to understand how to compress code and to do this NMI Stuff before this challenge.


Before I fix. Is there another way to manage jumping? Look at from Jump to Animation


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 78 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Bing [Bot] and 12 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