-
Notifications
You must be signed in to change notification settings - Fork 1
/
fixedmath.dasm
77 lines (65 loc) · 1.88 KB
/
fixedmath.dasm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
; There is no fxadds or fxsubs, because ADD and SUB are all you need.
:fxaddd
; Add YX to BA, leave overflow in EX
ADD A, X
ADX B, Y
SET PC, POP
:fxsubd
; Subtract YX from BA, leave underflow in EX
SUB A, X
SBX B, Y
SET PC, POP
:fxmuls
; Multiply A by B, leave overflow in EX
; AA.AA * BB.BB = OOCC.DDxx
; CC.DD is the answer we want, XX gets thrown away, OO is the overflow
MUL A, B ; A = DDXX, EX = OOCC
SET X, EX ; X = OOCC
SHR A, 8 ; A = 00DD
SHL X, 8 ; X = CC00, EX = 00OO
BOR A, X ; A = CCDD
SET PC, POP
:fxmuld
; Multiply B.A by Y.X, leave overflow in EX
; BBBB.AAAA
; * YYYY.XXXX
; -------------------
; XXXX*AAAA
; XXXX*BBBB
; YYYY*AAAA
; YYYY*BBBB
; -----------------
; OOOO BBBB.AAAA xxxx
SET I, A ; we can't lose A yet
MUL I, X ; X*A
SET C, EX ; save overflow of X*A for second column
MUL A, Y ; Y*A (duh), and begin accumulating in A
SET Z, EX ; save overflow of Y*A for third column, begin accumulating in Z
ADD A, C ; accumulate overflow of X*A, we can now reuse C
ADD Z, EX ; potential carry from the second column
; the above cannot produce a propagating carry
MUL X, B ; X*B (duh)
ADD Z, EX ; accumulate overflow of X*B for third column
SET C, EX ; which can produce a carry
ADD A, X ; accumulate X*B
ADD Z, EX ; this can carry again, and we accumulate the third column in Z
ADD C, EX ; potential carry from third column
MUL B, Y ; Y*B, begin accumulating in B
ADD C, EX ; add overflow of Y*B to fourth column
; fourth column cannot overflow
ADD B, Z ; accumulate the rest of the third column
ADD C, EX ; potential carry
SET EX, C ; set EX
SET PC, POP
:fxdivs
; Divide A by B (UNSIGNED)
; AA.AA / BB.BB = OOCC.DDxx
DIV A, B ; A = OOCC, EX = DDxx
SET X, EX ; X = DDxx
SHR X, 8 ; X = 00DD
SHL A, 8 ; A = CC00, EX = 00OO
BOR A, X ; A = CCDD
SET PC, POP
:fxdivd
; Divide AB by XY
; unimplemented