It is currently Sun Oct 22, 2017 7:46 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 29 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Wed Jan 14, 2015 10:43 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5732
Location: Canada
Just to be clear, you're not expecting registers to be preserved during JSR and restored at RTS, right?

If you're using ca65, you can output your labels to a text file with the -Ln linker flag. You can then search for the label in that text file to find its address, or better yet, turn that label file into an FCEUX debug symbols file which will show the labels directly in the debugger. There is a python script that does this in an example I made a while ago: minimal ca65 example


Last edited by rainwarrior on Wed Jan 14, 2015 10:54 am, edited 2 times in total.

Top
 Profile  
 
PostPosted: Wed Jan 14, 2015 10:50 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5732
Location: Canada
Other helpful things when debugging:

1. Debug > Trace logger.

This lets you dump a text file containing every instruction executed and the status of every register/flag at each step.

2. Conditional breakpoints.

This lets you set a breakpoint that also has a condition.
See: FCEUX debugger guide


For example, if you know that if something is wrong if A is 5 at line $8075, then what you can do it start a trace log at a time before things go wrong, create an execuition breakpoint on 8075 with the condition A==#5, then run until the breakpoint is hit. Stop the trace at this point, and you will have a log of everything that happened up until that breakpoint. From here you can work backwards from the end of the file until you see exactly what caused the problem.


Top
 Profile  
 
PostPosted: Wed Jan 14, 2015 12:28 pm 
Offline

Joined: Tue Jul 01, 2014 4:02 pm
Posts: 254
Quote:
Just to be clear, you're not expecting registers to be preserved during JSR and restored at RTS, right?


They're not? Hm...that is definitely news to me...

So if I were to do something like this:

Code:

     LDX #$01
     JSR whatever


.......

whatever:
    TXA
    RTS


...could I not expect 1 to now be in the accumulator (not to mention, X register still as well...)? If that's the case...eek...


I'm guessing what you meant is that THIS will not work:

Code:

      LDX #$01
      JSR whatever

.....

whatever:
      INX  ; no longer preserved, because something was done to affect it
      TXA ; accumulator is no longer preserved as it was before the jump, because something was done to affect it
      RTS



...that I wouldn't expect X to be preserved as '1', because it was affected in the subroutine...so now, both the accumulator and x register should be '2', right? If you're asking if I was expecting the accum and x reg to still be preserved as they were prior to the jump in THIS case, no. I understand they have been affected so their values will be different continuing on. However, if you're saying I can not count on the value of the variables at all if I'm JSR->RTSing...that I couldn't even count on this subroutine returning '2'...I'm afraid I have a fundamental flaw in my understanding...


Top
 Profile  
 
PostPosted: Wed Jan 14, 2015 1:10 pm 
Offline

Joined: Tue Aug 12, 2014 11:25 pm
Posts: 9
Location: Sonora, Mexico
I guess you miss kasumi's comment.

