[TI ASM] storing data

Got questions? Got answers? Go here for both.

Moderator: MaxCoderz Staff

King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

how about checking where the point/comma is in OP1?
then you can tell a loop to loop 2 times the numer of bytes before the point -1 (not the first one, but not -2 because you do want the one directly before the comma)
chickendude
Extreme Poster
Posts: 340
Joined: Fri 07 Jul, 2006 2:39 pm

Post by chickendude »

What do you mean about the point/comma? The decimal place? That's what it should be doing; the first byte says whether the number is positive or negative and the second byte holds the length of the whole number (10^xth power).

If OP1 holds: 16843600000000
and the second byte is $80, then the floating point number equals 1.68436 x 10^0

If the second byte holds $85, then the FPN equals 1.68436 x 10^5, or 168436.0

Therefore, if the user entered the number 345 OP1 should hold:
.db 00,$82,$34,$50,the rest zeros.

If we read in OP1+1 into a, a should equal $82. We then subtract $7F (because $80 means that there is one integer digit, and the rest of the digits belong after the decimal point) to set a equal to three. If we load a into b, we can use b to pull out the three digits from the OP register and stop. That's what the snippet of code that I gave you is SUPPOSED to do... hah.

Did that make any sense? I'm not terribly good at explaining things.

EDIT: By we can use b to pull out the three digits, I mean that we can use that as a counter variable where we subtract one from it (until it equals zero) each time a number is extracted from the register and stored into the var_name variable.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

oh i see.. the code you gave me didnt make much sense to me, but since it can do that, it can do it right.
since i now know how it works i think i can figure out a way
chickendude
Extreme Poster
Posts: 340
Joined: Fri 07 Jul, 2006 2:39 pm

Post by chickendude »

Oh, I'm sorry! Let me explain it real quick:

Code: Select all

 ld ix,OP1+2 	;this is the start of the integer series
 ld hl,var_name+4
 ld a,(OP1+1) 	;this grabs the length of the integer series (+$7F)
 sub a,$7F 	;stores the length to a
 ld b,a 		;store a into b to use as a counter variable
loop: 
 ld a,(ix) 		;grab the first byte
 and $F0 		;$F0 = %11110000.  This loads the first integer into a.
		;say the first two digits you entered were 3 and 8.
		;OP1+2 would hold the hex value: $38, or %0011 1000.
		;%0011 = 3, so if we and %11110000, then the value in a will
		;hold %00110000.  We now need to slide a over four bits.
 srl a 		;a=%00011000
 srl a 		;a=%00001100
 srl a 		;a=%00000110
 srl a 		;a=%00000011, or 3
 add a,$30 	;get the ascii code and load it into the variable, var_name
 ld (hl),a 
 inc hl 		;go to the next byte in the variable
 dec b 		;we've worked one digit, so subtract one from b
 jr z,exit 		;if b=0, we've worked all the digits and exit
 ld a,(ix) 		;load the first byte into a again (%00111000)
 and $0F 		;and %00001111 to a.  a should now hold %00001000, or 8
 add a,$30 	;get the ascii value...
 ld (hl),a 		;and load into (hl)
 inc ix 		;get the next byte in the OP register
 inc hl 		;go to the next byte in the var_name variable
 djnz,loop 	;subtract one from b.  if b doesn't equal zero, repeat the process
exit:
[/code]
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

oh i see, but then im going to say (again) that starting just left of the decimal in OP1 and then working towards the end (so dex ix and dec hl, instead of inc, and with a funny start of ix) would place the zero's at the place they should be, wouldnt it?

now the highest value comes first, but the lowest value should come last, if the value is not 5 digits long this is not the same thing..
chickendude
Extreme Poster
Posts: 340
Joined: Fri 07 Jul, 2006 2:39 pm

Post by chickendude »

