The VAT is the wonderful place in RAM where information about every variable can be found. The OS offers a handful of bcalls for dealing with the VAT, but sometimes they may seem too slow or too limited. Here are some routines that might be useful.
SearchVarBC
This clever routine allows you to search for an OS named variable (like Pic1, Str7, and the like) whose name is in BC. For example, if BC was 0160h, it would look for Pic2 since the hex for Pic2 is 6001h. It is also pretty small and fast and has the same outputs as rFindSym
SearchVarBC:
ld hl,$FE60 ;This is at the end of the VAT (or beginning, depending on how you look at it)
SVBCLoop:
ld a,c ;Check the first byte of the name
cp (hl) ;Compare to the byte at HL
dec hl ;HL points to the next byte of the name
jr nz,VarNoMatch ;No match, so check the next var
ld a,b
cp (hl)
jr z,VarMatch ;Yay, both bytes matched
VarNoMatch:
ld de,-8
add hl,de ;We essentially subtracted 8 from HL, pointing to the next var
ex de,hl ;Swap HL and DE, we need to check if we are at the end of the VAT
ld hl,(9830h) ;This RAM address holds the location of the end of the symbol VAT
sbc hl,de ;Subtract HL and DE. Normally, we need to worry about the c flag, but here we don't (c is always set, subtracting 1 more from HL). If HL=DE, then HL-DE=0, so the z flag will be set
ex de,hl ;re swap HL and DE, so HL is appropriate
scf ;Set Carry Flag (we just do this to pass info to the callee)
jr nz,SVBCLoop
VarMatch:
ld c,3 ;Length of var name
inc hl
inc hl
ld b,(hl) ;flash page the var is on
inc hl
ld d,(hl) ;High byte of the var address
inc hl
ld e,(hl) ;low byte of the var address
inc hl
inc hl
inc hl
ld a,(hl) ;The variable type
ret
ChkFindVar
This routine is for searching for lists, programs, appvars, and other user-defined variables. This has a subroutine that allows you to use another RAM location other than OP1. This is useful as you won't need to copy the name to OP1. Combined with SearchVarBC, an alternative to bcall(_ChkFindSym) can be created, with the same outputs.
;===============================================================
ChkFindVar:
;===============================================================
;Inputs:
; OP1 contains the var name to search for
;Outputs:
; A is the type
; B is the flashpage
; C is the name length
; DE points to the size bytes
; HL points to the symentry
;Destroys:
; Last 2 bytes in OP1
;===============================================================
ld de,8478h
ChkFindVarAtDE: ;(you can call here instead with DE pointing to the var name)
ld bc,9
ld a,(de)
and 1Fh
ld (de),a
ld hl,OP2-1
cp 5
jr nz,$+4
ld (hl),6
cp 6
jr nz,$+4
ld (hl),5
ex de,hl
ld a,b
push hl
cpir
jr z,$+3
dec c
ld a,7
sub c
ld (OP2-2),a
pop hl
rst 10h
ld hl,(9830h)
CompareOverLoop:
ld de,8478h
CompareLoop:
ld bc,(982Eh)
or a
sbc hl,bc
add hl,bc
ccf
ret z
ld a,(de)
ld bc,-6
cp (hl)
jr z,TypeMatch
ld a,(OP2-1)
cp (hl)
jr z,TypeMatch
add hl,bc
ld c,(hl)
inc c
inc b
or a
sbc hl,bc
jr CompareLoop
NotMatch:
pop af
or a
sbc hl,bc
jr CompareOverLoop
TypeMatch:
add hl,bc
push hl
ld a,(OP2-2)
ld c,(hl)
dec hl
inc b
cp c
jr nz,NotMatch
inc de
CompareName:
ld a,(de)
inc de
cpd
jr nz,NotMatch
jp pe,CompareName
FoundVar:
pop hl
ld c,(hl)
inc hl
ld b,(hl)
inc hl
ld d,(hl)
inc hl
ld e,(hl)
inc hl
inc hl
inc hl
ld a,(hl)
ret