Difference between revisions of "Fast signed multiply"

From Nesdev wiki
Jump to navigationJump to search
m (cat)
m (lokup -> lookup)
 
(3 intermediate revisions by one other user not shown)
Line 1: Line 1:
The following code multiplies two 8-bit signed integers, of range (-64..+64). The output is a signed 16-bit result, in range (-4096..4096). It uses a 256 byte lokup table, but is quite fast.
+
The following code multiplies two 8-bit signed integers, of range (-64..+64). The output is a signed 16-bit result, in range (-4096..4096). It uses a 256 byte lookup table, but is quite fast.
  
<source lang="6502tasm">
+
<pre>
 
;Fast table driven signed multiply routine
 
;Fast table driven signed multiply routine
 
;It multiplies Y with A, and relies on the mathematical fact (a+b)^2-(a-b)^2 = 4*a*b
 
;It multiplies Y with A, and relies on the mathematical fact (a+b)^2-(a-b)^2 = 4*a*b
Line 8: Line 8:
  
 
Multiply
 
Multiply
        sty Temp
+
sty Temp
 
pha
 
pha
 
clc
 
clc
Line 35: Line 35:
 
lda SquareTbl+1,X
 
lda SquareTbl+1,X
 
sbc SquareTbl+1,Y
 
sbc SquareTbl+1,Y
        tay
+
tay
        pla
+
pla
 
rts
 
rts
  
Line 50: Line 50:
 
.endr
 
.endr
 
.ends
 
.ends
</source>
+
</pre>
 
[[Category:Arithmetic]]
 
[[Category:Arithmetic]]

Latest revision as of 22:25, 6 March 2019

The following code multiplies two 8-bit signed integers, of range (-64..+64). The output is a signed 16-bit result, in range (-4096..4096). It uses a 256 byte lookup table, but is quite fast.

;Fast table driven signed multiply routine
;It multiplies Y with A, and relies on the mathematical fact (a+b)^2-(a-b)^2 = 4*a*b
;Also both inputs and outputs are SIGNED and are never supposed to be outside of the range (-64; +64)
;Return with YA = 4*A*Y (result can be shifted as necessary)

Multiply
	sty Temp
	pha
	clc
	adc Temp	;Add two multiplicands together
	bpl +
	eor #$ff
	clc
	adc #$01	;If result is negative, force it to be positive
+	asl A
	tax		;The square of a negative number is equal to its pos counterpart anyways

	pla
	sec
	sbc Temp       ;Compute difference of two multiplicands
	bpl +
	eor #$ff       ;Again, force the result to be positive
	clc
	adc #$01
+	asl A
	tay

	lda SquareTbl,X
	sec
	sbc SquareTbl,Y    ;Compute (a+y)^2-(a-y)^2
	pha
	lda SquareTbl+1,X
	sbc SquareTbl+1,Y
	tay
	pla
	rts

;This is a square table for the multiply routine
;Note that this macro is for WLA-DX, but can be adapted
;For most assemblers

SquareTbl
.def i = 0
.rept 128
	.dw i^2			;Create a square table with 128 word entries
	.redef i i+1
.endr
.ends