z80:VAT Routines

From Learn @ Cemetech
Jump to navigationJump to search

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