|
|
1.1 root 1: ;FPRIMS32.S - rsalib assembler primitives for MC680x0
2: ; (Pure-C/Atari ST version, 32-bit units)
3: ;
4: ;Written by Stephan Baucke 19-Oct-91
5: ;Assembler: Pure-PASM
6: ;
7: ;On systems with 68020 or higher it might be faster to use 32-Bit units
8: ;instead of 16 Bits (I didn't yet test this, but there is no improvement
9: ;on a plain 68000).
10: ;
11: ;Note that the function P_SETP of the Intel primitives is not needed here.
12: ;`set_precision' has to be defined just like in `PORTABLE' mode in rsalib.h
13:
14: IMPORT global_precision
15: EXPORT P_ADDC, P_SUBB, P_ROTL, P_SETP, P_SMUL
16:
17: TEXT
18:
19: ;boolean P_ADDC(unitptr r1, unitptr r2, boolean carry);
20: ; /* multiprecision add with carry r2 to r1, result in r1 */
21: ;Parameters: A0.l: r1, A1.l: r2, D0.b: carry
22: ;Result: D0.b: new carry
23: ;Modifies: D0-D2/A0-A1
24:
25: P_ADDC: move.b d0,d1 ;boolean carry
26: sne d1 ;set bit 0 to carry
27: move.w global_precision,d2 ;# of units
28: move.w d2,d0 ;make copy
29: lsl.w #2,d2 ;calc # of bytes (4 per unit)
30: add.w d2,a0 ;point r1 to least significant unit
31: add.w d2,a1 ;point r2 to least significant unit
32: lsr.w #1,d2 ;divide back (now 2 * units)
33: and.w #2*7,d2 ;yields 2 * (units % 8)
34: neg.w d2 ;negative offset (for 2-Byte instructions)
35: lsr.w #3,d0 ;units / 8
36: beq.s .onebyone ;skip loop if zero count
37:
38: subq.w #1,d0 ;one off (dbf counter)
39: lsr.b d1 ;set X if carry
40: .loop: REPT 8 ;8 units per run
41: addx.l -(a1),-(a0)
42: ENDM
43: dbf d0,.loop
44: jmp .base(pc,d2.w) ;do remaining units
45:
46: .onebyone: lsr.b d1 ;set X if carry
47: jmp .base(pc,d2.w) ;do remaining units
48:
49: REPT 7 ;max 7 units remaining
50: addx.l -(a1),-(a0) ;(2-byte instruction)
51: ENDM
52: .base: scs d0 ;set returned carry
53: rts
54:
55: ;boolean P_SUBB(unitptr r1, unitptr r2, boolean borrow);
56: ; /* multiprecision subtract with borrow, r2 from r1, result in r1 */
57: ;Parameters: A0.l: r1, A1.l: r2, D0.b: borrow
58: ;Result: D0.b: new borrow
59: ;Modifies: D0-D2/A0/A1
60:
61: P_SUBB: move.b d0,d1 ;boolean carry
62: sne d1 ;set bit 0 to carry
63: move.w global_precision,d2 ;# of units
64: move.w d2,d0 ;make copy
65: lsl.w #2,d2 ;calc # of bytes (4 per unit)
66: add.w d2,a0 ;point r1 to least significant unit
67: add.w d2,a1 ;point r2 to least significant unit
68: lsr.w #1,d2 ;divide back (now 2 * units)
69: and.w #2*7,d2 ;yields 2 * (units % 8)
70: neg.w d2 ;negative offset (for 2-byte instructions)
71: lsr.w #3,d0 ;units / 8
72: beq.s .onebyone ;skip loop if zero count
73:
74: subq.w #1,d0 ;one off (dbf counter)
75: lsr.b d1 ;set X if carry
76: .loop: REPT 8 ;8 units per run
77: subx.l -(a1),-(a0)
78: ENDM
79: dbf d0,.loop
80: jmp .base(pc,d2.w) ;do remaining units
81:
82: .onebyone: lsr.b d1 ;set X if carry
83: jmp .base(pc,d2.w) ;do remaining units
84:
85: REPT 7 ;max 7 units remaining
86: subx.l -(a1),-(a0) ;(2-byte instruction)
87: ENDM
88: .base: scs d0 ;set returned carry
89: rts
90:
91: ;boolean P_ROTL(unitptr r1, boolean carry);
92: ; /* multiprecision rotate left 1 bit with carry, result in r1. */
93: ;Parameters: A0.l: r1, D0.b: carry
94: ;Result: D0.b: new carry
95: ;Modifies: D0-D2/A0
96:
97: P_ROTL: move.b d0,d1 ;boolean carry
98: sne d1 ;set bit 0 to carry
99: move.w global_precision,d2 ;# of units
100: move.w d2,d0 ;make copy
101: lsl.w #2,d2 ;calc # of bytes (4 per unit)
102: add.w d2,a0 ;point r1 to least significant unit
103: and.w #4*7,d2 ;yields 4 * (units % 8)
104: neg.w d2 ;negative offset (for 4-byte instructions)
105: lsr.w #3,d0 ;units / 8
106: beq.s .onebyone ;skip loop if zero count
107:
108: subq.w #1,d0 ;one off (dbf counter)
109: lsr.b d1 ;set X if carry
110: .loop: REPT 8 ;8 units per run
111: roxl.w -(a0) ;(roxl.l <ea> is not allowed on the 68000)
112: roxl.w -(a0)
113: ENDM
114: dbf d0,.loop
115: jmp .base(pc,d2.w) ;do remaining units
116:
117: .onebyone: lsr.b d1 ;set X if carry
118: jmp .base(pc,d2.w) ;do remaining units
119:
120: REPT 7 ;max 7 units remaining
121: roxl.w -(a0) ;(4 bytes instructions per unit)
122: roxl.w -(a0)
123: ENDM
124: .base: scs d0 ;set returned carry
125: rts
126:
127:
128: ;void P_SETP(short nbits);
129: ; /* sets working precision to specified number of bits. */
130: ; /* only to minimize portation differences */
131: ;Parameters: --
132: ;Result: --
133:
134: P_SETP: rts
135:
136: ; ***NOT TESTED***
137: ;
138: ;void P_SMUL(MULTUNIT *prod, MULTUNIT *multiplicand, MULTUNIT multiplier)
139: ; /* multiprecision multiply */
140: ;Parameters: A0.l: prod, A1.l: multiplicand, D0.w: multiplier
141: ;Modifies: D0-D3/A0-A1
142: ;Result: --
143:
144: P_SMUL: move.w global_precision,d3
145: lsl.w #1,d3
146: subq.w #1,d3
147: clr.l d2
148: clr.l d1
149:
150: .loop: move.w -(a1),d1
151: mulu.l d0,d1
152: add.l d2,d1
153: add.w d1,-(a0)
154: scs d2
155: lsr.l #16,d1
156: add.w d1,d2
157: dbf d3,.loop
158:
159: move.w d2,(a0)
160: rts
161:
162:
163: END
164:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.