Math Routines for the 65Org16

Topics relating to PALs, CPLDs, FPGAs, and other PLDs used for the support or creation of 65-family processors, both hardware and HDL.
Post Reply
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Math Routines for the 65Org16

Post by ElEctric_EyE »

I successfully converted one of Lee Davidson's contributions. I'll add more as time goes on.
It uses 3 zeropage variables: Number is the input $0000-$00FF only. Sqr is the output. Tempsq is temp storage.
This is the Square Routine:

Code: Select all

; How to calculate the 16-bit unsigned integer square of a signed 16-bit integer.
; By Lee Davison (leeedavison@googlemail.com), 19 October 2000.
; Modified for the 65Org16 By Sam Gaskill, 13 March 2013.
; Calculates the 16 bit unsigned integer square of the signed 16 bit integer in
; Number.  The result is always in the range 0 to 65025 and is held in
; Sqr
;
; The maximum input range is only +/-255 and no checking is done to ensure that
; this is so.
;
; This routine is useful if you are trying to draw circles as for any circle
;
; x^2+y^2=r^2 where x and y are the co-ordinates of any point on the circle and
; r is the circle radius
;
; Destroys all registers


Square      LDA #$00            ; clear A
            STA Sqr             ; clear square 
            LDA	Number     
NoNneg      STA	Tempsq          ; save ABS(number)
	          LDX	#$10            ; set bit count

Nextr2bit	  ASL	Sqr             ; low byte *2
	          ASL	A               ; shift number byte
	          BCC	NoSqadd         ; don't do add if C = 0
	          TAY                 ; save A
	          CLC                 ; clear carry for add
	          LDA	Tempsq          ; get number
	          ADC	Sqr             ; add number^2
	          STA	Sqr             ; save number^2
	          TYA                 ; get A back

NoSqadd     DEX                 ; decrement bit count
	          BNE	Nextr2bit       ; go do next bit
            RTS
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Math Routines for the 65Org16

Post by ElEctric_EyE »

Needs some refinements which I'll make soon, but I didn't want to break it. So this appears to be working for Square Root:

Code: Select all

; How to calculate the 8-bit unsigned integer square root of an unsigned 16-bit integer.
; By Lee Davison (leeedavison@googlemail.com), 23 July 2001.
; Modified for the 65Org16 by Sam Gaskill, 13 March 2013.
; Calculates the 8 bit root and 9 bit remainder of a 16 bit unsigned integer in
; Numberl. Numberh=0. The result is always in the range 0 to 255 and is held in
; Root, the remainder is in the range 0 to 511 and is held in Reml/Remh
;
; partial results are held in templ/temph
;
; This routine is the complement to the integer square program.
;
; Destroys A, X registers.
                     
SqRoot      LDA	#$00		; clear A
	          STA	Reml		; clear remainder low byte
	          STA	Remh		; clear remainder high byte
	          STA	Root		; clear Root
	          LDX	#$10		; 16 pairs of bits to do
Loop
	          ASL	Root		; Root = Root * 2

	          ASL	Numberl	; shift highest bit of number ..
	          ROL	Numberh	;
	          ROL	Reml		; .. into remainder
	          ROL	Remh		;

	          ASL	Numberl	; shift highest bit of number ..
	          ROL	Numberh	;
	          ROL	Reml		; .. into remainder
	          ROL	Remh		;

	          LDA	Root		; copy Root ..
	          STA	templ		; .. to templ
	          LDA	#$00		; clear byte
	          STA	temph		; clear temp high byte

	          SEC			    ; +1
	          ROL	templ		; temp = temp * 2 + 1
	          ROL	temph		;

	          LDA	Remh		; get remainder high byte
	          CMP	temph		; comapre with partial high byte
	          BCC	Next		; skip sub if remainder high byte smaller

            BNE	Subtr		; do sub if <> (must be remainder>partial !)

	          LDA	Reml		; get remainder low byte
	          CMP	templ		; comapre with partial low byte
	          BCC	Next		; skip sub if remainder low byte smaller

				                ; else remainder>=partial so subtract then
				                ; and add 1 to root. carry is always set here
Subtr
	          LDA	Reml		; get remainder low byte
	          SBC	templ		; subtract partial low byte
	          STA	Reml		; save remainder low byte
	          LDA	Remh		; get remainder high byte
	          SBC	temph		; subtract partial high byte
	          STA	Remh		; save remainder high byte

	          INC	Root		; increment Root
Next
	          DEX			    ; decrement bit pair count
	          BNE	Loop		; loop if not all done

	          RTS
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Math Routines for the 65Org16

Post by BigEd »

Did you only have to change the loop counters? If this works it's a nice demonstration of how easy it is to port code from 6502 to 65Org16!
I notice that the comments still describe a 16 bit function - it should in fact now be a 32bit function. Reducing it back to 16bits should show the advantage of the 16bit nature of the machine.
Cheers
Ed
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Math Routines for the 65Org16

Post by ElEctric_EyE »

BigEd wrote:
Did you only have to change the loop counters?...
Cheers
Ed
That was one change, I had to change it from $0008 to $0010. Note that Bitwise's AS65 assembler right justifies 8bit values, ie a value you might see of $ee, is actually $00ee. One is allowed to present it either way to the assembler, but just realize the rules.

The other detail, was putting the entire 16 bit value into the Numberl variable. I forced Numberh to zero.

I will double check this routine now in ISim, as my circle plotting routine is still not functional.

EDIT: This is correct. After storing a value of $E100 in Numberl, and $0000 in Numberh, with the loop counter @ $0010, the returned result was $00F0 for Root variable with no other changes to the original 6502 software in this case.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Math Routines for the 65Org16

Post by ElEctric_EyE »

My plotting routine is now functional due to some other errors that were present in my 65Org16 code. Lee's code was functional as presented above, but I'm sure some variables can be eliminated. I'll look into optimizing it next week...
User avatar
dclxvi
Posts: 362
Joined: 11 Mar 2004

Re: Math Routines for the 65Org16

Post by dclxvi »

There is an optimized (6502) version here:

http://6502org.wikidot.com/software-math-sqrt
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Math Routines for the 65Org16

Post by ElEctric_EyE »

Awesome, thanks Bruce. I have a few routines to compare speeds now and to convert over to 65Org16. I should probably .zip each one up and add to the header.
Post Reply