[TI-84 ASM] Reading From Regular Variables?

Got questions? Got answers? Go here for both.

Moderator: MaxCoderz Staff

Post Reply
User avatar
waeV
New Member
Posts: 74
Joined: Wed 23 Apr, 2008 12:52 am
Location: Maine

[TI-84 ASM] Reading From Regular Variables?

Post by waeV »

Hi everyone, I have been following the "Learn TI-83 Plus Assembly in 28 Days" and want to make a program that checks if matrix J has been changed when it starts to run. I have been trying to understand the way that explains "User variables", but it doesn't give any examples.

As I understand it now, this is how I would access matrix J (Which i know to be wrong :P )

Code: Select all

ld hl, MatObj tVarMat tMatJ $00
Can anyone help me out?


Edit: Okay, I found how to read a matrix (tell me of the code below is incorrect please)

Code: Select all

	ld hl, (matrixJ)
matrixJ:	.db MatObj, tVarMat, tMatJ, 0

What I need to figure out now is how to either be able to load one value of a matrix at a time ("[J](2,5)" in TiBASIC) or have a whole matrix stored in a .dw. Anyone know the format for either?
^
^
^
^
^
^
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Well first off, you can't load more than 2 bytes into HL.
So even in the second attempt, you will end up with HL holding MotObj and tVarMat, which is not what you want.
What you want, is a pointer to the matrix itself, so you'll have to do a system call to look it up.

A matrix is a regular variable which can be found with _FindSym (rst rFindSym) - for FindSym, the name has to be in OP1, so the code is:

Code: Select all

ld de,OP1
ld hl,matrixJ
ldi ;(or load BC with 4 and ldir)
ldi
ldi
ldi
rst rFindSym
;de points to matrix data, carry set if not found
You can now use that pointer to do anything you like, but keep in mind that it will be made out of TIFloat's, recommended system routines are:
AdrMEle (gets pointer to element)
AdrMRow (pointer to row)
GetMtoOP1 (loads an element into OP1)
PutToMat (loads OP1 into an element of matrix)
all these routines need the pointer to the start of the data in DE, as output by rFindSym, and most use BC (or B) for the row/col of the element.
User avatar
waeV
New Member
Posts: 74
Joined: Wed 23 Apr, 2008 12:52 am
Location: Maine

Post by waeV »

Ok, so trying to understand the meaning behind all this code;

Code: Select all

ld de,OP1
How does this "put the name in OP1"? To me it looks like this is loading the value of OP1 into de.

Code: Select all

ld hl,matrixJ
Ok, so this loads hl with the location of the matrix.

Code: Select all

ldi ;(or load BC with 4 and ldir)
ldi
ldi
ldi
What does ldi do, and why does it need to be done four times?

Code: Select all

rst rFindSym
;de points to matrix data, carry set if not found 
is "rst rFindSym" at all like "b_call(_FindSym)"?


Edit: I reread what you wrote, and would I be right in saying that this prepares for a b_call(_FindSym) by loading the location of the matrix into de? Or does this load the equivalent of the matrix into de? (Such that de doesn't hold the matrix per se, but all operations affecting de affect the matrix)
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

ld de,OP1 does not "put the name in OP1", it loads the address of OP1 into de

this entire block of code, in its entirety, is used to first load the name into op1 like this:

Code: Select all

ld de,OP1  ;destination
ld hl,matrixj  ;source
ldi
ldi
ldi
ldi  ;load 4 bytes from source to dest
that code does:

Code: Select all

memcpy(OP1, matrixj, 4);
with the loop unrolled.
Note that OP1 and matrixj are both constant-pointers (OP1 is defined in ti83plus.inc, matrixj is the label of that name), and should be treated as such. (alternative they can be used as 16bit numbers, but that usually isn't relevant)
4 bytes are copied from the location matrixj to the location OP1
so OP1 holds .db MatObj, tVarMat, tMatJ, 0, unchanged, unchanged, unchanged, etc

rst rFindSym is the faster/smaller equivalent of the bcall of the same name yes. Try to use the the rst form whenever possible, not because I said so but because it's smaller (only 1 byte, whereas bcall is 3 bytes) and faster. (rst is never conditional though and there may be other reasons to use the bcall in some cases)

Not knowing what LDI does is a bit odd though, no offence, but maybe you should read a tutorial

in regard to the edit: the code indeed first prepares for the symbol lookup (FindSym) - a pointer to the matrix will then be in DE, any direct operations on DE will only affect DE (ok and PC too since all instructions do something with PC) ever since DE is just a normal register, but when used indirectly it may affect the matrix. ld (de),a for example will overwrite the first byte of the matrix with a value of register A. The system-routines for matrices expect DE to be a pointer to a matrix, but will mostly still work if it's not (at your peril).

The matrix itself looks like:
.db columns, rows
;row times:
;column times:
.tifloat value
see 83psysroutines.pdf for system-routines that work with floats..
User avatar
waeV
New Member
Posts: 74
Joined: Wed 23 Apr, 2008 12:52 am
Location: Maine

Post by waeV »

Okay, that makes sense, thanks a ton.

In regard to the tutorial, I hadn't read day 16 yet. I've been sort of skimping on "vocabulary" if you will and focusing on technique, looking up a command when I need to use it. The 28 days' tutorial on user variables just threw me for a loop.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

It's day 19 actually but ok, I'm glad you understand now
User avatar
waeV
New Member
Posts: 74
Joined: Wed 23 Apr, 2008 12:52 am
Location: Maine

Post by waeV »

I mean I skipped day 16 on ldi, cpi etc. to get to user variables, which I didn't understand.
User avatar
benryves
Maxcoderz Staff
Posts: 3087
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

The Z80 Family CPU User Manual is a pretty useful instruction reference.
Post Reply