1 \ -*- coding: utf-8 -*-
3 \ displays all FastForth specifications
6 \ FastForth kernel compilation minimal options:
7 \ TERMINAL3WIRES, TERMINAL4WIRES
8 \ MSP430ASSEMBLER, CONDCOMP
10 \ TARGET ( = the name of \INC\target.pat file without extension):
11 \ MSP_EXP430FR5739 MSP_EXP430FR5969 MSP_EXP430FR5994 MSP_EXP430FR6989
12 \ MSP_EXP430FR4133 CHIPSTICK_FR2433 MSP_EXP430FR2433 MSP_EXP430FR2355
15 \ JMJ_BOX_2018_10_29 JMJ_BOX_2022_07_28
17 \ from scite editor : copy your TARGET selection in (shift+F8) parameter 1:
18 \ copy COMPLEMENT if used in (shift+F8) parameter 2:
22 \ from file explorer : drag and drop this file onto SendSourceFileToTarget.bat
23 \ then select your TARGET + COMPLEMENT when asked.
25 ; ---------------------------------
27 ; ---------------------------------
29 \ first, we do some tests allowing the download
33 MOV &VERSION,TOS \ ARG
34 SUB #401,TOS \ FastForth V4.1
36 'CR' EMIT \ return to column 1, no 'LF'
37 ABORT" FastForth V4.1 please!"
38 RST_RET \ remove ABORT_FF_SPECS definition before resuming
41 ABORT_FF_SPECS \ run tests
43 ; ------------------------------------------------------------------
44 ; first we download the set of definitions we need, from CORE_ANS
45 ; ------------------------------------------------------------------
47 [UNDEFINED] DUP [IF] \ define DUP and DUP?
48 \ https://forth-standard.org/standard/core/DUP
49 \ DUP x -- x x duplicate top of stack
51 BW1 SUB #2,PSP \ 2 push old TOS..
52 MOV TOS,0(PSP) \ 3 ..onto stack
56 \ https://forth-standard.org/standard/core/qDUP
57 \ ?DUP x -- 0 | x x DUP if nonzero
59 CMP #0,TOS \ 2 test for TOS nonzero
66 \ https://forth-standard.org/standard/core/OVER
67 \ OVER x1 x2 -- x1 x2 x1
69 MOV TOS,-2(PSP) \ 3 -- x1 (x2) x2
70 MOV @PSP,TOS \ 2 -- x1 (x2) x1
71 SUB #2,PSP \ 1 -- x1 x2 x1
77 \ https://forth-standard.org/standard/core/DROP
78 \ DROP x -- drop top of stack
86 \ https://forth-standard.org/standard/core/SWAP
87 \ SWAP x1 x2 -- x2 x1 swap top two items
97 \ https://forth-standard.org/standard/core/ROT
98 \ ROT x1 x2 x3 -- x2 x3 x1
100 MOV @PSP,W \ 2 fetch x2
101 MOV TOS,0(PSP) \ 3 store x3
102 MOV 2(PSP),TOS \ 3 fetch x1
103 MOV W,2(PSP) \ 3 store x2
109 \ https://forth-standard.org/standard/core/toR
110 \ >R x -- R: -- x push to return stack
119 \ https://forth-standard.org/standard/core/Rfrom
120 \ R> -- x R: x -- pop from return stack ; CALL #RFROM performs DOVAR
130 \ https://forth-standard.org/standard/core/Zeroless
131 \ 0< n -- flag true if TOS negative
133 ADD TOS,TOS \ 1 set carry if TOS negative
134 SUBC TOS,TOS \ 1 TOS=-1 if carry was clear
135 XOR #-1,TOS \ 1 TOS=-1 if carry was set
141 \ https://forth-standard.org/standard/core/Equal
142 \ = x1 x2 -- flag test x1=x2
146 AND #0,TOS \ 1 flag Z = 1
154 [UNDEFINED] U< [IF] \ define U> and U>
155 \ https://forth-standard.org/standard/core/Uless
156 \ U< u1 u2 -- flag test u1<u2, unsigned
158 SUB @PSP+,TOS \ 2 u2-u1
166 \ https://forth-standard.org/standard/core/Umore
170 U< ?GOTO BW1 \ 2 flag = true, Z = 0
171 FW1 AND #0,TOS \ 1 Z = 1
176 [UNDEFINED] IF [IF] \ define IF and THEN
177 \ https://forth-standard.org/standard/core/IF
178 \ IF -- IFadr initialize conditional forward branch
182 MOV &DP,TOS \ -- HERE
183 ADD #4,&DP \ compile one word, reserve one word
184 MOV #QFBRAN,0(TOS) \ -- HERE compile QFBRAN
185 ADD #2,TOS \ -- HERE+2=IFadr
189 \ https://forth-standard.org/standard/core/THEN
190 \ THEN IFadr -- resolve forward branch
192 MOV &DP,0(TOS) \ -- IFadr
198 [UNDEFINED] ELSE [IF]
199 \ https://forth-standard.org/standard/core/ELSE
200 \ ELSE IFadr -- ELSEadr resolve forward IF branch, leave ELSEadr on stack
202 ADD #4,&DP \ make room to compile two words
205 MOV W,0(TOS) \ HERE+4 ==> [IFadr]
207 MOV W,TOS \ -- ELSEadr
212 [UNDEFINED] BEGIN [IF] \ define BEGIN UNTIL AGAIN WHILE REPEAT
214 \ https://forth-standard.org/standard/core/BEGIN
215 \ BEGIN -- BEGINadr initialize backward branch
220 \ https://forth-standard.org/standard/core/UNTIL
221 \ UNTIL BEGINadr -- resolve conditional backward branch
222 CODE UNTIL \ immediate
224 BW1 ADD #4,&DP \ compile two words
226 MOV X,-4(W) \ compile Bran or QFBRAN at HERE
227 MOV TOS,-2(W) \ compile bakcward adr at HERE+2
232 \ https://forth-standard.org/standard/core/AGAIN
233 \ AGAIN BEGINadr -- resolve uncondionnal backward branch
239 \ https://forth-standard.org/standard/core/WHILE
240 \ WHILE BEGINadr -- WHILEadr BEGINadr
245 \ https://forth-standard.org/standard/core/REPEAT
246 \ REPEAT WHILEadr BEGINadr -- resolve WHILE loop
248 POSTPONE AGAIN POSTPONE THEN
252 [UNDEFINED] DO [IF] \ define DO LOOP +LOOP
254 HDNCODE XDO \ DO run time
255 MOV #$8000,X \ 2 compute 8000h-limit = "fudge factor"
257 MOV TOS,Y \ 1 loop ctr = index+fudge
258 ADD X,Y \ 1 Y = INDEX
259 PUSHM #Z,X \ 4 PUSHM X,Y, i.e. PUSHM LIMIT, INDEX
264 \ https://forth-standard.org/standard/core/DO
265 \ DO -- DOadr L: -- 0
269 ADD #2,&DP \ make room to compile xdo
270 MOV &DP,TOS \ -- HERE+2
271 MOV #XDO,-2(TOS) \ compile xdo
272 ADD #2,&LEAVEPTR \ -- HERE+2 LEAVEPTR+2
274 MOV #0,0(W) \ -- HERE+2 L-- 0
278 HDNCODE XLOOP \ LOOP run time
279 ADD #1,0(RSP) \ 4 increment INDEX
280 BW1 BIT #$100,SR \ 2 is overflow bit set?
281 0= IF \ branch if no overflow
285 ADD #4,RSP \ 1 empties RSP
286 ADD #2,IP \ 1 overflow = loop done, skip branch ofs
287 MOV @IP+,PC \ 4 14~ taken or not taken xloop/loop
290 \ https://forth-standard.org/standard/core/LOOP
291 \ LOOP DOadr -- L-- an an-1 .. a1 0
294 BW2 ADD #4,&DP \ make room to compile two words
296 MOV X,-4(W) \ xloop --> HERE
297 MOV TOS,-2(W) \ DOadr --> HERE+2
298 BEGIN \ resolve all "leave" adr
299 MOV &LEAVEPTR,TOS \ -- Adr of top LeaveStack cell
300 SUB #2,&LEAVEPTR \ --
301 MOV @TOS,TOS \ -- first LeaveStack value
302 CMP #0,TOS \ -- = value left by DO ?
304 MOV W,0(TOS) \ move adr after loop as UNLOOP adr
310 HDNCODE XPLOO \ +LOOP run time
311 ADD TOS,0(RSP) \ 4 increment INDEX by TOS value
312 MOV @PSP+,TOS \ 2 get new TOS, doesn't change flags
316 \ https://forth-standard.org/standard/core/PlusLOOP
317 \ +LOOP adrs -- L-- an an-1 .. a1 0
325 \ https://forth-standard.org/standard/core/I
326 \ I -- n R: sys1 sys2 -- sys1 sys2
327 \ get the innermost loop index
329 SUB #2,PSP \ 1 make room in TOS
331 MOV @RSP,TOS \ 2 index = loopctr - fudge
337 [UNDEFINED] HERE [IF]
344 \ https://forth-standard.org/standard/core/CFetch
345 \ C@ c-addr -- char fetch char from memory
352 [UNDEFINED] SPACES [IF]
353 \ https://forth-standard.org/standard/core/SPACES
354 \ SPACES n -- output n spaces
367 MOV @PSP+,TOS \ -- drop n
373 \ https://forth-standard.org/standard/core/OnePlus
374 \ 1+ n1/u1 -- n2/u2 add 1 to TOS
382 \ https://forth-standard.org/standard/core/Plus
383 \ + n1/u1 n2/u2 -- n3/u3 add n1+n2
391 \ https://forth-standard.org/standard/core/Minus
392 \ - n1/u1 n2/u2 -- n3/u3 n3 = n1-n2
394 SUB @PSP+,TOS \ 2 -- n2-n1 ( = -n3)
396 ADD #1,TOS \ 1 -- n3 = -(n2-n1) = n1-n2
402 \ https://forth-standard.org/standard/core/TwoTimes
403 \ 2* x1 -- x2 arithmetic left shift
411 \ https://forth-standard.org/standard/core/TwoDiv
412 \ 2/ x1 -- x2 arithmetic right shift
419 [UNDEFINED] UM/MOD [IF]
420 \ https://forth-standard.org/standard/core/UMDivMOD
421 \ UM/MOD udlo|udhi u1 -- r q unsigned 32/16->r16 q16
424 MOV #MUSMOD,PC \ execute MUSMOD then return to DROP
428 [UNDEFINED] MOVE [IF]
429 \ https://forth-standard.org/standard/core/MOVE
430 \ MOVE addr1 addr2 u -- smart move
431 \ VERSION FOR 1 ADDRESS UNIT = 1 CHAR
434 MOV @PSP+,Y \ Y = addr2 = dst
435 MOV @PSP+,X \ X = addr1 = src
436 MOV @PSP+,TOS \ pop new TOS
437 CMP #0,W \ count = 0 ?
438 0<> IF \ if 0, already done !
439 CMP X,Y \ Y-X \ dst - src
440 0<> IF \ if dst = src, already done !
441 U< IF \ U< if src > dst
448 THEN \ U>= if dst > src
449 ADD W,Y \ copy W bytes beginning with the end
464 \ https://forth-standard.org/standard/core/CR
465 \ CR -- send CR+LF to the output device
467 \ create a primary defered word, i.e. with its default runtime beginning at the >BODY of the definition
468 CODE CR \ part I : DEFERed definition of CR
469 MOV #NEXT_ADR,PC \ [PFA] = NEXT_ADR
472 :NONAME \ part II : :NONAME part as default runtime of CR
474 ; IS CR \ set [PFA] of CR = >BODY addr of CR = CFA of :NONAME part
478 [UNDEFINED] CASE [IF] \ define CASE OF ENDOF ENDCASE
480 \ https://forth-standard.org/standard/core/CASE
483 ; IMMEDIATE \ -- #of-1
485 \ https://forth-standard.org/standard/core/OF
486 : OF \ #of-1 -- orgOF #of
488 >R \ move off the stack in case the control-flow stack is the data stack.
490 POSTPONE = \ copy and test case value
491 POSTPONE IF \ add orig to control flow stack
492 POSTPONE DROP \ discards case value if =
493 R> \ we can bring count back now
496 \ https://forth-standard.org/standard/core/ENDOF
497 : ENDOF \ orgOF #of -- orgENDOF #of
498 >R \ move off the stack in case the control-flow stack is the data stack.
500 R> \ we can bring count back now
503 \ https://forth-standard.org/standard/core/ENDCASE
504 : ENDCASE \ orgENDOF1..orgENDOFn #of --
512 ; --------------------------
513 ; end of definitions we need
514 ; --------------------------
523 [UNDEFINED] S? [IF] \
524 CODE S? \ sep --- to compile: sep S? <string>sep
525 MOV #S"+$0A,PC \ (S" + 10) --> PC
530 CODE ESC \ we can't use
\e which is trapped by TERMINAL !
532 0= IF MOV @IP+,PC \ interpret time usage disallowed
535 'ESC' \ -- char escape
536 POSTPONE LITERAL \ compile-time code : lit 'ESC'
537 POSTPONE EMIT \ compile-time code : EMIT
538 'SP' \ char SPACE as separator for end of string
539 POSTPONE S? \ compile-time code : S?
540 POSTPONE TYPE \ compile-time code : TYPE
544 [DEFINED] FORTH [IF] \ word-set addon ?
545 \ NFA address is always even
546 \ [NFA] = count_of_string + Immediate_flag
547 \ NFA + count_of_string_odd = CFA
548 \ NFA + count_of_string_even + 1 = CFA
549 CODE BODY>SQNFA \ BODY -- NFA(addr cnt) BODY > SQuoteNFA
550 SUB #2,PSP \ -- x BODY
551 SUB #4,TOS \ -- x CFA
555 SUB #2,X \ -- X = CFA-2i = NFA ?
556 MOV X,0(PSP) \ -- CFA-2i x
557 MOV.B @X+,TOS \ -- CFA-2i cnt_test+Imm
558 RRA TOS \ -- CFA-2I cnt_test
561 BIT #1,W \ cnt_test even ?
563 ADD #1,W \ if yes add #1 to cnt_test
565 ADD X,W \ CFA-2i + aligned_cnt_test
566 CMP W,Y \ CFA-2i + aligned_cnt_test = CFA ?
567 0<> WHILE \ out of loop if yes
568 MOV @PSP,X \ loop back to test with CFA-2(i+1)
570 MOV @IP+,PC \ -- addr cnt
574 : SPECS \ to see all FastForth specifications
576 RST_RET \ before computing free bytes, remove all FF_SPECS previous definitions
578 ESC [8;42;80t \ set 42L * 80C terminal display
580 \ title in reverse video
582 ESC [7m \ Turn reverse video on
585 0 <# # 'BS' HOLD # '.' HOLD #S #> TYPE
587 HERE \ HERE - MAIN_ORG = bytes code
588 DEVICEID @ \ value kept in TLV area
591 \ device_ID OF ." xxxx," $MAIN_ORG ENDOF \ <-- add here your device
592 $8102 OF ." 5738," $C200 ENDOF
593 $8103 OF ." 5739," $C200 ENDOF
594 $810D OF ." 5986," $4400 ENDOF
595 $8160 OF ." 5948," $4400 ENDOF
596 $8169 OF ." 5969," $4400 ENDOF
597 $81A8 OF ." 6989," $4400 ENDOF
598 $81F0 OF ." 4133," $C400 ENDOF
599 $8240 OF ." 2433," $C400 ENDOF
600 $825D OF ." 5972," $4400 ENDOF
601 $82A1 OF ." 5994," $4000 ENDOF
602 $830C OF ." 2355," $8000 ENDOF
603 $830D OF ." 2353," $C000 ENDOF
604 $831E OF ." 2155," $8000 ENDOF
605 $831D OF ." 2153," $C000 ENDOF
606 $832A OF ." 2476," $8000 ENDOF
607 $832B OF ." 2475," $8000 ENDOF
608 $833C OF ." 2633," $C400 ENDOF
609 $833D OF ." 2533," $C400 ENDOF
610 ABORT" xxxx <-- unrecognized device!"
611 ENDCASE \ -- HERE MAIN_ORG
613 ['] ['] DUP @ $1284 = \ DOCOL = CALL rDOCOL opcode
614 IF ." =1," DROP \ [CFA] = CALL rDOCOL
616 IF ." =2," \ [CFA] = PUSH IP, [CFA+2] = CALL rDOCOL
617 ELSE ." =3," \ [CFA] = PUSH IP, [CFA+2] = MOV PC,IP
621 THREADS @ U. 'BS' EMIT
622 ." -Entry word set, " \ number of Entry word set,
623 FREQ_KHZ @ 0 1000 UM/MOD U. \ frequency
624 ?DUP IF 'BS' EMIT ',' EMIT U. \ if remainder
625 THEN ." MHz, " \ MCLK
626 - U. ." bytes" \ HERE - MAIN_ORG = number of bytes code,
627 ESC [0m \ Turn off character attributes
632 ." /COUNTED-STRING = 255" CR
635 ." ADDRESS-UNIT-BITS = 16" CR
636 ." FLOORED DIVISION = "
637 [DEFINED] SM/REM [IF] ." false" [THEN]
638 [DEFINED] FM/MOD [IF] ." true" [THEN]
640 ." MAX-CHAR = 255" CR
643 ." MAX-D = 2147483647" CR
644 ." MAX-UD = 4294967295" CR
645 ." STACK-CELLS = 48" CR
646 ." RETURN-STACK-CELLS= 48" CR
647 ." Definitions are forced UPPERCASE" CR
648 \ ." BACKGROUND, COLD, WARM, ABORT customizable" CR
649 \ ." automatic garbage collector" CR
652 CR ESC [7m ." KERNEL add-ons" ESC [0m CR \ subtitle in reverse video
654 2*DUP 0< IF ." 32.768kHz LF XTAL" CR THEN \ BIT14
655 2*DUP 0< IF ." /CTS " THEN \ BIT13
656 2*DUP 0< IF ." /RTS " THEN \ BIT12
657 2*DUP 0< IF ." XON/XOFF " THEN \ BIT11
658 2*DUP 0< IF ." Half-Duplex " THEN \ BIT10
659 2*DUP 0< IF ." I2C_Master TERMINAL" \ BIT9
660 ELSE ." UART TERMINAL" \ /BIT9
663 0< IF ." DOUBLE and " \ BIT8 + BIT7
664 THEN ." Q15.16 numbers handling" CR
666 0< IF ." DOUBLE numbers handling" CR \ /BIT8 + BIT7
669 2*DUP 0< IF ." MSP430 16/20bits" \ BIT6 BIT5
670 ELSE 2*DUP ." MSP430 16bits" \ /BIT6
671 0< IF ." (20bits addr)" \ BIT5
673 THEN ." assembler, with TI's syntax" CR
675 [DEFINED] FORTH [IF] ." word-set management" CR
677 [DEFINED] LOAD" [IF] ." SD_CARD Load + Bootloader" CR
679 [DEFINED] READ" [IF] ." SD_CARD Read/Write/Del/CopyTERM2SD" CR
683 CR ESC [7m ." EXTENSIONS" ESC [0m \ subtitle in reverse video
684 [DEFINED] {CORE_ANS} [IF] CR ." CORE ANS94 'CORETEST passed'"
686 [DEFINED] {DOUBLE} [IF] CR ." DOUBLE numbers set"
688 [DEFINED] {UTILITY} [IF] CR ." UTILITY"
690 [DEFINED] {FIXPOINT} [IF] CR ." Q15.16 ADD SUB MUL DIV"
692 [DEFINED] {CORDIC} [IF] CR ." CORDIC engine"
694 [DEFINED] {SD_TOOLS} [IF] CR ." SD_TOOLS"
696 [DEFINED] {RTC} [IF] CR ." RTC utility"
698 [DEFINED] {UARTI2CS} [IF] CR ." UART to I2C_FastForth bridge"
703 \ ------------------------------------\
704 LASTVOC \ -- VOCLINK addr.
706 @ ?DUP \ -- VOCLINK word-set here ?
708 \ --------------------------------\
709 ESC [7m \ word-set TITLE in reverse video
710 DUP THREADS @ 2* - \ -- VLK WORDSET_BODY
711 [DEFINED] FORTH \ word-set addon ?
712 [IF] DUP BODY>SQNFA \ -- VLK WRDST_BODY addr cnt
713 [ELSE] OVER @ \ -- VLK WRDST_BODY NEXT_VLINK
714 IF S" hidden" \ if next_vlink <>0
715 ELSE S" FORTH" \ if next_vlink = 0
716 THEN \ -- VLK WRDST_BODY addr cnt
717 [THEN] TYPE \ type word-set name
718 ." word-set" \ -- VLK WRDST_BODY
720 \ --------------------------------\
722 \ --------------------------------\
724 \ CONTEXT @ \ -- VOC_BODY
725 PAD_ORG \ -- VOC_BODY PAD MOVE all threads from VOC_BODY to PAD_ORG
726 THREADS @ 2* \ -- VOC_BODY PAD THREADS*2
727 MOVE \ -- vocabulary entries are copied in PAD_ORG
729 0 DUP \ -- ptr=0 MAX=0
730 THREADS @ 2* 0 \ -- ptr=0 MAX=0 THREADS*2 0
731 DO \ -- ptr MAX I = PAD_ptr = thread*2
732 DUP I PAD_ORG + @ \ -- ptr MAX MAX NFAx
733 U< IF \ -- ptr MAX if MAX U< NFAx
734 DROP DROP I \ -- drop ptr and MAX
735 DUP PAD_ORG + @ \ -- new_ptr new_MAX
738 ?DUP \ -- ptr MAX MAX | -- ptr 0 (all threads in PAD = 0)
739 WHILE \ -- ptr MAX replace it by its LFA
741 2 - @ \ -- ptr MAX [LFA]
742 ROT \ -- MAX [LFA] ptr
743 PAD_ORG + \ -- MAX [LFA] thread
744 ! \ -- MAX MAX=highest_NFA [LFA]=new_NFA updates PAD_ORG+ptr
745 COUNT 2/ \ -- addr name_count 2/ to hide Immediate flag
746 DUP >R TYPE \ -- R-- count
747 $10 R> - SPACES \ -- R-- complete with spaces modulo 16 chars
750 \ ; \ all threads in PAD are filled with 0
751 \ --------------------------------\
752 CR \ -- VLINK definitions display
754 \ ------------------------------------\ --
758 SPECS \ performs RST_RET and displays FastForth specs