Shop OBEX P1 Docs P2 Docs Learn Events
BS2P Crossbank Calls — Parallax Forums

BS2P Crossbank Calls

msh5686msh5686 Posts: 70
edited 2012-05-23 23:14 in BASIC Stamp
I have been using Tracy Allen's method of doing crossbank calls and am wondering if anyone has experience expanding the calls to further branches. Specifically, in the attached program I am trying to use the calling methods Tracy describes, but I need the program to do something a little different. I want to start by going to V00 then V01 to V10 to V02 to V11 and finally back to V00. On all subsequent loops I want to be able to run from V00 to V02 to V11 and back to V00. If anyone has a method of doing this or any insight as to how I can do this, it would be greatly appreciated!

Mike

Branch_1.bsp
2Banks_5Branches_0.bsp

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2012-05-22 08:20
    All you're doing is skipping V01 and V10 after they've been called once. The easiest way to do this is to have a bit variable that will be initialized to zero on a reset (already done). If this variable is a one, V00 calls V02 rather than V01 and V02 will always set this variable to a one.
  • Martin_HMartin_H Posts: 4,051
    edited 2012-05-22 10:15
    I extended Tracy Allen's method to use the scratch pad as a call stack. That way I can nest cross bank calls and return to any bank from any bank. Here's a sample:

    MotionScriptMain.bse

    MotorsAndSensors.BSE
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-05-22 11:27
    Like Mike said, it sounds like what you need is a one-bit flag that indicates that all the initialization has been done.... The important thing in multi-slot programming is that the flags be in a specific location in all of the slots. In my programs I usually always have a lot of flags, so I dedicate the second word variable in memory to them, in all slots:
    [SIZE=1][FONT=courier new]wsx VAR word                 ' this is the slot xchange variable, first word
      spot VAR wsx.byte0
        spotRun VAR spot.nib1  ' this is the target slot number, 0-7
        spotGo VAR  spot.nib0   ' this is the branch-to index in the target slot
    
    flags VAR word
      config VAR flags.byte0   ' configuration flags read from eeprom at starup
      status VAR flags.byte1  ' status flags change during program execution
        first VAR status.bit4     '  initialization flag
    ' ..
    first = 1 [/FONT][/SIZE]
    

    Accordingly, the code that decides whether or not to execute the initialization...
    [SIZE=1][SIZE=1][FONT=courier new]x_initialize  CON $11   ' name for target index 1 in slot 1
    x_ret_initialize CON $01   ' return to slot 0, index 1 after initialize
    IF first THEN
       PUT back x_ret_initialize   ' return vector
       spot = x_initialize
       RUN spotRun
       first = 0    ' done with initialization
    
    [/FONT][/SIZE][/SIZE][SIZE=1][SIZE=1][FONT=courier new]ret_initialize[/FONT][/SIZE][/SIZE][SIZE=1][SIZE=1][FONT=courier new]  ' the return index $01 points to this label.
    ' and so on[/FONT][/SIZE]
    [/SIZE]
    
  • msh5686msh5686 Posts: 70
    edited 2012-05-23 08:30
    Hi, I really appreciate you helping with my snag but I have some clarifying questions. I have tried using a BIT when I first came upon this issue, but it didn't seem to work. What I did was this is put the branch statements in an IF:THEN:ELSEIF loop as can be seen in the code.

    Bank 0:
    ' {$STAMP BS2p, Branch_1}
    ' {$PBASIC 2.5}
    
    
    ' ----------[ Variables ]---------------------------------------------------------
    Jump          VAR             Word                                    ' Word variable for switching vectors
    Ret           VAR             Jump.BYTE1                              ' High BYTE of "Jump" for "return to" target bank and branch
    Go            VAR             Jump.BYTE0                              ' Low BYTE of "Jump" for bank switching to a target bank and branch
    GoRun         VAR             Go.NIB1                                 ' High NIB of "Go" for specifying tagret bank
    Go2           VAR             Go.NIB0                                 ' Low NIB of "Go" for specifying target branch
    Flags         VAR             Word                                    ' Word variable for storing flags
    Status        VAR             Flags.BYTE1                             ' Status flags change during program execution
    Config        VAR             Flags.BYTE0                             ' Low BYTE of "Flags" for configuration flags read from EEPROM on startup
    First         VAR             Status.BIT4                             ' Initialization flag
    n             VAR             Nib
    
    
    ' ----------[ Constants ]---------------------------------------------------------
    ' Bank 0 Targets:
    V_00          CON             $00
    V_01          CON             $01
    V_02          CON             $02
    
    
    ' Bank 1 Targets:
    V_10          CON             $10
    V_11          CON             $11
    
    
    ' ----------[ Program ]----------------------------------------------------------
    IF First = 0 THEN
    BRANCH Go2, [V00, V01, V02]
    ELSEIF First = 1 THEN
    BRANCH Go2, [V00, V02]
    ENDIF
    
    
    V00:
      DEBUG "Main Routine", CR
      PAUSE 1000
      Ret = V_00
      Go2 = V_01
    
    
    V01:
      DEBUG "Going to Memory Initialization", CR
      PAUSE 1000
      Go = V_10
      RUN GoRun
    
    
    V02:
      DEBUG "Going to DataLogging", CR
      PAUSE 1000
      Go = V_01
    

    Bank 1:
    ' {$STAMP BS2p}' {$PBASIC 2.5}
    
    
    ' ----------[ Variables ]---------------------------------------------------------
    Jump          VAR             Word                                    ' Word variable for switching vectors
    Ret           VAR             Jump.BYTE1                              ' High BYTE of "Jump" for "return to" target bank and branch
    x             VAR             Ret.NIB1
    Go            VAR             Jump.BYTE0                              ' Low BYTE of "Jump" for bank switching to a target bank and branch
    GoRun         VAR             Go.NIB1                                 ' High NIB of "Go" for specifying tagret bank
    Go2           VAR             Go.NIB0                                 ' Low NIB of "Go" for specifying target branch
    n             VAR             Nib
    
    
    ' ----------[ Constants ]---------------------------------------------------------
    ' Bank 0 Targets:
    V_00          CON             $00
    V_01          CON             $01
    V_02          CON             $02
    
    
    ' Bank 1 Targets:
    V_10          CON             $10
    V_11          CON             $11
    
    
    ' ----------[ Program ]-----------------------------------------------------------
    BRANCH Go2, [V10, V11]
    
    
    V10:
      DEBUG "Initializing", CR
      PAUSE 1000
      n = 1
      Go2 = V_11
    
    
    V11:
      DEBUG "Data Logging", CR
      PAUSE 1000
      Go = V_00
      RUN  GoRun
    

    My question is, is this the correct way to skip the initialization with the branch command?

    Stupid question, but why does the bit need to be put in the SPRAM? Maybe I'm misunderstanding things, but I thought as long as the variables were defined in exactly the same order in each bank the values would carry over.

    Mike
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-05-23 23:14
    You have the return vector stored in jump.byte1, and that is fine. The scheme is designed to be symmetrical. The routine being called in the second slot should normally move the return vector back into the go vector when it is ready to make the return. It is a one-level return stack, KISS. I don't follow exactly what you are trying to accomplish, but I find that it helps if the labels and the index numbers are given matching mnemonics. In the following, the initialization routine starts in slot 0 and finishes up with memoryInit in slot 1, and then back to the main routine. Subsequently the action jumps back and forth between the main routine in slot 0 and and the dataLogging routine in slot 1.

    [SIZE=1][FONT=courier new]' {$STAMP BS2pe, "slotDemo (slot 1).bpe"}
    ' {$PBASIC 2.5}
    ' this is the slot 0 routine
    v_startup CON $00
    v_mainRoutine CON $01
    v_ret_mainRoutine CON $02
    v_memoryInit CON $10
    v_dataLogging CON $11
    
    jump VAR WORD
     ret VAR jump.BYTE1
     go  VAR jump.BYTE0
      goRun VAR go.NIB1
      go2   VAR go.NIB0
    
    BRANCH go2,[startup,mainRoutine,ret_mainRoutine]
    startup:
    ' some  stuff
      Ret = v_mainRoutine
      Go =v_memoryInit
      RUN goRun       ' runs the memoryInit routine and returns to mainRoutine
    
    mainRoutine:
      DO
      'main stuff
      Ret=v_ret_mainRoutine
      Go=v_dataLogging
      RUN goRun        ' runs the dataLogging routine and returns to the next instruction below
    ret_mainRoutine:
     ' more main stuff
      LOOP[/FONT][/SIZE]
    
    [SIZE=1][FONT=courier new]' {$STAMP BS2pe}
    ' {$PBASIC 2.5}
    ' Slot 1, same variables and constants as slot0
    
    v_startup CON $00
    v_mainRoutine CON $01
    v_ret_mainRoutine CON $02
    v_memoryInit CON $10
    v_dataLogging CON $11
    
    jump VAR WORD
     ret VAR jump.BYTE1
     go  VAR jump.BYTE0
      goRun VAR go.NIB1
      go2   VAR go.NIB0
    
    BRANCH go2,[memoryInit, dataLogging]
    
    memoryInit:
      ' do stuff
      go = ret     ' note that this returns via the vector set up in slot 0
      RUN goRUN    
    
    dataLogging:
      ' do it
      go = ret     ' ditto, it is just a one-level stack, but KISS
      RUN goRun[/FONT][/SIZE]
    

    This does not use the "first" flag, but it it did, it would be necessary to lower the flag at the end of the first cycle.
Sign In or Register to comment.