Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Detect origin of JSR in subroutine?
2010-11-05 15:53
Mace

Registered: May 2002
Posts: 1799
Detect origin of JSR in subroutine?

Is it possible to detect where a JSR came from when you're in a subroutine?

I mean...

BLAH:   jsr SUB    // make border white
FOO:    jsr SUB    // make border black
        rts
SUB:    {some code}// (detect where this came from)
        cmp BLAH   // or something of this sort
        beq SKIP
        lda #$00
        sta $d020
        rts
        lda #$01
        sta $d020
        rts

2010-11-05 16:07
WVL

Registered: Mar 2002
Posts: 902
Yes, by reading the stack!

pla -> least significant byte
pla -> most significant byte

(or was it the other way around?)

be careful to put the data back on the stack though..

pla
tax
pla
tay
pha
txa
pha

-> origin in x/y

you can also do something like
tsx
lda $0100,x ;not quite sure, maybe it's $0101? or $00ff?
ldy $0101,x ;not quite sure, maybe it's $0102?


Anyway, read up in the programmer's reference guide.
2010-11-05 16:08
doynax
Account closed

Registered: Oct 2004
Posts: 212
Yes, JSR pushes the return address onto the stack, and you can extract the stack bytes manually to figure out where the function was called from. Beware that JSR actually pushes the return address minus one though!

Here's a quick example of testing for a particular call site:
caller:
	jsr callee
	.
	.
	.

callee:
	tsx
	lda $101,x
	cmp #<caller+2
	lda $102,x
	sbc #>caller+2
	beq match
	.
	.
	.


edit: WVL beat me to it.
2010-11-05 17:00
Oswald

Registered: Apr 2002
Posts: 5094
whatever you need this for this is the worst solution i bet. rather set a flag or smth before calling.
2010-11-05 20:04
Mace

Registered: May 2002
Posts: 1799
Ah, right... the stack. Could've know!
Nah, that's too unreliable for debugging, I indeed better try Oswalds advice ;-)
2010-11-05 20:20
Copyfault

Registered: Dec 2001
Posts: 478
Does the subroutine really depend on the position it was called from or rather on how often the routine has been called already? Seeing the comments in your example code sniplet made me wonder...

In the second case it may be helpful to install a counter inside the subrout, i.e. like this

SUB:
ldx COUNTER
inx
lda color,x
sta $D020
stx COUNTER
rts

Most probably you won't need $100 different subrout states, so a little masking of COUNTER would have to be added to this...

Otherwise checking the stack is mandatory; maybe in your case it is enough to only check the low-byte of jsr-adress.
2010-11-05 20:31
Oswald

Registered: Apr 2002
Posts: 5094
or just use as many subroutines as many you need :)
2010-11-05 20:37
Mace

Registered: May 2002
Posts: 1799
@ Copyfault: Of course, my example was only that, an example.
The program I'm working on has more complex subroutines, but some are very similar, apart from a few lines.
I was thinking of putting something inside the routine to switch between the particular bits, depending on the origin of the JSR.
Or rather... it was a thought experiment. :-)
2010-11-05 20:49
Oswald

Registered: Apr 2002
Posts: 5094
then put the different lines into another subroutine, and keep what's the same in one ?
2010-11-05 20:58
Copyfault

Registered: Dec 2001
Posts: 478
@Mace: if the differing lines are occuring as a connected sequence in the subrout, you could place a jump-command there and tweak the jump-adress before calling the subrout.

This way only the differing parts of the subrout must be placed somewhere in memory.

However, Oswald's suggestion to have as many subrouts as needed will ofcourse be optimal when it comes to timing - unfortunatly not for mem usage :(


Looking forward to the result of your experiments!
2010-11-05 21:17
Mace

Registered: May 2002
Posts: 1799
Ah, yeah, self modifying code is a cool idea too.
However, you will not see the result, as I'm working on a program to check lottery tickets at someone's request, not some demo, game or useful tool.
And it's in Dutch...
2010-11-06 12:49
Krill

