1 \ -*- coding: utf-8 -*-
3 \ to see kernel options, download FastForthSpecs.f
4 \ FastForth kernel options: MSP430ASSEMBLER, CONDCOMP, FIXPOINT_INPUT
6 \ TARGET SELECTION ( = the name of \INC\target.pat file without the extension)
7 \ MSP_EXP430FR5739 MSP_EXP430FR5969 MSP_EXP430FR5994 MSP_EXP430FR6989
8 \ MSP_EXP430FR2433 MSP_EXP430FR4133 CHIPSTICK_FR2433 MSP_EXP430FR2355
11 \ from scite editor : copy your target selection in (shift+F8) parameter 1:
15 \ drag and drop this file onto SendSourceFileToTarget.bat
16 \ then select your TARGET when asked.
20 \ rDODOES to rEXIT must be saved before use and restored after
21 \ scratch registers Y to S are free for use
22 \ under interrupt, IP is free for use
24 \ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, rEXIT,rDOVAR,rDOCON, rDODOES, R3, SR,RSP, PC
25 \ PUSHM order : PSP,TOS,IP,S,T,W, X, Y, rDOCOL , rDOVAR , rDOCON , rDODOES , R3, SR, RSP, PC
27 \ example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
29 \ POPM order : PC,RSP, SR, R3, rDODOES,rDOCON,rDOVAR,rEXIT, Y, X, W, T, S, IP,TOS,PSP
30 \ POPM order : PC, RSP, SR, R3, rDODOES , rDOCON , rDOVAR , rDOCOL , Y, X,W,T,S,IP,TOS,PSP
32 \ example : POPM #6,IP pop Y,X,W,T,S,IP registers from return stack
34 \ FORTH conditionnals: unary{ 0= 0< 0> }, binary{ = < > U< }
36 \ ASSEMBLER conditionnal usage with IF UNTIL WHILE S< S>= U< U>= 0= 0<> 0>=
37 \ ASSEMBLER conditionnal usage with ?JMP ?GOTO S< S>= U< U>= 0= 0<> 0<
45 0<> IF MOV #0,TOS THEN \ if TOS <> 0 (FIXPOINT input), set TOS = 0
48 SUB #307,TOS \ FastForth V3.7
50 $0D EMIT \ return to column 1 without CR
51 ABORT" FastForth version = 3.7 please!"
52 ABORT" buil FastForth with FIXPOINT_INPUT addon !"
53 PWR_STATE \ if no abort remove this word
54 $1B EMIT $63 EMIT \ send 'ESC c' (clear screen)
59 ; -----------------------------------------------------
61 ; -----------------------------------------------------
63 [DEFINED] {FIXPOINT} [IF] {FIXPOINT} [THEN]
68 \ https://forth-standard.org/standard/core/Plus
69 \ + n1/u1 n2/u2 -- n3/u3 add n1+n2
77 \ https://forth-standard.org/standard/core/Rfrom
78 \ R> -- x R: x -- pop from return stack ; CALL #RFROM performs DOVAR
88 \ https://forth-standard.org/standard/core/Equal
89 \ = x1 x2 -- flag test x1=x2
96 XOR #-1,TOS \ 1 flag Z = 1
101 \ https://forth-standard.org/standard/core/Uless
102 \ U< u1 u2 -- flag test u1<u2, unsigned
105 SUB @PSP+,TOS \ 2 u2-u1
109 AND #0,TOS \ 1 flag Z = 1
116 [UNDEFINED] DABS [IF]
117 \ https://forth-standard.org/standard/double/DABS
118 \ DABS d1 -- |d1| absolute value
120 AND #-1,TOS \ clear V, set N
131 [UNDEFINED] HOLDS [IF]
132 \ https://forth-standard.org/standard/core/HOLDS
133 \ Adds the string represented by addr u to the pictured numeric output string
134 \ compilation use: <# S" string" HOLDS #>
135 \ free chars area in the 32+2 bytes HOLD buffer = {26,23,2} chars with a 32 bits sized {hexa,decimal,binary} number.
136 \ (2 supplementary bytes are room for sign - and decimal point)
139 MOV @PSP+,X \ 2 X=src
140 BW3 ADD TOS,X \ 1 X=src_end
142 BEGIN SUB #1,X \ 1 src-1
144 U>= WHILE SUB #1,Y \ 1 dst-1
148 MOV @IP+,PC \ 4 15 words
152 CODE F+ \ add Q15.16|double numbers
153 ADD @PSP+,2(PSP) \ -- sumlo d1hi d2hi
154 ADDC @PSP+,TOS \ -- sumlo sumhi
158 CODE F- \ substract Q15.16|double numbers
159 SUB @PSP+,2(PSP) \ -- diflo d1hi d2hi
160 SUBC TOS,0(PSP) \ -- diflo difhi d2hi
165 TLV_ORG 4 + @ $81F3 U<
166 $81EF TLV_ORG 4 + @ U<
167 = [IF] ; MSP430FR413x subfamily without hardware_MPY
169 \ unsigned multiply 32*32 = 64
170 \ don't use S reg (keep sign)
173 PUSHM #4,rDOVAR \ 6 save rDOVAR to rDOCOL regs to use M to R alias
174 MOV 4(PSP),IP \ 3 MDlo
175 MOV 2(PSP),T \ 3 MDhi
179 MOV #0,4(PSP) \ 3 RESlo=0
180 MOV #0,2(PSP) \ 3 REShi=0
183 MOV #1,X \ 1 BIT TEST REGlo
184 MOV #0,Y \ 1 BIT TEST2 REGhi
186 0<> IF BIT X,W \ 2+1 TEST ACTUAL BIT MRlo
187 ELSE BIT Y,TOS \ 2+1 TEST ACTUAL BIT MRhi
189 0<> IF ADD IP,4(PSP) \ 2+3 IF 1: ADD MDlo TO RESlo
190 ADDC T,2(PSP) \ 3 ADDC MDhi TO REShi
191 ADDC M,Q \ 1 ADDC MDLO TO RESLO
192 ADDC P,R \ 1 ADDC MDHI TO RESHI
193 THEN ADD IP,IP \ 1 (RLA LSBs) MDlo *2
194 ADDC T,T \ 1 (RLC MSBs) MDhi *2
195 ADDC M,M \ 1 (RLC LSBs) MDLO *2
196 ADDC P,P \ 1 (RLC MSBs) MDHI *2
197 ADD X,X \ 1 (RLA) NEXT BIT TO TEST
198 ADDC Y,Y \ 1 (RLC) NEXT BIT TO TEST
199 U>= UNTIL MOV Q,0(PSP) \ 2+2 IF BIT IN CARRY: FINISHED 32 * 16~ (average loop)
200 MOV R,TOS \ 1 high result in TOS
201 POPM #4,rDOVAR \ 6 restore rDOCOL to rDOVAR
206 CODE F* \ s15.16 * s15.16 --> s15.16 result
208 XOR TOS,S \ 1s15 XOR 2s15 --> S keep sign of result
209 BIT #$8000,2(PSP) \ MD < 0 ?
210 0<> IF XOR #-1,2(PSP)
215 DABS UDM* \ -- RES0 RES1 RES2 RES3
218 MOV @PSP+,TOS \ -- RES0 RES1 RES2
219 MOV @PSP+,0(PSP) \ -- RES1 RES2
220 AND #-1,S \ clear V, set N; process S sign
221 S< IF XOR #-1,0(PSP) \ INV(QUOTlo)
222 XOR #-1,TOS \ INV(QUOThi)
223 ADD #1,0(PSP) \ INV(QUOTlo)+1
224 ADDC #0,TOS \ INV(QUOThi)+C
229 \ F#S Qlo Qhi len -- Qhi 0 convert fractional part Qlo of Q15.16 fixed point number
232 MOV @PSP,S \ -- Qlo Qhi len S = Qhi
234 PUSHM #3,IP \ R-- IP Qhi count
235 MOV 2(PSP),0(PSP) \ -- Qlo Qlo len
236 MOV TOS,2(PSP) \ -- len Qlo len
237 BEGIN MOV &BASEADR,TOS \ -- len Qlo base
239 UM* \ u1 u2 -- RESlo REShi
240 HI2LO \ -- len RESlo digit
241 CMP #10,TOS \ digit to char
243 THEN ADD #$30,TOS \ -- len RESlo char
245 MOV.B TOS,HOLDS_ORG(T) \ char to string_org(T)
248 CMP 2(PSP),T \ -- len RESlo char count=len ?
249 U>= UNTIL POPM #3,IP \ S=Qhi, T=len
250 MOV T,TOS \ -- len RESlo len
251 MOV S,2(PSP) \ -- Qhi RESlo len
252 MOV #0,0(PSP) \ -- Qhi 0 len
253 MOV #HOLDS_ORG,X \ -- Qhi 0 len X=HOLDS_ORG
254 GOTO BW3 \ 36~ JMP HOLDS
258 [ELSE] ; hardware multiplier
260 CODE F* \ signed s15.16 multiplication --> s15.16 result
261 MOV 4(PSP),&MPYS32L \ 5 Load 1st operand
262 MOV 2(PSP),&MPYS32H \ 5
263 MOV @PSP,&OP2L \ 4 load 2nd operand
265 ADD #4,PSP \ 1 remove 2 cells
272 \ F#S Qlo Qhi len -- Qhi 0 convert fractionnal part of Q15.16 fixed point number
275 MOV 2(PSP),X \ -- Qlo Qhi len X = Qlo
276 MOV @PSP,2(PSP) \ -- Qhi Qhi len
277 MOV X,0(PSP) \ -- Qhi Qlo len
280 BEGIN MOV @PSP,&MPY \ Load 1st operand
281 MOV &BASEADR,&OP2 \ Load 2nd operand
282 MOV &RES0,0(PSP) \ -- Qhi RESlo x low result on stack
283 MOV &RES1,TOS \ -- Qhi RESlo REShi high result in TOS
284 CMP #10,TOS \ digit to char
287 MOV.B TOS,HOLDS_ORG(S) \ -- Qhi RESlo char char to string
289 CMP T,S \ count=len ?
290 0= UNTIL MOV T,TOS \ -- len RESlo len
291 MOV #0,0(PSP) \ -- Qhi 0 len
292 MOV #HOLDS_ORG,X \ -- Qhi 0 len X=HOLDS_ORG
293 GOTO BW3 \ 35~ JMP HOLDS+2
297 [THEN] \ end of hardware/software multiplier
299 CODE F/ \ Q15.16 / Q15.16 --> Q15.16 result
300 MOV TOS,Y \ 1 Y=DVRhi
301 MOV @PSP+,W \ 2 W=DVRlo
302 MOV @PSP+,X \ 2 X=DVDhi
303 MOV @PSP,T \ 2 T=DVDlo
304 PUSHM #5,X \ 7 PUSHM DVDhi,DVRhi, M, P, Q
305 AND #-1,Y \ 1 Y=DVRhi < 0 ?
306 S< IF XOR #-1,W \ 1 W=INV(DVRlo)
307 XOR #-1,Y \ 1 Y=INV(DVRhi)
308 ADD #1,W \ 1 W=INV(DVRlo)+1
309 ADDC #0,Y \ 1 Y=INV(DVRhi)+C
311 AND #-1,X \ 1 X=DVDhi < 0 ?
312 S< IF XOR #-1,T \ 1 T=INV(DVDlo)
313 XOR #-1,X \ 1 X=INV(DVDhi)
314 ADD #1,T \ 1 T=INV(DVDlo)+1
315 ADDC #0,X \ 1 X=INV(DVDhi)+C
317 MOV X,M \ 1 DVDhi --> REMlo to adjust Q15.16 division
318 MOV T,X \ 1 DVDlo --> DVDhi
319 MOV #0,T \ 1 0 --> DVDlo
320 \ ------------------------------------------------------------------------
321 \ don't uncomment lines below, don't rub out, please !
322 \ ------------------------------------------------------------------------
323 \ UD/MOD DVDlo DVDhi DVRlo DVRhi -- REMlo REMhi QUOTlo QUOThi
324 \ ------------------------------------------------------------------------
325 \ MOV TOS,Y \ 1 Y=DVRhi
326 \ MOV @PSP+,W \ 2 W=DVRlo
327 \ MOV @PSP+,X \ 2 X=DVDhi
328 \ MOV @PSP,T \ 2 T=DVDlo
329 \ PUSHM #5,X \ 7 PUSHM DVDhi,DVRhi, M, P, Q
330 \ MOV #0,M \ 1 M=REMlo = 0
331 MOV #0,P \ 1 P=REMhi = 0
332 MOV #32,Q \ 2 Q=count
333 BW1 CMP Y,P \ 1 REMhi = DVRhi ?
334 0= IF CMP W,M \ 1 REMlo U< DVRlo ?
336 U>= IF SUB W,M \ 1 no: REMlo - DVRlo (carry is set)
337 SUBC Y,P \ 1 REMhi - DVRhi
339 BEGIN ADDC S,S \ 1 RLC quotLO
340 ADDC TOS,TOS \ 1 RLC quotHI
341 SUB #1,Q \ 1 Decrement loop counter
342 U>= WHILE \ 2 out of loop if count<0
343 ADD T,T \ 1 RLA DVDlo
344 ADDC X,X \ 1 RLC DVDhi
345 ADDC M,M \ 1 RLC REMlo
346 ADDC P,P \ 1 RLC REMhi
347 U< ?GOTO BW1 \ 2 19~ loop
348 SUB W,M \ 1 REMlo - DVRlo
349 SUBC Y,P \ 1 REMhi - DVRhi
352 \ MOV M,T \ 1 T=REMlo
353 \ MOV P,W \ 1 W=REMhi
354 POPM #5,X \ 7 X=DVDhi, Y=DVRhi, system regs M,P,Q restored
355 \ CMP #0,X \ 1 sign of Rem ?
356 \ S< IF XOR #-1,T \ 1 INV(REMlo)
357 \ XOR #-1,W \ 1 INV(REMhi)
358 \ ADD #1,T \ 1 INV(REMlo)+1
359 \ ADDC #0,W \ 1 INV(REMhi)+C
362 \ MOV T,4(PSP) \ REMlo
363 \ MOV W,2(PSP) \ REMhi
364 XOR X,Y \ Y = sign of Quot
365 CMP #0,Y \ sign of Quot ?
366 S< IF XOR #-1,S \ 1 INV(QUOTlo)
367 XOR #-1,TOS \ 1 INV(QUOThi)
368 ADD #1,S \ 1 INV(QUOTlo)+1
369 ADDC #0,TOS \ 1 INV(QUOThi)+C
371 MOV S,0(PSP) \ 3 QUOTlo
376 CODE F. \ display a Q15.16 number with 4/5/16 digits after comma
378 MOV #4,T \ T = 4 preset 4 digits for base 16 and by default
382 ADD #1,T \ T = 5 set 5 digits
386 MOV #$10,T \ T = 16 set 16 digits
389 PUSHM #3,IP \ R-- IP sign #digit
391 <# DABS \ -- uQlo uQhi R-- IP sign #digit
392 R> F#S \ -- uQhi 0 R-- IP sign
393 $2C HOLD \ $2C = char ','
395 R> SIGN #> \ -- addr len R-- IP
399 CODE S>F \ convert a signed number to a Q15.16 (signed) number
408 ; -----------------------
409 ; complement (volatile) for tests below
410 ; -----------------------
413 \ https://forth-standard.org/standard/core/Store
414 \ ! x a-addr -- store cell in memory
422 [UNDEFINED] DOES> [IF]
423 \ https://forth-standard.org/standard/core/DOES
424 \ DOES> -- set action for the latest CREATEd definition
426 MOV &LAST_CFA,W \ W = CFA of CREATEd word
427 MOV #DODOES,0(W) \ replace CFA (DOCON) by new CFA (DODOES)
428 MOV IP,2(W) \ replace PFA by the address after DOES> as execution address
434 [UNDEFINED] CONSTANT [IF]
435 \ https://forth-standard.org/standard/core/CONSTANT
436 \ CONSTANT <name> n -- define a Forth CONSTANT
440 MOV TOS,-2(W) \ PFA = n
447 [UNDEFINED] 2CONSTANT [IF]
448 \ https://forth-standard.org/standard/double/TwoCONSTANT
449 : 2CONSTANT \ udlo/dlo/Qlo udhi/dhi/Qhi -- to create double or Q15.16 CONSTANT
450 CREATE , , \ compile Qhi then Qlo
451 DOES> \ execution part addr -- Qhi Qlo
462 \ https://forth-standard.org/standard/double/Dd
463 \ D. dlo dhi -- display d (signed)
465 MOV #U.,W \ U. + 10 = D.
471 [UNDEFINED] BASE [IF]
472 \ https://forth-standard.org/standard/core/BASE
473 \ BASE -- a-addr holds conversion radix
474 BASEADR CONSTANT BASE
479 ; -----------------------
480 ; (volatile) tests for FIXPOINT.asm|FIXPOINT.f
481 ; -----------------------
484 PI -1,0 F* 2CONSTANT -PI
486 PI D. ; D. is not appropriate -->
487 -PI D. ; D. is not appropriate -->
489 PI F. ; F. is a good choice! --->
490 -PI F. ; F. is a good choice! --->
509 32768,0 1,0 F* F. ; overflow! -->
510 32768,0 1,0 F/ F. ; overflow! -->
511 -32768,0 -1,0 F* F. ; overflow! -->
512 -32768,0 -1,0 F/ F. ; overflow! -->
514 32767,99999 1,0 F* F.
515 32767,99999 1,0 F/ F.
516 32767,99999 2,0 F/ F.
517 32767,99999 4,0 F/ F.
518 32767,99999 8,0 F/ F.
519 32767,99999 16,0 F/ F.
534 ; SQRT(32768)^2 = 32768
535 181,01933598375 181,01933598375 F* F.
536 181,01933598375 -181,01933598375 F* F.
537 -181,01933598375 181,01933598375 F* F.
538 -181,01933598375 -181,01933598375 F* F.