Author Topic: Documentation dump  (Read 3074 times)

0 Members and 1 Guest are viewing this topic.

Offline Iambian

  • Coder Of Tomorrow
  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 739
  • Rating: +216/-3
  • Cherry Flavoured Nommer of Fishies
    • View Profile
Documentation dump
« on: January 05, 2011, 07:51:28 pm »
What I have here is for someone on the omni chat room. It explains a little about the VAT. If you find this useful, move this topic to some other place.

Code: [Select]
On the TI-83 Plus graphing calculator, there are three different tables used to
allocate memory to programs, or to determine the presence of each program or
variable to the calculator. For the reason the table exists, it's often times
called the "VAT", or "Variable Allocation Table". Usually, this name is given to
the second part of the entire table, or to be most specific, the first part of the
table, with a fixed beginning, is called the "Symbol VAT" and the next part is
called the "Program VAT", but some people would call it the "Symbol Table" and the
"VAT", respectively. The third part, which few people know about, is the Temporary
Variable section, which is pointed to by (pTemp). (pgmPtr) points to the Program
VAT.

All entries on any table are written in backwards, from high memory to low memory.

All entries on Program VAT vary depending on the name length

==============================================
| -(n+6)    -6    -5   -4    -3    -2  -1  0 |
==============================================
| VarName  N.Len Page DadrH DadrL Ver  T2  T |
==============================================

VarName can be up to 8 characters in length
T= first five bits are datatype,
   b5= graph equ selected
   b6= variable used during graphing
   b7= link transfer flag
T2=for future use [TI-OS keeps it at ZERO]
Ver= version code to not recieve if higher than current OS code
DadrL = data address, LSB
DadrH = data address, MSB
Page  = if archived, holds flash page. Otherwise, = 0
N.Len = following name's length. For lists, this includes token and formula #

For lists, the name can be up to 5 characters in length.
Preceding the name is the list token ($5D), and postceding it is the formula number, which is
set to zero if there is no formula attached. If there is, then a number will be given to point
to a corresponding unique name for an EQU variable in the Symbol VAT.

All entries on the Symbol VAT are fixed in size.

==============================================
| -8   -7   -6    -5   -4    -3    -2  -1  0 |
==============================================
|  0   Tok2 Tok1 Page DadrH DadrL Ver  T2  T |
==============================================
Tok1 = first token of name
Tok2 = second token of name

A symbol table entry for a formula would be where:
Tok1 = $3F
Tok2 = F, where "F" would be the corresponding function # found with the list.

If you want, here's some code that'll perform a sort on the program VAT. My hope is that it'll help you better understand code that works with the VAT:
Code: [Select]
#define equ .equ
#define EQU .equ
#define EQU .nostub

.org $9D93
.dw  $6DBB
;Program used to sort the Program/List VAT alphabetically
;(progPtr) is the start of the VAT. First order of business is to determine
;how many entries are in the VAT. Then we can go ahead and blindly sort the
;entire contents of the VAT.
;Checking against (pTemp) at the end of the run. Gets us this manieth entries
;
;
#define bcall(xxxx)     rst 28h         \ .dw xxxx
_DispHL EQU 4507h

pTemp                EQU  982Eh
progPtr              EQU  9830h
tempSwapArea         EQU  82A5h
curptr   equ tempswaparea   ;2 bytes, current location in the VAT
swaptemp equ curptr+32      ;up to 30 bytes for temporary swapping. Backwards

ProgramStart:
 ld ix,0
 ld bc,(ptemp)
 ld hl,(progPtr)
ProgramLoop1:
 call GetNextEntry
 inc ix
 push hl    ;preserve HL for the check.
  or a
  sbc hl,bc  ;checking to see if it's at the end.
 pop hl
 jr nz,ProgramLoop1 ;If end of VAT is not current pointer, keep going.
 push ix
 pop bc
ProgramLoop2:
 ld hl,(progPtr)  ;pointer to the start of the VAT, to start off with each run
 dec bc
 ld a,b
 or c
 ret z            ;Kill routine if there's no more entries to sort through
 push bc          ;saving this variable for later...
