OSDN Git Service

la der de der
[fast-forth/master.git] / MSP430-FORTH / TSTWORDS.f
1 \ -----------------------------
2 \ MSP-EXP430FR5969_TSTWORDS.f
3 \ -----------------------------
4
5 \ first, we do some tests allowing the download
6     CODE ABORT_TSTWORDS
7     SUB #2,PSP
8     MOV TOS,0(PSP)
9     MOV &VERSION,TOS
10     SUB #401,TOS        \ FastForth V4.1
11     COLON
12     'CR' EMIT            \ return to column 1 without 'LF'
13     ABORT" FastForth V4.1 please!"
14     RST_RET           \ remove ABORT_TEST_ASM definition before resuming
15     ;
16
17     ABORT_TSTWORDS      \ abort test
18
19 ; ------------------------------------------------------------------
20 ; first we download the set of definitions we need (from CORE_ANS.f)
21 ; ------------------------------------------------------------------
22
23     [UNDEFINED] 0=
24     [IF]
25 \ https://forth-standard.org/standard/core/ZeroEqual
26 \ 0=     n/u -- flag    return true if TOS=0
27     CODE 0=
28     SUB #1,TOS      \ 1 borrow (clear cy) if TOS was 0
29     SUBC TOS,TOS    \ 1 TOS=-1 if borrow was set
30     MOV @IP+,PC
31     ENDCODE
32     [THEN]
33
34     [UNDEFINED] DUP
35     [IF]    \ define DUP and ?DUP
36 \ https://forth-standard.org/standard/core/DUP
37 \ DUP      x -- x x      duplicate top of stack
38     CODE DUP
39 BW1 SUB #2,PSP      \ 2  push old TOS..
40     MOV TOS,0(PSP)  \ 3  ..onto stack
41     MOV @IP+,PC     \ 4
42     ENDCODE
43
44 \ https://forth-standard.org/standard/core/qDUP
45 \ ?DUP     x -- 0 | x x    DUP if nonzero
46     CODE ?DUP
47     CMP #0,TOS      \ 2  test for TOS nonzero
48     0<> ?GOTO BW1   \ 2
49     MOV @IP+,PC     \ 4
50     ENDCODE
51     [THEN]
52
53     [UNDEFINED] IF
54     [IF]     \ define IF THEN
55
56 \ https://forth-standard.org/standard/core/IF
57 \ IF       -- IFadr    initialize conditional forward branch
58     CODE IF
59     SUB #2,PSP              \
60     MOV TOS,0(PSP)          \
61     MOV &DP,TOS             \ -- HERE
62     ADD #4,&DP            \           compile one word, reserve one word
63     MOV #QFBRAN,0(TOS)      \ -- HERE   compile QFBRAN
64     ADD #2,TOS              \ -- HERE+2=IFadr
65     MOV @IP+,PC
66     ENDCODE IMMEDIATE
67
68 \ https://forth-standard.org/standard/core/THEN
69 \ THEN     IFadr --                resolve forward branch
70     CODE THEN
71     MOV &DP,0(TOS)          \ -- IFadr
72     MOV @PSP+,TOS           \ --
73     MOV @IP+,PC
74     ENDCODE IMMEDIATE
75     [THEN]
76
77     [UNDEFINED] ELSE
78     [IF]
79 \ https://forth-standard.org/standard/core/ELSE
80 \ ELSE     IFadr -- ELSEadr        resolve forward IF branch, leave ELSEadr on stack
81     CODE ELSE
82     ADD #4,&DP              \ make room to compile two words
83     MOV &DP,W               \ W=HERE+4
84     MOV #BRAN,-4(W)
85     MOV W,0(TOS)            \ HERE+4 ==> [IFadr]
86     SUB #2,W                \ HERE+2
87     MOV W,TOS               \ -- ELSEadr
88     MOV @IP+,PC
89     ENDCODE IMMEDIATE
90     [THEN]
91
92     [UNDEFINED] SWAP
93     [IF]
94 \ https://forth-standard.org/standard/core/SWAP
95 \ SWAP     x1 x2 -- x2 x1    swap top two items
96     CODE SWAP
97     PUSH TOS            \ 3
98     MOV @PSP,TOS        \ 2
99     MOV @RSP+,0(PSP)    \ 4
100     MOV @IP+,PC         \ 4
101     ENDCODE
102     [THEN]
103
104     [UNDEFINED] BEGIN
105     [IF]  \ define BEGIN UNTIL AGAIN WHILE REPEAT
106
107 \ https://forth-standard.org/standard/core/BEGIN
108 \ BEGIN    -- BEGINadr             initialize backward branch
109     CODE BEGIN
110     MOV #BEGIN,PC
111     ENDCODE IMMEDIATE
112
113 \ https://forth-standard.org/standard/core/UNTIL
114 \ UNTIL    BEGINadr --             resolve conditional backward branch
115     CODE UNTIL
116     MOV #QFBRAN,X
117 BW1 ADD #4,&DP          \ compile two words
118     MOV &DP,W           \ W = HERE
119     MOV X,-4(W)         \ compile Bran or QFBRAN at HERE
120     MOV TOS,-2(W)       \ compile bakcward adr at HERE+2
121     MOV @PSP+,TOS
122     MOV @IP+,PC
123     ENDCODE IMMEDIATE
124
125 \ https://forth-standard.org/standard/core/AGAIN
126 \ AGAIN    BEGINadr --             resolve uncondionnal backward branch
127     CODE AGAIN
128     MOV #BRAN,X
129     GOTO BW1
130     ENDCODE IMMEDIATE
131
132 \ https://forth-standard.org/standard/core/WHILE
133 \ WHILE    BEGINadr -- WHILEadr BEGINadr
134     : WHILE
135     POSTPONE IF SWAP
136     ; IMMEDIATE
137
138 \ https://forth-standard.org/standard/core/REPEAT
139 \ REPEAT   WHILEadr BEGINadr --     resolve WHILE loop
140     : REPEAT
141     POSTPONE AGAIN POSTPONE THEN
142     ; IMMEDIATE
143     [THEN]
144
145     [UNDEFINED] DO
146     [IF]     \ define DO LOOP +LOOP
147
148 \ https://forth-standard.org/standard/core/DO
149 \ DO       -- DOadr   L: -- 0
150     HDNCODE XDO         \ DO run time
151     MOV #$8000,X        \ 2 compute 8000h-limit = "fudge factor"
152     SUB @PSP+,X         \ 2
153     MOV TOS,Y           \ 1 loop ctr = index+fudge
154     ADD X,Y             \ 1 Y = INDEX
155     PUSHM #2,X          \ 4 PUSHM X,Y, i.e. PUSHM LIMIT, INDEX
156     MOV @PSP+,TOS       \ 2
157     MOV @IP+,PC         \ 4
158     ENDCODE
159
160     CODE DO
161     SUB #2,PSP          \
162     MOV TOS,0(PSP)      \
163     ADD #2,&DP          \   make room to compile xdo
164     MOV &DP,TOS         \ -- HERE+2
165     MOV #XDO,-2(TOS)    \   compile xdo
166     ADD #2,&LEAVEPTR    \ -- HERE+2     LEAVEPTR+2
167     MOV &LEAVEPTR,W     \
168     MOV #0,0(W)         \ -- HERE+2     L-- 0, init
169     MOV @IP+,PC
170     ENDCODE IMMEDIATE
171
172     HDNCODE XLOOP       \   LOOP run time
173     ADD #1,0(RSP)       \ 4 increment INDEX
174 BW1 BIT #$100,SR        \ 2 is overflow bit set?
175     0= IF               \   branch if no overflow
176         MOV @IP,IP
177         MOV @IP+,PC
178     THEN
179     ADD #4,RSP          \ 1 empties RSP
180     ADD #2,IP           \ 1 overflow = loop done, skip branch ofs
181     MOV @IP+,PC         \ 4 14~ taken or not taken xloop/loop
182     ENDCODE             \
183
184 \ https://forth-standard.org/standard/core/LOOP
185 \ LOOP    DOadr --         L-- an an-1 .. a1 0
186     CODE LOOP
187     MOV #XLOOP,X
188 BW2 ADD #4,&DP          \ make room to compile two words
189     MOV &DP,W
190     MOV X,-4(W)         \ xloop --> HERE
191     MOV TOS,-2(W)       \ DOadr --> HERE+2
192     BEGIN                   \ resolve all "leave" adr
193         MOV &LEAVEPTR,TOS   \ -- Adr of top LeaveStack cell
194         SUB #2,&LEAVEPTR    \ --
195         MOV @TOS,TOS        \ -- first LeaveStack value
196         CMP #0,TOS          \ -- = value left by DO ?
197     0<> WHILE
198         MOV W,0(TOS)        \ move adr after loop as UNLOOP adr
199     REPEAT
200     MOV @PSP+,TOS
201     MOV @IP+,PC
202     ENDCODE IMMEDIATE
203
204     HDNCODE XPLOO   \   +LOOP run time
205     ADD TOS,0(RSP)  \ 4 increment INDEX by TOS value
206     MOV @PSP+,TOS   \ 2 get new TOS, doesn't change flags
207     GOTO BW1        \ 2
208     ENDCODE         \
209
210 \ https://forth-standard.org/standard/core/PlusLOOP
211 \ +LOOP   adrs --   L-- an an-1 .. a1 0
212     CODE +LOOP
213     MOV #XPLOO,X
214     GOTO BW2
215     ENDCODE IMMEDIATE
216     [THEN]
217
218 ; --------------------------
219 ; end of definitions we need
220 ; --------------------------
221
222 ECHO
223
224 ; -----------------------------------------------------------------------
225 ; test some assembler words and show how to mix FORTH/ASSEMBLER routines
226 ; -----------------------------------------------------------------------
227
228 LOAD" \misc\TestASM.4th"
229
230 ECHO
231
232 ; -------------------------------------
233 ; here we returned in the TestWords.4th
234 ; -------------------------------------
235
236 \ ----------
237 \ LOOP tests
238 \ ----------
239 : LOOP_TEST 8 0 DO I . LOOP
240 ;
241
242 LOOP_TEST   \ you should see 0 1 2 3 4 5 6 7 -->
243
244
245 : LOOP_TEST1    \   n <LOOP_TEST1> ---
246     BEGIN   DUP U. 1 -
247     ?DUP
248     0= UNTIL
249 ;
250 \
251 \ : LOOP_MAX      \ FIND_NOTHING      --
252 \     0 0
253 \     DO
254 \     LOOP            \ 14 cycles by loop
255 \     ABORT" 65536 LOOP "
256 \ ;
257 \
258 : FIND_TEST            \ FIND_TEST <word>     --
259    $20 WORD             \ -- c-addr
260        50000 0
261        DO              \ -- c-addr
262            DUP
263            FIND DROP DROP
264        LOOP
265     FIND
266     0=  IF ABORT" <-- not found !"
267         ELSE ABORT" <-- found !"
268         THEN
269  ;
270 \
271 \ \ seeking $ word, FIND jumps all words on their first character so time of word loop is 20 cycles
272 \ \ see FIND in the source file for more information
273 \ \
274 \ \ FIND_TEST <lastword> result @ 8MHz, monothread : 1,2s
275 \ \
276 \ \ FIND_TEST $ results @ 8MHz, monothread, 201 words in vocabulary FORTH :
277 \ \ 27 seconds with only FORTH vocabulary in CONTEXT
278 \ \ 540 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
279 \ \ 2.6866 us / word, 21,49 cycles / word (for 20 cycles calculated (see FIND in source file)
280 \ \
281 \ \
282 \ \ FIND_TEST $ results @ 8MHz, 2 threads, 201 words in vocabulary FORTH :
283 \ \ 13 second with only FORTH vocabulary in CONTEXT
284 \ \ 260 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
285 \ \ 1,293 us / word, 10,34 cycles / word
286 \ \
287 \ \ FIND_TEST $ results @ 8MHz, 4 threads, 201 words in vocabulary FORTH :
288 \ \ 8 second with only FORTH vocabulary in CONTEXT
289 \ \ 160 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
290 \ \ 0,796 us / word, 6,37 cycles / word
291 \ \
292 \ \ FIND_TEST $ results @ 8MHz, 8 threads, 201 words in vocabulary FORTH :
293 \ \ 4.66 second with only FORTH vocabulary in CONTEXT
294 \ \ 93 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
295 \ \ 0,4463 us / word, 3,7 cycles / word
296 \ \
297 \ \ FIND_TEST $ results @ 8MHz, 16 threads, 201 words in vocabulary FORTH :
298 \ \ 2,8 second with only FORTH vocabulary in CONTEXT
299 \ \ 56 us for one search ( which gives the delay for QNUMBER in INTERPRET routine)
300 \ \ 0,278 us / word, 2,22 cycles / word
301 \ \
302 \ \ --------
303 \ \ KEY test
304 \ \ --------
305 \ : KEY_TEST
306 \     ."  type a key : "
307 \     KEY EMIT    \ wait for a KEY, then emit it
308 \ ;
309 \ \ KEY_TEST
310