60 lines
1.6 KiB
Tal
60 lines
1.6 KiB
Tal
( use short as a fixed point number 8.8 )
|
|
( )
|
|
( so #0001 is interpreted as 1/256 )
|
|
( and #ffff is interpreted as 255+255/256 )
|
|
( )
|
|
( x = x0 + x1/256 )
|
|
( y = y0 + y1/256 )
|
|
( )
|
|
( many 8.8 operations are equivalent to u16: )
|
|
( * comparisons/equality )
|
|
( * addition/subtraction )
|
|
( )
|
|
( but due to 16-bit truncation multiplication is different. )
|
|
( )
|
|
( x*y = x0*y0 + x0*y1/256 + x1*y0/256 + x1*y1/65536 )
|
|
( )
|
|
( since we only have 16-bits: )
|
|
( 1. we need to drop the 8 high bits from x0*y0 )
|
|
( 2. we need to drop the 8 low bits from x1*y1 )
|
|
( 3. we need to use all the bits from x0*y1 and x1*y0 )
|
|
|
|
%EMIT { #18 DEO }
|
|
%DIGIT { #00 SWP ;digits ADD2 LDA EMIT }
|
|
%SPACE { #20 EMIT }
|
|
%NEWLINE { #0a EMIT }
|
|
%EMIT-BYTE { DUP #04 SFT DIGIT #0f AND DIGIT }
|
|
|
|
( program )
|
|
|0100
|
|
#0100 #0100 ;mul-fix JSR2 ;emit-short JSR2 NEWLINE
|
|
#0999 #0100 ;mul-fix JSR2 ;emit-short JSR2 NEWLINE
|
|
#abcd #0100 ;mul-fix JSR2 ;emit-short JSR2 NEWLINE
|
|
#0200 #0200 ;mul-fix JSR2 ;emit-short JSR2 NEWLINE
|
|
#0400 #0200 ;mul-fix JSR2 ;emit-short JSR2 NEWLINE
|
|
BRK
|
|
|
|
%LO { NIP #00 SWP }
|
|
%HI { POP #00 SWP }
|
|
|
|
@mul-fix ( x* y* -> z* )
|
|
OVR2 OVR2 LO SWP2 LO MUL2 ( x1*y1 )
|
|
#08 SFT2 STH2 ( z = (x1*y1)>>8 )
|
|
|
|
OVR2 OVR2 HI SWP2 LO MUL2 ( x0*y1 )
|
|
STH2 ADD2r ( z += x0*y1 )
|
|
|
|
OVR2 OVR2 LO SWP2 HI MUL2 ( x1*y0 )
|
|
STH2 ADD2r ( z += x1*y0 )
|
|
|
|
HI SWP2 HI MUL2 ( x0*y0 )
|
|
#80 SFT2 STH2r ADD2 ( z += (x0*y0)<<8 )
|
|
JMP2r
|
|
|
|
@emit-short SWP EMIT-BYTE EMIT-BYTE JMP2r
|
|
|
|
( convenience for less branching when printing hex )
|
|
@digits
|
|
30 31 32 33 34 35 36 37
|
|
38 39 61 62 63 64 65 66
|