Hi Al,

I hereby send you the final outcomings of the program calling issue. It presents a stack mechanism for the Basic Stamp BS2SX, BS2E and BS2P. Maybe you are willing to put it on the faq list so others can benefit from it.

Multilevel stack design and usage for Basic Stamp BS2SX, BS2E and BS2P using the scratchpad.

Many thanks to Tracy Allen for all his input and positive suggestions.

This design uses the available scratchpad to hold a multilevel stack that can be used to call functions (with parameters if required) in other programs and to create named local variables for use within gosubs. It shows a general program setup that can be used as a template.

Features: up to 32 entry/return points per program nested program calls parameter passing via stack named local variables for subroutines

Limitations: program calls can only execute at main level code outside for-next loops. names for local variables must be unique as they are seen as aliases no stackpointer check

'scratchpad usage (TOS stands for Top Of Stack) 
'TOS-0 = entryID/runID 1 
'TOS-1 = entryID/runID 2 
'TOS-2 = entryID/runID 3 
'etc.
'program 0
TopOfStack1 con 62 'top of stack for BS2SX, BS2E 
TopOfStack2 con 126 'top of stack for BS2P
TOS con TopOfStack2 'pick the right top of stack 
STACKSIZE con 30 'define stacksize 
BOS con TOS-STACKSIZE 'bottom of stack
EN1P0 con (1<<3)+0 'entry01 in program 0 
EN2P0 con (2<<3)+0 'entry02 in program 0 
EN3P0 con (3<<3)+0 'entry03 in program 0 
EN4P0 con (4<<3)+0 'entry04 in program 0 
EN5P0 con (5<<3)+0 'entry05 in program 0 
EN4P3 con (4<<3)+4 'entry 4 in program 3 
EN14P4 con (14<<3)+4 'entry 14 in program 4 
EN6P7 con (6<<3)+7 'entry 6 in program 7
'system variables 
TargetID var byte 'entry index and program to run 
runID var TargetID.lownib 'entry index b0, program to run 
entryID var TargetID.highnib 'entry index b4-b1 
StackPointer var byte 'stackpointer
'application variables 
x var byte 
y var byte 
z var byte
ProgramID con 0
begin0: branch (TargetID>>3),[main0,entry01,netry02,...,entry1F]'first entry for direct run
main0: StackPointer=TOS 'insert init code here
main0loop: 'insert mainloop code here
z=0 
call_loop_example: '1st program call example, stackpointer check could be placed here 
put StackPointer,EN1P0 
StackPointer=StackPointer-1 
TargetID=EN14P4 
run TargetID 'execute entry 14 in program 4, then return to entry01 
entry01: 'return point for call 
z=z+1 
if z<10 then call_loop_example
'insert mainloop code here
'2nd call example, stackpointer check could be placed here 
put StackPointer,x 'first put parameters onto stack 
put StackPointer-1,y 
put StackPointer-2,EN2P0 'then put return point 
StackPointer=StackPointer-3 
TargetID=EN6P7 
run TargetID 'execute entry 6 in program 7, then return to entry02
entry02: 'return point for call 
get StackPointer+2,x 'retrieve results 
get StackPointer+1,y 
StackPointer=StackPointer+2 'remove results from stack
'insert mainloop code here
'direct run example 
TargetID=$03 
run TargetID 'run program 3 directly (no call but jump)
'insert mainloop code here
main0end: goto main0loop
'function entries for program calls
entry03: gosub function_03 
put StackPointer,EN4P3 
StackPointer=StackPointer-1 
TargetID=EN4P0 
run TargetID 'execute entry 14 in program 4, then return to entry04
entry04: 'return point for call 
goto ReturnFromProgramCall_0
entry05: get StackPointer+3,x 'get parameters from stack 
get StackPointer+2,y 
gosub function_04 'perform some math on x and y, results in x and y 
put StackPointer+3,x 'place results on stack 
put StackPointer+2,y 
goto ReturnFromProgramCall_0
ReturnFromProgramCall_0: 
StackPointer=StackPointer+1 'adjust stack here 
get StackPointer,TargetID 'get TargetID 
run TargetID 'return to parent program
'subroutines
function_03: 
gosub alloc4 'allocate 4 bytes for local variables 
x1 var W12 'local word variable 
y1 var B23 'local byte variable 
'code here 
goto free4 'free local variables and return from gosub
function_04: 
'code here 
return
alloc8: put StackPointer,B18 
'space is allocated from B25 upwards 
put StackPointer-1,B19 
put StackPointer-2,B20 
put StackPointer-3,B21 
StackPointer=StackPointer-4 
alloc4: put StackPointer,B22 
put StackPointer-1,B23 
put StackPointer-2,B24 
put StackPointer-3,B25 
StackPointer=StackPointer-4 
return
free8: get StackPointer+8,B18 
get StackPointer+7,B19 
get StackPointer+6,B20 
get StackPointer+5,B21 
get StackPointer+4,B22 
get StackPointer+3,B23 
get StackPointer+2,B24 
get StackPointer+1,B25 
StackPointer=StackPointer+8 
return
free4: get StackPointer+4,B22 
get StackPointer+3,B23 
get StackPointer+2,B24 
get StackPointer+1,B25 
StackPointer=StackPointer+4 
return
end