What that routine is SUPPOSED to do (but apparently doesn't :oops:!) is like this:
OP = 254
the length is 3 (3 digits), so we load that into b

1st iteration:
We extract the number 2, convert it to ascii value, and load it into hl.
var_name now holds: "Var2_ _ _ _",0
decrement b by 1.
b now holds 2
b does not equal zero, so continue onto the rest of the loop

2nd:
We extract the number 5, convert it to ascii value, and load it into hl.
var_name now holds: "Var25_ _ _",0
decrement b by 1
b=1
b does not equal zero, so repeat

3rd:
We extract the number 2, convert it to ascii value, and load it into hl.
var_name now holds: "Var254_ _",0, or Var254 with two spaces at the end and a null terminator.
decrement b by 1
b=0, so jump out of the loop.


It won't store extra zeros at the end, it'll stop after you've worked the three integers and quit, leaving what before were zeros as spaces. If you wanted, we could even put the null terminator right after it, but it wouldn't make too much of a difference.

As such, inputting the numbers 3, 30, and 300 would each result in a different appvar being created:
Var3_ _ _ _, Var30_ _ _, and Var300_ _ respectively.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

oh right, well if that what it's supposed to do i guess its ok, it didnt do that on TI's FlashSim (although thats really is a piece of crap..)

i thought about doing it like this:

OP = 324
get the last number ( 4 )
and put it in the last place
"var_ _ _ _ 4"

then get the second last number and place it in the second last place:
"var_ _ _ 2 4"
and then get the first number and place it in the 3rd last place
"var_ _ 3 2 4"
but your method should also work, i'll try it oncalc (hope it doesnt blow up)
chickendude
Extreme Poster
Posts: 340
Joined: Fri 07 Jul, 2006 2:39 pm

Post by chickendude »

Me too, let me know what it outputs. The code isn't all too different from the other one (that worked) so it shouldn't mess up/freeze your calculator (besides, it's only changing data within the variable var_name so there's little room for anything to go wrong.)

If it does combust, I deeply apologize.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

err it says
c:\asm\source\appvar.z80 line 0127: Label not found: (a)
c:\asm\source\appvar.z80 line 0127: Unknown token: (,)
c:\asm\source\appvar.z80 line 0127: Unknown token.
again..
edit: also a typo: djnz,loop instead of djnz loop (doesnt really matter though)
chickendude
Extreme Poster
Posts: 340
Joined: Fri 07 Jul, 2006 2:39 pm

Post by chickendude »

DOH! I copied/pasted that other code with the sub a,$7f. Change it to sub $7F. Ha, sorry about that...again.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

oh yea i should have remembered that..
ok this code is fine, thanx for helping me :)
(you probebly want to have credit for the name part if/when i release it?
unless you absolutely dont want to be named...)
chickendude
Extreme Poster
Posts: 340
Joined: Fri 07 Jul, 2006 2:39 pm

Post by chickendude »

I don't care really. You can use it freely, credit or not. It's more of a learning tool anyway; I won't be offended or upset if my name is left off :)
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

wouldnt be a problem to give you credit though
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

i have a very funny problem now, whenever i write to the appvar, the size changes, A LOT, with a bigger offset the problem seems bigger, this is very strange.. reading does not seem to change the size

Code: Select all

