_FindSym

z80 » Variables

Once you have the name loaded into OP1 you can call _FindSym to get the TI86 to return all the information and locations of the variable whose name is in OP1. Before calling _FindSym, you need to have OP1 containing the variable name you want to find (case is sensitive) in Variable Name Format. Once called, it will return: carry flag set if variable by that name doesn't exist, carry flag reset if variable exists, a is variable type, OP1 will still contain the variable in Variable Name Format, bde will be an Absolute Address Pointer to variable data, and hl will point to the address of the VAT entry of the variable.

_FindSym=$46cb

Description Finds the variable with the name stored in OP1.
Input OP1 - case sensitive variable name in Variable Name Format. Note: You can leave out the variable type byte, _FindSym ignores it and just finds a variable with the same name.
Destroys a, bc, de, and hl
Output Carry reset - variable exists
Carry set - variable doesn't exist
a - variable type
OP1 - case sensitive variable name in Variable Name Format
bde - absolute address pointer to variable data
hl - address of the symbol table entry

Check out _FindSym in context...

find_variable:
	ld hl,variable	;our variable's type and length
			; indexed name
	ld de,OP1	;where we want it to go
	ld bc,11	;OP_'s are 11 bytes long
	ldir		;(hl)->(de),dec bc,repeat till bc=0
	jp _FindSym	;go find it and return
variable:  .db $0c,$06,"Stupid"
			;we don't need any more text
			; after "Stupid" because the TI86
			; will just ignore it anyway so we
			; just copy whatever is after the
			; string along with the type and
			; length indexed string

There is a call that will copy 10 bytes starting at hl into OP1: _Mov10toOP1. This is even shortened more by just putting rst 20h instead of call _Mov10toOP1. So the above code would be 22 bytes (I'm counting opcodes) whereas the below code, doing exactly the same thing, would only be 13 bytes.

find_variable:
	ld hl,variable	;our variable's type and length
			; indexed name
	rst 20h		;same as 'call _Mov10toOP1'
	rst 10h		;same as 'call _FindSym'
	ret		;done so return
variable:  .db $0c,$06,"Stupid"

Remember that _FindSym ignores the type byte that the first byte of OP1 is holding. We can put some trash in there...anything you want. This can be to our advantage because we can have our routine copy the byte before our 'variable' storage area as the type; but we need to account for that when we're loading hl with the address of the name to be sure that it's copying starting one byte ahead of this label. This is really confusing so try to think through our new optimized routine.

find_variable:
	ld hl,variable-1
			;address of one byte before
			; 'variable' label
	rst 20h		;same as 'call _Mov10toOP1'
	rst 10h		;same as 'call _FindSym'
	ret
variable:  .db $06,"Stupid"
			;just need the length and string
			; now because we're using the byte
			; infront of this as our type

Our final draft of this routine is only 12 bytes long compared to the original that took up 22 bytes. Give me a second to do that higher math...1...4...2...we saved 10 bytes! That may not mean much to you now but in a game, every byte counts...you'll appreciate it later, maybe. (Those byte counts include the variable name which is 8 bytes in the first two examples and 7 bytes in the last example.)


More from z80 » Variables
Absolute Addressing // Binary Coded Decimal // Creating Variables // External Levels // _FindSym // Messing with Variable Data // OP Math // TI-OS Variable Manipulation // Variable Name Format // VAT Searches