Signetics 2650 & 2636 programming/Indexed branching

BSXA and BXA edit

These two instructions enable indexed branching. BXA is an unconditional indexed branch, while BSXA is an unconditional indexed branch to a subroutine. Register 3 must be specified as the index register.

The example below uses the BSXA instruction to execute one of four subroutines selected by the value in R3. Stepping through this with the WinArcadia debugger is a good way to understand how it works.

mybyte  equ     $1F0E      ; define a variable 
        lodi,r0 $20        ; initialise program status word, just to be sure!
        lpsu               ; inhibit interrupts, stack pointer=0
        lpsl               ; register bank 0, without carry, arithmetic compare
        stra,r0 mybyte
loop:
        lodi,r3 0            ;go and subtract 1
        bsxa    mysubs,r3
        lodi,r3 9            ;go and multiply by 4
        bsxa    mysubs,r3
        lodi,r3 6            ;go and add 16
        bsxa    mysubs,r3
        lodi,r3 3            ;go and divide by 2
        bsxa    mysubs,r3
        bctr,un loop
        
mysubs:
x0:     bcta,un subtract1
x3:     bcta,un divide2
x6:     bcta,un add16
x9:     bcta,un multiply4

subtract1:   
        loda,r0 mybyte
        subi,r0 1
        stra,r0 mybyte
        retc,un

divide2:   
        loda,r0 mybyte
        rrr,r0
        stra,r0 mybyte
        retc,un

add16:  loda,r0 mybyte
        addi,r0 16
        stra,r0 mybyte
        retc,un

multiply4:
        loda,r0 mybyte
        rrl,r0
        rrl,r0
        stra,r0 mybyte
        retc,un

Some points to note:

  • The index register must be R3
  • The index value goes in steps of three because the bcta instructions are three bytes long.
  • If the subroutines were all close enough together, bctr instructions could be used and the index would go in steps of two.
  • In some scenarios the table of branch instructions, mysubs, could be omitted altogether but the index values would be rather haphazard and might be difficult to maintain.

Creating a state machine edit

Indexed branching might typically be used where a 'case statement' would be used in a high-level language. One application of BSXA is to create a state machine to control parts of a program. It might be something global such as controlling which part of the program is running: splash screen, attract mode, select level screen, game play, or game over screen. It might also be used to control the state of certain elements within a program.

The code for this tutorial can be found at 'State machine'. In this program, the code draws two objects, one of them moving along a rectangular path, the other a triangular path. This could be done with code that tests the objects position and determines which way to move it on every frame, but this can quickly get messy. In a state machine model, the object moving in a rectangular pattern is in one four states: moving right, moving down, moving left or moving up. Each state does a check after every move to see if it has reached its endpoint, at which time it changes the state of the machine to the next operation. A variable is used to keep track of the state, and this acts as the index to the appropriate subroutine. In this code, a second state machine asynchronously controls the object moving on the triangular path.

Further reading edit

  • Nystrom, Robert (2014). "State". Game Programming Patterns. Genever Benning. ISBN 0990582906. Retrieved 6 January 2022. {{cite book}}: Unknown parameter |month= ignored (help) State machines in game programming with examples in high-level language.
  • Finite-State Machines: Theory and Implementation
  • Artificial Intelligence 1: Finite State Machines
  • Why developers never use state machines Some pitfalls of state-machines (note: they are more formally called finite state machines) and when not to use them.

Exercise edit

Add a third state machine that controls a blue rectangle moving back-and-forth along a path like a greater-than symbol, >