ProgramLoop3:
  push bc          ;save loop counter for VAT traversal
   push hl         ;save current address to the VAT location
    ld de,-6       ;to get to...
    add hl,de      ;...file name size of this VAT entry
    ld c,(hl)      ;getting size of entry #1 into C
    push hl        ;saving first address point   
     ld a,c        ;
     cpl           ;getting past name and first decrement
     add a,e       ;-6+-1+-sizeofcurrenname = entry #2 name size
     ld e,a        ;Hehe. Loading this back into DE
     add hl,de     ;now at size of second file
     ld b,(hl)     ;And putting filename size #2 into B
     dec hl        ;moving HL to the filename's start (#2)
    pop de         ;DE is 1st file, HL is second file. Starting at their names.
    dec de         ;moving DE to the filename's start (#1)
    ld a,c         ;Start comparison of namelength fields.
    cp b           ;C=(#1) B=(#2); C-B. Carry if C is shorter
    ld a,1         ;If first name is longer, then perform swap if all is equal
    jr nc,$+4      ;If B(#1) is shorter (NC), skip. Else, set B to short and...
    dec a          ;...reset A to indicate no swap.
    ld b,c         ;Set B to the lowest possible
    ld c,a         ;Resetting C to function as a flag. Should it swap is the anser.
ProgramLoop4:
    ld a,(de)      ;1st file
    cp (hl)        ;2nd file.
    dec de         ;get next characters in the file names.
    dec hl
    jr nz,$+6      ;if the names do not match, jump past to continuation...
    djnz ProgramLoop4  ;only iterating for shortest number of characters.
    jr ProgramSkip5    ;If no more chars, do default swap action from last rtn.
    ld c,0             ;Remove flag from previous routine. Diff in name means...
    jr c,ProgramSkip5  ;(1f)-(2f) If carry, no swap needed.
    inc c              ;else, start up the routine used for swapping.
Programskip5:         ;we have our flags now. 0 for noswap, 1 for swap
   pop hl              ;get back current VAT address (starting)
   ld (curptr),hl      ;save this for future reference.
   call GetNextEntry   ;getting the next entry from HL
   dec c               ;checking for zero. If so, a swap is in order...
   jr nz,ProgramSkip6  ;if jump is taken, skip the swapping business
   ld de,swaptemp     ;loading the temporary writeout address
   call CopyEntry     ;copy second entry
   ld hl,(curptr)     ;get back the first entry location
   push hl            ;Save it as the location to write back to.
    call CopyEntry    ;copy the first entry as second into the buffer
    ld hl,swaptemp    ;loading higher address to HL and prepare for subtraction
    or a              ;clear out carry flag so sbc isn't affected.
    sbc hl,de         ;Subtract to get the size difference (number of bytes)
    ld b,h            ;number of bytes total to copy
    ld c,L
   pop de             ;back to first entry location
   push de            ;save that sucker again.
    ld hl,swaptemp    ;point to the start of the temporary buffer location
    lddr
   pop hl
   call GetNextEntry   ;getting the NEW next entry
ProgramSkip6:
  pop bc
  dec bc
  ld a,c
  or a
  jr nz,ProgramLoop3
 pop bc
 jr ProgramLoop2
 
CopyEntry:
 ld bc,6   ;write and decrement HL and DE the first 5 bytes of VAT entry.
 lddr      ;Uh. yeah.
 ld a,(hl) ;Get that sixth byte, which is size field
 inc a     ;Another for this byte as well...
 ldd       ;Perform one LDD for each byte of the name and the size field as...
 dec a     ;...indicated by this number.
 jr nz,$-3 ;And loop until the entire things is written out into the buffer
 ret
GetNextEntry:
 ld de,-6            ;go ahead and skip past current entry...
 add hl,de           ;
 ld a,(hl)           ;get those size bytes.
 cpl                 ;and as we did before
 ld e,a              ;add them together with the CPL's autodecrement
 add hl,de           ;and we're at the start of entry #2.
 ret

.end

The following bit of source comes right out of Celtic III. It searches the VAT for some given variable in Op1. It's supposed to be a replica of the ChkFindSym romcall, but I wrote it because I wanted something faster than a romcall. I believe this code searches both the Symbol Table and the Program/List VAT structures.
Code: [Select]
SearchVAT:
 ld hl,(Op1)
 ld h,$00
 ld de,SearchVTbl
 add hl,de
 ld a,(hl)
 or a
 jr nz,SearchVP
SearchVS:
 ld hl,(progptr)
 ld de,-6
 add hl,de
 ex de,hl
 ld hl,symtable-6
 ld bc,-9
SearchVSL:
 push hl
  ld a,(Op1+1)
  cp (hl)
  dec hl
  jp nz,SearchVSN
  ld a,(Op1+2)
  cp (hl)
  dec hl
  jp nz,SearchVSN
  ld a,(Op1+3)
  cp (hl)
  dec hl
  jp nz,SearchVSN
  ld bc,4
  add hl,bc
  ld b,(hl)
  inc hl
  ld d,(hl)
  inc hl
  ld e,(hl)
  jr SearchVSE
SearchVSN:
 pop hl
 add hl,bc
 or a
 sbc hl,de
 add hl,de
 jp nz,SearchVSL
 scf
 ret
SearchVSE:
 pop hl
 ld a,(Op1)
 or a
 ret
SearchVP:
 ld hl,Op1+1
 xor a
 ld c,a
 cp (hl)
 jr z,$+8
 inc hl
 inc c
 bit 3,c
 jr z,$-7
 ld hl,(progptr)
 ld de,-6
SearchVPL:
 ld a,(Op1)
 cp (hl)
 jr nz,SearchVPS
 push hl
  ld de,Op1+1
  ld b,c
  ld a,(de)
  cp (hl)
  jr nz,SearchVPSP
  inc de
  inc hl
  djnz $-6
 pop hl
 push hl
  dec hl
  dec hl
  dec hl
  ld e,(hl)
  dec hl
  ld d,(hl)
  dec hl
  ld b,(hl)
 pop hl
 or a
 ret
SearchVPSP:
  ld de,-6
 pop hl
SearchVPS:
 add hl,de
 push de
  ld a,(hl)
  neg
  ld e,a
  add hl,de
  ld de,(ptemp)
  or a
  sbc hl,de
  add hl,de
 pop de
 jr nz,SearchVPL
 scf
 ret

SearchVTbl:
.db 0  ;00 real
.db 1  ;01 list
.db 0  ;02 matrix
.db 0  ;03 equation
.db 0  ;04 string
.db 1  ;05 program
.db 1  ;06 protected program
.db 0  ;07 picture
.db 0  ;08 graph database
.db 0  ;09 unused
.db 0  ;0A unused
.db 0  ;0B new equation
.db 0  ;0C complex
.db 1  ;0D complex list
.db 0  ;0E unused
.db 0  ;0F unused
.db 0  ;10 unused
.db 0  ;11 unused
.db 0  ;12 unused
.db 0  ;13 unused
.db 0  ;14 application. Passthrough.
.db 1  ;15 appvar
.db 1  ;16 temporary program
.db 1  ;17 group
« Last Edit: January 05, 2011, 08:16:12 pm by Iambian »
A Cherry-Flavored Iambian draws near... what do you do? ...

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Documentation dump
« Reply #1 on: January 05, 2011, 08:30:55 pm »
I'll move this to the ASM section in case someone might find this useful.

Offline Iambian

  • Coder Of Tomorrow
  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 739
  • Rating: +216/-3
  • Cherry Flavoured Nommer of Fishies
    • View Profile
Re: Documentation dump
« Reply #2 on: January 05, 2011, 08:39:16 pm »
Double-post (I think). This now involves understanding how a romcall works. I've attached a romcall routine replacement used in E:SoR. It relocates itself to RAM, which is why there are masses of strange labels. It also uses SMC to ease a few ... things.
Code: [Select]
XPC equ XPCBASE+($-XPCS)  ;This is the one that needs to be called.
;Will be relocated to $9D95 eventually. Need to initialize XPCZ with base page.
;Just "in a,(6) \ ld (XPCZ),a" after copying this routine to RAM.
;After restoring registers,
;ret takes you to address of new page.(3)
;The ret after that takes you to the XPM routine (2)
;The pop restores your page number (1)
;The last RET takes you back to the routine (base)
 push hl  ;Slot1        ;1 1
 push hl  ;Slot2        ;1 2
 push hl  ;Slot3        ;1 3
 push hl                ;1 4
  push de               ;1 5
   push af              ;1 6
    ld hl,12            ;3 9
    add hl,sp           ;1 10
    ld sp,hl            ;1 11
    pop hl              ;1 12
    ld e,(hl)           ;1 13
    inc hl              ;1 14
    ld d,(hl)           ;1 15
    inc hl              ;1 16
    ld a,(hl)           ;1 17
    inc hl              ;1 18
    push hl   ;base     ;1 19
XPCB equ XPCBASE+($-XPCS)
    ld L,a              ;1 20
    in a,(6)            ;2 22
    push af   ;1        ;1 23
XPCZ equ XPCBASE+($-XPCS)+1
    ld a,00             ;2 25
    sub L               ;1 26
    out (6),a ;got page ;2 28
    ld hl,XPCM          ;3 31
    push hl   ;2        ;1 32
    push de   ;3        ;1 33
    ld hl,-6            ;3 36
    add hl,sp           ;1 37
    ld sp,hl            ;1 38
   pop af               ;1 39
  pop de                ;1 40
 pop hl                 ;1 41
 ret          ;jp 3     ;1 42
XPCM equ XPCBASE+($-XPCS)
 push af ;2 above base  ;1 43
  inc sp \ inc sp  ;1   ;2 45
  pop af           ;0   ;1 46
  out (6),a             ;2 48
  push af          ;1   ;1 49
  dec sp \ dec sp  ;2   ;2 51
 pop af            ;1   ;1 52
 inc sp \ inc sp   ;0   ;2 54
 ret                    ;1 55 bytes this routine takes up.
XPCE:                   ;9D95 has 107 bytes prior to next high byte.
A Cherry-Flavored Iambian draws near... what do you do? ...