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 #309,TOS \ FastForth V3.9
50 $0D EMIT \ return to column 1 without CR
51 ABORT" FastForth V3.9 please!"
52 ABORT" build FastForth with Q15.16_INPUT addon !"
53 RST_RET \ if no abort remove this word
54 $1B EMIT $63 EMIT \ send 'ESC c' (clear screen)
59 ; -----------------------------------------------------
61 ; -----------------------------------------------------
65 \ https://forth-standard.org/standard/core/Plus
66 \ + n1/u1 n2/u2 -- n3/u3 add n1+n2
75 \ https://forth-standard.org/standard/core/Rfrom
76 \ R> -- x R: x -- pop from return stack ; CALL #RFROM performs DOVAR
87 \ https://forth-standard.org/standard/core/Equal
88 \ = x1 x2 -- flag test x1=x2
97 XOR #-1,TOS \ 1 flag Z = 1
102 \ https://forth-standard.org/standard/core/Uless
103 \ U< u1 u2 -- flag test u1<u2, unsigned
107 SUB @PSP+,TOS \ 2 u2-u1
111 AND #0,TOS \ 1 flag Z = 1
118 \ https://forth-standard.org/standard/double/DABS
119 \ DABS d1 -- |d1| absolute value
123 AND #-1,TOS \ clear V, set N
134 \ https://forth-standard.org/standard/core/HOLDS
135 \ Adds the string represented by addr u to the pictured numeric output string
136 \ compilation use: <# S" string" HOLDS #>
137 \ free chars area in the 32+2 bytes HOLD buffer = {26,23,2} chars with a 32 bits sized {hexa,decimal,binary} number.
138 \ (2 supplementary bytes are room for sign - and decimal point)
143 MOV @PSP+,X \ 2 X=src
144 BW3 ADD TOS,X \ 1 X=src_end
155 MOV @IP+,PC \ 4 15 words
159 CODE F+ \ add Q15.16|double numbers
160 ADD @PSP+,2(PSP) \ -- sumlo d1hi d2hi
161 ADDC @PSP+,TOS \ -- sumlo sumhi
165 CODE F- \ substract Q15.16|double numbers
166 SUB @PSP+,2(PSP) \ -- diflo d1hi d2hi
167 SUBC TOS,0(PSP) \ -- diflo difhi d2hi
172 TLV_ORG 4 + @ $81F3 U<
173 $81EF TLV_ORG 4 + @ U<
174 = [IF] ; MSP430FR413x subfamily without hardware_MPY
176 \ unsigned multiply 32*32 = 64
177 \ don't use S reg (keep sign)
180 PUSHM #4,rDOVAR \ 6 save rDOVAR to rDOCOL regs to use M to R alias
181 MOV 4(PSP),IP \ 3 MDlo
182 MOV 2(PSP),T \ 3 MDhi
186 MOV #0,4(PSP) \ 3 RESlo=0
187 MOV #0,2(PSP) \ 3 REShi=0
190 MOV #1,X \ 1 BIT TEST REGlo
191 MOV #0,Y \ 1 BIT TEST2 REGhi
195 BIT X,W \ 2+1 TEST ACTUAL BIT MRlo
197 BIT Y,TOS \ 2+1 TEST ACTUAL BIT MRhi
200 ADD IP,4(PSP) \ 2+3 IF 1: ADD MDlo TO RESlo
201 ADDC T,2(PSP) \ 3 ADDC MDhi TO REShi
202 ADDC M,Q \ 1 ADDC MDLO TO RESLO
203 ADDC P,R \ 1 ADDC MDHI TO RESHI
205 ADD IP,IP \ 1 (RLA LSBs) MDlo *2
206 ADDC T,T \ 1 (RLC MSBs) MDhi *2
207 ADDC M,M \ 1 (RLC LSBs) MDLO *2
208 ADDC P,P \ 1 (RLC MSBs) MDHI *2
209 ADD X,X \ 1 (RLA) NEXT BIT TO TEST
210 ADDC Y,Y \ 1 (RLC) NEXT BIT TO TEST
212 MOV Q,0(PSP) \ 2+2 IF BIT IN CARRY: FINISHED 32 * 16~ (average loop)
213 MOV R,TOS \ 1 high result in TOS
214 POPM #4,rDOVAR \ 6 restore rDOCOL to rDOVAR
219 CODE F* \ s15.16 * s15.16 --> s15.16 result
221 XOR TOS,S \ 1s15 XOR 2s15 --> S keep sign of result
222 BIT #$8000,2(PSP) \ MD < 0 ?
230 DABS UDM* \ -- RES0 RES1 RES2 RES3
233 MOV @PSP+,TOS \ -- RES0 RES1 RES2
234 MOV @PSP+,0(PSP) \ -- RES1 RES2
235 AND #-1,S \ clear V, set N; process S sign
237 XOR #-1,0(PSP) \ INV(QUOTlo)
238 XOR #-1,TOS \ INV(QUOThi)
239 ADD #1,0(PSP) \ INV(QUOTlo)+1
240 ADDC #0,TOS \ INV(QUOThi)+C
245 \ F#S Qlo Qhi len -- Qhi 0 convert fractional part Qlo of Q15.16 fixed point number
248 MOV @PSP,S \ -- Qlo Qhi len S = Qhi
250 PUSHM #3,IP \ R-- IP Qhi count
251 MOV 2(PSP),0(PSP) \ -- Qlo Qlo len
252 MOV TOS,2(PSP) \ -- len Qlo len
254 MOV &BASEADR,TOS \ -- len Qlo base
256 UM* \ u1 u2 -- RESlo REShi
257 HI2LO \ -- len RESlo digit
258 CMP #10,TOS \ digit to char
262 ADD #$30,TOS \ -- len RESlo char
264 MOV.B TOS,HOLDS_ORG(T) \ char to string_org(T)
267 CMP 2(PSP),T \ -- len RESlo char count=len ?
269 POPM #3,IP \ S=Qhi, T=len
270 MOV T,TOS \ -- len RESlo len
271 MOV S,2(PSP) \ -- Qhi RESlo len
272 MOV #0,0(PSP) \ -- Qhi 0 len
273 MOV #HOLDS_ORG,X \ -- Qhi 0 len X=HOLDS_ORG
274 GOTO BW3 \ 36~ JMP HOLDS
277 [ELSE] ; hardware multiplier
279 CODE F* \ signed s15.16 multiplication --> s15.16 result
280 MOV 4(PSP),&MPYS32L \ 5 Load 1st operand
281 MOV 2(PSP),&MPYS32H \ 5
282 MOV @PSP,&OP2L \ 4 load 2nd operand
284 ADD #4,PSP \ 1 remove 2 cells
291 \ F#S Qlo Qhi len -- Qhi 0 convert fractionnal part of Q15.16 fixed point number
294 MOV 2(PSP),X \ -- Qlo Qhi len X = Qlo
295 MOV @PSP,2(PSP) \ -- Qhi Qhi len
296 MOV X,0(PSP) \ -- Qhi Qlo len
300 MOV @PSP,&MPY \ Load 1st operand
301 MOV &BASEADR,&OP2 \ Load 2nd operand
302 MOV &RES0,0(PSP) \ -- Qhi RESlo x low result on stack
303 MOV &RES1,TOS \ -- Qhi RESlo REShi high result in TOS
304 CMP #10,TOS \ digit to char
309 MOV.B TOS,HOLDS_ORG(S) \ -- Qhi RESlo char char to string
311 CMP T,S \ count=len ?
313 MOV T,TOS \ -- len RESlo len
314 MOV #0,0(PSP) \ -- Qhi 0 len
315 MOV #HOLDS_ORG,X \ -- Qhi 0 len X=HOLDS_ORG
316 GOTO BW3 \ 35~ JMP HOLDS+2
319 [THEN] ; end of hardware/software multiplier
321 CODE F/ \ Q15.16 / Q15.16 --> Q15.16 result
322 MOV TOS,Y \ 1 Y=DVRhi
323 MOV @PSP+,W \ 2 W=DVRlo
324 MOV @PSP+,X \ 2 X=DVDhi
325 MOV @PSP,T \ 2 T=DVDlo
326 PUSHM #5,X \ 7 PUSHM DVDhi,DVRhi, M, P, Q
327 AND #-1,Y \ 1 Y=DVRhi < 0 ?
329 XOR #-1,W \ 1 W=INV(DVRlo)
330 XOR #-1,Y \ 1 Y=INV(DVRhi)
331 ADD #1,W \ 1 W=INV(DVRlo)+1
332 ADDC #0,Y \ 1 Y=INV(DVRhi)+C
334 AND #-1,X \ 1 X=DVDhi < 0 ?
336 XOR #-1,T \ 1 T=INV(DVDlo)
337 XOR #-1,X \ 1 X=INV(DVDhi)
338 ADD #1,T \ 1 T=INV(DVDlo)+1
339 ADDC #0,X \ 1 X=INV(DVDhi)+C
341 MOV X,M \ 1 DVDhi --> REMlo to adjust Q15.16 division
342 MOV T,X \ 1 DVDlo --> DVDhi
343 MOV #0,T \ 1 0 --> DVDlo
344 \ ------------------------------------------------------------------------
345 \ don't uncomment lines below, don't rub out, please !
346 \ ------------------------------------------------------------------------
347 \ UD/MOD DVDlo DVDhi DVRlo DVRhi -- REMlo REMhi QUOTlo QUOThi
348 \ ------------------------------------------------------------------------
349 \ MOV TOS,Y \ 1 Y=DVRhi
350 \ MOV @PSP+,W \ 2 W=DVRlo
351 \ MOV @PSP+,X \ 2 X=DVDhi
352 \ MOV @PSP,T \ 2 T=DVDlo
353 \ PUSHM #5,X \ 7 PUSHM DVDhi,DVRhi, M, P, Q
354 \ MOV #0,M \ 1 M=REMlo = 0
355 MOV #0,P \ 1 P=REMhi = 0
356 MOV #32,Q \ 2 Q=count
357 BW1 CMP Y,P \ 1 REMhi = DVRhi ?
359 CMP W,M \ 1 REMlo U< DVRlo ?
362 SUB W,M \ 1 no: REMlo - DVRlo (carry is set)
363 SUBC Y,P \ 1 REMhi - DVRhi
366 ADDC S,S \ 1 RLC quotLO
367 ADDC TOS,TOS \ 1 RLC quotHI
368 SUB #1,Q \ 1 Decrement loop counter
369 U>= WHILE \ 2 out of loop if count<0
370 ADD T,T \ 1 RLA DVDlo
371 ADDC X,X \ 1 RLC DVDhi
372 ADDC M,M \ 1 RLC REMlo
373 ADDC P,P \ 1 RLC REMhi
374 U< ?GOTO BW1 \ 2 19~ loop
375 SUB W,M \ 1 REMlo - DVRlo
376 SUBC Y,P \ 1 REMhi - DVRhi
379 \ MOV M,T \ 1 T=REMlo
380 \ MOV P,W \ 1 W=REMhi
381 POPM #5,X \ 7 X=DVDhi, Y=DVRhi, system regs M,P,Q restored
382 \ CMP #0,X \ 1 sign of Rem ?
383 \ S< IF XOR #-1,T \ 1 INV(REMlo)
384 \ XOR #-1,W \ 1 INV(REMhi)
385 \ ADD #1,T \ 1 INV(REMlo)+1
386 \ ADDC #0,W \ 1 INV(REMhi)+C
389 \ MOV T,4(PSP) \ REMlo
390 \ MOV W,2(PSP) \ REMhi
391 XOR X,Y \ Y = sign of Quot
392 CMP #0,Y \ sign of Quot ?
394 XOR #-1,S \ 1 INV(QUOTlo)
395 XOR #-1,TOS \ 1 INV(QUOThi)
396 ADD #1,S \ 1 INV(QUOTlo)+1
397 ADDC #0,TOS \ 1 INV(QUOThi)+C
399 MOV S,0(PSP) \ 3 QUOTlo
403 CODE F. \ display a Q15.16 number with 4/5/16 digits after comma
405 MOV #4,T \ T = 4 preset 4 digits for base 16 and by default
409 ADD #1,T \ T = 5 set 5 digits
413 MOV #$10,T \ T = 16 set 16 digits
416 PUSHM #3,IP \ R-- IP sign #digit
418 <# DABS \ -- uQlo uQhi R-- IP sign #digit
419 R> F#S \ -- uQhi 0 R-- IP sign
420 $2C HOLD \ $2C = char ','
422 R> SIGN #> \ -- addr len R-- IP
426 CODE S>F \ convert a signed number to a Q15.16 (signed) number
434 ; -----------------------
435 ; complement (volatile) for tests below
436 ; -----------------------
438 \ https://forth-standard.org/standard/core/Store
439 \ ! x a-addr -- store cell in memory
449 \ https://forth-standard.org/standard/core/DOES
450 \ DOES> -- set action for the latest CREATEd definition
454 MOV &LAST_CFA,W \ W = CFA of CREATEd word
455 MOV #DODOES,0(W) \ replace CFA (DOCON) by new CFA (DODOES)
456 MOV IP,2(W) \ replace PFA by the address after DOES> as execution address
462 \ https://forth-standard.org/standard/core/CONSTANT
463 \ CONSTANT <name> n -- define a Forth CONSTANT
469 MOV TOS,-2(W) \ PFA = n
476 \ https://forth-standard.org/standard/double/TwoCONSTANT
477 [UNDEFINED] 2CONSTANT
479 : 2CONSTANT \ udlo/dlo/Qlo udhi/dhi/Qhi -- to create double or Q15.16 CONSTANT
480 CREATE , , \ compile Qhi then Qlo
481 DOES> \ execution part addr -- Qhi Qlo
491 \ https://forth-standard.org/standard/double/Dd
492 \ D. dlo dhi -- display d (signed)
496 MOV #U.,W \ U. + 10 = D.
502 \ https://forth-standard.org/standard/core/BASE
503 \ BASE -- a-addr holds conversion radix
506 BASEADR CONSTANT BASE
511 ; -----------------------
512 ; (volatile) tests for FIXPOINT.asm|FIXPOINT.f
513 ; -----------------------
516 PI -1,0 F* 2CONSTANT -PI
518 PI D. ; D. is not appropriate -->
519 -PI D. ; D. is not appropriate -->
521 PI F. ; F. is a good choice! --->
522 -PI F. ; F. is a good choice! --->
541 32768,0 1,0 F* F. ; overflow! -->
542 32768,0 1,0 F/ F. ; overflow! -->
543 -32768,0 -1,0 F* F. ; overflow! -->
544 -32768,0 -1,0 F/ F. ; overflow! -->
546 32767,99999 1,0 F* F.
547 32767,99999 1,0 F/ F.
548 32767,99999 2,0 F/ F.
549 32767,99999 4,0 F/ F.
550 32767,99999 8,0 F/ F.
551 32767,99999 16,0 F/ F.
566 ; SQRT(32768)^2 = 32768
567 181,01933598375 181,01933598375 F* F.
568 181,01933598375 -181,01933598375 F* F.
569 -181,01933598375 181,01933598375 F* F.
570 -181,01933598375 -181,01933598375 F* F.