Post Reply 
(15C) 95 virtual labels: vLBL and vGTO
04-10-2018, 11:20 PM (This post was last modified: 04-11-2018 12:12 AM by Michael Zinn.)
Post: #1
(15C) 95 virtual labels: vLBL and vGTO
Define and go to 95 virtual labels (0-94) which can point to line numbers 001 to 099.

This is useful if you want to have more than 20 programs in your calculator at once.



Basic Idea

Jumping to line numbers is problematic because you will have to change all call sites when the line number changes. The solution is a lookup table from virtual label numbers to line numbers. To prevent the lookup table from moving around itself it is stored in registers (5 labels per register).



vLBL

Use this to define or redefine a virtual label.

1. Switch to run mode
2. Enter the line number to jump to (1 to 99)
3. Enter the virtual label number (0 to 94)
4. Run the vLBL program



vGTO

Jump to a virtual label. You can either use this like GTO or GSB.

1. Enter virtual label number that you defined previously (0-94)
2a. GTO vGTO (works like GTO)
2b. GSB vGTO (works like GSB)



Writing a Virtual Subroutine

vGTO puts the line number into I and the original I into X, so the first thing a virtual subroutine has to do is restore I and the stack:

1. Go to the line number after which you want to add a new virtual subroutine
2. STO I
3. Remember the currently shown line number
4. Switch to run mode to run the vLBL program (see above)
5. Switch back to program mode
6. Rv
7. Enter your subroutine code like usually.



Recommended Memory Layout

Since virtual labels point to line numbers, code should be layed out in a way that minimizes label movements:

Code:
001: GTO 0  ; to run something on R/S
002-?: virtually labeled code
?-End of program memory: regularly labeled code

When you want to add more virtually labeled code you GTO the first real label, switch to program mode, go one step back and start inserting your code.

Note that virtual labels are stored starting in register 18 and grow backwards: virtual registers 0 to 4 are in real register 18, virtual registers 5 to 9 are in real register 17 and so on. Virtual register 94 is in real register 0.

If you have to move code around you will only have to redefine the virtual label. Calling code need not be changed because of the indirection.



Code

Note that this requires the vSTO and vRCL programs.

vLBL
Code:
LBL "vLBL"
  9
  4
  x<>y
  -
  GTO "vSTO"

vGTO
Code:
LBL "vGTO"
  9
  4
  x<>y
  -
  GSB "vRCL"
  CHS
  x<>I
  GTO I
Find all posts by this user
Quote this message in a reply
04-12-2018, 06:43 PM
Post: #2
RE: (15C) 95 virtual labels: vLBL and vGTO
I used this to squeeze 30 programs into my calculator, but it was a tedious and error prone process which I don't recommend to anybody.

At this point all this has reached a level of complexity that would require some sort of compiler/memory layouting program with dependency management that sets up the labels and register allocation automatically. You would save your programs in a machine readable format (e.g. edn) and concatenate them, similar to C's #include function. The configuration could be compiled and be deployed via USB to a DM14L automatically.

It might look something like this:
Code:

{
        :configurations [
                ["budget/adjust", "budget/calc", "run", "vSTO", "vRCL"]
                ["xth root of y", "to binary", "log_x(y)", "y mod x", "dice"]
                ["cash register/abort", "cash register/bye", "cash register/change", "cash register/done"]
        ]
        :registers {
                0 "cash register/total"
                7 "dice/count"
                8 "dice/faces"
                9 "budget/budget"
        }
        :programs [
                "programs/whatever.edn"
                {
                        :name "dice"
                        :author "Michael Zinn (@RedNifre)"
                        :date "2018-04-06"
                        :code [
                                (FIX 0)
                                (RCL "count")
                                (STO I)
                                (CLx)
                                (LBL "loop"
                                        (RAN#)
                                        (RCL * "faces")
                                        (INT)
                                        (+)
                                        (DSE I
                                                (GTO "loop")))
                                (for ("i" 15 0)
                                        (eee)
                                        (aaa))
                                (RCL + 7)
                        ]
                }
                {
                        :name "cash register"
                        :author "Michael Zinn (@RedNifre)"
                        :date "2018-04-06"
                        :code [
                                (LBL "entry"
                                        (STO I)
                                        (RCL (i))
                                        (STO + "_tally")
                                        (R v)
                                        (RTN))

                                (LBL "done"
                                        (RCL "_tally")
                                        (RTN))

                                (LBL "change"
                                        (-)
                                        (RTN))

                                (LBL "bye"
                                        (RCL "_tally")
                                        (STO + "drawer"))
                                (LBL "abort"
                                        (FIX 2)
                                        (CLX)
                                        (STO "_tally")
                                        (RTN))
                        ]
                }
...

I'll probably not do this at this point but if somebody wants to continue the work I'm all ears!
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)