this is what I think your code is doing(' is for branch).
Code:
loop:                             ;(6)
 jmp TileCheckRigth               ;(1)
somewhere:                        ;   ('4)
 ;...
skipdec:                          ;(4)
 jmp loop                         ;(5)('5)

TileCheckRigth:                   ;(2)
 ;...
 jmp skipdec                      ;(3)     there is not a problem, everything is jump
 ;...
 jmp somewhere                    ;   ('3)


versus jsr way

Code:
loop:                             ;(6)
 jsr TileCheckRigth               ;(1)     push program counter to stack
somewhere:                        ;    ('4)
 ;...
skipdec:                          ;(4)
 jmp loop                         ;(5) ('5)

TileCheckRigth:                   ;(2)
 ;...
 jmp skipdec                      ;(3)      miss one rts, this corrupts stack
 ;...
 rts                              ;    ('3)


Top
 Profile  
 
PostPosted: Wed Jan 14, 2015 1:32 pm 
Offline

Joined: Tue Jul 01, 2014 4:02 pm
Posts: 254
Oooooh! I gotcha now. I think some synapse just fired.

So I'd have to RTS back from the JSR, or otherwise get rid of the last value pushed to the stack, as it's hooked to the RTS. It's just still sitting on the stack lingering, and the next time something pulls from the stack, it's pulling that value...something like that?

Huh. Man...I better go through my code with a highlighter and make sure I haven't made this mistake anywhere else!


Top
 Profile  
 
PostPosted: Wed Jan 14, 2015 2:53 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
JoeGtake2 wrote:
Quote:
Just to be clear, you're not expecting registers to be preserved during JSR and restored at RTS, right?
They're not? Hm...that is definitely news to me...

To expand on rainwarrior's comment/question: the contents of A, X, and Y are not "backed up" and "restored" when doing a JSR/RTS. Take this code for example:

Code:
  lda #$01
  ldx #$aa
  ldy #$bb
;
; At this point in the code, A = $01, X = $AA, Y = $BB
;
  jsr someplace
;
; At this point in the code, A = $00, X = $22, Y = $BB
;
loop:
  jmp loop   ; Just to keep the code below this from being run

someplace:
  ldx #$22
  lda #0
  rts

That code should be clear/concise and easy to understand.

If that comes as a surprise to you, i.e. "I thought A/X/Y were backed up when JSR was used, and restored when RTS was used!", then that would be a bug. Is it *the* bug? I don't know, that's for you to figure out.

So if you need to back up and restore registers, you need to make sure your subroutines push those values onto the stack when the routine starts, and pull them off right before the end (and remember to pull them off the stack in the opposite order as you pushed them on). Again the same code, but fixed to back up and restore A/X/Y:

Code:
  lda #$01
  ldx #$aa
  ldy #$bb
;
; At this point in the code, A = $01, X = $AA, Y = $BB
;
  jsr someplace
;
; At this point in the code, A = $01, X = $AA, Y = $BB
;
loop:
  jmp loop   ; Just to keep the code below this from being run

someplace:
  phx
  pha
  ldx #$22
  lda #0
  pla
  plx
  rts

You could also accomplish the same thing by putting the pushes and pulls around (before and after) the JSR, but that's for you to decide. Usually when making subroutines people do the backup/restore within the routine itself (at the start of the routine, and immediately before the RTS).

I don't use PHY/PLY anywhere in the "someplace" routine because Y isn't modified; but you could add it there just as a safety net if you wanted, no harm done (other than some CPU cycles wasted).


Top
 Profile  
 
PostPosted: Wed Jan 14, 2015 3:57 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2131
Location: Minneapolis, Minnesota, United States
I'm sorry, I might be on drugs here... But PLX/PHX and PLY/PHY are not real 6502 commands... Right?


Top
 Profile  
 
PostPosted: Wed Jan 14, 2015 4:10 pm 
Offline

Joined: Tue Jul 01, 2014 4:02 pm
Posts: 254
No I got it.

Celius, I think he was just using that to abbreviate TAX -> PHA. I knew what he meant. Unless I'm mistaken.

But Koitsu, yeah, I get it. I was misreading Rainwarriors meaning (specified in the edit). I get it. I had a moment of revelation when Nostromo posted that visual example. It was the exact same thing EVERYONE was saying, but seeing it like that for some reason just kicked over whatever blockage was happening in my brain.

JSR puts a value into the stack. Without the RTS, the value never gets pulled. So when I was JMPing out of the subroutine, there was leftover junk in the stack, and I'm pretty sure that's what was causing the problem. I may have done this in other places too, so I'll have to go back through and check. I wasn't making the correlation between JSRing and the stack...I understood using PHA PLA to push and pull the accumulator the stack, but just didn't know (or at least, didn't factor) that JSR RTS also pushed and pulled to the stack.

Thanks for all the input - sorry for being so dense! haha


Top
 Profile  
 
PostPosted: Wed Jan 14, 2015 4:13 pm 
Offline
User avatar

Joined: Sat Jul 12, 2014 3:04 pm
Posts: 936
Celius wrote:
PLX/PHX and PLY/PHY are not real 6502 commands... Right?

Nope! {PH|PL}{X|Y} were added on the 65C02.

You might also want a PHP/PLP sometimes.
(Interrupts and RTI include status push-pulls and don't need them added.)

Also, if you had imbalanced push-pulls, those use the same stack as the return address generated/used by JSR/RTS.


Top
 Profile  
 
PostPosted: Wed Jan 14, 2015 8:22 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2131
Location: Minneapolis, Minnesota, United States
I figured they weren't, but it seems like the kind of thing I would glance over and then learn about 10 years later :). It's also good to clarify here for anyone browsing the Newbie Help Center so they don't get confused.


Top
 Profile  
 
PostPosted: Wed Jan 14, 2015 10:52 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Celius wrote:
I'm sorry, I might be on drugs here... But PLX/PHX and PLY/PHY are not real 6502 commands... Right?

Sigh. :( As Myask pointed out they're 65c02. I often forget which opcodes the 65c02 introduced in comparison to the original 6502 (and to me that's funny since I started with 6502, went to 65c02 within about 6 months, then later to 65816) -- the only one I always remember is how inc (a.k.a. inc a) doesn't exist on 6502 (instead forced to clc / adc #1); the others I often forget. Thanks guys for keeping me on my toes + pointing out this mistake of mine. Apologies if anyone reading this thread misses that mistake / gets bitten by it.

Revamped routine which does the same thing but works on 6502:

Code:
someplace:
  pha
  txa
  pha
  ldx #$22
  lda #0
  pla
  tax
  pla
  rts


Top
 Profile  
 
PostPosted: Thu Jan 15, 2015 2:30 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5732
Location: Canada
JoeGtake2: You had the part I was asking about correct, I was just asking because you mentioned that using TAY/TYA to manually restore A helped. It sounds like you have cleared up your confusion though, otherwise.


Top
 Profile  
 
PostPosted: Sat Jan 17, 2015 5:28 pm 
Offline
User avatar

Joined: Sat Jul 12, 2014 3:04 pm
Posts: 936
koitsu wrote:
Celius wrote:
I'm sorry, I might be on drugs here... But PLX/PHX and PLY/PHY are not real 6502 commands... Right?

Sigh. :( As Myask pointed out they're 65c02. I often forget which opcodes the 65c02 introduced in comparison to the original 6502 (and to me that's funny since I started with 6502, went to 65c02 within about 6 months, then later to 65816)

This is of modest use, though a bunch of the 816 opcodes get overridden by the new ones he put in. (Might also be c02, not sure; only barely familiar with either).

It looks nice, anyway.


Top
 Profile  
 
PostPosted: Sat Jan 17, 2015 7:56 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Myask wrote:
This is of modest use, though a bunch of the 816 opcodes get overridden by the new ones he put in. (Might also be c02, not sure; only barely familiar with either).

It looks nice, anyway.

Charts like that tend to be hard for me to follow because they seem "thrown together" (and in my experience a lot of people who have "charts of opcodes" end up making mistakes -- there are all sorts of 6502 web pages that have these which are riddled with mistakes. They get mentioned here once in a while). I prefer stuff like what's in the WDC manual:

...but then I just realised on the per-opcode-breakdown, the formatting (column sizes and layout) in the PDF is completely botched compared to the actual Ron Lichty and David Eyes book, making the one in PDF format hard to read. Hahaha wow... way to go WDC. *sigh*


Attachments:
File comment: WDC PDF: Opcode chart
03.png
03.png [ 100.89 KiB | Viewed 1530 times ]
File comment: Ron Lichty/David Eyes book: LDA break-down
02.jpg
02.jpg [ 228.72 KiB | Viewed 1530 times ]
File comment: WDC PDF: LDA break-down
01.png
01.png [ 100.24 KiB | Viewed 1530 times ]
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 29 posts ]  Go to page Previous  1, 2

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 10 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