1 \ -*- coding: utf-8 -*-
3 \ to see kernel options, download FastForthSpecs.f
4 \ FastForth kernel options: MSP430ASSEMBLER, CONDCOMP
6 \ TARGET SELECTION ( = the name of \INC\target.pat file without the extension)
7 \ MSP_EXP430FR5739 MSP_EXP430FR5969 MSP_EXP430FR5994 MSP_EXP430FR6989
8 \ MSP_EXP430FR4133 MSP_EXP430FR2433 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 \ R4 to R7 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 : R15,R14,R13,R12,R11,R10, R9, R8, R7 , R6 , R5 , R4 , R3, R2, R1, R0
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 : R0, R1, R2, R3, R4 , R5 , R6 , R7 , R8, R9,R10,R11,R12,R13,R14,R15
32 \ example : POPM #6,IP pop Y,X,W,T,S,IP registers from return stack
35 \ FORTH conditionnals: unary{ 0= 0< 0> }, binary{ = < > U< }
37 \ ASSEMBLER conditionnal usage with IF UNTIL WHILE S< S>= U< U>= 0= 0<> 0>=
38 \ ASSEMBLER conditionnal usage with ?JMP ?GOTO S< S>= U< U>= 0= 0<> 0<
40 ; --------------------------------
42 ; --------------------------------
44 \ first, we do some tests allowing the download
49 SUB #401,TOS \ FastForth V4.1
51 'CR' EMIT \ return to column 1 without 'LF'
52 ABORT" FastForth V4.1 please!"
53 RST_RET \ remove ABORT_UTILITY definition before resuming
65 ; ------------------------------------------------------------------
66 ; first we download the set of definitions we need (from CORE_ANS.f)
67 ; ------------------------------------------------------------------
70 \ https://forth-standard.org/standard/core/EXIT
71 \ EXIT -- exit a colon definition; CALL #EXIT performs ASMtoFORTH (10 cycles)
72 \ JMP #EXIT performs EXIT
74 MOV @RSP+,IP \ 2 pop previous IP (or next PC) from return stack
75 MOV @IP+,PC \ 4 = NEXT
81 \ https://forth-standard.org/standard/core/SWAP
82 \ SWAP x1 x2 -- x2 x1 swap top two items
92 \ https://forth-standard.org/standard/core/Uless
93 \ U< u1 u2 -- flag test u1<u2, unsigned
95 SUB @PSP+,TOS \ 2 u2-u1
99 AND #0,TOS \ 1 flag Z = 1
106 [UNDEFINED] IF [IF] \ define IF and THEN
107 \ https://forth-standard.org/standard/core/IF
108 \ IF -- IFadr initialize conditional forward branch
112 MOV &DP,TOS \ -- HERE
113 ADD #4,&DP \ compile one word, reserve one word
114 MOV #QFBRAN,0(TOS) \ -- HERE compile QFBRAN
115 ADD #2,TOS \ -- HERE+2=IFadr
119 \ https://forth-standard.org/standard/core/THEN
120 \ THEN IFadr -- resolve forward branch
121 CODE THEN \ immediate
122 MOV &DP,0(TOS) \ -- IFadr
128 [UNDEFINED] BEGIN [IF] \ define BEGIN UNTIL AGAIN WHILE REPEAT
129 \ https://forth-standard.org/standard/core/BEGIN
130 \ BEGIN -- BEGINadr initialize backward branch
135 \ https://forth-standard.org/standard/core/UNTIL
136 \ UNTIL BEGINadr -- resolve conditional backward branch
137 CODE UNTIL \ immediate
139 BW1 ADD #4,&DP \ compile two words
141 MOV X,-4(W) \ compile Bran or QFBRAN at HERE
142 MOV TOS,-2(W) \ compile bakcward adr at HERE+2
147 \ https://forth-standard.org/standard/core/AGAIN
148 \ AGAIN BEGINadr -- resolve uncondionnal backward branch
149 CODE AGAIN \ immediate
154 \ https://forth-standard.org/standard/core/WHILE
155 \ WHILE BEGINadr -- WHILEadr BEGINadr
160 \ https://forth-standard.org/standard/core/REPEAT
161 \ REPEAT WHILEadr BEGINadr -- resolve WHILE loop
163 POSTPONE AGAIN POSTPONE THEN
167 [UNDEFINED] DO [IF] \ define DO LOOP +LOOP
169 HDNCODE XDO \ DO run time
170 MOV #$8000,X \ 2 compute 8000h-limit = "fudge factor"
172 MOV TOS,Y \ 1 loop ctr = index+fudge
173 ADD X,Y \ 1 Y = INDEX
174 PUSHM #2,X \ 4 PUSHM X,Y, i.e. PUSHM LIMIT, INDEX
179 \ https://forth-standard.org/standard/core/DO
180 \ DO -- DOadr L: -- 0
184 ADD #2,&DP \ make room to compile xdo
185 MOV &DP,TOS \ -- HERE+2
186 MOV #XDO,-2(TOS) \ compile xdo
187 ADD #2,&LEAVEPTR \ -- HERE+2 LEAVEPTR+2
189 MOV #0,0(W) \ -- HERE+2 L-- 0
193 HDNCODE XLOOP \ LOOP run time
194 ADD #1,0(RSP) \ 4 increment INDEX
195 BW1 BIT #$100,SR \ 2 is overflow bit set?
196 0= IF \ branch if no overflow
200 ADD #4,RSP \ 1 empties RSP
201 ADD #2,IP \ 1 overflow = loop done, skip branch ofs
202 MOV @IP+,PC \ 4 14~ taken or not taken xloop/loop
205 \ https://forth-standard.org/standard/core/LOOP
206 \ LOOP DOadr -- L-- an an-1 .. a1 0
209 BW2 ADD #4,&DP \ make room to compile two words
211 MOV X,-4(W) \ xloop --> HERE
212 MOV TOS,-2(W) \ DOadr --> HERE+2
213 BEGIN \ resolve all "leave" adr
214 MOV &LEAVEPTR,TOS \ -- Adr of top LeaveStack cell
215 SUB #2,&LEAVEPTR \ --
216 MOV @TOS,TOS \ -- first LeaveStack value
217 CMP #0,TOS \ -- = value left by DO ?
219 MOV W,0(TOS) \ move adr after loop as UNLOOP adr
225 HDNCODE XPLOO \ +LOOP run time
226 ADD TOS,0(RSP) \ 4 increment INDEX by TOS value
227 MOV @PSP+,TOS \ 2 get new TOS, doesn't change flags
231 \ https://forth-standard.org/standard/core/PlusLOOP
232 \ +LOOP adrs -- L-- an an-1 .. a1 0
240 \ https://forth-standard.org/standard/core/I
241 \ I -- n R: sys1 sys2 -- sys1 sys2
242 \ get the innermost loop index
244 SUB #2,PSP \ 1 make room in TOS
246 MOV @RSP,TOS \ 2 index = loopctr - fudge
252 [UNDEFINED] DUP [IF] \ define DUP and ?DUP
253 \ https://forth-standard.org/standard/core/DUP
254 \ DUP x -- x x duplicate top of stack
256 BW1 SUB #2,PSP \ 2 push old TOS..
257 MOV TOS,0(PSP) \ 3 ..onto stack
261 \ https://forth-standard.org/standard/core/qDUP
262 \ ?DUP x -- 0 | x x DUP if nonzero
264 CMP #0,TOS \ 2 test for TOS nonzero
270 [UNDEFINED] DROP [IF]
271 \ https://forth-standard.org/standard/core/DROP
272 \ DROP x -- drop top of stack
280 \ https://forth-standard.org/standard/core/toR
281 \ >R x -- R: -- x push to return stack
290 \ https://forth-standard.org/standard/core/Rfrom
291 \ R> -- x R: x -- pop from return stack ; CALL #RFROM performs DOVAR
300 [UNDEFINED] SPACE [IF]
301 \ https://forth-standard.org/standard/core/SPACE
302 \ SPACE -- output a space
307 [UNDEFINED] SPACES [IF]
308 \ https://forth-standard.org/standard/core/SPACES
309 \ SPACES n -- output n spaces
323 MOV @PSP+,TOS \ -- drop n
328 [UNDEFINED] 2DUP [IF]
329 \ https://forth-standard.org/standard/core/TwoDUP
330 \ 2DUP x1 x2 -- x1 x2 x1 x2 dup top 2 cells
340 \ https://forth-standard.org/standard/core/OnePlus
341 \ 1+ n1/u1 -- n2/u2 add 1 to TOS
349 \ https://forth-standard.org/standard/core/Plus
350 \ + n1/u1 n2/u2 -- n3/u3 add n1+n2
358 \ https://forth-standard.org/standard/core/Minus
359 \ - n1/u1 n2/u2 -- n3/u3 n3 = n1-n2
361 SUB @PSP+,TOS \ 2 -- n2-n1
363 ADD #1,TOS \ 1 -- n3 = -(n2-n1) = n1-n2
369 \ https://forth-standard.org/standard/core/CFetch
370 \ C@ c-addr -- char fetch char from memory
378 \ https://forth-standard.org/standard/core/ROT
379 \ ROT x1 x2 x3 -- x2 x3 x1
381 MOV @PSP,W \ 2 fetch x2
382 MOV TOS,0(PSP) \ 3 store x3
383 MOV 2(PSP),TOS \ 3 fetch x1
384 MOV W,2(PSP) \ 3 store x2
389 [UNDEFINED] MAX [IF] \ define MAX and MIN
390 CODE MAX \ n1 n2 -- n3 signed maximum
397 CODE MIN \ n1 n2 -- n3 signed minimum
405 [UNDEFINED] OVER [IF]
406 \ https://forth-standard.org/standard/core/OVER
407 \ OVER x1 x2 -- x1 x2 x1
409 MOV TOS,-2(PSP) \ 3 -- x1 (x2) x2
410 MOV @PSP,TOS \ 2 -- x1 (x2) x1
411 SUB #2,PSP \ 1 -- x1 x2 x1
416 [UNDEFINED] MOVE [IF]
417 \ https://forth-standard.org/standard/core/MOVE
418 \ MOVE addr1 addr2 u -- smart move
419 \ VERSION FOR 1 ADDRESS UNIT = 1 CHAR
422 MOV @PSP+,Y \ Y = addr2 = dst
423 MOV @PSP+,X \ X = addr1 = src
424 MOV @PSP+,TOS \ pop new TOS
425 CMP #0,W \ count = 0 ?
426 0<> IF \ if 0, already done !
427 CMP X,Y \ Y-X \ dst - src
428 0= ?GOTO FW1 \ already done !
429 U< IF \ U< if src > dst
436 ELSE \ U>= if dst > src
437 ADD W,Y \ copy W bytes beginning with the end
452 \ https://forth-standard.org/standard/core/CR
453 \ CR -- send CR+LF to the output device
454 CODE CR \ create a DEFER definition of CR
464 \ https://forth-standard.org/standard/core/TwoTimes
465 \ 2* x1 -- x2 arithmetic left shift
473 \ https://forth-standard.org/standard/core/TwoDiv
474 \ 2/ x1 -- x2 arithmetic right shift
481 [UNDEFINED] CONSTANT [IF]
482 \ https://forth-standard.org/standard/core/CONSTANT
483 \ CONSTANT <name> n -- define a Forth CONSTANT
487 MOV TOS,-2(W) \ PFA = n
494 [UNDEFINED] BASE [IF]
495 \ https://forth-standard.org/standard/core/BASE
496 \ BASE -- a-addr holds conversion radix
497 BASEADR CONSTANT BASE
500 [UNDEFINED] HERE [IF]
501 \ https://forth-standard.org/standard/core/HERE
502 \ HERE -- addr addr is the data-space pointer.
504 MOV #BEGIN,PC \ execute ASM BEGIN
508 ; --------------------------
509 ; end of definitions we need
510 ; --------------------------
513 \ https://forth-standard.org/standard/tools/DotS
514 \ .S TOS -- TOS display <depth> of param Stack and stack contents in hexadecimal if not empty
516 MOV TOS,-2(PSP) \ -- TOS ( TOS x x )
517 MOV PSP,TOS \ -- PSP ( TOS x x )
518 SUB #2,TOS \ -- PSP ( TOS x x ) to take count that TOS is first cell
519 MOV TOS,-6(PSP) \ -- TOS ( TOS x PSP )
520 MOV #PSTACK,TOS \ -- P0 ( TOS x PSP )
521 SUB #2,TOS \ -- P0 ( TOS x PSP ) to take count that TOS is first cell
522 BW1 MOV TOS,-4(PSP) \ -- S0 ( TOS S0 PSP ) | -- TOS ( TOS R0 RSP )
523 SUB #6,PSP \ -- TOS S0 PSP S0 | -- TOS R0 RSP R0
524 SUB @PSP,TOS \ -- TOS S0 PSP S0-SP | -- TOS R0 RSP R0-RSP
525 RRA TOS \ -- TOS S0 PSP #cells | -- TOS R0 RSP #cells
530 $3E EMIT SPACE \ char '>' SPACE
534 THEN \ display content of stack in hexadecimal
535 BASE @ >R \ base_address @ >R
546 \ .RS TOS -- TOS display <depth> of Return Stack and stack contents if not empty
548 MOV TOS,-2(PSP) \ -- TOS ( TOS x x )
549 MOV RSP,-6(PSP) \ -- TOS ( TOS x RSP )
550 MOV #RSTACK,TOS \ -- R0 ( TOS x RSP )
556 \ https://forth-standard.org/standard/tools/q
557 \ ? adr -- display the content of adr
564 [UNDEFINED] WORDS [IF]
565 \ https://forth-standard.org/standard/tools/WORDS
566 \ list all words of vocabulary first in CONTEXT.
569 CONTEXT @ \ -- VOC_BODY
570 PAD_ORG \ -- VOC_BODY PAD_ORG MOVE all threads of VOC_BODY in PAD_ORG
571 THREADS @ 2* \ -- VOC_BODY PAD_ORG THREAD*2
572 MOVE \ -- vocabumary entries are copied in PAD_ORG
574 0 DUP \ -- ptr=0 MAX=0
575 THREADS @ 2* 0 \ -- ptr=0 MAX=0 THREADS*2 0
576 DO \ -- ptr MAX I = PAD_ptr = thread*2
577 DUP I PAD_ORG + @ \ -- ptr MAX MAX NFAx
578 U< IF \ -- ptr MAX if MAX U< NFAx
579 DROP DROP \ -- drop ptr and MAX
581 PAD_ORG + @ \ -- new_ptr new_MAX
584 ?DUP \ -- ptr MAX MAX | -- ptr 0 (all threads in PAD_ORG = 0)
585 WHILE \ -- ptr MAX replace it by its LFA
587 2 - @ \ -- ptr MAX [LFA]
588 ROT \ -- MAX [LFA] ptr
589 PAD_ORG + \ -- MAX [LFA] thread
590 ! \ -- MAX MAX=highest_NFA [LFA]=new_NFA updates PAD_ORG+ptr
591 COUNT 2/ \ -- addr count 2/ to hide Immediate flag
592 DUP >R TYPE \ -- R-- count
593 R> $10 SWAP - SPACES \ -- R-- complete with spaces modulo 16 chars
596 ; \ all threads in PAD_ORG are filled with 0
601 : U.R \ u n -- display u unsigned in n width (n >= 2)
603 R> OVER - 0 MAX SPACES TYPE
607 [UNDEFINED] DUMP [IF]
608 \ https://forth-standard.org/standard/tools/DUMP
609 CODE DUMP \ adr n -- dump memory
611 PUSH &BASEADR \ save current base
612 MOV #$10,&BASEADR \ HEX base
613 ADD @PSP,TOS \ -- ORG END
617 4 SPACES $10 0 DO I 3 U.R LOOP
618 DO CR \ generate line
619 I 4 U.R \ generate address
623 I $10 + I \ display 16 chars
624 DO I C@ $7E MIN $20 MAX EMIT LOOP
626 R> BASE ! \ restore current base
628 [THEN] \ endof [UNDEFINED] DUMP
632 [THEN] \ endof [UNDEFINED] {UTILITY}