1 \ -*- coding: utf-8 -*-
3 ; -----------------------------------------------------------------------
5 ; -----------------------------------------------------------------------
8 \ MSP_EXP430FR5739 MSP_EXP430FR5969 MSP_EXP430FR5994 MSP_EXP430FR6989
9 \ MSP_EXP430FR4133 MSP_EXP430FR2433 MSP_EXP430FR2355 CHIPSTICK_FR2433
11 \ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, rEXIT,rDOVAR,rDOCON, rDODOES, R3, SR,RSP, PC
12 \ PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8, R7 , R6 , R5 , R4 , R3, R2, R1, R0
14 \ example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
16 \ POPM order : PC,RSP, SR, R3, rDODOES,rDOCON,rDOVAR,rEXIT, Y, X, W, T, S, IP,TOS,PSP
17 \ POPM order : R0, R1, R2, R3, R4 , R5 , R6 , R7 , R8, R9,R10,R11,R12,R13,R14,R15
19 \ example : POPM #6,IP pop Y,X,W,T,S,IP registers from return stack
21 \ ASSEMBLER conditionnal usage after IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
22 \ ASSEMBLER conditionnal usage before ?JMP ?GOTO : S< S>= U< U>= 0= 0<> 0<
24 \ FORTH conditionnal : 0= 0< = < > U<
27 \ https://forth-standard.org/standard/core/toR
28 \ >R x -- R: -- x push to return stack
37 \ https://forth-standard.org/standard/core/Rfrom
38 \ R> -- x R: x -- pop from return stack ; CALL #RFROM performs DOVAR
45 \ https://forth-standard.org/standard/core/Plus
46 \ + n1/u1 n2/u2 -- n3/u3 add n1+n2
54 \ https://forth-standard.org/standard/core/Minus
55 \ - n1/u1 n2/u2 -- n3/u3 n3 = n1-n2
57 SUB @PSP+,TOS \ 2 -- n2-n1 ( = -n3)
59 ADD #1,TOS \ 1 -- n3 = -(n2-n1) = n1-n2
65 \ https://forth-standard.org/standard/core/SWAP
66 \ SWAP x1 x2 -- x2 x1 swap top two items
75 [UNDEFINED] MAX [IF] \ MAX and MIN are defined in {UTILITY}
77 CODE MAX \ n1 n2 -- n3 signed maximum
84 CODE MIN \ n1 n2 -- n3 signed minimum
94 \ https://forth-standard.org/standard/core/Fetch
95 \ @ c-addr -- char fetch char from memory
103 \ https://forth-standard.org/standard/core/Store
104 \ ! x a-addr -- store cell in memory
113 \ https://forth-standard.org/standard/core/CFetch
114 \ C@ c-addr -- char fetch char from memory
121 [UNDEFINED] VARIABLE [IF]
122 \ https://forth-standard.org/standard/core/VARIABLE
123 \ VARIABLE <name> -- define a Forth VARIABLE
127 MOV #DOVAR,-4(W) \ CFA = DOVAR
133 [UNDEFINED] CONSTANT [IF]
134 \ https://forth-standard.org/standard/core/CONSTANT
135 \ CONSTANT <name> n -- define a Forth CONSTANT
139 MOV TOS,-2(W) \ PFA = n
146 [UNDEFINED] DEFER [IF]
147 \ https://forth-standard.org/standard/core/DEFER
148 \ DEFER "<spaces>name" --
149 \Skip leading space delimiters. Parse name delimited by a space.
150 \Create a definition for name with the execution semantics defined below.
153 \Execute the xt that name is set to execute, i.e. NEXT (nothing),
154 \until the phrase ' word IS name is executed, causing a new value of xt to be assigned to name.
158 MOV #$4030,-4(W) \ CFA = MOV @PC+,PC = BR MOV @IP+,PC
159 MOV #NEXT_ADR,-2(W) \ PFA = address of MOV @IP+,PC to do nothing.
165 [UNDEFINED] >BODY [IF]
166 \ https://forth-standard.org/standard/core/toBODY
167 \ >BODY -- addr leave BODY of a CREATEd word\ also leave default ACTION-OF primary DEFERred word
174 [UNDEFINED] SPACE [IF]
175 \ https://forth-standard.org/standard/core/SPACE
176 \ SPACE -- output a space
181 [UNDEFINED] SPACES [IF]
182 \ https://forth-standard.org/standard/core/SPACES
183 \ SPACES n -- output n spaces
197 MOV @PSP+,TOS \ -- drop n
203 \ https://forth-standard.org/standard/core/DUP
204 \ DUP x -- x x duplicate top of stack
206 BW1 SUB #2,PSP \ 2 push old TOS..
207 MOV TOS,0(PSP) \ 3 ..onto stack
212 [UNDEFINED] OVER [IF]
213 \ https://forth-standard.org/standard/core/OVER
214 \ OVER x1 x2 -- x1 x2 x1
216 MOV TOS,-2(PSP) \ 3 -- x1 (x2) x2
217 MOV @PSP,TOS \ 2 -- x1 (x2) x1
218 SUB #2,PSP \ 1 -- x1 x2 x1
223 [UNDEFINED] U.R [IF] \ defined in {UTILITY}
224 : U.R \ u n -- display u unsigned in n width (n >= 2)
226 R> OVER - 0 MAX SPACES TYPE
231 \ https://forth-standard.org/standard/core/DO
232 \ DO -- DOadr L: -- 0
236 ADD #2,&DP \ make room to compile xdo
237 MOV &DP,TOS \ -- HERE+2
238 MOV #XDO,-2(TOS) \ compile xdo
239 ADD #2,&LEAVEPTR \ -- HERE+2 LEAVEPTR+2
241 MOV #0,0(W) \ -- HERE+2 L-- 0
246 [UNDEFINED] LOOP [IF]
247 \ https://forth-standard.org/standard/core/LOOP
248 \ LOOP DOadr -- L-- an an-1 .. a1 0
249 CODE LOOP \ immediate
251 BW1 ADD #4,&DP \ make room to compile two words
253 MOV X,-4(W) \ xloop --> HERE
254 MOV TOS,-2(W) \ DOadr --> HERE+2
255 BEGIN \ resolve all "leave" adr
256 MOV &LEAVEPTR,TOS \ -- Adr of top LeaveStack cell
257 SUB #2,&LEAVEPTR \ --
258 MOV @TOS,TOS \ -- first LeaveStack value
259 CMP #0,TOS \ -- = value left by DO ?
261 MOV W,0(TOS) \ move adr after loop as UNLOOP adr
268 [UNDEFINED] +LOOP [IF]
269 \ https://forth-standard.org/standard/core/PlusLOOP
270 \ +LOOP adrs -- L-- an an-1 .. a1 0
271 CODE +LOOP \ immediate
278 \ https://forth-standard.org/standard/core/I
279 \ I -- n R: sys1 sys2 -- sys1 sys2
280 \ get the innermost loop index
282 SUB #2,PSP \ 1 make room in TOS
284 MOV @RSP,TOS \ 2 index = loopctr - fudge
290 [UNDEFINED] DUMP [IF] \ defined in {UTILITY}
291 \ https://forth-standard.org/standard/tools/DUMP
292 CODE DUMP \ adr n -- dump memory
294 PUSH &BASEADR \ save current base
295 MOV #$10,&BASEADR \ HEX base
296 ADD @PSP,TOS \ -- ORG END
299 DO CR \ generate line
300 I 4 U.R SPACE \ generate address
307 I $10 + I \ display 16 chars
308 DO I C@ $7E MIN $20 MAX EMIT LOOP
310 R> BASEADR ! \ restore current base
314 \ -----------------------------------------------------------------------
315 \ test CPUx instructions PUSHM, POPM, RLAM, RRAM, RRCM, RRUM
316 \ -----------------------------------------------------------------------
319 \ PUSHM #16,R14 \ uncomment to test error "out of bounds"
320 \ PUSHM #2,R0 \ uncomment to test error "out of bounds"
321 \ PUSHM #0,IP \ uncomment to test error "out of bounds"
322 \ POPM #17,R15 \ uncomment to test error "out of bounds"
323 \ POPM #2,R0 \ uncomment to test error "out of bounds"
324 \ POPM #0,IP \ uncomment to test error "out of bounds"
331 PUSHM #4,IP \ PUSHM IP,S,T,W
332 POPM #4,IP \ POPM W,T,S,IP
334 MOV TOS,8(PSP) \ save old TOS
340 \ RLAM #0,TOS \ uncomment to test error "out of bounds"
341 \ RLAM #5,TOS \ uncomment to test error "out of bounds"
342 RRAM #1,TOS \ 0 < shift value < 5
346 COLON \ high level part of the word starts here...
348 ; \ and finishes here.
350 TESTPUSHM ; you should see 11111 3 2 1 0 -->
353 GOTO BW1 \ JMP TESTPUSHM
357 TESTPOPM ; you should see 11111 3 2 1 0 -->
361 \ -----------------------------------------------------------------------
362 \ test symbolic branch in assembler
363 \ test a FORTH section encapsulated in an assembly word
364 \ -----------------------------------------------------------------------
365 CODE TEST1 \ the word "CODE" add ASSEMBLER as CONTEXT vocabulary...
367 MOV &BASEADR,&BASEADR \ to test &xxxx src operand
369 0<> IF MOV #2,&BASEADR \ if base <> 2
370 ELSE MOV #$0A,&BASEADR \ else base = 2
372 COLON \ tips : no "ok" displayed in start of line <==> compilation mode
373 BASEADR @ U. \ always display 10 !
377 \ -----------------------------------------------------------------------
378 \ test a word that starts as word FORTH and ends as assembly word
379 \ -----------------------------------------------------------------------
380 : TEST2 \ ":" starts compilation
381 BASEADR @ U. \ always display 10 !
382 HI2LO \ switch FORTH to ASM : compile one word (next address)
383 \ add vocabulary ASSEMBLER as CONTEXT vocabulary
384 \ switch in interpret mode
386 0<> IF MOV #2, &BASEADR \ if variable system BASE <> 2
387 ELSE MOV #10,&BASEADR \ else (BASE = 2)
389 \ MOV #EXIT,PC \ to pair with ":" i.e. to restore IP saved by : then execute NEXT.
390 \ but even compile two words, it's better to compile an inline EXIT :
391 MOV @RSP+,IP \ restore IP
393 ENDCODE \ ends assembler : remove vocabulary ASSEMBLER from CONTEXT
396 \ -----------------------------------------------------------------------
397 \ test a word that starts as assembly word and ends as FORTH word
398 \ -----------------------------------------------------------------------
399 CODE TEST3 \ "CODE" starts assembler, i.e. add ASSEMBLER as CONTEXT vocabulary
401 0<> IF MOV #2, &BASEADR \ if variable system BASE <> 2
402 ELSE MOV #10,&BASEADR \ else (BASE = 2)
404 BASEADR @ U. \ always display 10 !
409 \ -----------------------------------------------------------------------
410 \ test an assembly jump spanning a section written in FORTH
411 \ -----------------------------------------------------------------------
417 MOV #%1010,TOS \ init count = 10
420 \ IP is already saved by word ":"
421 DUP U. \ display count
424 0= UNTIL MOV @PSP+,TOS
425 \ MOV #EXIT,PC \ to pair with ":" i.e. to restore IP saved by : then execute NEXT.
426 MOV @RSP+,IP \ restore IP
430 TEST5 ; you should see : 9 8 7 6 5 4 3 2 1 0 -->
433 \ -----------------------------------------------------------------------
434 \ tests indexing address
435 \ -----------------------------------------------------------------------
438 \ https://forth-standard.org/standard/core/CComma
439 \ C, char -- append char
450 \ https://forth-standard.org/standard/core/CFetch
451 \ C@ c-addr -- char fetch char from memory
466 8 BYTES_TABLE_IDX BYTES_TABLE \ create table "BYTES_TABLE" with bytes content = 0,1,2,3,4,5,6,7
468 2 BYTES_TABLE C@ . ; you should see 2 -->
472 VARIABLE BYTES_TABLE1
474 $0201 BYTES_TABLE1 ! \ words written in memory are little endian !
476 CODE IDX_TEST1 \ index -- value
477 MOV.B BYTES_TABLE1(TOS),TOS \ -- value
482 0 IDX_TEST1 ; you should see 1 -->
490 1 TEST6 . ; you should see 1 -->
493 \ -----------------------------------------------------------------------
494 \ tests access to a CREATED word with assembler
495 \ -----------------------------------------------------------------------
524 TABLE 2 - CONSTANT PFA_TABLE \ PFA_TABLE leave the PFA of TABLE
527 CODE REDIRECT ; <table> -- redirects TABLE to argument <table>
534 CODE REDIRECT0 ; -- redirects TABLE to TABLE0
535 MOV #TABLE0,&PFA_TABLE
540 CODE REDIRECT10 ; -- redirects TABLE to TABLE10
541 MOV #TABLE10,&PFA_TABLE
546 CODE REDIRECT20 ; -- redirects TABLE to TABLE20
547 MOV #TABLE20,&PFA_TABLE
559 TABLE0 REDIRECT TABLE 10 DUMP
561 TABLE10 REDIRECT TABLE 10 DUMP
563 TABLE20 REDIRECT TABLE 10 DUMP
566 REDIRECT0 TABLE 10 DUMP
568 REDIRECT10 TABLE 10 DUMP
570 REDIRECT20 TABLE 10 DUMP
573 TABLE0 PFA_TABLE ! TABLE 10 DUMP
575 TABLE10 PFA_TABLE ! TABLE 10 DUMP
577 TABLE20 PFA_TABLE ! TABLE 10 DUMP
580 \ -----------------------------------------------------------------------
581 \ tests behaviour of assembly error
582 \ -----------------------------------------------------------------------
583 \ R16 causes an error, assembler context is aborted and the word TEST7 is "hidden".
586 \ MOV 0(truc),0(R16) ; display an error "out of bounds" -->
588 ; -----------------------------------------------------------------------
589 ; create a primary DEFERred assembly word
590 ; -----------------------------------------------------------------------
593 DEFER TRUC ; here, TRUC is a secondary DEFERred word (i.e. without BODY)
597 CODENNM ; leaves its execution address (CFA) on stack
605 IS TRUC ; TRUC becomes a primary DEFERred word
606 ; with its default action (DUP) located at its BODY addresse.
608 TRUC . ; display TOS value -->
611 ' TRUC >BODY IS TRUC ; TRUC is reinitialzed with its default action
614 TRUC . ; display TOS value -->
616 \ ' DROP IS TRUC ; TRUC is redirected to DROP
618 \ TRUC ; The generated error displays stack empty! in reverse video, removes the TRUC definition and restarts the interpretation after the end of the file. And as you see, FastForth is able to display long lines, interesting, doesn't it? -->