-->
0 Members and 1 Guest are viewing this topic.
On the TI-83 Plus graphing calculator, there are three different tables used toallocate memory to programs, or to determine the presence of each program orvariable to the calculator. For the reason the table exists, it's often timescalled the "VAT", or "Variable Allocation Table". Usually, this name is given tothe second part of the entire table, or to be most specific, the first part of thetable, with a fixed beginning, is called the "Symbol VAT" and the next part iscalled 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 TemporaryVariable section, which is pointed to by (pTemp). (pgmPtr) points to the ProgramVAT.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 lengthT= first five bits are datatype, b5= graph equ selected b6= variable used during graphing b7= link transfer flagT2=for future use [TI-OS keeps it at ZERO]Ver= version code to not recieve if higher than current OS codeDadrL = data address, LSBDadrH = data address, MSBPage = if archived, holds flash page. Otherwise, = 0N.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 isset to zero if there is no formula attached. If there is, then a number will be given to pointto 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 nameTok2 = second token of nameA symbol table entry for a formula would be where:Tok1 = $3FTok2 = F, where "F" would be the corresponding function # found with the list.
#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 4507hpTemp EQU 982EhprogPtr EQU 9830htempSwapArea EQU 82A5hcurptr equ tempswaparea ;2 bytes, current location in the VATswaptemp equ curptr+32 ;up to 30 bytes for temporary swapping. BackwardsProgramStart: 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 bcProgramLoop2: 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 entryProgramSkip6: 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 retGetNextEntry: 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
SearchVAT: ld hl,(Op1) ld h,$00 ld de,SearchVTbl add hl,de ld a,(hl) or a jr nz,SearchVPSearchVS: ld hl,(progptr) ld de,-6 add hl,de ex de,hl ld hl,symtable-6 ld bc,-9SearchVSL: 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 SearchVSESearchVSN: pop hl add hl,bc or a sbc hl,de add hl,de jp nz,SearchVSL scf retSearchVSE: pop hl ld a,(Op1) or a retSearchVP: 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,-6SearchVPL: 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 retSearchVPSP: ld de,-6 pop hlSearchVPS: 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 retSearchVTbl:.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
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 19XPCB equ XPCBASE+($-XPCS) ld L,a ;1 20 in a,(6) ;2 22 push af ;1 ;1 23XPCZ 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 42XPCM 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.