OSDN Git Service

V308
[fast-forth/master.git] / MSP430-FORTH / UTILITY.f
1 \ -*- coding: utf-8 -*-
2
3 \
4 \ to see kernel options, download FastForthSpecs.f
5 \ FastForth kernel options: MSP430ASSEMBLER, CONDCOMP
6 \
7 \ TARGET SELECTION ( = the name of \INC\target.pat file without the extension)
8 \ MSP_EXP430FR5739  MSP_EXP430FR5969    MSP_EXP430FR5994    MSP_EXP430FR6989
9 \ MSP_EXP430FR4133  MSP_EXP430FR2433    CHIPSTICK_FR2433    MSP_EXP430FR2355
10 \ LP_MSP430FR2476
11 \
12 \ from scite editor : copy your target selection in (shift+F8) parameter 1:
13 \
14 \ OR
15 \
16 \ drag and drop this file onto SendSourceFileToTarget.bat
17 \ then select your TARGET when asked.
18 \
19 \
20 \ REGISTERS USAGE
21 \ R4 to R7 must be saved before use and restored after
22 \ scratch registers Y to S are free for use
23 \ under interrupt, IP is free for use
24 \
25 \ PUSHM order : PSP,TOS, IP,  S,  T,  W,  X,  Y, rEXIT,rDOVAR,rDOCON, rDODOES, R3, SR,RSP, PC
26 \ PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8,  R7  ,  R6  ,  R5  ,   R4   , R3, R2, R1, R0
27 \
28 \ example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
29 \
30 \ POPM  order :  PC,RSP, SR, R3, rDODOES,rDOCON,rDOVAR,rEXIT,  Y,  X,  W,  T,  S, IP,TOS,PSP
31 \ POPM  order :  R0, R1, R2, R3,   R4   ,  R5  ,  R6  ,  R7 , R8, R9,R10,R11,R12,R13,R14,R15
32 \
33 \ example : POPM #6,IP   pop Y,X,W,T,S,IP registers from return stack
34 \
35 \
36 \ FORTH conditionnals:  unary{ 0= 0< 0> }, binary{ = < > U< }
37 \
38 \ ASSEMBLER conditionnal usage with IF UNTIL WHILE  S<  S>=  U<   U>=  0=  0<>  0>=
39 \ ASSEMBLER conditionnal usage with ?JMP ?GOTO      S<  S>=  U<   U>=  0=  0<>  0<
40
41 ; ------------------------------------------------------------------------------
42 ; UTILITY.f
43 ; ------------------------------------------------------------------------------
44
45 \ first, we test for downloading driver only if UART TERMINAL target
46 CODE ABORT_UTILITY
47 SUB #2,PSP
48 MOV TOS,0(PSP)
49 MOV &VERSION,TOS
50 SUB #308,TOS        \ FastForth V3.8
51 COLON
52 'CR' EMIT           \ return to column 1 without 'LF'
53 ABORT" FastForth V3.8 please!"
54 PWR_STATE           \ remove ABORT_UTILITY definition before resuming
55 ;
56
57 ABORT_UTILITY
58
59 PWR_STATE
60
61 [DEFINED] {TOOLS} [IF]  {TOOLS} [THEN]
62
63 [UNDEFINED] {TOOLS} [IF]
64
65 MARKER {TOOLS} 
66
67 [UNDEFINED] EXIT [IF]
68 \ https://forth-standard.org/standard/core/EXIT
69 \ EXIT     --      exit a colon definition; CALL #EXIT performs ASMtoFORTH (10 cycles)
70 \                                           JMP #EXIT performs EXIT
71 CODE EXIT
72 MOV @RSP+,IP    \ 2 pop previous IP (or next PC) from return stack
73 MOV @IP+,PC     \ 4 = NEXT
74                 \ 6 (ITC-2)
75 ENDCODE
76 [THEN]
77
78 [UNDEFINED] SWAP [IF]
79 \ https://forth-standard.org/standard/core/SWAP
80 \ SWAP     x1 x2 -- x2 x1    swap top two items
81 CODE SWAP
82 MOV @PSP,W      \ 2
83 MOV TOS,0(PSP)  \ 3
84 MOV W,TOS       \ 1
85 MOV @IP+,PC     \ 4
86 ENDCODE
87 [THEN]
88
89 \ https://forth-standard.org/standard/core/Uless
90 \ U<    u1 u2 -- flag       test u1<u2, unsigned
91 [UNDEFINED] U< [IF]
92 CODE U<
93 SUB @PSP+,TOS   \ 2 u2-u1
94 0<> IF
95     MOV #-1,TOS     \ 1
96     U< IF           \ 2 flag 
97         AND #0,TOS  \ 1 flag Z = 1
98     THEN
99 THEN
100 MOV @IP+,PC     \ 4
101 ENDCODE
102 [THEN]
103
104 [UNDEFINED] IF [IF]     \ define IF and THEN
105 \ https://forth-standard.org/standard/core/IF
106 \ IF       -- IFadr    initialize conditional forward branch
107 CODE IF       \ immediate
108 SUB #2,PSP              \
109 MOV TOS,0(PSP)          \
110 MOV &DP,TOS             \ -- HERE
111 ADD #4,&DP            \           compile one word, reserve one word
112 MOV #QFBRAN,0(TOS)      \ -- HERE   compile QFBRAN
113 ADD #2,TOS              \ -- HERE+2=IFadr
114 MOV @IP+,PC
115 ENDCODE IMMEDIATE
116
117 \ https://forth-standard.org/standard/core/THEN
118 \ THEN     IFadr --                resolve forward branch
119 CODE THEN               \ immediate
120 MOV &DP,0(TOS)          \ -- IFadr
121 MOV @PSP+,TOS           \ --
122 MOV @IP+,PC
123 ENDCODE IMMEDIATE
124 [THEN]
125
126 [UNDEFINED] BEGIN [IF]  \ define BEGIN UNTIL AGAIN WHILE REPEAT
127 \ https://forth-standard.org/standard/core/BEGIN
128 \ BEGIN    -- BEGINadr             initialize backward branch
129 CODE BEGIN
130     MOV #HEREXEC,PC
131 ENDCODE IMMEDIATE
132
133 \ https://forth-standard.org/standard/core/UNTIL
134 \ UNTIL    BEGINadr --             resolve conditional backward branch
135 CODE UNTIL
136     MOV #QFBRAN,X
137 BW1 ADD #4,&DP          \ compile two words
138     MOV &DP,W           \ W = HERE
139     MOV X,-4(W)         \ compile Bran or QFBRAN at HERE
140     MOV TOS,-2(W)       \ compile bakcward adr at HERE+2
141     MOV @PSP+,TOS
142     MOV @IP+,PC
143 ENDCODE IMMEDIATE
144
145 \ https://forth-standard.org/standard/core/AGAIN
146 \ AGAIN    BEGINadr --             resolve uncondionnal backward branch
147 CODE AGAIN
148 MOV #BRAN,X
149 GOTO BW1
150 ENDCODE IMMEDIATE
151
152 \ https://forth-standard.org/standard/core/WHILE
153 \ WHILE    BEGINadr -- WHILEadr BEGINadr
154 : WHILE
155 POSTPONE IF SWAP
156 ; IMMEDIATE
157
158 \ https://forth-standard.org/standard/core/REPEAT
159 \ REPEAT   WHILEadr BEGINadr --     resolve WHILE loop
160 : REPEAT
161 POSTPONE AGAIN POSTPONE THEN
162 ; IMMEDIATE
163 [THEN]
164
165 [UNDEFINED] DO [IF]     \ define DO LOOP +LOOP
166 \ https://forth-standard.org/standard/core/DO
167 \ DO       -- DOadr   L: -- 0
168 CODE DO                 \ immediate
169 SUB #2,PSP              \
170 MOV TOS,0(PSP)          \
171 ADD #2,&DP              \   make room to compile xdo
172 MOV &DP,TOS             \ -- HERE+2
173 MOV #XDO,-2(TOS)        \   compile xdo
174 ADD #2,&LEAVEPTR        \ -- HERE+2     LEAVEPTR+2
175 MOV &LEAVEPTR,W         \
176 MOV #0,0(W)             \ -- HERE+2     L-- 0
177 MOV @IP+,PC
178 ENDCODE IMMEDIATE
179
180 \ https://forth-standard.org/standard/core/LOOP
181 \ LOOP    DOadr --         L-- an an-1 .. a1 0
182 CODE LOOP               \ immediate
183     MOV #XLOOP,X
184 BW1 ADD #4,&DP          \ make room to compile two words
185     MOV &DP,W
186     MOV X,-4(W)         \ xloop --> HERE
187     MOV TOS,-2(W)       \ DOadr --> HERE+2
188 BEGIN                   \ resolve all "leave" adr
189     MOV &LEAVEPTR,TOS   \ -- Adr of top LeaveStack cell
190     SUB #2,&LEAVEPTR    \ --
191     MOV @TOS,TOS        \ -- first LeaveStack value
192     CMP #0,TOS          \ -- = value left by DO ?
193 0<> WHILE
194     MOV W,0(TOS)        \ move adr after loop as UNLOOP adr
195 REPEAT
196     MOV @PSP+,TOS
197     MOV @IP+,PC
198 ENDCODE IMMEDIATE
199
200 \ https://forth-standard.org/standard/core/PlusLOOP
201 \ +LOOP   adrs --   L-- an an-1 .. a1 0
202 CODE +LOOP
203 MOV #XPLOOP,X
204 GOTO BW1        \ goto BW1 LOOP
205 ENDCODE IMMEDIATE
206 [THEN]
207
208 [UNDEFINED] I [IF]
209 \ https://forth-standard.org/standard/core/I
210 \ I        -- n   R: sys1 sys2 -- sys1 sys2
211 \                  get the innermost loop index
212 CODE I
213 SUB #2,PSP              \ 1 make room in TOS
214 MOV TOS,0(PSP)          \ 3
215 MOV @RSP,TOS            \ 2 index = loopctr - fudge
216 SUB 2(RSP),TOS          \ 3
217 MOV @IP+,PC             \ 4 13~
218 ENDCODE
219 [THEN]
220
221 [UNDEFINED] DUP [IF]    \ define DUP and ?DUP
222 \ https://forth-standard.org/standard/core/DUP
223 \ DUP      x -- x x      duplicate top of stack
224 CODE DUP
225 BW1 SUB #2,PSP      \ 2  push old TOS..
226     MOV TOS,0(PSP)  \ 3  ..onto stack
227     MOV @IP+,PC     \ 4
228 ENDCODE
229
230 \ https://forth-standard.org/standard/core/qDUP
231 \ ?DUP     x -- 0 | x x    DUP if nonzero
232 CODE ?DUP
233 CMP #0,TOS      \ 2  test for TOS nonzero
234 0<> ?GOTO BW1    \ 2
235 MOV @IP+,PC     \ 4
236 ENDCODE
237 [THEN]
238
239 [UNDEFINED] SWAP [IF]
240 \ https://forth-standard.org/standard/core/SWAP
241 \ SWAP     x1 x2 -- x2 x1    swap top two items
242 CODE SWAP
243 MOV @PSP,W      \ 2
244 MOV TOS,0(PSP)  \ 3
245 MOV W,TOS       \ 1
246 MOV @IP+,PC     \ 4
247 ENDCODE
248 [THEN]
249
250
251 [UNDEFINED] DROP [IF]
252 \ https://forth-standard.org/standard/core/DROP
253 \ DROP     x --          drop top of stack
254 CODE DROP
255 MOV @PSP+,TOS   \ 2
256 MOV @IP+,PC     \ 4
257 ENDCODE
258 [THEN]
259
260 [UNDEFINED] >R [IF]
261 \ https://forth-standard.org/standard/core/toR
262 \ >R    x --   R: -- x   push to return stack
263 CODE >R
264 PUSH TOS
265 MOV @PSP+,TOS
266 MOV @IP+,PC
267 ENDCODE
268 [THEN]
269
270 [UNDEFINED] R> [IF]
271 \ https://forth-standard.org/standard/core/Rfrom
272 \ R>    -- x    R: x --   pop from return stack ; CALL #RFROM performs DOVAR
273 CODE R>
274 SUB #2,PSP      \ 1
275 MOV TOS,0(PSP)  \ 3
276 MOV @RSP+,TOS   \ 2
277 MOV @IP+,PC     \ 4
278 ENDCODE
279 [THEN]
280
281 [UNDEFINED] SPACE [IF]
282 \ https://forth-standard.org/standard/core/SPACE
283 \ SPACE   --               output a space
284 : SPACE
285 $20 EMIT ;
286 [THEN]
287
288 [UNDEFINED] SPACES [IF]
289 \ https://forth-standard.org/standard/core/SPACES
290 \ SPACES   n --            output n spaces
291 CODE SPACES
292 CMP #0,TOS
293 0<> IF
294     PUSH IP
295     BEGIN
296         LO2HI
297         $20 EMIT
298         HI2LO
299         SUB #2,IP 
300         SUB #1,TOS
301     0= UNTIL
302     MOV @RSP+,IP
303 THEN
304 MOV @PSP+,TOS           \ --         drop n
305 NEXT              
306 ENDCODE
307 [THEN]
308
309 [UNDEFINED] 2DUP [IF]    \
310 \ https://forth-standard.org/standard/core/TwoDUP
311 \ 2DUP   x1 x2 -- x1 x2 x1 x2   dup top 2 cells
312 CODE 2DUP
313 MOV TOS,-2(PSP)     \ 3
314 MOV @PSP,-4(PSP)    \ 4
315 SUB #4,PSP          \ 1
316 MOV @IP+,PC         \ 4
317 ENDCODE
318 [THEN]
319
320 [UNDEFINED] 1+ [IF]
321 \ https://forth-standard.org/standard/core/OnePlus
322 \ 1+      n1/u1 -- n2/u2       add 1 to TOS
323 CODE 1+
324 ADD #1,TOS
325 MOV @IP+,PC
326 ENDCODE
327 [THEN]
328
329 [UNDEFINED] + [IF]
330 \ https://forth-standard.org/standard/core/Plus
331 \ +       n1/u1 n2/u2 -- n3/u3     add n1+n2
332 CODE +
333 ADD @PSP+,TOS
334 MOV @IP+,PC
335 ENDCODE
336 [THEN]
337
338 [UNDEFINED] - [IF]
339 \ https://forth-standard.org/standard/core/Minus
340 \ -      n1/u1 n2/u2 -- n3/u3      n3 = n1-n2
341 CODE -
342 SUB @PSP+,TOS   \ 2  -- n2-n1
343 XOR #-1,TOS     \ 1
344 ADD #1,TOS      \ 1  -- n3 = -(n2-n1) = n1-n2
345 MOV @IP+,PC
346 ENDCODE
347 [THEN]
348
349 [UNDEFINED] C@ [IF]
350 \ https://forth-standard.org/standard/core/CFetch
351 \ C@     c-addr -- char   fetch char from memory
352 CODE C@
353 MOV.B @TOS,TOS
354 MOV @IP+,PC
355 ENDCODE
356 [THEN]
357
358 [UNDEFINED] AND [IF]
359 \ https://forth-standard.org/standard/core/AND
360 \ C AND    x1 x2 -- x3           logical AND
361 CODE AND
362 AND @PSP+,TOS
363 MOV @IP+,PC
364 ENDCODE
365 [THEN]
366
367 [UNDEFINED] ROT [IF]
368 \ https://forth-standard.org/standard/core/ROT
369 \ ROT    x1 x2 x3 -- x2 x3 x1
370 CODE ROT
371 MOV @PSP,W          \ 2 fetch x2
372 MOV TOS,0(PSP)      \ 3 store x3
373 MOV 2(PSP),TOS      \ 3 fetch x1
374 MOV W,2(PSP)        \ 3 store x2
375 MOV @IP+,PC
376 ENDCODE
377 [THEN]
378
379 [UNDEFINED] MAX [IF]    \ define MAX and MIN
380     CODE MAX    \    n1 n2 -- n3       signed maximum
381         CMP @PSP,TOS    \ n2-n1
382         S< ?GOTO FW1    \ n2<n1
383 BW1     ADD #2,PSP
384         MOV @IP+,PC
385     ENDCODE
386
387     CODE MIN    \    n1 n2 -- n3       signed minimum
388         CMP @PSP,TOS    \ n2-n1
389         S< ?GOTO BW1    \ n2<n1
390 FW1     MOV @PSP+,TOS
391         MOV @IP+,PC
392     ENDCODE
393 [THEN]
394
395 [UNDEFINED] OVER [IF]
396 \ https://forth-standard.org/standard/core/OVER
397 \ OVER    x1 x2 -- x1 x2 x1
398 CODE OVER
399 MOV TOS,-2(PSP)     \ 3 -- x1 (x2) x2
400 MOV @PSP,TOS        \ 2 -- x1 (x2) x1
401 SUB #2,PSP          \ 1 -- x1 x2 x1
402 MOV @IP+,PC
403 ENDCODE
404 [THEN]
405
406 [UNDEFINED] MOVE [IF]
407 \ https://forth-standard.org/standard/core/MOVE
408 \ MOVE    addr1 addr2 u --     smart move
409 \             VERSION FOR 1 ADDRESS UNIT = 1 CHAR
410 CODE MOVE
411 MOV TOS,W           \ W = cnt
412 MOV @PSP+,Y         \ Y = addr2 = dst
413 MOV @PSP+,X         \ X = addr1 = src
414 MOV @PSP+,TOS       \ pop new TOS
415 CMP #0,W            \ count = 0 ?
416 0<> IF              \ if 0, already done !
417     CMP X,Y         \ Y-X \ dst - src
418     0= ?GOTO FW1    \ already done !
419     U< IF           \ U< if src > dst
420         BEGIN       \ copy W bytes
421             MOV.B @X+,0(Y)
422             ADD #1,Y
423             SUB #1,W
424         0= UNTIL
425         MOV @IP+,PC
426     ELSE            \ U>= if dst > src
427         ADD W,Y     \ copy W bytes beginning with the end
428         ADD W,X
429         BEGIN
430             SUB #1,X
431             SUB #1,Y
432             MOV.B @X,0(Y)
433             SUB #1,W
434         0= UNTIL
435     THEN
436 THEN
437 FW1 MOV @IP+,PC
438 ENDCODE
439 [THEN]
440
441 [UNDEFINED] .S [IF]    \
442 \ https://forth-standard.org/standard/tools/DotS
443 \ .S        TOS -- TOS          display <depth> of param Stack and stack contents in hedadecimal if not empty
444 CODE .S
445     MOV     TOS,-2(PSP) \ -- TOS ( TOS x x )
446     MOV     PSP,TOS     \ -- PSP ( TOS x x )
447     SUB     #2,TOS      \ -- PSP ( TOS x x )  to take count that TOS is first cell
448     MOV     TOS,-6(PSP) \ -- TOS ( TOS x  PSP )
449     MOV     #PSTACK,TOS \ -- P0  ( TOS x  PSP )
450     SUB     #2,TOS      \ -- P0  ( TOS x  PSP ) to take count that TOS is first cell
451 BW1 MOV     TOS,-4(PSP) \ -- S0  ( TOS S0 PSP ) |  -- TOS ( TOS R0 RSP )
452     SUB     #6,PSP      \ -- TOS S0 PSP S0      |  -- TOS R0 RSP R0 
453     SUB     @PSP,TOS    \ -- TOS S0 PSP S0-SP   |  -- TOS R0 RSP R0-RSP 
454     RRA     TOS         \ -- TOS S0 PSP #cells  |  -- TOS R0 RSP #cells 
455 COLON
456     $3C EMIT            \ char '<'
457     .                   \ display #cells
458     $08 EMIT            \ backspace
459     $3E EMIT SPACE      \ char '>' SPACE
460     2DUP 1+             \ 
461     U< IF 
462         DROP DROP EXIT
463     THEN                \ display content of stack in hexadecimal
464     BASEADR @ >R
465     $10 BASEADR !
466     DO 
467         I @ U.
468     2 +LOOP
469     R> BASEADR !
470 ;
471 [THEN]
472
473 [UNDEFINED] .RS [IF]    \
474 \ .RS         TOS -- TOS           display <depth> of Return Stack and stack contents if not empty
475 CODE .RS
476     MOV     TOS,-2(PSP) \ -- TOS ( TOS x x ) 
477     MOV     RSP,-6(PSP) \ -- TOS ( TOS x  RSP )
478     MOV     #RSTACK,TOS \ -- R0  ( TOS x  RSP )
479     GOTO    BW1
480 ENDCODE
481 [THEN]
482
483 [UNDEFINED] ? [IF]    \
484 \ https://forth-standard.org/standard/tools/q
485 \ ?         adr --            display the content of adr
486 CODE ?          
487     MOV @TOS,TOS
488     MOV #U.,PC  \ goto U.
489 ENDCODE
490 [THEN]
491
492 [UNDEFINED] WORDS [IF]
493 \ https://forth-standard.org/standard/tools/WORDS
494 \ list all words of vocabulary first in CONTEXT.
495 : WORDS                         \ --            
496 CR 
497 CONTEXT @ PAD_ORG                   \ -- VOC_BODY PAD_ORG                  MOVE all threads of VOC_BODY in PAD_ORG
498 THREADS @ DUP +                 \ -- VOC_BODY PAD_ORG THREAD*2
499 MOVE                            \ -- vocabumary entries are copied in PAD_ORG
500 BEGIN                           \ -- 
501     0 DUP                       \ -- ptr=0 MAX=0                
502     THREADS @ DUP + 0           \ -- ptr=0 MAX=0 THREADS*2 0
503         DO                      \ -- ptr MAX            I =  PAD_ptr = thread*2
504         DUP I PAD_ORG + @           \ -- ptr MAX MAX NFAx
505             U< IF               \ -- ptr MAX            if MAX U< NFAx
506                 DROP DROP       \ --                    drop ptr and MAX
507                 I DUP PAD_ORG + @   \ -- new_ptr new_MAX
508             THEN                \ 
509         2 +LOOP                 \ -- ptr MAX
510     ?DUP                        \ -- ptr MAX MAX | -- ptr 0 (all threads in PAD_ORG = 0)
511 WHILE                           \ -- ptr MAX                    replace it by its LFA
512     DUP                         \ -- ptr MAX MAX
513     2 - @                       \ -- ptr MAX [LFA]
514     ROT                         \ -- MAX [LFA] ptr
515     PAD_ORG +                       \ -- MAX [LFA] thread
516     !                           \ -- MAX                [LFA]=new_NFA updates PAD_ORG+ptr
517     DUP                         \ -- MAX MAX
518     COUNT $7F AND               \ -- MAX addr count (with suppr. of immediate bit)
519     TYPE                        \ -- MAX
520     C@ $0F AND                  \ -- count_of_chars
521     $10 SWAP - SPACES           \ --                    complete with spaces modulo 16 chars
522 REPEAT                          \ --
523 DROP                            \ ptr --
524 ;                               \ all threads in PAD_ORG are filled with 0
525 [THEN]
526
527 [UNDEFINED] U.R [IF]
528 : U.R                       \ u n --           display u unsigned in n width (n >= 2)
529 >R  <# 0 # #S #>  
530 R> OVER - 0 MAX SPACES TYPE
531 ;
532 [THEN]
533
534 [UNDEFINED] DUMP [IF]    \
535 \ https://forth-standard.org/standard/tools/DUMP
536 CODE DUMP                   \ adr n  --   dump memory
537 PUSH IP
538 PUSH &BASEADR               \ save current base
539 MOV #$10,&BASEADR           \ HEX base
540 ADD @PSP,TOS                \ -- ORG END
541 LO2HI
542   SWAP 2DUP                 \ -- END ORG END ORG 
543   U. U.                     \ -- END ORG        display org end 
544   $FFF0 AND                 \ -- END ORG_modulo_16
545   DO  CR                    \ generate line
546     I 4 U.R SPACE           \ generate address
547       I 8 + I               \ display first 8 bytes
548       DO I C@ 3 U.R LOOP
549       SPACE
550       I $10 + I 8 +         \ display last 8 bytes
551       DO I C@ 3 U.R LOOP  
552       SPACE SPACE
553       I $10 + I             \ display 16 chars
554       DO I C@ $7E MIN $20 MAX EMIT LOOP
555   $10 +LOOP
556   R> BASEADR !                 \ restore current base
557 ;
558 [THEN]  \ endof [UNDEFINED] DUMP
559
560 RST_HERE
561
562 [THEN]  \ endof [UNDEFINED] {TOOLS}
563 ECHO