'Gosub Slot' idea

Jeremy Leach

Senior Member
This is just a rough idea and not tried it. It's an attempt to make the 'jump to slot' Run command act like a GOSUB and not a GOTO...

Scenario ...
Slot 3 holds a routine 'SubX' and there's nothing else in the Slot 3. Slot 0 want to run SubX. At this point the stack in Slot 0 has been created by a series of Gosubs ... Gosub SubA, Gosub SubB, Gosub SubC

Idea ...
The subroutines SubA, SubB, SubC in Slot 0 are just regular subroutines, except they start with the line If ReturnedFromSlot = 1 Then RSAJ_1
Code:
SubA:
    If ReturnedFromSlot = 1 Then RSAJ_1
    <code>
Return
 
SubB:
    If ReturnedFromSlot = 1 Then RSAJ_1
    <code>
Return
 
SubC:
    If ReturnedFromSlot = 1 Then RSAJ_1
    <code>
Return
We execute the following code in Slot 0, in order to jump to SubX in Slot 3 ...
Code:
ReturnPointRef = 1
Run 3
ReturnPoint01:
Slot 3 ends it's SubX routine by executing ..
Code:
SubX:
.
.
ReturnedFromSlot = 1
Run 0
At this point, the stack that existed in Slot 0 has been reset.

At the START of Slot0 we have the following RestackAndJump routine ...

Code:
ReStackAndJump:
    If ReturnedFromSlot = 1 Then
        Address = ReturnPointRef * 10
        Read Address,StackDepth
 
        For Count = 1 to StackDepth
            Read SubRef
            On SubRef Gosub SubA,SubB,SubC,SubD
            RSAJ_1:
        Next
 
        ReturnedFromSlot = 0
        On ReturnPointRef Goto ReturnPoint01,ReturnPoint02 ....
    EndIf
This ReStackAndJump routine isn't executed when Slot0 initially boots up, because ReturnedFromSlot will be 0. But when we jump back in this example, from Slot 3, it executes and recreates the stack and then jumps to the point after the initial Run 3. So it's effectively performed a Gosub Sub X but in a long-winded way !

As I say, I haven't tried this, but might do once I get into X2s...
 

BeanieBots

Moderator
I've not gone through your post in every detail but the idea is sound.
I HAVE done it (it does work) and did post something about it a while back.

In a nutshell, all variables are common to each slot, so jumping between slots and then making a jump dependant upon a variable should be fairly simple.
It's really a conditional jump rather than a 'gosub' with the condition set to make it 'return' to where it came from.

Your idea is more in depth to what I tried.
Might even be scope to 'poke' the stack pointer given enough info about it. ???
 

Jeremy Leach

Senior Member
Well, it would be great to be able to manipulate the picaxe stack, but I don't think we've been able to do that yet?

In that post above I was imagining a manually contructed jump table in EEPROM to make sure you jump back to the right place, but actually all you need to do is automatically create a 'mirror stack'. i.e before each GOSUB in slot 0 also push the return address onto your own mirror stack. This will mirror the picaxe stack and can be used to recreate the picaxe stack when returning to Slot 0.

Although do-able it would add an overhead to Slot 0 code. But I like the idea of making best use of all the slots and having subroutines spread across them all called from Slot 0, the 'master' slot.
 

BeanieBots

Moderator
I know what you mean about making good use of the slots.
I have sort of done it with my datalogger which plays "Captains Mistress".

Not really gosubs as such, more of a state engine in which each slot can manipulate the 'state' and hence program flow of another slot.
One slot is dedicated to menus so that the main slot can hold nothing other than the main program. Simple branch statements then decide where execution resumes after 'returning'.

So I guess it works in a very similar manner to your "stack mirror" concept.
You just need to be careful to add the labels and jump-to line for each 'gosub' that is used.

Treat yourself to a couple of X2s. They really are something else:)
I keep meaning to do some command speed tests when running external slots but it does not perceptually go much slower than an internal one which quite surprised me.
 

hippy

Technical Support
Staff member
You can create a pseudo-stack using @bptr or @ptr and friends, and use the same technique of what the numbers pushed mean when executing an equivalent return via an ON-GOTO/BRANCH. This is also one way to get around the 256 GOSUB limitation if it ever arises.

It really is turning the main program(s) into a state-machine but having the state-controller with its own stack.
 

eddu

New Member
If the program counter could be read or written to directly it would be as easy as just reading its value before our gosub and saving it in variables which are not erased on a jump to a different slot. On return the program counter could be loaded with the values saved in the variables.
On reading the pic 18f4520 datasheet (the datasheet for the raw pic used in the picaxe 40X2) one realises that PCH (the high byte of the program counter) and PCU (the upper byte of the program counter) are not directly readable or changeable.
However one can easily note the values on the top of stack by reading the three registers TOSU:TOSH:TOSL. These would give the address which is automatically pushed by a goto command. These special function registers (SFRs) are addressable at 0xFF, 0xFE and 0xFD but unfortunately on trying to peek at these SFRs using the peeksfr command (even poking for that matter) gives an error in the picaxe programming editor. I beleive this is a block from software side either because of the bootloader or the compiler itself.
Some insider knowhow would be helpful in order to solve this slot to slot gosub probem once and for all.
 

hippy

Technical Support
Staff member
Welcome to the PICAXE Forum, eddu.

The PICAXE itself is an interpreter chip so it executes firmware to interpret tokens which represent the Basic program. The internal chip PC and TOS SFR's are therefore used by the firmware and not by the user's program. Altering those will undoubtedly crash the firmware and they are not accessible on the X2.
 

eddu

New Member
10x hippy.

Great explanation just the confirmation I needed. I understand that a work around should be found just like the branch example or the routine procedure described by Jeremy Leach. The pseudo-stack idea is also good but i bet it needs some good planning of the program.
 
Top