FP stuff

A General Discussion forum for TI calculators

Moderator: MaxCoderz Staff

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

FP stuff

Post by King Harold »

I wrote a little routine that devides OP1 (or OP2, actually anything) by 2.
And it even works* (didn't expect that huh?), I'm sure it can be optimized though (and please give some clues as to where it can be optimised)
*: well in most cases anyway

Code: Select all

DivOp1by2:
	ld hl,op1+2
	ld b,8	;number of bytes in the FP number to devide
	ld c,0
	ld (iy+asm_flag1),c
-:	xor a		;clear C for rra (could have used shift but there is no speed gain)
	ld a,(hl)	;load 2 numbers
	rra		;"devide" them by 2 (can leave garbage in bit 3 if the high nibble is odd)
	rr (iy+asm_flag1)	;store CA
	add a,c	;add c, because I use c to store the correction
	ld c,0		;reset c
	rl (iy+asm_flag1)	;retrieve CA (which means that the low nibble was odd and we have to add $50 to the next byte
	jr nc,{+}	;do not set c to $50 if not CA
	ld c,$50	;do so if CA
+:	ld d,a		;save a
	and %01110111	;kill the garbage bits (bit 7 doesn't really have to be 0, but why not make it 0 anyway?)
	cp d		;compare - gives nz if bit 3 was set
	jr z,{+}	;do not add 5 if it was set
	add a,5	;do so if it wasn't
+:	ld (hl),a	;write the result back
	inc hl		;move to next byte
	djnz {-}	;repeat untill you hit the end of the number
	ret
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Fixed the leading zero bug:

Code: Select all

DivOp1by2:
	ld hl,op1+2	;[10]
	ld b,8		;[7]mantissa + guard
	ld c,0		;[7]
	ld (iy+asm_flag1),c	;[19]
-:	xor a		;[4]clear C for rra (could have used shift but there is no speed gain)
	ld a,(hl)	;[7]load 2 numbers
	rra		;[4]"devide" them by 2 (can leave garbage in bit 3 if the high nibble is odd)
	rr (iy+asm_flag1)	;[23]store CA
	add a,c	;[4]add c, because I use c to store the correction
	ld c,0		;[7]reset c
	rl (iy+asm_flag1)	;[23]retrieve CA (which means that the low nibble was odd and we have to add $50 to the next byte
	jr nc,{+}	;[7/12]do not set c to $50 if not CA
	ld c,$50	;[7]do so if CA
+:	ld d,a		;[4]save a
	and %01110111	;[4]kill the garbage bits (bit 7 doesn't really have to be 0, but why not?)
	cp d		;[4]compare - gives nz if bit 3 was set
	jr z,{+}	;[7/12]do not add 5 if it was set
	add a,5	;[4]do so if it wasn't
+:	ld (hl),a	;[7]write the result back
	inc hl		;[4]move to next byte
	djnz {-}	;[8/13]repeat untill you hit the end of the number
	ld hl,op1+2	;[10]move back to beginning of mantissa
	ld a,(hl)	;[7]load in a
	and $F0	;[4]only look at high nibble
	ret nz		;[5/11]return if it is not zero
	ld hl,op1+10	;[10]otherwise go to end of op1
	ld b,9		;[7]b needs to be 9
	xor a		;[4]clear a
-:	rld		;[18]effectively shifts (hl) left 1 nibble
	dec hl		;[4]move to next number
	djnz {-}	;[8/13]again if b != 0
	dec (hl)	;[7]ajusts the exponent
	ret		;[10]return
Last edited by King Harold on Sat 18 Nov, 2006 5:46 pm, edited 1 time in total.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

new: multiply op1 by 2.
Seems to work in all cases, yes all, unlike the deviding routine which has some sort of bug in it.

Code: Select all

Op1Times2:	;input: op1 = number. output: op1*2. destroys: af,b(not c),hl
	ld hl,op1+10
	ld b,9
	or a	;clear flags
-:	ld a,(hl)
	adc a,a
	daa
	ld (hl),a
	dec hl
	djnz {-}
	ret nc
	ld hl,op1+1
	inc (hl)
	inc hl
	ld a,1
	ld b,9
-:	rrd
	inc hl
	djnz {-}
	ret
Other code a little optimised (OMG why WHY was I using iy+asm_flag1???)

Code: Select all

DivOp1by2:	;inputs: op1 is number. destroys: af,bc,de,hl. returns: op1*2
	ld hl,op1+2	;[10]
div:	ld b,8		;[7]mantissa + guard
	ld c,0		;[7]
	ld e,c		;[4]
-:	xor a		;[4]clear C for rra (could have used shift but there is no speed gain)
	ld a,(hl)	;[7]load 2 numbers
	rra		;[4]"devide" them by 2 (can leave garbage in bit 3 if the high nibble is odd)
	rr e		;[8]store CA
	add a,c	;[4]add c, because I use c to store the correction
	ld c,0		;[7]reset c
	rl e		;[8]retrieve CA (which means that the low nibble was odd and we have to add $50 to the next byte
	jr nc,{+}	;[7/12]do not set c to $50 if not CA
	ld c,$50	;[7]do so if CA
+:	ld d,a		;[4]save a
	and %01110111	;[4]kill the garbage bits (bit 7 doesn't really have to be 0, but why not?)
	cp d		;[4]compare - gives nz if bit 3 was set
	jr z,{+}	;[7/12]do not add 5 if it was set
	add a,5	;[4]do so if it wasn't
+:	ld (hl),a	;[7]write the result back
	inc hl		;[4]move to next byte
	djnz {-}	;[8/13]repeat untill you hit the end of the number
	ld hl,op1+2	;[10]move back to beginning of mantissa
	ld a,(hl)	;[7]load in a
	and $F0	;[4]only look at high nibble
	ret nz		;[5/11]return if it is not zero
	ld hl,op1+10	;[10]otherwise go to end of op1
	ld b,9		;[7]b needs to be 9
	xor a		;[4]clear a
-:	rld		;[18]effectively shifts (hl) left 1 nibble
	dec hl		;[4]move to next number
	djnz {-}	;[8/13]again if b != 0
	dec (hl)	;[7]ajusts the exponent
	ret		;[10]return
If I were you I wouldn't use it though..
Post Reply