OSDN Git Service

v 3.4 newcommer: FastForth I2C TERMINAL
[fast-forth/master.git] / MSP430-FORTH / TESTASM.F
1 \ -*- coding: utf-8 -*-
2
3 ; -----------------------------------------------------------------------
4 ; TEST_ASM.f
5 ; -----------------------------------------------------------------------
6 \
7 \ TARGET SELECTION
8 \ MSP_EXP430FR5739  MSP_EXP430FR5969    MSP_EXP430FR5994    MSP_EXP430FR6989
9 \ MSP_EXP430FR4133  MSP_EXP430FR2433    MSP_EXP430FR2355    CHIPSTICK_FR2433
10 \
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
13 \
14 \ example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
15 \
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
18 \
19 \ example : POPM #6,IP   pop Y,X,W,T,S,IP registers from return stack
20 \
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< 
23 \
24 \ FORTH conditionnal    : 0= 0< = < > U<
25
26 [UNDEFINED] >R [IF]
27 \ https://forth-standard.org/standard/core/toR
28 \ >R    x --   R: -- x   push to return stack
29 CODE >R
30 PUSH TOS
31 MOV @PSP+,TOS
32 MOV @IP+,PC
33 ENDCODE
34 [THEN]
35
36 [UNDEFINED] R> [IF]
37 \ https://forth-standard.org/standard/core/Rfrom
38 \ R>    -- x    R: x --   pop from return stack ; CALL #RFROM performs DOVAR
39 CODE R>
40 MOV rDOVAR,PC
41 ENDCODE
42 [THEN]
43
44 [UNDEFINED] + [IF]
45 \ https://forth-standard.org/standard/core/Plus
46 \ +       n1/u1 n2/u2 -- n3/u3     add n1+n2
47 CODE +
48 ADD @PSP+,TOS
49 MOV @IP+,PC
50 ENDCODE
51 [THEN]
52
53 [UNDEFINED] - [IF]
54 \ https://forth-standard.org/standard/core/Minus
55 \ -      n1/u1 n2/u2 -- n3/u3     n3 = n1-n2
56 CODE -
57 SUB @PSP+,TOS   \ 2  -- n2-n1 ( = -n3)
58 XOR #-1,TOS     \ 1
59 ADD #1,TOS      \ 1  -- n3 = -(n2-n1) = n1-n2
60 MOV @IP+,PC
61 ENDCODE
62 [THEN]
63
64 [UNDEFINED] SWAP [IF]
65 \ https://forth-standard.org/standard/core/SWAP
66 \ SWAP     x1 x2 -- x2 x1    swap top two items
67 CODE SWAP
68 MOV @PSP,W      \ 2
69 MOV TOS,0(PSP)  \ 3
70 MOV W,TOS       \ 1
71 MOV @IP+,PC     \ 4
72 ENDCODE
73 [THEN]
74
75 [UNDEFINED] MAX [IF]    \ MAX and MIN are defined in {UTILITY}
76
77 CODE MAX    \    n1 n2 -- n3       signed maximum
78     CMP @PSP,TOS    \ n2-n1
79     S<  ?GOTO FW1   \ n2<n1
80 BW1 ADD #2,PSP
81     MOV @IP+,PC
82 ENDCODE
83
84 CODE MIN    \    n1 n2 -- n3       signed minimum
85     CMP @PSP,TOS     \ n2-n1
86     S<  ?GOTO BW1    \ n2<n1
87 FW1 MOV @PSP+,TOS
88     MOV @IP+,PC
89 ENDCODE
90
91 [THEN]
92
93 [UNDEFINED] @ [IF]
94 \ https://forth-standard.org/standard/core/Fetch
95 \ @     c-addr -- char   fetch char from memory
96 CODE @
97 MOV @TOS,TOS
98 MOV @IP+,PC
99 ENDCODE
100 [THEN]
101
102 [UNDEFINED] ! [IF]
103 \ https://forth-standard.org/standard/core/Store
104 \ !        x a-addr --   store cell in memory
105 CODE !
106 MOV @PSP+,0(TOS)    \ 4
107 MOV @PSP+,TOS       \ 2
108 MOV @IP+,PC         \ 4
109 ENDCODE
110 [THEN]
111
112 [UNDEFINED] C@ [IF]
113 \ https://forth-standard.org/standard/core/CFetch
114 \ C@     c-addr -- char   fetch char from memory
115 CODE C@
116 MOV.B @TOS,TOS
117 MOV @IP+,PC
118 ENDCODE
119 [THEN]
120
121 [UNDEFINED] VARIABLE [IF]
122 \ https://forth-standard.org/standard/core/VARIABLE
123 \ VARIABLE <name>       --                      define a Forth VARIABLE
124 : VARIABLE 
125 CREATE
126 HI2LO
127 MOV #DOVAR,-4(W)        \   CFA = DOVAR
128 MOV @RSP+,IP
129 MOV @IP+,PC
130 ENDCODE
131 [THEN]
132
133 [UNDEFINED] CONSTANT [IF]
134 \ https://forth-standard.org/standard/core/CONSTANT
135 \ CONSTANT <name>     n --                      define a Forth CONSTANT 
136 : CONSTANT 
137 CREATE
138 HI2LO
139 MOV TOS,-2(W)           \   PFA = n
140 MOV @PSP+,TOS
141 MOV @RSP+,IP
142 MOV @IP+,PC
143 ENDCODE
144 [THEN]
145
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.
151
152 \name Execution:   --
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.
155 : DEFER
156 CREATE
157 HI2LO
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.
160 MOV @RSP+,IP
161 MOV @IP+,PC
162 ENDCODE
163 [THEN]
164
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
168 CODE >BODY
169 ADD #4,TOS
170 MOV @IP+,PC
171 ENDCODE
172 [THEN]
173
174 [UNDEFINED] SPACE [IF]
175 \ https://forth-standard.org/standard/core/SPACE
176 \ SPACE   --               output a space
177 : SPACE
178 $20 EMIT ;
179 [THEN]
180
181 [UNDEFINED] SPACES [IF]
182 \ https://forth-standard.org/standard/core/SPACES
183 \ SPACES   n --            output n spaces
184 CODE SPACES
185 CMP #0,TOS
186 0<> IF
187     PUSH IP
188     BEGIN
189         LO2HI
190         $20 EMIT
191         HI2LO
192         SUB #2,IP 
193         SUB #1,TOS
194     0= UNTIL
195     MOV @RSP+,IP
196 THEN
197 MOV @PSP+,TOS           \ --         drop n
198 NEXT              
199 ENDCODE
200 [THEN]
201
202 [UNDEFINED] DUP [IF]
203 \ https://forth-standard.org/standard/core/DUP
204 \ DUP      x -- x x      duplicate top of stack
205 CODE DUP
206 BW1 SUB #2,PSP      \ 2  push old TOS..
207     MOV TOS,0(PSP)  \ 3  ..onto stack
208     MOV @IP+,PC     \ 4
209 ENDCODE
210 [THEN]
211
212 [UNDEFINED] OVER [IF]
213 \ https://forth-standard.org/standard/core/OVER
214 \ OVER    x1 x2 -- x1 x2 x1
215 CODE OVER
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
219 MOV @IP+,PC
220 ENDCODE
221 [THEN]
222
223 [UNDEFINED] U.R [IF]        \ defined in {UTILITY}
224 : U.R                       \ u n --           display u unsigned in n width (n >= 2)
225   >R  <# 0 # #S #>  
226   R> OVER - 0 MAX SPACES TYPE
227 ;
228 [THEN]
229
230 [UNDEFINED] DO [IF]
231 \ https://forth-standard.org/standard/core/DO
232 \ DO       -- DOadr   L: -- 0
233 CODE DO                 \ immediate
234 SUB #2,PSP              \
235 MOV TOS,0(PSP)          \
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
240 MOV &LEAVEPTR,W         \
241 MOV #0,0(W)             \ -- HERE+2     L-- 0
242 MOV @IP+,PC
243 ENDCODE IMMEDIATE
244 [THEN]
245
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
250     MOV #XLOOP,X
251 BW1 ADD #4,&DP          \ make room to compile two words
252     MOV &DP,W
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 ?
260 0<> WHILE
261     MOV W,0(TOS)        \ move adr after loop as UNLOOP adr
262 REPEAT
263     MOV @PSP+,TOS
264     MOV @IP+,PC
265 ENDCODE IMMEDIATE
266 [THEN]
267
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
272 MOV #XPLOOP,X
273 GOTO BW1
274 ENDCODE IMMEDIATE
275 [THEN]
276
277 [UNDEFINED] I [IF]
278 \ https://forth-standard.org/standard/core/I
279 \ I        -- n   R: sys1 sys2 -- sys1 sys2
280 \                  get the innermost loop index
281 CODE I
282 SUB #2,PSP              \ 1 make room in TOS
283 MOV TOS,0(PSP)          \ 3
284 MOV @RSP,TOS            \ 2 index = loopctr - fudge
285 SUB 2(RSP),TOS          \ 3
286 MOV @IP+,PC             \ 4 13~
287 ENDCODE
288 [THEN]
289
290 [UNDEFINED] DUMP [IF]       \ defined in {UTILITY}
291 \ https://forth-standard.org/standard/tools/DUMP
292 CODE DUMP                   \ adr n  --   dump memory
293 PUSH IP
294 PUSH &BASEADR               \ save current base
295 MOV #$10,&BASEADR           \ HEX base
296 ADD @PSP,TOS                \ -- ORG END
297 LO2HI
298   SWAP                      \ -- END ORG
299   DO  CR                    \ generate line
300     I 4 U.R SPACE           \ generate address
301       I 8 + I
302       DO I C@ 3 U.R LOOP
303       SPACE
304       I $10 + I 8 +
305       DO I C@ 3 U.R LOOP  
306       SPACE SPACE
307       I $10 + I             \ display 16 chars
308       DO I C@ $7E MIN $20 MAX EMIT LOOP
309   $10 +LOOP
310   R> BASEADR !              \ restore current base
311 ;
312 [THEN]
313
314 \ -----------------------------------------------------------------------
315 \ test CPUx instructions PUSHM, POPM, RLAM, RRAM, RRCM, RRUM
316 \ -----------------------------------------------------------------------
317 CODE TESTPUSHM
318 BW1
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"
325             MOV     #22222,Y
326             MOV     #3,X
327             MOV     #2,W
328             MOV     #1,T
329             MOV     #0,S
330
331             PUSHM   #4,IP       \ PUSHM IP,S,T,W
332             POPM    #4,IP       \ POPM  W,T,S,IP
333             SUB     #10,PSP
334             MOV     TOS,8(PSP)  \ save old TOS
335             MOV     S,6(PSP)
336             MOV     T,4(PSP)
337             MOV     W,2(PSP)
338             MOV     X,0(PSP)
339             MOV     Y,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
343             RLAM    #2,TOS
344             RRCM    #1,TOS
345             RRUM    #1,TOS
346             COLON               \ high level part of the word starts here...
347             space . . . . .
348             ;                   \ and finishes here.
349     \
350 TESTPUSHM  ; you should see 11111 3 2 1 0 -->
351
352 CODE TESTPOPM
353             GOTO BW1            \ JMP TESTPUSHM
354 ENDCODE
355
356     \
357 TESTPOPM  ; you should see 11111 3 2 1 0 -->
358
359
360
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...
366
367             MOV &BASEADR,&BASEADR \ to test &xxxx src operand
368             CMP #%10,&BASEADR
369 0<> IF      MOV #2,&BASEADR    \ if base <> 2
370 ELSE        MOV #$0A,&BASEADR  \ else base = 2
371 THEN        
372             COLON           \ tips : no "ok" displayed in start of line <==> compilation mode
373             BASEADR @ U.       \ always display 10 !
374             ;
375     \
376
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
385             CMP #2, &BASEADR
386 0<> IF      MOV #2, &BASEADR   \ if variable system BASE <> 2
387 ELSE        MOV #10,&BASEADR   \ else (BASE = 2)
388 THEN
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
392             MOV @IP+,PC     \ = NEXT
393 ENDCODE                     \ ends assembler : remove vocabulary ASSEMBLER from CONTEXT
394     \
395
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
400             CMP #2, &BASEADR
401 0<> IF      MOV #2, &BASEADR   \ if variable system BASE <> 2
402 ELSE        MOV #10,&BASEADR   \ else (BASE = 2)
403 THEN        COLON           \
404             BASEADR @  U.      \ always display 10 !
405 ;                           \
406     \
407
408
409 \ -----------------------------------------------------------------------
410 \ test an assembly jump spanning a section written in FORTH
411 \ -----------------------------------------------------------------------
412 : TEST5
413             SPACE
414             HI2LO
415             SUB #2,PSP
416             MOV TOS,0(PSP)
417             MOV #%1010,TOS  \ init count = 10
418 BEGIN       SUB #$0001,TOS
419             LO2HI
420                             \ IP is already saved by word ":"
421             DUP U.          \ display count
422             HI2LO
423             CMP #0,TOS
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
427             MOV @IP+,PC     \ = NEXT
428 ENDCODE
429     \
430 TEST5  ; you should see :  9 8 7 6 5 4 3 2 1 0 -->
431     \
432
433 \ -----------------------------------------------------------------------
434 \ tests indexing address
435 \ -----------------------------------------------------------------------
436
437 [UNDEFINED] C, [IF]
438 \ https://forth-standard.org/standard/core/CComma
439 \ C,   char --        append char
440 CODE C,
441 MOV &DP,W
442 MOV.B TOS,0(W)
443 ADD #1,&DP
444 MOV @PSP+,TOS
445 MOV @IP+,PC
446 ENDCODE
447 [THEN]
448
449 [UNDEFINED] C@ [IF]
450 \ https://forth-standard.org/standard/core/CFetch
451 \ C@     c-addr -- char   fetch char from memory
452 CODE C@
453 MOV.B @TOS,TOS
454 MOV @IP+,PC
455 ENDCODE
456 [THEN]
457
458 : BYTES_TABLE_IDX
459 CREATE 
460 0 DO I C,
461 LOOP
462 DOES>
463 +
464 ;
465
466 8 BYTES_TABLE_IDX BYTES_TABLE \ create table "BYTES_TABLE" with bytes content = 0,1,2,3,4,5,6,7
467     \
468 2 BYTES_TABLE C@ . ; you should see 2 -->
469 \
470
471
472 VARIABLE BYTES_TABLE1
473
474 $0201 BYTES_TABLE1 !              \ words written in memory are little endian !
475
476 CODE IDX_TEST1                     \ index -- value
477     MOV.B   BYTES_TABLE1(TOS),TOS  \ -- value
478 COLON
479     U. 
480 ;      
481
482 0 IDX_TEST1     ; you should see 1 -->
483
484 CODE TEST6
485             MOV 0(PSP),0(PSP)  \
486             MOV @IP+,PC
487 ENDCODE
488
489
490 1 TEST6 .       ; you should see 1 -->
491
492
493 \ -----------------------------------------------------------------------
494 \ tests access to a CREATED word with assembler 
495 \ -----------------------------------------------------------------------
496
497
498     \
499 CREATE TABLE0
500 0 C,
501 1 C,
502 2 C,
503 3 C,
504     \
505
506 CREATE TABLE10
507 $10 C,
508 $11 C,
509 $12 C,
510 $13 C,
511
512     \
513
514 CREATE TABLE20
515 $20 C,
516 $21 C,
517 $22 C,
518 $23 C,
519     \
520
521 CREATE TABLE
522
523
524 TABLE 2 - CONSTANT PFA_TABLE      \ PFA_TABLE leave the PFA of TABLE
525
526
527 CODE REDIRECT       ; <table> --    redirects TABLE to argument <table>    
528 MOV TOS,&PFA_TABLE
529 MOV @PSP+,TOS
530 MOV @IP+,PC
531 ENDCODE
532     \
533
534 CODE REDIRECT0      ; --            redirects TABLE to TABLE0        
535 MOV #TABLE0,&PFA_TABLE
536 MOV @IP+,PC
537 ENDCODE
538     \
539
540 CODE REDIRECT10     ; --            redirects TABLE to TABLE10        
541 MOV #TABLE10,&PFA_TABLE
542 MOV @IP+,PC
543 ENDCODE
544     \
545
546 CODE REDIRECT20     ; --            redirects TABLE to TABLE20        
547 MOV #TABLE20,&PFA_TABLE
548 MOV @IP+,PC
549 ENDCODE
550     \
551
552 ' TABLE0 10 DUMP
553     \
554 ' TABLE10 10 DUMP
555     \
556 ' TABLE20 10 DUMP
557     \
558     \
559 TABLE0 REDIRECT TABLE 10 DUMP
560     \
561 TABLE10 REDIRECT TABLE 10 DUMP
562     \
563 TABLE20 REDIRECT TABLE 10 DUMP
564     \
565     \
566 REDIRECT0 TABLE 10 DUMP
567     \
568 REDIRECT10 TABLE 10 DUMP
569     \
570 REDIRECT20 TABLE 10 DUMP
571     \
572
573 TABLE0 PFA_TABLE ! TABLE 10 DUMP
574     \
575 TABLE10 PFA_TABLE ! TABLE 10 DUMP
576     \
577 TABLE20 PFA_TABLE ! TABLE 10 DUMP
578     \
579
580 \ -----------------------------------------------------------------------
581 \ tests behaviour of assembly error 
582 \ -----------------------------------------------------------------------
583 \ R16 causes an error, assembler context is aborted and the word TEST7 is "hidden".
584
585 \CODE TEST7
586 \           MOV 0(truc),0(R16)  ; display an error "out of bounds" -->
587
588 ; -----------------------------------------------------------------------
589 ; create a primary DEFERred assembly word
590 ; -----------------------------------------------------------------------
591
592
593 DEFER TRUC              ; here, TRUC is a secondary DEFERred word (i.e. without BODY)
594     \
595
596
597 CODENNM                 ; leaves its execution address (CFA) on stack
598     SUB #2,PSP
599     MOV TOS,0(PSP)
600     MOV @IP+,PC
601 ENDCODE 
602
603 DUP .
604
605 IS TRUC                 ; TRUC becomes a primary DEFERred word
606                         ; with its default action (DUP) located at its BODY addresse.
607
608 TRUC .                  ; display TOS value -->
609
610
611 ' TRUC >BODY IS TRUC    ; TRUC is reinitialzed with its default action
612
613
614 TRUC .                  ; display TOS value --> 
615
616 \ ' DROP IS TRUC          ; TRUC is redirected to DROP
617 \  
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? --> 
619 \    
620 \ bla
621 \ bla
622 \ bla
623
624
625
626
627
628
629
630 \ bla
631 \ ...
632
633
634
635