2 \ MSP_EXP430FR5739 MSP_EXP430FR5969 MSP_EXP430FR5994 MSP_EXP430FR6989
3 \ MSP_EXP430FR2433 MSP_EXP430FR4133 MSP_EXP430FR2355 CHIPSTICK_FR2433
9 [DEFINED] {FIXPOINT} [IF] {FIXPOINT} [THEN] \ remove {FIXPOINT} if outside core
12 [UNDEFINED] {FIXPOINT} [IF] \ assembler required, don't replicate {FIXPOINT} inside core
18 \ https://forth-standard.org/standard/core/HOLDS
19 \ Adds the string represented by addr u to the pictured numeric output string
20 \ compilation use: <# S" string" HOLDS #>
21 \ free chars area in the 32+2 bytes HOLD buffer = {26,23,2} chars with a 32 bits sized {hexa,decimal,binary} number.
22 \ (2 supplementary bytes are room for sign - and decimal point)
28 BEGIN SUB #1,X \ 1 src-1
30 U>= WHILE SUB #1,Y \ 1 dst-1
34 MOV @IP+,PC \ 4 15 words
38 CODE F+ \ add Q15.16 numbers
39 ADD @PSP+,2(PSP) \ -- sumlo d1hi d2hi
40 ADDC @PSP+,TOS \ -- sumlo sumhi
45 CODE F- \ substract Q15.16 numbers
46 SUB @PSP+,2(PSP) \ -- diflo d1hi d2hi
47 SUBC TOS,0(PSP) \ -- diflo difhi d2hi
53 CODE F/ \ Q15.16 / Q15.16 --> Q15.16 result
55 XOR TOS,S \ MDhi XOR MRhi --> S keep sign of result
57 MOV 4(PSP),Y \ DVDlo --> DVDhi
58 MOV 2(PSP),X \ DVDhi --> REMlo
59 BIT #8000,X \ MD < 0 ?
70 \ don't uncomment lines below !
71 \ ------------------------------------------------------------------------
72 \ UD/MOD DVDlo DVDhi DVRlo DVRhi -- REMlo REMhi QUOTlo QUOThi
73 \ ------------------------------------------------------------------------
74 \ MOV 4(PSP),T \ DVDlo
75 \ MOV 2(PSP),Y \ DVDhi
76 \ MOV #0,X \ REMlo = 0
80 MOV #32,R5 \ init loop count
81 BW1 CMP TOS,W \ 1 REMhi = DIVhi ?
82 0= IF CMP R6,X \ 1 REMlo U< DIVlo ?
84 U>= IF SUB R6,X \ 1 no: REMlo - DIVlo (carry is set)
85 SUBC TOS,W \ 1 REMhi - DIVhi
87 BW2 ADDC R7,R7 \ 1 RLC quotLO
88 ADDC R4,R4 \ 1 RLC quotHI
89 SUB #1,R5 \ 1 Decrement loop counter
90 0< ?GOTO FW1 \ 2 out of loop if count<0
92 ADDC Y,Y \ 1 RLC DVDhi
93 ADDC X,X \ 1 RLC REMlo
94 ADDC W,W \ 1 RLC REMhi
95 U< ?GOTO BW1 \ 2 15~ loop
96 SUB R6,X \ 1 REMlo - DIVlo
97 SUBC TOS,W \ 1 REMhi - DIVhi
101 \ MOV X,4(PSP) \ REMlo
102 \ MOV W,2(PSP) \ REMhi
103 ADD #4,PSP \ skip REMlo REMhi
105 MOV R7,0(PSP) \ QUOTlo
107 POPM R4,R7 \ restore R7 to R4
108 \ MOV @IP+,PC \ end of UD/MOD
109 \ ------------------------------------------------------------------------
110 BW1 AND #-1,S \ clear V, set N
119 $1A04 C@ $EF > [IF] ; test tag value MSP430FR413x subfamily without hardware_MPY
122 \ F#S Qhi Qlo -- Qhi 0 convert fractional part Qlo of Q15.16 fixed point number
124 MOV @PSP,X \ -- Qlo Qhi X = Qlo
125 MOV TOS,0(PSP) \ -- Qhi Qhi
126 SUB #2,PSP \ -- Qhi x Qhi
127 MOV X,0(PSP) \ -- Qhi Qlo Qhi
128 MOV #4,TOS \ -- Qhi Qlo x TOS = limit for base 16
130 0= IF ADD #1,TOS \ TOS = limit for base 10
132 MOV #0,S \ -- Qhi Qlo x
133 BEGIN PUSH S \ R-- limit IP count
134 MOV &BASE,TOS \ -- Qhi Qlo base
136 UM* \ u1 u2 -- RESlo REShi
137 HI2LO \ -- Qhi RESlo digit
139 CMP #10,TOS \ digit to char
142 MOV @RSP+,S \ R-- limit IP
143 MOV.B TOS,HOLDS_ORG(S) \ -- Qhi RESlo char char to string
145 CMP 2(RSP),S \ count=limit ?
146 U>= UNTIL POPM IP,TOS \
147 MOV #0,0(PSP) \ -- Qhi 0 len
148 SUB #2,PSP \ -- Qhi 0 x len
149 MOV #HOLDS_ORG,0(PSP) \ -- Qhi 0 addr len
154 \ unsigned multiply 32*32 = 64
155 \ don't use S reg (keep sign)
158 PUSHM R7,R4 \ 6 save R7 ~ R4 regs
159 MOV 4(PSP),IP \ 3 MDlo
160 MOV 2(PSP),T \ 3 MDhi
164 MOV #0,4(PSP) \ 3 RESlo=0
165 MOV #0,2(PSP) \ 3 REShi=0
166 MOV #0,R6 \ 1 RESLO=0
167 MOV #0,R7 \ 1 RESHI=0
168 MOV #1,X \ 1 BIT TEST REGlo
169 MOV #0,Y \ 1 BIT TEST2 REGhi
171 0<> IF BIT X,W \ 1 TEST ACTUAL BIT MRlo
172 ELSE BIT Y,TOS \ 1 TEST ACTUAL BIT MRhi
174 0<> IF ADD IP,4(PSP) \ 3 IF 1: ADD MDlo TO RESlo
175 ADDC T,2(PSP) \ 3 ADDC MDhi TO REShi
176 ADDC R4,R6 \ 1 ADDC MDLO TO RESLO
177 ADDC R5,R7 \ 1 ADDC MDHI TO RESHI
178 THEN ADD IP,IP \ 1 (RLA LSBs) MDlo *2
179 ADDC T,T \ 1 (RLC MSBs) MDhi *2
180 ADDC R4,R4 \ 1 (RLA LSBs) MDLO *2
181 ADDC R5,R5 \ 1 (RLC MSBs) MDHI *2
182 ADD X,X \ 1 (RLA) NEXT BIT TO TEST
183 ADDC Y,Y \ 1 (RLA) NEXT BIT TO TEST
184 U>= UNTIL MOV R6,0(PSP) \ 2 IF BIT IN CARRY: FINISHED 32 * 16~ (average loop)
185 MOV R7,TOS \ 1 high result in TOS
186 POPM R4,R7 \ 6 restore R4 ~ R7 regs
192 CODE F* \ s15.16 * s15.16 --> s15.16 result
194 XOR TOS,S \ 1s15 XOR 2s15 --> S keep sign of result
195 BIT #$8000,2(PSP) \ MD < 0 ?
196 0<> IF XOR #-1,2(PSP)
202 DABS UDM* \ -- RES0 RES1 RES2 RES3
205 MOV @PSP+,TOS \ -- RES0 RES1 RES2
206 MOV @PSP+,0(PSP) \ -- RES1 RES2
207 GOTO BW1 \ goto end of F/ to process sign of result
211 [ELSE] \ hardware multiplier
214 \ F#S Qhi Qlo -- Qhi 0 convert fractionnal part of Q15.16 fixed point number (direct order)
216 MOV @PSP,X \ -- Qlo Qhi X = Qlo
219 \ ADD #1,X \ -- display by excess (experimental)
221 MOV TOS,0(PSP) \ -- Qhi Qhi
222 SUB #2,PSP \ -- Qhi x Qhi
223 MOV X,0(PSP) \ -- Qhi Qlo Qhi
224 MOV #4,T \ -- Qhi Qlo x T = limit for base 16
226 0= IF ADD #1,T \ T = limit for base 10
227 THEN MOV #0,S \ S = count
228 BEGIN MOV @PSP,&MPY \ Load 1st operand
229 MOV &BASE,&OP2 \ Load 2nd operand
230 MOV &RES0,0(PSP) \ -- Qhi RESlo x low result on stack
231 MOV &RES1,TOS \ -- Qhi RESlo REShi high result in TOS
232 CMP #10,TOS \ digit to char
235 MOV.B TOS,HOLDS_ORG(S) \ -- Qhi RESlo char char to string
237 CMP T,S \ count=limit ?
238 U>= UNTIL MOV T,TOS \ -- Qhi RESlo limit
239 MOV #0,0(PSP) \ -- Qhi 0 limit
240 SUB #2,PSP \ -- Qhi 0 x len
241 MOV #HOLDS_ORG,0(PSP) \ -- Qhi 0 addr len
246 CODE F* \ signed s15.16 multiplication --> s15.16 result
247 MOV 4(PSP),&MPYS32L \ 5 Load 1st operand
248 MOV 2(PSP),&MPYS32H \ 5
249 MOV @PSP,&OP2L \ 4 load 2nd operand
251 ADD #4,PSP \ 1 remove 2 cells
253 \ NOP2 \ 2 wait 8 cycles after write OP2L before reading RES1
260 [THEN] \ hardware multiplier
263 : F. \ display a Q15.16 number
264 <# DUP >R DABS \ -- Qlo Qhi R-- sign
266 $2C HOLD #S \ -- sign 0 0
267 R> SIGN #> \ -- addr len R--
272 CODE S>F \ convert a signed number to a Q15.16 (signed) number
279 [UNDEFINED] 2CONSTANT [IF]
282 \ https://forth-standard.org/standard/core/TwoFetch
283 \ 2@ a-addr -- x1 x2 fetch 2 cells ; the lower address will appear on top of stack
292 \ https://forth-standard.org/standard/double/TwoCONSTANT
293 : 2CONSTANT \ udlo/dlo/Qlo udhi/dhi/Qhi -- to create double or Q15.16 CONSTANT
295 , , \ compile Qhi then Qlo
308 ; -----------------------
310 ; -----------------------
312 PI -1,0 F* 2CONSTANT -PI