.nolist
#include "ti83plus.inc"
#define    ProgStart    $9D95
.list
.org    ProgStart - 2
    .db    t2ByteTok, tAsmCmp
	bcall(_ClrLCDFull)
	bcall(_RclAns)		;ans gets lost somewhere..
	ld hl, 3		;3rd list element (offset/size)
	bcall(_GetLtoOp1)	;put it in op1
	bcall(_ConvOp1)		;store the hex value in de
	push de			;push de because it gets destructed
	bcall(_RclAns)
	ld hl,2
	bcall(_GetLtoOp1)
	call name_loop
        bcall(_RclAns)		; recall Ans
        ld hl,1			; 1st element in Real List
        bcall(_GetLtoOp1)	; get element
        bcall(_ConvOp1)		; returns a as LSByte (and de as the total 16bit value)
	or a			
	JP Z,create_var	
	dec a			;  jumps:	
	JP Z,del_var		; 
	dec a			;0->create_var
	JP Z,put_int		;1->del_var
	dec a			;2->put_int
	JP Z,read_int		;3->read_int
	dec a			;4->put_char
	JP Z,put_char		;5->read_char
	dec a			;6->shrink_var	(starts at [offset],deletes [value] bytes)
	JP Z,read_char		;7->grow_var	(starts at [offset],inserts [value] bytes)
	dec a			;
	JP Z,shrink_var		;
	dec a			;
	JP Z,grow_var		;{function,name,[offset/size],[value]
	ret	

create_var:	;-------------------------------------------------------------------------
	bcall(_NewLine)
	ld hl,0
	ld (PenCol),hl
	ld hl,msg_create
	bcall(_PutS)
	ld hl, var_name		;load the name
	bcall(_Mov9toop1)	;moves the name to OP1
	bcall(_ChkFindSym)	;see if it needs to be deleted
	JP NC,err_code_1	;jump if exists
	pop hl			;pop size (was de) in hl, name is still in OP1
	bcall(_CreateAppVar)	;duhh..
	ret
del_var:	;--------------------------------------------------------------------------
	bcall(_NewLine)
	ld hl,0
	ld (PenCol),hl
	ld hl,msg_del
	bcall(_PutS)
	ld hl, var_name		;load the name
	bcall(_Mov9ToOP1)	;name in op1
	bcall(_ChkFindSym)	;check if it exists, cant delete non-existant things
	JP C, err_code_1	;if not found, dont delete
	bcall(_DelVar)		;else delete
	xor a			;0 in a
	bcall(_SetxxOP1)	;0 in op1
	bcall(_StoX)		;op1 in x (tell user that the appvar has (probebly) been deleted
	ret
put_int:	;--------------------------------------------------------------------------
	bcall(_NewLine)
	ld hl,0
	ld (PenCol),hl
	ld hl,msg_writeint
	bcall(_PutS)
	bcall(_RclAns)
	ld hl, 4		;recall the 4th element  (value)
	bcall(_GetLtoOp1)
	bcall(_ConvOp1)		;put the LSB in a
	ld hl, var_int		;we're going to store a in var_int so first load the pointer
	ld (hl),a		;save a to var_int
	ld hl, var_name		;load the name
	bcall(_Mov9toop1)	;moves the name to OP1
	bcall(_ChkFindSym)	;see if it exists (cant write to no-place can you?)
	push de
	JP C, err_code_1	;jump if it doesnt exist
	ld a, b			;load rom page in a
	or a			;compare a = 0
	b_callnz(_Arc_Unarc)	;if a is not 0 unarc, else do nothing
	pop de
	pop hl			;data offset in hl
	add hl, de		;de is pointer to begin of appvar, de is offset
	ex de, hl		;put it in de for ldi 
	ld hl, var_int		;load pointer to var_int to hl for ldi
	ldi			;actual saving
	ret			
read_int:	;----------------------------------------------------------------------------
	bcall(_NewLine)
	ld hl,0
	ld (PenCol),hl
	ld hl,msg_readint
	bcall(_PutS)
	ld hl, var_name		;load the name
	bcall(_Mov9toop1)	;moves the name to OP1
	bcall(_ChkFindSym)	;see if it needs to be deleted
	push de
	JR C, err_code_1	;jump if it doesnt exist
	ld a, b			;load rom page in a
	or a			;compare a = 0
	b_callnz(_Arc_Unarc)	;rom page =! 0 so change Archived state
	pop de
	pop hl			;pop offset from stack
	add hl, de		;add begin to offset
	ld de, var_int		;load pointer to var_int
	ldi			;move the data
	dec de			;ldi inc's de so we dec it
	ld a,(de)		;de points to var_int again
	bcall(_SetxxOp1)	;put a in op1
	bcall(_StoAns)		;store the byte in ans
	ret
put_char:	;-----------------------------------------------------------------------------
	ret
read_char:	;-----------------------------------------------------------------------------
	ret
shrink_var:	;-----------------------------------------------------------------------------
	ret
grow_var:	;-----------------------------------------------------------------------------
	ret


name_loop:	;----------nameloop by Chickendude, thanx for your help mate :)---------------
	ld ix,OP1+2	;this is the start of the integer series
	ld hl,var_name+4
	ld a,(OP1+1)    ;this grabs the length of the integer series (+$7F)
	sub $7F		;stores the length to a
	ld b,a		;store a into b to use as a counter variable
loop:
	ld a,(ix)       ;grab the first byte
	and $F0       	;$F0 = %11110000.  This loads the first integer into a.
			;say the first two digits you entered were 3 and 8.
			;OP1+2 would hold the hex value: $38, or %0011 1000.
			;%0011 = 3, so if we and %11110000, then the value in a will
			;hold %00110000.  We now need to slide a over four bits.
	srl a		;a=%00011000
	srl a		;a=%00001100
	srl a		;a=%00000110
	srl a		;a=%00000011, or 3
	add a,$30	;get the ascii code and load it into the variable, var_name
	ld (hl),a
	inc hl		;go to the next byte in the variable
	dec b		;we've worked one digit, so subtract one from b
	jr z,exit       ;if b=0, we've worked all the digits and exit
	ld a,(ix)       ;load the first byte into a again (%00111000)
	and $0F		;and %00001111 to a.  a should now hold %00001000, or 8
	add a,$30	;get the ascii value...
	ld (hl),a       ;and load into (hl)
	inc ix		;get the next byte in the OP register
	inc hl		;go to the next byte in the var_name variable
	djnz loop	;subtract one from b.  if b doesn't equal zero, repeat the process
exit:
	ret
err_code_1:	;-------------------------------------------------------------------------------
	ld a, 1			;1 to a
	bcall(_SetxxOp1)	;a to op1
	bcall(_StoX)		;op1 to x (1 to x)
	ret
var_name:	;-------------------------------------------------------------------------------
	.db AppVarObj, "Var", $20, $20, $20, $20, $20, 0
var_int:
	.db $00
msg_create:
	.db "Create var",0
msg_del:
	.db "DelVar",0
msg_writeint:
	.db "WriteInt",0
msg_readint:
	.db "ReadInt",0
.end
END
the msg's are there the check if it jumped to the right label (cant debug properly atm, and this sortof works) turns out that it does, actually, jump to "put_int" and change the size of the AppVar
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

I found out a little more, read_int as it is returns the size, which means i could somehow be "writing to the size" with put_int, this should not happen though.. i thought i had done it the right way
edit: fixed, but how do you store to a string? say Str0 or Ans being a string
Post Reply