2 \ MSP_EXP430FR5739 MSP_EXP430FR5969 MSP_EXP430FR5994 MSP_EXP430FR6989
3 \ MSP_EXP430FR2433 MSP_EXP430FR4133 MSP_EXP430FR2355 CHIPSTICK_FR2433
4 \ MY_MSP430FR5738_1 MY_MSP430FR5738 MY_MSP430FR5948 MY_MSP430FR5948_1
8 \ rDODOES to rEXIT must be saved before use and restored after
9 \ scratch registers Y to S are free for use
10 \ under interrupt, IP is free for use
12 \ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, rEXIT,rDOVAR,rDOCON, rDODOES, R3, SR,RSP, PC
13 \ PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8, R7 , R6 , R5 , R4 , R3, R2, R1, R0
15 \ example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
17 \ POPM order : PC,RSP, SR, R3, rDODOES,rDOCON,rDOVAR,rEXIT, Y, X, W, T, S, IP,TOS,PSP
18 \ POPM order : R0, R1, R2, R3, R4 , R5 , R6 , R7 , R8, R9,R10,R11,R12,R13,R14,R15
20 \ example : POPM #6,IP pop Y,X,W,T,S,IP registers from return stack
22 \ FORTH conditionnals: unary{ 0= 0< 0> }, binary{ = < > U< }
24 \ ASSEMBLER conditionnal usage with IF UNTIL WHILE S< S>= U< U>= 0= 0<> 0>=
26 \ ASSEMBLER conditionnal usage with ?JMP ?GOTO S< S>= U< U>= 0= 0<> <0
32 [DEFINED] {FIXPOINT} [IF] {FIXPOINT} [THEN] \ remove {FIXPOINT} if outside core
35 [UNDEFINED] {FIXPOINT} [IF] \ assembler required, don't replicate {FIXPOINT} inside core
41 \ https://forth-standard.org/standard/core/HOLDS
42 \ Adds the string represented by addr u to the pictured numeric output string
43 \ compilation use: <# S" string" HOLDS #>
44 \ free chars area in the 32+2 bytes HOLD buffer = {26,23,2} chars with a 32 bits sized {hexa,decimal,binary} number.
45 \ (2 supplementary bytes are room for sign - and decimal point)
51 BEGIN SUB #1,X \ 1 src-1
53 U>= WHILE SUB #1,Y \ 1 dst-1
57 MOV @IP+,PC \ 4 15 words
61 CODE F+ \ add Q15.16 numbers
62 ADD @PSP+,2(PSP) \ -- sumlo d1hi d2hi
63 ADDC @PSP+,TOS \ -- sumlo sumhi
68 CODE F- \ substract Q15.16 numbers
69 SUB @PSP+,2(PSP) \ -- diflo d1hi d2hi
70 SUBC TOS,0(PSP) \ -- diflo difhi d2hi
80 $1A04 C@ $EF > [IF] ; test tag value MSP430FR413x subfamily without hardware_MPY
84 CODE F/ \ Q15.16 / Q15.16 --> Q15.16 result
86 XOR TOS,S \ DVDhi XOR DVRhi --> S keep sign of result
88 MOV 4(PSP),Y \ DVDlo --> DVDhi
89 MOV 2(PSP),X \ DVDhi --> REMlo
90 BIT #8000,X \ DVD < 0 ?
91 0<> IF XOR #-1,Y \ INV(DVDlo)
92 XOR #-1,X \ INV(DVDhi)
93 ADD #1,Y \ INV(DVDlo)+1
94 ADDC #0,X \ INV(DVDhi)+C
95 THEN BIT #8000,TOS \ DVR < 0 ?
96 0<> IF XOR #-1,0(PSP) \ INV(DVRlo)
97 XOR #-1,TOS \ INV(DVRhi)
98 ADD #1,0(PSP) \ INV(DVRlo)+1
99 ADDC #0,TOS \ INV(DVRhi)+C
101 \ don't uncomment lines below !
102 \ ------------------------------------------------------------------------
103 \ UD/MOD DVDlo DVDhi DVRlo DVRhi -- REMlo REMhi QUOTlo QUOThi
104 \ ------------------------------------------------------------------------
105 \ MOV 4(PSP),T \ DVDlo
106 \ MOV 2(PSP),Y \ DVDhi
107 \ MOV #0,X \ REMlo = 0
112 MOV #32,R5 \ init loop count
113 BW1 CMP TOS,W \ 1 REMhi = DVRhi ?
114 0= IF CMP R6,X \ 1 REMlo U< DVRlo ?
116 U>= IF SUB R6,X \ 1 no: REMlo - DVRlo (carry is set)
117 SUBC TOS,W \ 1 REMhi - DVRhi
119 BW2 ADDC R7,R7 \ 1 RLC quotLO
120 ADDC R4,R4 \ 1 RLC quotHI
121 SUB #1,R5 \ 1 Decrement loop counter
122 0< ?GOTO FW1 \ 2 out of loop if count<0
123 ADD T,T \ 1 RLA DVDlo
124 ADDC Y,Y \ 1 RLC DVDhi
125 ADDC X,X \ 1 RLC REMlo
126 ADDC W,W \ 1 RLC REMhi
127 U< ?GOTO BW1 \ 2 15~ loop
128 SUB R6,X \ 1 REMlo - DVRlo
129 SUBC TOS,W \ 1 REMhi - DVRhi
131 GOTO BW2 \ 2 16~ loop
133 \ MOV X,4(PSP) \ REMlo
134 \ MOV W,2(PSP) \ REMhi
135 ADD #4,PSP \ skip REMlo REMhi
137 MOV R7,0(PSP) \ QUOTlo
139 POPM #4,R7 \ restore R4 to R7
140 \ MOV @IP+,PC \ end of UD/MOD
141 \ ------------------------------------------------------------------------
142 BW1 AND #-1,S \ clear V, set N; QUOT < 0 ?
143 S< IF XOR #-1,0(PSP) \ INV(QUOTlo)
144 XOR #-1,TOS \ INV(QUOThi)
145 ADD #1,0(PSP) \ INV(QUOTlo)+1
146 ADDC #0,TOS \ INV(QUOThi)+C
151 \ F#S Qhi Qlo -- Qhi 0 convert fractional part Qlo of Q15.16 fixed point number
153 MOV @PSP,X \ -- Qlo Qhi X = Qlo
154 MOV TOS,0(PSP) \ -- Qhi Qhi
155 SUB #2,PSP \ -- Qhi x Qhi
156 MOV X,0(PSP) \ -- Qhi Qlo Qhi
157 MOV #4,TOS \ -- Qhi Qlo x TOS = limit for base 16
159 0= IF ADD #1,TOS \ TOS = limit for base 10
162 PUSHM #2,TOS \ save TOS,IP
163 MOV #0,S \ -- Qhi Qlo x
164 BEGIN PUSH S \ R-- limit IP count
165 MOV &BASE,TOS \ -- Qhi Qlo base
167 UM* \ u1 u2 -- RESlo REShi
168 HI2LO \ -- Qhi RESlo digit
170 CMP #10,TOS \ digit to char
173 MOV @RSP+,S \ R-- limit IP
174 MOV.B TOS,HOLDS_ORG(S) \ -- Qhi RESlo char char to string
176 CMP 2(RSP),S \ count=limit ?
178 POPM #2,TOS \ restore IP,TOS
179 MOV #0,0(PSP) \ -- Qhi 0 len
180 SUB #2,PSP \ -- Qhi 0 x len
181 MOV #HOLDS_ORG,0(PSP) \ -- Qhi 0 addr len
186 \ unsigned multiply 32*32 = 64
187 \ don't use S reg (keep sign)
190 \ PUSHM R7,R4 \ 6 save R7 ~ R4 regs
191 PUSHM #4,R7 \ 6 save R7 ~ R4 regs
192 MOV 4(PSP),IP \ 3 MDlo
193 MOV 2(PSP),T \ 3 MDhi
197 MOV #0,4(PSP) \ 3 RESlo=0
198 MOV #0,2(PSP) \ 3 REShi=0
199 MOV #0,R6 \ 1 RESLO=0
200 MOV #0,R7 \ 1 RESHI=0
201 MOV #1,X \ 1 BIT TEST REGlo
202 MOV #0,Y \ 1 BIT TEST2 REGhi
204 0<> IF BIT X,W \ 1 TEST ACTUAL BIT MRlo
205 ELSE BIT Y,TOS \ 1 TEST ACTUAL BIT MRhi
207 0<> IF ADD IP,4(PSP) \ 3 IF 1: ADD MDlo TO RESlo
208 ADDC T,2(PSP) \ 3 ADDC MDhi TO REShi
209 ADDC R4,R6 \ 1 ADDC MDLO TO RESLO
210 ADDC R5,R7 \ 1 ADDC MDHI TO RESHI
211 THEN ADD IP,IP \ 1 (RLA LSBs) MDlo *2
212 ADDC T,T \ 1 (RLC MSBs) MDhi *2
213 ADDC R4,R4 \ 1 (RLA LSBs) MDLO *2
214 ADDC R5,R5 \ 1 (RLC MSBs) MDHI *2
215 ADD X,X \ 1 (RLA) NEXT BIT TO TEST
216 ADDC Y,Y \ 1 (RLA) NEXT BIT TO TEST
217 U>= UNTIL MOV R6,0(PSP) \ 2 IF BIT IN CARRY: FINISHED 32 * 16~ (average loop)
218 MOV R7,TOS \ 1 high result in TOS
219 POPM #4,R7 \ 6 restore R4 to R7
225 CODE F* \ s15.16 * s15.16 --> s15.16 result
227 XOR TOS,S \ 1s15 XOR 2s15 --> S keep sign of result
228 BIT #$8000,2(PSP) \ MD < 0 ?
229 0<> IF XOR #-1,2(PSP)
235 DABS UDM* \ -- RES0 RES1 RES2 RES3
238 MOV @PSP+,TOS \ -- RES0 RES1 RES2
239 MOV @PSP+,0(PSP) \ -- RES1 RES2
240 GOTO BW1 \ goto end of F/ to process sign of result
244 [ELSE] \ hardware multiplier
247 CODE F/ \ Q15.16 / Q15.16 --> Q15.16 result
249 XOR TOS,S \ DVDhi XOR DVRhi --> S keep sign of result
251 MOV 4(PSP),Y \ DVDlo --> DVDhi
252 MOV 2(PSP),X \ DVDhi --> REMlo
253 BIT #8000,X \ DVD < 0 ?
254 0<> IF XOR #-1,Y \ INV(DVDlo)
255 XOR #-1,X \ INV(DVDhi)
256 ADD #1,Y \ INV(DVDlo)+1
257 ADDC #0,X \ INV(DVDhi)+C
258 THEN BIT #8000,TOS \ DVR < 0 ?
259 0<> IF XOR #-1,0(PSP) \ INV(DVRlo)
260 XOR #-1,TOS \ INV(DVRhi)
261 ADD #1,0(PSP) \ INV(DVRlo)+1
262 ADDC #0,TOS \ INV(DVRhi)+C
264 \ don't uncomment lines below !
265 \ ------------------------------------------------------------------------
266 \ UD/MOD DVDlo DVDhi DVRlo DVRhi -- REMlo REMhi QUOTlo QUOThi
267 \ ------------------------------------------------------------------------
268 \ MOV 4(PSP),T \ DVDlo
269 \ MOV 2(PSP),Y \ DVDhi
270 \ MOV #0,X \ REMlo = 0
271 \ PUSHM R7,R4 \ PUSHM R7 to 4
272 PUSHM #4,R7 \ PUSHM R7 to R4
275 MOV #32,R5 \ init loop count
276 BW1 CMP TOS,W \ 1 REMhi = DVRhi ?
277 0= IF CMP R6,X \ 1 REMlo U< DVRlo ?
279 U>= IF SUB R6,X \ 1 no: REMlo - DVRlo (carry is set)
280 SUBC TOS,W \ 1 REMhi - DVRhi
282 BW2 ADDC R7,R7 \ 1 RLC quotLO
283 ADDC R4,R4 \ 1 RLC quotHI
284 SUB #1,R5 \ 1 Decrement loop counter
285 0< ?GOTO FW1 \ 2 out of loop if count<0
286 ADD T,T \ 1 RLA DVDlo
287 ADDC Y,Y \ 1 RLC DVDhi
288 ADDC X,X \ 1 RLC REMlo
289 ADDC W,W \ 1 RLC REMhi
290 U< ?GOTO BW1 \ 2 15~ loop
291 SUB R6,X \ 1 REMlo - DVRlo
292 SUBC TOS,W \ 1 REMhi - DVRhi
294 GOTO BW2 \ 2 16~ loop
296 \ MOV X,4(PSP) \ REMlo
297 \ MOV W,2(PSP) \ REMhi
298 ADD #4,PSP \ skip REMlo REMhi
300 MOV R7,0(PSP) \ QUOTlo
302 POPM #4,R7 \ restore R4 to R7
303 \ MOV @IP+,PC \ end of UD/MOD
304 \ ------------------------------------------------------------------------
305 AND #-1,S \ clear V, set N; QUOT < 0 ?
306 S< IF XOR #-1,0(PSP) \ INV(QUOTlo)
307 XOR #-1,TOS \ INV(QUOThi)
308 ADD #1,0(PSP) \ INV(QUOTlo)+1
309 ADDC #0,TOS \ INV(QUOThi)+C
315 \ F#S Qhi Qlo -- Qhi 0 convert fractionnal part of Q15.16 fixed point number (direct order)
317 MOV @PSP,X \ -- Qlo Qhi X = Qlo
320 \ ADD #1,X \ -- display by excess (experimental)
322 MOV TOS,0(PSP) \ -- Qhi Qhi
323 SUB #2,PSP \ -- Qhi x Qhi
324 MOV X,0(PSP) \ -- Qhi Qlo Qhi
325 MOV #4,T \ -- Qhi Qlo x T = limit for base 16
327 0= IF ADD #1,T \ T = limit for base 10
328 THEN MOV #0,S \ S = count
329 BEGIN MOV @PSP,&MPY \ Load 1st operand
330 MOV &BASE,&OP2 \ Load 2nd operand
331 MOV &RES0,0(PSP) \ -- Qhi RESlo x low result on stack
332 MOV &RES1,TOS \ -- Qhi RESlo REShi high result in TOS
333 CMP #10,TOS \ digit to char
336 MOV.B TOS,HOLDS_ORG(S) \ -- Qhi RESlo char char to string
338 CMP T,S \ count=limit ?
339 U>= UNTIL MOV T,TOS \ -- Qhi RESlo limit
340 MOV #0,0(PSP) \ -- Qhi 0 limit
341 SUB #2,PSP \ -- Qhi 0 x len
342 MOV #HOLDS_ORG,0(PSP) \ -- Qhi 0 addr len
347 CODE F* \ signed s15.16 multiplication --> s15.16 result
348 MOV 4(PSP),&MPYS32L \ 5 Load 1st operand
349 MOV 2(PSP),&MPYS32H \ 5
350 MOV @PSP,&OP2L \ 4 load 2nd operand
352 ADD #4,PSP \ 1 remove 2 cells
354 \ NOP2 \ 2 wait 8 cycles after write OP2L before reading RES1
361 [THEN] \ hardware multiplier
364 : F. \ display a Q15.16 number
365 <# DUP >R DABS \ -- Qlo Qhi R-- sign
367 $2C HOLD #S \ -- sign 0 0
368 R> SIGN #> \ -- addr len R--
373 CODE S>F \ convert a signed number to a Q15.16 (signed) number
380 [UNDEFINED] 2CONSTANT [IF]
382 \ https://forth-standard.org/standard/core/TwoFetch
383 \ 2@ a-addr -- x1 x2 fetch 2 cells ; the lower address will appear on top of stack
392 \ https://forth-standard.org/standard/double/TwoCONSTANT
393 : 2CONSTANT \ udlo/dlo/Qlo udhi/dhi/Qhi -- to create double or Q15.16 CONSTANT
395 , , \ compile Qhi then Qlo
400 [THEN] \of [UNDEFINED] 2CONSTANT [IF]
404 [THEN] \ of [UNDEFINED] {FIXPOINT}
409 ; -----------------------
411 ; -----------------------
415 PI -1,0 F* 2CONSTANT -PI