Registered: Apr 2002
Posts: 2980
Detecting the JSR's origin for some decision-making in the subroutine sounds like a complicated and hard-to-maintain idea.

It's better to have the caller pass all necessary arguments, and then to use macros for calling the subroutine so you can minimize boilerplate code.

If the three registers and the flags aren't enough, consider using the stack for extra arguments, or pass them by putting them behind the JSR and letting the subroutine return to after the extra arguments. This needs checking the call's origin, but only to find the extra arguments, and to manipulate the return address.

Another approach would be to write the extra arguments to some static memory area before calling the routine, but this does not work well with multi-threading (like calling the same routine in the main loop and from an IRQ handler while the main thread is inside the call). This can be solved by passing a pointer to some caller-allocated structure containing all arguments.

If the sub-routine needs to maintain an internal state: What Copyfault said. :)
2010-11-06 20:06
Ervin

Registered: May 2008
Posts: 14
Quoting Krill

...have the caller pass all necessary arguments...
...using the stack for extra arguments...
...passing a pointer to some caller-allocated structure...
...the sub-routine needs to maintain an internal state...

Er, umm, what about considering the usage of a not-so-high-level language, such as C, which has native support for all these? ;) ;) ;)
2010-11-07 07:05
Oswald

Registered: Apr 2002
Posts: 5094
"I'm working on a program to check lottery tickets "

how about basic, if it must run on a c64?
2010-11-07 21:13
Copyfault

Registered: Dec 2001
Posts: 478
Quoting Mace
...
And it's in Dutch...

Ik denk niet dat "Nederlandstalig" een echt probleem is ;))

But as this is for some lottery thing, it will ofcourse not show up here on CSDB.

Would be nice if let us know how you solved your problem when you're finished.

Good luck!

PS: and what Oswald asked: why not do this with BASIC?
2010-11-07 22:10
Mace

Registered: May 2002
Posts: 1799
Quoting Oswald
"I'm working on a program to check lottery tickets "

how about basic, if it must run on a c64?

Because it has to test 10 files with 50 possible ticket combinations each, against a draw of 7 numbers.
On top of that: I already have the program that does it, it only needs some minor changes because the rules of the lottery changed.

Please let's not go into detail about the how and why of this program. Consider it a fact from where we head off... ;-)

As for the solution of the problem: I kept the various routines as there's no lack of memory but I do want to finish this project and thus don't want to spend much more time on it.
2010-11-23 21:05
MagerValp

Registered: Dec 2001
Posts: 1078
I used this technique once for a bank switching jump table:
function1: jsr bankswitch
function2: jsr bankswitch
function3: jsr bankswitch
...

bankswitch:
        sta save_a
        stx save_x
        lda #newbank
        sta bank_ctl
        pla
        tax
        lda jmptab,x
        sta vector
        lda jmptab + 1,x
        sta vector + 1
save_a = * + 1
        lda #$5e
save_x = * + 1
        ldx #$5e
vector = * + 1
        jmp vector

Can't remember which platform this was though...
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
MWR/Visdom
Steffan/BOOM!
algorithm
Sulevi/Virtual Dreams
Barfly/Extend
DJB/Onslaught / Blue..
Guests online: 108
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 Edge of Disgrace  (9.6)
6 What Is The Matrix 2  (9.6)
7 The Demo Coder  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 No Listen  (9.6)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 Dawnfall V1.1  (9.5)
7 Rainbow Connection  (9.5)
8 Onscreen 5k  (9.5)
9 Morph  (9.5)
10 Libertongo  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Censor Design  (9.3)
5 Triad  (9.3)
Top NTSC-Fixers
1 Pudwerx  (10)
2 Booze  (9.7)
3 Stormbringer  (9.7)
4 Fungus  (9.6)
5 Grim Reaper  (9.3)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.048 sec.