I was considering a feature that sets a BASIC variable if a certain condition occurs within a machine language utility. Ultimately, I decided not to implement this feature, in favor of another strategy, but I thought that you folks might benefit from what I learned.
The scope of my project was somewhat limited in that (1) I was only interested in integer (%) variables, and (2) I was only interested in setting a variable with a single-letter name. I haven't yet delved into float and string variables, although I already have a pretty good understanding of float variable storage and manipulation. Updating these routines to use two-letter variables should be trivial, and to handle other variable types less so.
SetIntVal is essentially a miniature replacement for LET. You provide a variable name, n, and a new value, and the subroutine sets the variable n%. You don't have to worry about whether the variable already exists, as this is part of the variable search code at $DOE7. After invoking SetIntVal, you can do PRINT n% to see the value you've set.
An interesting thing about integer variable storage is that the integer is stored backwards, in high/low format. Also, BASIC will treat your value as a signed integer.
Here are the subroutines:
Code: Select all
; Set BASIC Integer
; Preparations
; A = Letter variable name
; X = New value, low
; Y = New value, high
SetIntVal: sta $49 ; Stash A for safekeeping
txa ; Push new value bytes for later
pha ; ,,
tya ; ,,
pha ; ,,
lda $49 ; A is the variable letter name
jsr GetVarAddr
ldy #$00 ; Offset for the high byte
pla ; Get high byte value (formerly Y) from stack
sta ($49),y ; Store it in BASIC memory at found address
iny ; Advance to next byte
pla ; Get low byte value (formerly X) from stack
sta ($49),y ; Store it in BASIC memory
rts
; Get BASIC Integer
; Preparations
; A = Letter variable name
; Return
; X = New value, low
; Y = New value, high
GetIntVal: jsr GetVarAddr ; Get the address of the variable data
ldy #$01 ; Values are stored in high/low order, so
lda ($49),y ; start at offset 1 to get the low byte
tax ; and put it in X
dey ; Now move to index 0 to get the high byte
lda ($49),y ; ,,
tay ; and put it in Y
rts
; Get BASIC Variable Address
; Preparations
; A = Letter variable name
; Effect
; Sets $49/$4a with pointer to variable storage address
GetVarAddr: ora #$80 ; Variable names are letter with high bit set
sta $45 ; First character of variable name
lda #$80
sta $46 ; Second character of variable name (empty)
sta $0e ; Variable type integer (n%)
asl
sta $0d ; Set to numeric variable
jsr $d0e7 ; Get address of n% by finding or creating new
sta $49 ; Set low and high bytes of variable address
sty $4a ; ,,
rts