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

User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

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

"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
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

TYA

Post by IMAGICA »

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: Select all

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: Select all

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 70 times
KitsuneTales.nes
(40.02 KiB) Downloaded 74 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
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Pallete affects scroll value

Post by Kasumi »

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: Select all

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.
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

Alright! GOT IT TO WORRK. now to the character moving
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 »

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.
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

To reassure, EVERYTIME RTS and ARI comes in, place the PLA Trio THERE?
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 »

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
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

NICE
now my mainproblem is tht the code in the nmi isn't working.
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 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: Select all

  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.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Pallete affects scroll value

Post by dougeff »

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
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Pallete affects scroll value

Post by Pokun »

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.
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

In a nutshell it looks like this?

Code: Select all

  PHA
  STA temp
  LDA temp
  TXA
  PHA
  STA temp
  LDA temp
  TYA
  pha
  LDA temp
Attachments
Kitsunetales.asm
(26.02 KiB) Downloaded 68 times
KitsuneTales.nes
ghhjk,
(40.02 KiB) Downloaded 71 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
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Pallete affects scroll value

Post by Kasumi »

No, it should look exactly like it was in my post.

Code: Select all

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: Select all

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: Select all

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: Select all

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: Select all

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.
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

NMI Is frozen / Not fully working

Post by IMAGICA »

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
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]
Post Reply