-
Notifications
You must be signed in to change notification settings - Fork 6
/
mult66.a
90 lines (77 loc) · 1.99 KB
/
mult66.a
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
; mult66.a
; from TobyLobster, based on Nick Jameson's 3D Demo for the BBC Micro (1994), https://github.com/simondotm/bbc-micro-3d/blob/master/source/culling.asm
; (see mult65.a)
;
; 8 bit x 8bit unsigned multiply, 16 bit result
; Average cycles: 45.49
; 1580 bytes
result = $04 ; 2 bytes
lmul0 = $06 ; pointer into table 1 low
lmul1 = $08 ; pointer into table 1 high
prod_low = $0a
* = $0200
; table1 = n*n/4, where n=0..510
; table2 = 0 if n=0 else (256-n)*(n-256)/4, where n=0..255
; Table 1 must be aligned to start of a page
squaretable1_lsb
!for i, 0, 510 {
!byte <((i*i)/4)
}
!byte 0 ; unused, needed for alignment of next table
squaretable1_msb
!for i, 0, 510 {
!byte >((i*i)/4)
}
!byte 0 ; unused, needed for alignment of next table
; Table 2 should be aligned to the start of a page for speed
squaretable2_lsb
!byte 0
!for i, 1, 255 {
!byte <(((256-i)*(256-i))/4-1)
}
squaretable2_msb
!byte 0
!for i, 1, 255 {
!byte >(((256-i)*(256-i))/4-1)
}
; Unsigned multiplication of two 8-bit terms is computed as:
; if Y >= X:
; r = table1[X+Y] - table1[Y-X]
; else:
; r = table1[X+Y] - table2[Y-X]
; where r is a 16-bit unsigned result
; and 'Y-X' is calculated as a single byte value (0 to 255)
; 8 bit x 8bit unsigned multiply, 16 bit result
;
; On Entry:
; X: multiplier
; Y: multiplicand
; On Exit:
; (prod_low, A): product
mult
stx lmul0
stx lmul1
tya
sec
sbc lmul0
tax
lda (lmul0),Y
bcc +
sbc squaretable1_lsb,X
sta prod_low
lda (lmul1),Y
sbc squaretable1_msb,X
rts
+
sbc squaretable2_lsb,X
sta prod_low
lda (lmul1),Y
sbc squaretable2_msb,X
rts
; call this once to initialise high bytes of pointers to table
mult_init
lda #>squaretable1_lsb ; high byte (#2 in this instance)
sta lmul0+1
lda #>squaretable1_msb ; high byte (#4 in this instance)
sta lmul1+1
rts