z80:VAT Routines
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