swapforth
1// The CALL0 calling convention is:
2//
3// a0 Return address
4// a1 Stack pointer
5// a2-a7 Function args, scratch
6// a8 scratch
7// a12-a15 Callee-saved
8
9// So SwapForth assigns
10
11#define RTOS a0 // return address
12#define RSP a1 // return stack pointer
13#define TOS a2 // top of data stack
14#define DSP a3 // data stack pointer
15#define X0 a4 // temp reg
16#define X1 a5 // temp reg
17#define X2 a6 // temp reg
18#define X3 a7 // temp reg
19#define X4 a8 // temp reg
20#define X5 a9 // temp reg
21#define X6 a10 // temp reg
22#define X7 a11 // temp reg
23#define CTX a12 // context pointer
24#define LPC a13 // loop count
25#define LPO a14 // loop offset
26#define TRUE a15 // constant -1
27
28.set ramhere,0
29
30.macro allot name size
31.equ \name,ramhere
32.set ramhere,ramhere+\size
33.endm
34
35allot context_0,0
36allot _dp,4 /* RAM data pointer */
37allot _cp,4 /* Code pointer */
38allot _forth,4 /* Dictionary pointer */
39allot kpool,4 /* Constant pool */
40allot aname,32 /* name buffer, used during dictionary search */
41allot sourceA,4 /* tib+1 */
42allot sourceC,4
43allot _in,4 /* >IN */
44allot _inwas,4 /* >IN at start of previous word */
45allot recent,4 /* most recent CREATE */
46allot thisxt,4 /* most recent xt */
47allot attachpt,4 /* attach point for ; */
48allot leaves,4*8 /* chain of LEAVE pointers */
49allot leaveptr,4 /* Current LEAVE */
50allot delim,4
51allot _source_id,4
52allot _state,4
53allot _base,4
54allot _tethered,4
55allot oburn,4 /* burn offset */
56
57allot _dsp,4
58allot _lpc,4
59allot _lpo,4
60allot _rsp,4
61allot _rdepth,4
62allot _pc,4
63allot _rstk,(4*32)
64
65allot tib,256 /* terminal input buffer */
66allot burn,1024 /* flash burn area */
67
68.if 0
69allot cwl,4 /* Compilation word list */
70allot wordlists,4 /* All word lists */
71allot nsearch,4 /* Number of word lists in searchlist */
72allot searchlist,4*16 /* search list */
73allot context_1,0
74allot forth,8 /* Forth word list */
75allot internal,8 /* Internal word list */
76allot handler,4 /* exception handler */
77.endif
78
79.set forth_link,0
80.equ INLINE,2
81.equ IMMEDIATE,1
82
83.macro noheader label
84.section .irom0.text
85.p2align 2
86\label:
87.endm
88
89.macro header fname,label,immediate=0
90.section .irom0.text
91.p2align 2
92.long forth_link + (\immediate ^ 1)
93.set forth_link,.-4
94.byte 1f-.-1
95.ascii "\fname"
961:
97.p2align 2
98\label:
99.endm
100
101.macro c d
102call0 \d
103.endm
104
105// prolog, epilog
106// are the entry/exit sequences for non-leaf words
107
108.macro prolog
109addi RSP,RSP,-4
110s32i a0,RSP,0
111.endm
112
113.macro epilog
114l32i a0,RSP,0
115addi RSP,RSP,4
116ret
117.endm
118
119.macro tail d
120l32i.n a0,RSP,0
121addi RSP,RSP,4
122j \d
123.endm
124
125// prologL, epilogL are
126// as above but also preserving the C callee-saved
127// registers a12-15
128//
129.macro prologL
130addi RSP,RSP,-32
131s32i a0,RSP,0
132s32i LPC,RSP,4
133s32i LPO,RSP,8
134s32i a15,RSP,12
135s32i CTX,RSP,16
136.endm
137
138.macro epilogL
139l32i a0,RSP,0
140l32i LPC,RSP,4
141l32i LPO,RSP,8
142l32i a15,RSP,12
143l32i CTX,RSP,16
144addi RSP,RSP,32
145ret
146.endm
147
148.macro tailL d
149l32i.n a0,RSP,0
150l32i LPC,RSP,4
151l32i LPO,RSP,8
152addi RSP,RSP,16
153j \d
154.endm
155
156.macro dup
157addi DSP,DSP,-4
158s32i TOS,DSP,0
159.endm
160
161.macro lit v
162dup
163movi TOS,\v
164.endm
165
166.macro lita o
167dup
168addi TOS,CTX,\o
169.endm
170
171.macro ctxvar o
172dup
173l32i TOS,CTX,\o
174.endm
175
176.macro popX0
177l32i X0,DSP,0
178addi DSP,DSP,4
179.endm
180
181.macro binop op
182popX0
183\op TOS,X0,TOS
184ret
185.endm
186
187.macro _dropN n
188l32i TOS,DSP,4*(\n-1)
189addi DSP,DSP,4*\n
190.endm
191
192.macro _drop
193_dropN 1
194.endm
195
196.macro tosX0
197mov X0,TOS
198_drop
199.endm
200
201.macro to_r
202addi RSP,RSP,-4
203s32i TOS,RSP,0
204_drop
205.endm
206
207.macro r_at
208dup
209l32i.n TOS,RSP,0
210.endm
211
212.macro r_from
213r_at
214addi RSP,RSP,4
215.endm
216
217.macro cmpop op
218popX0
219b\op X0,TOS,1f
220movi TOS,0
221ret
2221:
223movi TOS,-1
224ret
225.endm
226
227.macro icmpop op
228popX0
229b\op TOS,X0,1f
230movi TOS,0
231ret
2321:
233movi TOS,-1
234ret
235.endm
236
237//
238// How DO...LOOP is implemented
239//
240// Uses two registers:
241// LPC is the counter; it starts negative and counts up. When it reaches 0, loop exits
242// LPO is the offset. It is set up at loop start so that I can be computed from (LPC+LPO)
243//
244// So when DO we have ( limit start ) on the stack so need to compute:
245// LPC = start - limit
246// LPO = limit
247//
248// E.g. for "13 3 DO"
249// LPC = -10
250// LPO = 13
251//
252// So the loop runs:
253// LPC -10 -9 -8 -7 -6 -5 -4 -3 -2 -1
254// I 3 4 5 6 7 8 9 10 11 12
255//
256// +LOOP must detect when LPC transitions from -ve to +ve. If the increment is -ve, then
257// the sense of this transition is reversed.
258//
259//
260
261.macro _do
262addi RSP,RSP,-8
263s32i LPC,RSP,0
264s32i LPO,RSP,4
265
266l32i LPO,DSP,0 // TOS: start, LPO: limit
267sub LPC,TOS,LPO
268_dropN 2
269.endm
270
271.macro _qdo
272addi RSP,RSP,-8
273s32i LPC,RSP,0
274s32i LPO,RSP,4
275
276l32i LPO,DSP,0 // TOS: start, LPO: limit
277sub LPC,TOS,LPO
278_dropN 1
279mov TOS,LPC
280.endm
281
282.macro _unloop
283l32i LPC,RSP,0
284l32i LPO,RSP,4
285addi RSP,RSP,8
286.endm
287
288.macro _i
289dup
290add TOS,LPC,LPO
291.endm
292
293
294// ==================== FORTH WORDS =======================
295
296// See p.598 of
297// Xtensa Instruction Set Architecture (ISA) Reference Manual
298// which lists useful idioms
299
300.section .irom0.text
301
302header ".x",dotx
303prolog
304dup
305extui TOS,TOS,28,4
306c hex1
307dup
308extui TOS,TOS,24,4
309c hex1
310dup
311extui TOS,TOS,20,4
312c hex1
313dup
314extui TOS,TOS,16,4
315c hex1
316dup
317extui TOS,TOS,12,4
318c hex1
319dup
320extui TOS,TOS,8,4
321c hex1
322hex2:
323dup
324extui TOS,TOS,4,4
325c hex1
326extui TOS,TOS,0,4
327c hex1
328c space
329epilog
330hex1:
331blti TOS,10,2f
332addi TOS,TOS,'A'-'0'-10
3332: addi TOS,TOS,'0'
334j emit
335
336header ".x2",dotx2
337prolog
338j hex2
339
340header "bye",bye
341j abort
342header "emit",emit
343movi X1,0x60000000
3441:
345l32i X0,X1,0x1c // wait until TX fifo not full
346extui X0,X0,16,8
347beqi X0,0x80,1b
348s32i TOS,X1,0 // transmit
349j drop
350
351header "key",key
352prolog
353c suspend
354c drop
355epilog
356
357header "depth",depth
358dup
359movi X0,(dstk-4)
360sub TOS,X0,DSP
361srai TOS,TOS,2
362ret
363
364header "base",base
365lita _base
366ret
367
368header ">in",to_in
369lita _in
370ret
371
372header "source",source
373lita sourceA
374j two_fetch
375
376header "source-id",source_id
377ctxvar _source_id
378ret
379
380header "2*",two_times,INLINE
381add TOS,TOS,TOS
382ret
383
384header "2/",two_slash,INLINE
385srai TOS,TOS,1
386ret
387
388header "1+",one_plus,INLINE
389addi TOS,TOS,1
390ret
391
392header "1-",one_minus,INLINE
393addi TOS,TOS,-1
394ret
395
396header "0=",zero_equals,INLINE
397movnez TOS,TRUE,TOS
398xor TOS,TOS,TRUE
399ret
400
401header "cell+",cell_plus,INLINE
402addi TOS,TOS,4
403ret
404
405header "cells",cells,INLINE
406slli TOS,TOS,2
407ret
408
409header "<>",not_equal,INLINE
410cmpop ne
411
412header "=",equal,INLINE
413cmpop eq
414
415header ">",greater,INLINE
416icmpop lt
417
418header "<",less,INLINE
419cmpop lt
420
421header "0<",less_than_zero,INLINE
422srai TOS,TOS,31
423ret
424
425header "0>",greater_than_zero,INLINE
426beqz TOS,1f
427srai TOS,TOS,31
428xor TOS,TOS,TRUE
4291:
430ret
431
432header "0<>",not_equal_zero,INLINE
433movnez TOS,TRUE,TOS
434ret
435
436header "u<",unsigned_less,INLINE
437cmpop ltu
438
439header "u>",unsigned_greater,INLINE
440icmpop ltu
441
442header "+",plus,INLINE
443binop add
444
445header "s>d",s_to_d,INLINE
446dup
447srai TOS,TOS,31
448ret
449
450header "d>s",d_to_s,INLINE
451j drop
452
453header "m+",m_plus
454prolog
455c s_to_d
456tail d_plus
457
458header "d+",d_plus
459l32i X0,DSP,0
460l32i X1,DSP,4
461l32i X2,DSP,8
462
463add X0,X0,X2
464add TOS,TOS,X1
465bgeu X0,X2,1f
466addi TOS,TOS,1
4671:
468addi DSP,DSP,8
469s32i X0,DSP,0
470ret
471
472header "d=",d_equal
473l32i X1,DSP,4
474bne TOS,X1,d_false
475l32i X0,DSP,0
476l32i X2,DSP,8
477bne X0,X2,d_false
478d_true:
479movi TOS,-1
480addi DSP,DSP,12
481ret
482d_false:
483movi TOS,0
484addi DSP,DSP,12
485ret
486
487header "du<",d_u_less
488l32i X1,DSP,4
489bltu TOS,X1,d_false
490bne X1,TOS,d_true
491l32i X0,DSP,0
492l32i X2,DSP,8
493bltu X2,X0,d_true
494j d_false
495
496header "d<",d_less
497l32i X1,DSP,4
498blt TOS,X1,d_false
499bne X1,TOS,d_true
500l32i X0,DSP,0
501l32i X2,DSP,8
502bltu X2,X0,d_true
503j d_false
504
505header "d0<",d_less_than_zero
506srai TOS,TOS,31
507j nip
508
509header "dnegate",d_negate
510prolog
511c invert
512c swap
513c invert
514c swap
515lit 1
516tail m_plus
517
518header "d-",d_minus
519prolog
520c d_negate
521tail d_plus
522
523header "d2*",d_two_times,INLINE
524l32i X0,DSP,0
525ssai 32-1 // setup for left funnel shift
526src TOS,TOS,X0
527slli X0,X0,1
528s32i X0,DSP,0
529ret
530
531header "d2/",d_two_slash,INLINE
532l32i X0,DSP,0
533ssai 1 // setup for right funnel shift
534src X0,TOS,X0
535srai TOS,TOS,1
536s32i X0,DSP,0
537ret
538
539header "-",minus,INLINE
540binop sub
541
542header "negate",negate,INLINE
543neg TOS,TOS
544ret
545
546header "invert",invert,INLINE
547xor TOS,TOS,TRUE
548ret
549
550header "and",and,INLINE
551binop and
552
553header "or",or,INLINE
554binop or
555
556header "xor",xor,INLINE
557binop xor
558
559header "lshift",lshift,INLINE
560popX0
561ssl TOS
562sll TOS,X0
563ret
564
565header "rshift",rshift,INLINE
566popX0
567ssr TOS
568srl TOS,X0
569ret
570
571header "abs",_abs,INLINE
572abs TOS,TOS
573ret
574
575header "um*",u_m_multiply,INLINE
576l32i X0,DSP,0
577extui X1,TOS,16,16
578extui X2,X0,16,16
579mul16u X3,TOS,X0 // lo part
580mul16u X4,X1,X0
581mul16u X5,TOS,X2
582mul16u TOS,X1,X2 // hi part
583add X5,X5,X4 // mid part
584bgeu X5,X4,1f // mid carry into hi
585movi X4,0x10000
586add TOS,TOS,X4
5871:
588extui X4,X5,16,16
589add TOS,TOS,X4
590slli X5,X5,16
591add X3,X3,X5
592bgeu X3,X5,1f
593addi TOS,TOS,1
5941:
595s32i X3,DSP,0
596ret
597
598header "*",multiply,INLINE
599binop mull
600
601header "um/mod",u_m_slash_mod
602l32i X2,DSP,0
603l32i X3,DSP,4 // X2:X3 is the dividend
604// TOS is the divisor
605movi X0,32
606ssai 32-1 // setup for left funnel shift
6070:
608// Handle large X2 case. After shift, (X2 >= 2**32), so certainly greater than TOS
609bltz X2,3f
610src X2,X2,X3
611slli X3,X3,1
612bltu X2,TOS,1f
6132:
614sub X2,X2,TOS
615addi X3,X3,1
6161:
617addi X0,X0,-1
618bnez X0,0b
619
620addi DSP,DSP,4
621s32i X2,DSP,0
622mov TOS,X3
623ret
624
6253:
626src X2,X2,X3
627slli X3,X3,1
628j 2b
629
630header "c@",c_fetch,INLINE
631l8ui TOS,TOS,0
632ret
633
634header "c!",c_store,INLINE
635l32i X0,DSP,0
636s8i X0,TOS,0
637j two_drop
638
639header "@",fetch,INLINE
640l32i TOS,TOS,0
641ret
642
643header "!",store,INLINE
644l32i X0,DSP,0
645s32i X0,TOS,0
646j two_drop
647
648header "2@",two_fetch,INLINE
649l32i X0,TOS,4
650l32i TOS,TOS,0
651addi DSP,DSP,-4
652s32i X0,DSP,0
653ret
654
655header "2!",two_store,INLINE
656l32i X0,DSP,0
657s32i X0,TOS,0
658l32i X0,DSP,4
659s32i X0,TOS,4
660
661l32i TOS,DSP,8
662addi DSP,DSP,12
663ret
664
665header "/string",slash_string
666prolog
667mov X0,TOS
668c drop
669l32i X1,DSP,0
670add X1,X1,X0
671s32i X1,DSP,0
672sub TOS,TOS,X0
673epilog
674
675header "swap",swap,INLINE
676l32i X0,DSP,0
677s32i TOS,DSP,0
678mov TOS,X0
679ret
680
681header "over",over,INLINE
682dup
683l32i TOS,DSP,4
684ret
685
686header "false",false,INLINE
687lit 0
688ret
689
690header "true",true,INLINE
691lit -1
692ret
693
694header "bl",_bl,INLINE
695lit ' '
696ret
697
698header "rot",rot,INLINE
699l32i X0,DSP,0
700s32i TOS,DSP,0
701l32i TOS,DSP,4
702s32i X0,DSP,4
703ret
704
705header "noop",noop
706ret
707
708header "-rot",minus_rot,INLINE
709l32i X0,DSP,0
710l32i X1,DSP,4
711
712s32i TOS,DSP,4
713s32i X1,DSP,0
714mov TOS,X0
715ret
716
717header "tuck",tuck
718prolog
719c swap
720c over
721epilog
722
723header "?dup",question_dupe
724beqz TOS,1f
725dup
7261: ret
727
728header "2dup",two_dup,INLINE
729prolog
730c over
731tail over
732
733header "+!",plus_store,INLINE
734l32i X0,DSP,0
735l32i X1,TOS,0
736add X1,X1,X0
737s32i X1,TOS,0
738j two_drop
739
740header "2swap",two_swap,INLINE
741// rot >r rot r>
742prolog
743c rot
744to_r
745c rot
746r_from
747epilog
748
749header "2over",two_over,INLINE
750dup
751l32i TOS,DSP,12
752dup
753l32i TOS,DSP,12
754ret
755
756header "min",min,INLINE
757popX0
758blt TOS,X0,1f
759mov TOS,X0
7601: ret
761
762header "max",max,INLINE
763popX0
764bge TOS,X0,1f
765mov TOS,X0
7661: ret
767
768header "space",space
769lit ' '
770j emit
771
772header "cr",cr
773prolog
774lit '\r'
775c emit
776lit '\n'
777c emit
778epilog
779
780header "count",count,INLINE
781mov X0,TOS
782addi TOS,TOS,1
783dup
784l8ui TOS,X0,0
785ret
786
787header "dup",dupe,INLINE
788dup
789ret
790
791header "drop",drop,INLINE
792_drop
793ret
794
795header "nip",nip,INLINE
796addi DSP,DSP,4
797ret
798
799header "2drop",two_drop,INLINE
800_dropN 2
801ret
802
803header "execute",execute
804mov X0,TOS
805_drop
806jx X0
807
808header "bounds",bounds,INLINE
809l32i X0,DSP,0
810add TOS,TOS,X0
811s32i TOS,DSP,0
812mov TOS,X0
813ret
814
815// : within over - >r - r> u< ;
816header "within",within,INLINE
817l32i X0,DSP,4
818l32i X1,DSP,0
819addi DSP,DSP,8
820// So now have: X0 X1 TOS
821// v lo hi
822sub TOS,TOS,X1 // TOS is hi-lo
823sub X0,X0,X1 // X0 is v-lo
824bltu X0,TOS,1f
825movi TOS,0
826ret
8271:
828movi TOS,-1
829ret
830
831header "type",type
832prolog
8331: beqz TOS,2f
834c over
835c c_fetch
836c emit
837lit 1
838c slash_string
839j 1b
8402: c two_drop
841epilog
842
843// ( addr -- addr' ) advance to next word in dictionary
844nextword:
845l32i TOS,TOS,0
846movi X0,~3
847and TOS,TOS,X0
848ret
849
850header "tolower",tolower
851prolog
852dup
853lit 'A'
854lit 'Z'+1
855c within
856lit 'a'-'A'
857c and
858tail plus
859
860noheader case_equal
861prolog
862c tolower
863c swap
864c tolower
865tail equal
866
867toaname: // ( caddr u -- ) store string in aname, padded with zeroes
868prolog
869dup
870lita aname
871c c_store
872
873lita aname+1
874lit 31
875lit 0
876c fill
877
878lita aname+1
879c swap
880c cmove
881
882lita aname
883c count
884c bounds
885_do
8861:
887_i
888c c_fetch
889c tolower
890_i
891c c_store
892
893addi LPC,LPC,1
894bnez LPC,1b
895_unloop
896epilog
897
898// SFIND
899// ( c-addr u -- c-addr u 0 | xt 1 | xt -1 )
900//
901// Find the definition named in the string at c-addr. If the
902// definition is not found, return c-addr and zero. If the definition
903// is found, return its execution token xt. If the definition is
904// immediate, also return one (1), otherwise also return minus-one
905// (-1).
906
907.p2align 2
908compares:
909.long 0
910.long cmp4
911.long cmp8
912.long cmp12
913.long cmp16
914.long cmp20
915.long cmp24
916.long cmp28
917.long cmp32
918
919header "sfind",sfind
920prolog
921dup
922addi TOS,TOS,1
923c aligned
924movi X0,compares
925add TOS,X0,TOS
926l32i TOS,TOS,0
927to_r
928
929c two_dup
930c toaname
931
932r_from
933mov X7,TOS
934_drop
935lita _forth
936trynext:
937c nextword
938beqz TOS,1f
939jx X7
940cmp32:
941l32i X0,CTX,aname
942l32i X1,TOS,4
943bne X0,X1,trynext
944cmp28:
945l32i X0,CTX,aname
946l32i X1,TOS,4
947bne X0,X1,trynext
948cmp24:
949l32i X0,CTX,aname
950l32i X1,TOS,4
951bne X0,X1,trynext
952cmp20:
953l32i X0,CTX,aname
954l32i X1,TOS,4
955bne X0,X1,trynext
956cmp16:
957l32i X0,CTX,aname
958l32i X1,TOS,4
959bne X0,X1,trynext
960cmp12:
961l32i X0,CTX,aname
962l32i X1,TOS,4
963bne X0,X1,trynext
964cmp8:
965l32i X0,CTX,aname+4
966l32i X1,TOS,8
967bne X0,X1,trynext
968cmp4:
969l32i X0,CTX,aname
970l32i X1,TOS,4
971bne X0,X1,trynext
972
973c nip
974c nip
975dup
976// TOS is address of word. Go to XT
977l32i X0,TOS,4
978extui X0,X0,0,8
979addi X0,X0,5
980add TOS,TOS,X0
981c aligned
982c swap
983l32i TOS,TOS,0
984extui TOS,TOS,0,1 // immediate: 1, otherwise 0
985add TOS,TOS,TOS // immediate: 2, otherwise 0
986addi TOS,TOS,-1 // immediate: 1, otherwise -1
987c negate
9881:
989epilog
990
991header "words",words
992prolog
993lita _forth
9942: c nextword
995beqz TOS,1f
996dup
997c cell_plus
998
999l32i X1,TOS,0
1000s32i X1,CTX,aname+0
1001l32i X1,TOS,4
1002s32i X1,CTX,aname+4
1003l32i X1,TOS,8
1004s32i X1,CTX,aname+8
1005l32i X1,TOS,12
1006s32i X1,CTX,aname+12
1007l32i X1,TOS,16
1008s32i X1,CTX,aname+16
1009l32i X1,TOS,20
1010s32i X1,CTX,aname+20
1011l32i X1,TOS,24
1012s32i X1,CTX,aname+24
1013l32i X1,TOS,28
1014s32i X1,CTX,aname+28
1015c drop
1016
1017lita aname
1018c count
1019c type
1020c space
1021
1022j 2b
10231:
1024tail drop
1025
1026header "accept",accept // ( c-addr +n1 -- +n2 )
1027prolog
1028lit 0x1e // tethered
1029c emit
1030
1031c drop
1032c dupe
10330:
1034c key
1035movi X0,13
1036beq TOS,X0,1f
1037c over
1038c c_store
1039c one_plus
1040j 0b
10411:
1042c drop
1043c swap
1044tail minus
1045
1046header "refill",refill
1047prolog
1048l32i X0,CTX,_source_id
1049bnez X0,false
1050
1051lita tib
1052c dupe
1053lit 128
1054c accept
1055lita sourceA
1056c two_store
1057lit 0
1058lita _in
1059c store
1060c true
10611: epilog
1062
1063// \ From Forth200x - public domain
1064//
1065// : isspace? ( c -- f )
1066// h# 21 u< ;
1067
1068isspace:
1069lit 0x21
1070j unsigned_less
1071
1072//
1073// : isnotspace? ( c -- f )
1074// isspace? 0= ;
1075
1076isnotspace:
1077prolog
1078c isspace
1079tail zero_equals
1080//
1081// : xt-skip ( addr1 n1 xt -- addr2 n2 ) \ gforth
1082// \ skip all characters satisfying xt ( c -- f )
1083// >r
1084// BEGIN
1085// over c@ r@ execute
1086// overand
1087// WHILE
1088// d# 1 /string
1089// REPEAT
1090// r> drop ;
1091
1092xt_skip:
1093prolog
1094to_r
10950:
1096c over
1097c c_fetch
1098r_at
1099c execute
1100c over
1101c and
1102tosX0
1103beqz X0,1f
1104lit 1
1105c slash_string
1106j 0b
11071:
1108r_from
1109tail drop
1110//
1111// header parse-name
1112// : parse-name ( "name" -- c-addr u )
1113// source >in @ /string
1114// ['] isspace? xt-skip over >r
1115// ['] isnotspace? xt-skip ( end-word restlen r: start-word )
1116// 2dup d# 1 min + source drop - >in !
1117// drop r> tuck -
1118// ;
1119
1120header "parse-name",parse_name
1121prolog
1122c source
1123ctxvar _in
1124c slash_string
1125lit isspace
1126c xt_skip
1127c over
1128to_r
1129lit isnotspace
1130c xt_skip
1131c two_dup
1132lit 1
1133c min
1134c plus
1135c source
1136c drop
1137c minus
1138c to_in
1139c store
1140c drop
1141r_from
1142c tuck
1143c minus
1144epilog
1145
1146// : digit? ( c -- u f )
1147// lower
1148// dup h# 39 > h# 100 and +
1149// dup h# 160 > h# 127 and - h# 30 -
1150// dup base @i u<
1151// ;
1152isdigit:
1153prolog
1154movi X0,'A'
1155movi X1,'Z'+1
1156blt TOS,X0,1f
1157bge TOS,X1,1f
1158addi TOS,TOS,0x20
11591:
1160c dupe
1161lit 0x39
1162c greater
1163lit 0x100
1164c and
1165c plus
1166
1167c dupe
1168lit 0x160
1169c greater
1170lit 0x127
1171c and
1172c minus
1173lit 0x30
1174c minus
1175
1176c dupe
1177ctxvar _base
1178tail unsigned_less
1179
1180// : >number ( ud1 c-addr1 u1 -- ud2 c-addr2 u2 )
1181// begin
1182// dup
1183// while
1184// over c@ digit?
1185// 0= if drop ; then
1186// >r 2swap base @i
1187// \ ud*
1188// tuck * >r um* r> +
1189// r> m+ 2swap
1190// 1/string
1191// repeat
1192// ;
1193header ">number",to_number
1194prolog
11950:
1196beqz TOS,1f
1197
1198c over
1199c c_fetch
1200c isdigit
1201tosX0
1202bnez X0,2f
1203tail drop
12042:
1205
1206to_r
1207c two_swap
1208ctxvar _base
1209
1210c tuck
1211c multiply
1212to_r
1213c u_m_multiply
1214r_from
1215c plus
1216
1217r_from
1218
1219c m_plus
1220c two_swap
1221
1222lit 1
1223c slash_string
1224j 0b
12251:
1226epilog
1227
1228
1229header "abort",abort
1230c cr
1231lit 'A'
1232c emit
1233lit 'B'
1234c emit
1235lit 'O'
1236c emit
1237lit 'R'
1238c emit
1239lit 'T'
1240c emit
1241c cr
12421:
1243j 1b
1244
1245header "postpone",postpone,IMMEDIATE
1246prolog
1247c parse_name
1248c sfind
1249tosX0
1250beqz X0,abort
1251bgez X0,1f
1252c literal
1253lit compile_comma
12541:
1255tail compile_comma
1256
1257isnotdelim:
1258ctxvar delim
1259j not_equal
1260
1261header "parse",parse
1262prolog
1263lita delim
1264c store
1265c source
1266ctxvar _in
1267c slash_string
1268
1269// over >r
1270c over
1271to_r
1272// ['] isnotdelim xt-skip
1273lit isnotdelim
1274c xt_skip
1275
1276// 2dup d# 1 min + source drop - >in !
1277c two_dup
1278lit 1
1279c min
1280c plus
1281c source
1282c drop
1283c minus
1284c to_in
1285c store
1286// drop r> tuck -
1287
1288c drop
1289r_from
1290c tuck
1291tail minus
1292
1293header "throw",throw
1294beqz TOS,drop
1295j abort
1296
1297header "evaluate",evaluate
1298prolog
1299c source
1300to_r
1301to_r
1302ctxvar _in
1303to_r
1304ctxvar _source_id
1305to_r
1306c true
1307lita _source_id
1308c store
1309
1310lita sourceA
1311c two_store
1312c false
1313lita _in
1314c store
1315
1316c interpret
1317
1318r_from
1319lita _source_id
1320c store
1321r_from
1322lita _in
1323c store
1324r_from
1325r_from
1326lita sourceA
1327tail two_store
1328
1329header "here",here
1330ctxvar _dp
1331ret
1332
1333header "dp",dp
1334lita _dp
1335ret
1336
1337header "chere",chere
1338j abort
1339
1340header "cp",cp
1341lita _cp
1342ret
1343
1344header "forth",forth
1345lita _forth
1346ret
1347
1348header "state",state
1349lita _state
1350ret
1351
1352header "unused",unused
1353j abort
1354
1355header "aligned",aligned
1356addi TOS,TOS,3
1357srli TOS,TOS,2
1358slli TOS,TOS,2
1359ret
1360
1361header "align",align
1362l32i X0,CTX,_dp
1363addi X0,X0,3
1364srli X0,X0,2
1365slli X0,X0,2
1366s32i X0,CTX,_dp
1367ret
1368
1369header "allot",allot
1370lita _dp
1371j plus_store
1372
1373header ",",comma
1374l32i X0,CTX,_dp
1375s32i TOS,X0,0
1376addi X0,X0,4
1377s32i X0,CTX,_dp
1378_drop
1379ret
1380
1381header "c,",c_comma
1382l32i X0,CTX,_dp
1383s8i TOS,X0,0
1384addi X0,X0,1
1385s32i X0,CTX,_dp
1386_drop
1387ret
1388
1389noheader createstub
1390epilog
1391
1392noheader docreate
1393dup
1394l32i TOS,a0,0
1395l32i X0,TOS,-4
1396jx X0
1397
1398header "create",create
1399prolog
1400c align
1401
1402l32i X0,CTX,_dp
1403s32i X0,CTX,recent
1404
1405lit createstub
1406c comma
1407
1408c mkhdr
1409lit s_prolog
1410c code_s_comma
1411lit docreate
1412c compile_comma
1413c here
1414c code_comma
1415c doburn
1416epilog
1417
1418header "s,",s_comma
1419j abort
1420
1421header ">r",to_r,IMMEDIATE
1422lit s_to_r
1423j code_s_comma
1424
1425header "r>",r_from,IMMEDIATE
1426lit s_r_from
1427j code_s_comma
1428
1429header "r@",r_at,IMMEDIATE
1430lit s_r_at
1431j code_s_comma
1432
1433header "2>r",two_to_r,IMMEDIATE
1434j abort
1435
1436header "2r>",two_r_from,IMMEDIATE
1437j abort
1438
1439header "2r@",two_r_at
1440j abort
1441
1442atburn:
1443ctxvar oburn
1444lita burn
1445j plus
1446
1447header "code.,",code_comma
1448prolog
1449c atburn
1450c store
1451lit 4
1452lita oburn
1453tail plus_store
1454
1455header "code.,",code_c_comma
1456prolog
1457c atburn
1458c c_store
1459lit 1
1460lita oburn
1461tail plus_store
1462
1463header "code.24,",code_24_comma
1464prolog
1465dup
1466c code_c_comma
1467
1468lit 8
1469c rshift
1470dup
1471c code_c_comma
1472
1473lit 8
1474c rshift
1475tail code_c_comma
1476
1477header "code.s,",code_s_comma
1478prolog
1479c count
14801:
1481beqz TOS,2f
1482c over
1483c c_fetch
1484c code_c_comma
1485lit 1
1486c slash_string
1487j 1b
14882: tail two_drop
1489
1490header ":noname",colon_noname
1491prolog
1492c right_bracket
1493
1494c false
1495lita attachpt
1496c store
1497
1498ctxvar _cp
1499dup
1500lita thisxt
1501c store
1502
1503lit s_prolog
1504tail code_s_comma
1505
1506noheader mkhdr
1507prolog
1508ctxvar _cp
1509lita attachpt
1510c store
1511
1512c parse_name
1513beqz TOS,abort
1514
1515ctxvar _forth
1516addi TOS,TOS,1 // default is non-immediate
1517c code_comma
1518
1519c tuck
1520c toaname
1521c one_plus
1522c aligned // ( n )
1523dup
1524
1525lita aname
1526c atburn
1527c rot // ( aname burn@ n )
1528c cmove
1529lita oburn
1530tail plus_store // advance burn pointer
1531
1532header ":",colon
1533prolog
1534c mkhdr
1535c right_bracket
1536
1537ctxvar _cp
1538ctxvar oburn
1539c plus
1540lita thisxt
1541c store
1542
1543lit s_prolog
1544tail code_s_comma
1545
1546header "flashbase",flashbase
1547lit 0x40200000
1548ret
1549
1550doburn:
1551prolog
1552
1553ctxvar oburn
1554c aligned
1555lita oburn
1556c store
1557
1558l32i X0,CTX,attachpt
1559beqz X0,1f
1560s32i X0,CTX,_forth
15611:
1562
1563ctxvar _cp
1564movi X0,0x40200000
1565sub TOS,TOS,X0
1566lita burn
1567ctxvar oburn
1568c _spi_flash_write
1569c throw
1570
1571ctxvar oburn
1572lita _cp
1573c plus_store
1574
1575c false
1576lita oburn
1577tail store
1578
1579header ";",semi_colon,IMMEDIATE
1580prolog
1581c exit
1582c doburn
1583tail left_bracket
1584
1585header "exit",exit,IMMEDIATE
1586lit s_epilog
1587j code_s_comma
1588
1589header "immediate",immediate
1590prolog
1591ctxvar _forth
1592l32i TOS,TOS,0
1593srli TOS,TOS,1 // Clear bit 0
1594slli TOS,TOS,1
1595s32i TOS,CTX,aname
1596_drop
1597
1598ctxvar _forth
1599movi X0,0x40200000
1600sub TOS,TOS,X0
1601lita aname
1602lit 4
1603c _spi_flash_write
1604tail throw
1605
1606header "does>",does
1607l32i X0,CTX,recent
1608s32i a0,X0,0
1609epilog
1610
1611header "[",left_bracket,IMMEDIATE
1612movi X0,0
1613s32i X0,CTX,_state
1614ret
1615
1616header "]",right_bracket
1617movi X0,3
1618s32i X0,CTX,_state
1619ret
1620
1621// ==================== LITERALS ==========================
1622
1623noheader k_1
1624dup
1625movi TOS,1
1626ret
1627
1628noheader k_2
1629dup
1630movi TOS,2
1631ret
1632
1633noheader k_3
1634dup
1635movi TOS,3
1636ret
1637
1638noheader k_4
1639dup
1640movi TOS,4
1641ret
1642
1643.p2align 2
1644.long true // -1
1645fastconsts:
1646.long false // 0
1647.long k_1
1648.long k_2
1649.long k_3
1650.long k_4
1651
1652header "literal",literal,IMMEDIATE
1653prolog
1654
1655dup
1656lit -1
1657lit 5
1658c within
1659tosX0
1660beqz X0,1f
1661
1662movi X0,fastconsts
1663addx4 TOS,TOS,X0
1664l32i TOS,TOS,0
1665tail compile_comma
1666
16671:
1668// Now search through kpool, stopping on a match or on FFFFFFFF
1669s32i TOS,CTX,aname
1670mov X0,TOS
1671l32i TOS,CTX,kpool
16722:
1673l32i X1,TOS,0
1674beq X1,X0,4f
1675beqi X1,-1,3f
1676
1677addi TOS,TOS,4
1678j 2b
1679
16803: // no match found, assign slot at TOS
1681
1682dup
1683movi X0,0x40200000
1684sub TOS,TOS,X0
1685lita aname
1686lit 4
1687c _spi_flash_write
1688c throw
1689
16904: // match found at TOS
1691
1692lit s_dup
1693c code_s_comma
1694
1695srli TOS,TOS,2
1696ctxvar _cp
1697ctxvar oburn
1698c plus
1699addi TOS,TOS,3
1700srli TOS,TOS,2
1701c minus
1702slli TOS,TOS,8
1703addi TOS,TOS,0x21 // l32r a2,
1704tail code_24_comma
1705
1706header "compile,",compile_comma
1707prolog
1708ctxvar _cp
1709ctxvar oburn
1710c plus
1711srli TOS,TOS,2
1712slli TOS,TOS,2
1713addi TOS,TOS,4
1714c minus
1715lit 2
1716c rshift
1717lit 6
1718c lshift
1719addi TOS,TOS,0x05
1720tail code_24_comma
1721
1722header "2literal",two_literal,IMMEDIATE
1723prolog
1724c swap
1725c literal
1726tail literal
1727
1728header "cmove",cmove
1729l32i X0,DSP,0
1730l32i X1,DSP,4
1731add TOS,TOS,X0
1732// Move bytes from X1 to X0 until X0 reaches TOS
1733j 2f
17341:
1735l8ui X2,X1,0
1736s8i X2,X0,0
1737addi X0,X0,1
1738addi X1,X1,1
17392:
1740bne TOS,X0,1b
1741three_drop:
1742l32i TOS,DSP,8
1743addi DSP,DSP,12
1744ret
1745
1746header "cmove>",cmove_up
1747l32i X0,DSP,0
1748l32i X1,DSP,4
1749add X0,X0,TOS
1750add TOS,TOS,X1
1751// Move bytes from TOS to X0 while TOS>=X1
1752j 2f
17531:
1754l8ui X2,TOS,0
1755s8i X2,X0,0
17562:
1757addi X0,X0,-1
1758addi TOS,TOS,-1
1759bgeu TOS,X1,1b
1760j three_drop
1761
1762header "fill",fill
1763l32i X0,DSP,0
1764l32i X1,DSP,4
1765add X0,X0,X1
1766// Fill X1 with TOS until X1 reaches X0
1767j 2f
17681:
1769s8i TOS,X1,0
1770addi X1,X1,1
17712:
1772bne X1,X0,1b
1773j three_drop
1774
1775header "begin",begin,IMMEDIATE
1776j atburn
1777
1778header "ahead",ahead,IMMEDIATE
1779prolog
1780c begin
1781lit 0x000006
1782tail code_24_comma
1783
1784header "if",if,IMMEDIATE
1785prolog
1786lit s_tosX0
1787c code_s_comma
1788c begin
1789lit 0x000416
1790tail code_24_comma
1791
1792header "then",then,IMMEDIATE
1793prolog
1794dup
1795addi TOS,TOS,4
1796c begin
1797c swap
1798c minus
1799tail patch
1800
1801// patch ( ptr offset )
1802// patch OFFSET into jump/branch instruction at byte-aligned PTR
1803// Byte at PTR determines the instruction pattern:
1804//
1805// 06: "J" instruction, so left-shift 6
1806// else: branch instruction, so left-shift 12
1807//
1808
1809patch:
1810l32i X0,DSP,0 // X0:ptr TOS:insn
1811
1812l8ui X1,X0,0
1813beqi X1,0x06,patch_j
1814slli TOS,TOS,12
1815j or24
1816patch_j:
1817slli TOS,TOS,6
1818or24:
1819or X1,X1,TOS
1820s8i X1,X0,0
1821
1822l8ui X1,X0,1
1823srli TOS,TOS,8
1824or X1,X1,TOS
1825s8i X1,X0,1
1826
1827l8ui X1,X0,2
1828srli TOS,TOS,8
1829or X1,X1,TOS
1830s8i X1,X0,2
1831
1832_dropN 2
1833ret
1834
1835header "again",again,IMMEDIATE
1836prolog
1837c begin
1838addi TOS,TOS,4
1839c minus
1840lit 6
1841c lshift
1842addi TOS,TOS,0x06
1843tail code_24_comma
1844
1845header "until",until,IMMEDIATE
1846prolog
1847lit s_tosX0
1848c code_s_comma
1849
1850c begin
1851addi TOS,TOS,4
1852c minus
1853slli TOS,TOS,12
1854lit 0x000416
1855c or
1856tail code_24_comma
1857
1858header "recurse",recurse,IMMEDIATE
1859ctxvar thisxt
1860j compile_comma
1861
1862noheader push_leave
1863l32i X0,CTX,leaveptr
1864s32i TOS,X0,0
1865addi X0,X0,4
1866s32i X0,CTX,leaveptr
1867j drop
1868
1869noheader pop_leave
1870l32i X0,CTX,leaveptr
1871dup
1872addi X0,X0,-4
1873l32i TOS,X0,0
1874s32i X0,CTX,leaveptr
1875ret
1876
1877header "do",do,IMMEDIATE
1878prolog
1879lit 0
1880c push_leave
1881lit s_do
1882c code_s_comma
1883tail begin
1884
1885header "?do",question_do,IMMEDIATE
1886prolog
1887
1888lit 0
1889c push_leave
1890
1891lit s_qdo
1892c code_s_comma
1893c if
1894c push_leave
1895
1896tail begin
1897
1898header "leave",leave,IMMEDIATE
1899prolog
1900c ahead
1901tail push_leave
1902
1903header "loop",loop,IMMEDIATE
1904prolog
1905lit s_loop
1906c code_s_comma
1907
1908c begin
1909addi TOS,TOS,4
1910c minus
1911slli TOS,TOS,12
1912lit 0x000d56 // bnez a13 ...
1913c or
1914c code_24_comma
1915loop_common:
1916c pop_leave
1917beqz TOS,1f
1918c then
1919j loop_common
19201:
1921_drop
1922tail unloop
1923
1924noheader do_plus_loop
1925// When LPC transitions from -ve to +ve
1926srai X0,TOS,31 // increment sign
1927xor X1,LPC,X0 // X1 old LPC
1928add LPC,LPC,TOS
1929xor X0,LPC,X0 // X0 new LPC
1930_drop
1931ret
1932
1933header "+loop",plus_loop,IMMEDIATE
1934prolog
1935lit do_plus_loop
1936c compile_comma
1937
1938c begin
1939addi TOS,TOS,4
1940c minus
1941slli TOS,TOS,16
1942lit 0x00b457 // bgeu X0,X1, ...
1943c or
1944c code_24_comma
1945j loop_common
1946
1947header "unloop",unloop,IMMEDIATE
1948lit s_unloop
1949j code_s_comma
1950
1951header "i",i,IMMEDIATE
1952lit s_i
1953j code_s_comma
1954
1955header "j",j
1956dup
1957l32i TOS,RSP,0
1958l32i X0,RSP,4
1959add TOS,TOS,X0
1960ret
1961
1962header "decimal",decimal
1963movi X0,10
1964s32i X0,CTX,_base
1965ret
1966
1967snap:
1968c cr
1969c depth
1970c dotx
1971c space
1972j 2f
19731:
1974c dotx
19752:
1976c depth
1977tosX0
1978bnez X0,1b
19793:
1980j 3b
1981
1982// ==================== NUMBERS ===========================
1983
1984// : isvoid ( caddr u -- ) \ any char remains, abort
1985isvoid:
1986addi DSP,DSP,4
1987tosX0
1988bnez X0,nosuchword
1989ret
1990
1991nosuchword:
1992lit 'N'
1993c emit
1994lit 'O'
1995c emit
1996c space
1997lit 'W'
1998c emit
1999c cr
2000c space
2001lita aname
2002c count
2003c type
2004c cr
2005
2006lit 0x1e
2007c emit
20081:
2009j 1b
2010
2011// : consume1 ( caddr u ch -- caddr' u' f )
2012// >r over c@ r> =
2013// over 0<> and
2014// dup>r d# 1 and /string r>
2015// ;
2016consume1:
2017prolog
2018to_r
2019c over
2020c c_fetch
2021r_from
2022c equal
2023
2024c over
2025c not_equal_zero
2026c and
2027
2028dup
2029to_r
2030c negate
2031c slash_string
2032r_from
2033epilog
2034
2035doubleAlso2:
2036prolog
2037lit 0
2038dup
2039c two_swap
2040lit '-'
2041c consume1
2042to_r
2043c to_number
2044lit '.'
2045c consume1
2046tosX0
2047beqz X0,1f
2048c isvoid
2049r_from
2050tosX0
2051beqz X0,2f
2052c d_negate
20532:
2054lit 2
2055epilog
2056
20571:
2058c isvoid
2059c drop
2060r_from
2061tosX0
2062beqz X0,3f
2063c negate
20643:
2065lit 1
2066epilog
2067
2068doubleAlso1:
2069prolog
2070// Handle 'X' here
2071bnei TOS,3,1f
2072l32i X0,DSP,0
2073movi X2,0x27 // ascii '
2074l8ui X1,X0,0
2075bne X1,X2,1f
2076l8ui X1,X0,2
2077bne X1,X2,1f
2078// matches 'X'. Return ( X 1 )
2079_drop
2080l8ui TOS,X0,1
2081lit 1
2082epilog
20831:
2084lit '$' // hex
2085c consume1
2086movi X1,16
2087tosX0
2088bnez X0,inbase
2089lit '#' // decimal
2090c consume1
2091tosX0
2092movi X1,10
2093bnez X0,inbase
2094lit '%' // binary
2095c consume1
2096tosX0
2097movi X1,2
2098bnez X0,inbase
2099tail doubleAlso2
2100
2101inbase: // conversion in base X1
2102dup
2103l32i TOS,CTX,_base
2104s32i X1,CTX,_base
2105to_r
2106c doubleAlso2
2107r_from
2108c base
2109tail store
2110
2111doubleAlso:
2112prolog
2113c doubleAlso1
2114tail drop
2115
2116doubleAlso_comma:
2117prolog
2118c doubleAlso1
2119tosX0
2120beqi X0,1,1f
2121c swap
2122c literal
21231:
2124tail literal
2125
2126.p2align 2
2127
2128.long execute
2129dispatch:
2130.long doubleAlso
2131.long execute
2132.long compile_comma
2133.long doubleAlso_comma
2134.long execute
2135
2136interpret:
2137prolog
21380:
2139c parse_name
2140beqz TOS,1f
2141c sfind // -1 0 +1
2142l32i X0,CTX,_state // -1 0 +1 +2 +3 +4
2143add TOS,TOS,X0
2144movi X0,dispatch
2145addx4 TOS,TOS,X0
2146l32i TOS,TOS,0
2147c execute
2148j 0b
21491: c two_drop
2150epilog
2151
2152// ==================== ESP SYSTEM INTERFACE ==============
2153
2154// Common calling subroutines. Named for number of
2155// arguments/return values:
2156//
2157// c_common_X_Y
2158//
2159// takes X arguments and returns Y values
2160//
2161
2162c_common_3_1:
2163l32i X0,DSP,4
2164l32i X1,DSP,0
2165mov X2,TOS
2166_dropN 2
2167j c_common_x_1
2168
2169c_common_2_1:
2170l32i X0,DSP,0
2171mov X1,TOS
2172_dropN 1
2173j c_common_x_1
2174
2175c_common_0_1:
2176dup
2177j c_common_x_1
2178
2179c_common_1_1:
2180mov X0,TOS
2181c_common_x_1:
2182addi RSP,RSP,-16
2183s32i DSP,RSP,4
2184s32i a0,RSP,0
2185
2186mov a2,X0
2187mov a3,X1
2188mov a4,X2
2189mov a5,X3
2190mov a6,X4
2191
2192callx0 X6
2193
2194l32i a0,RSP,0
2195l32i DSP,RSP,4
2196addi RSP,RSP,16
2197ret
2198
2199header "us@",us_fetch
2200movi X6,system_get_time
2201j c_common_0_1
2202
2203header "spi_flash_write",_spi_flash_write // ( byte-offset source len )
2204movi X6,spi_flash_write
2205j c_common_3_1
2206
2207header "spi_flash_erase_sector",_spi_flash_erase_sector // ( sector )
2208movi X6,spi_flash_erase_sector
2209j c_common_1_1
2210
2211header "ms",ms
2212addi RSP,RSP,-16
2213s32i a0,RSP,0
2214s32i DSP,RSP,4
2215mov a3,a2
2216movi a2,some_timer
2217movi a4,0
2218movi a5,1
2219movi a0,ets_timer_arm_new
2220callx0 a0
2221l32i a0,RSP,0
2222l32i DSP,RSP,4
2223addi RSP,RSP,16
2224_drop
2225j suspend
2226
2227noheader suspend
2228s32i a0,CTX,_pc
2229dup
2230s32i DSP,CTX,_dsp
2231mov a4,a1
2232l32i a1,CTX,_rsp
2233sub a5,a1,a4
2234s32i a5,CTX,_rdepth
2235// Preserve the Rstack by copying from a4..a1 to _rstk
2236addi a5,CTX,_rstk
2237j 2f
22381:
2239l32i a6,a4,0
2240s32i a6,a5,0
2241addi a4,a4,4
2242addi a5,a5,4
22432: bne a4,a1,1b
2244
2245epilogL
2246
2247header "quit",quit
2248prolog
22491:
2250c refill
2251c drop
2252c interpret
2253c space
2254lit 'o'
2255c emit
2256lit 'k'
2257c emit
2258c cr
2259j 1b
22601: epilog
2261
2262.p2align 2
2263.global swapforth
2264swapforth:
2265prologL
2266movi CTX,_ctx
2267s32i a1,CTX,_rsp
2268
2269movi DSP,dstk
2270movi TRUE,-1
2271
2272c decimal
2273
2274addi X0,CTX,leaves
2275s32i X0,CTX,leaveptr
2276
2277lit 64
22781:
2279dup
2280c _spi_flash_erase_sector
2281_drop
2282addi TOS,TOS,1
2283movi X0,96
2284bne TOS,X0,1b
2285_drop
2286
2287l32i X0,CTX,_cp
2288s32i X0,CTX,kpool
2289addi X0,X0,(4*256)
2290s32i X0,CTX,_cp
2291
2292c cr
2293c cr
2294j quit
2295
22961:
2297c refill
2298c dotx
2299ctxvar _rdepth
2300c dotx
2301j 1b
2302
2303
2304lit ssss
2305lit 80
2306lita sourceA
2307c two_store
2308
2309lit 0
2310lita _in
2311c store
2312
2313c interpret
2314c cr
2315
2316lit 0x947
2317to_r
2318
23191:
2320c refill
2321
2322c source
2323c type
2324j 1b
2325
23261:
2327c key
2328c dotx
2329j 1b
2330
2331c cr
2332r_from
2333dup
2334c dotx
2335c cr
2336c one_plus
2337to_r
2338
2339// lit 4000
2340// c ms
2341c suspend
2342
2343j 1b
2344
2345.p2align 2
2346.global swapforth2
2347swapforth2:
2348prologL
2349mov X0,a3
2350movi CTX,_ctx
2351s32i a1,CTX,_rsp
2352
2353l32i DSP,CTX,_dsp
2354movi TRUE,-1
2355
2356// Stage incoming arguments (a2, a3) on the stack
2357addi DSP,DSP,-4
2358s32i X0,DSP,0 // ( par sig )
2359
2360l32i a4,CTX,_rdepth
2361sub a1,a1,a4
2362addi a5,CTX,_rstk
2363add a4,a5,a4
2364// Restore the Rstack by copying from _rstk+4 to r1
2365// So copy a5..a4 to a1 up
2366mov a7,a1
2367j 2f
23681:
2369l32i a6,a5,0
2370s32i a6,a7,0
2371addi a5,a5,4
2372addi a7,a7,4
23732: bne a4,a5,1b
2374
2375l32i a0,CTX,_pc
2376jx a0
2377
2378.section .data
2379
2380s_prolog:
2381.byte 2f-1f
23821: prolog
23832:
2384
2385s_epilog:
2386.byte 2f-1f
23871: epilog
23882:
2389
2390s_tosX0:
2391.byte 2f-1f
23921: tosX0
23932:
2394
2395s_dup:
2396.byte 2f-1f
23971: dup
23982:
2399
2400s_do:
2401.byte 2f-1f
24021: _do
24032:
2404
2405s_qdo:
2406.byte 2f-1f
24071: _qdo
24082:
2409
2410s_loop:
2411.byte 2f-1f
24121: addi LPC,LPC,1
24132:
2414
2415s_unloop:
2416.byte 2f-1f
24171: _unloop
24182:
2419
2420s_i:
2421.byte 2f-1f
24221: _i
24232:
2424
2425s_to_r:
2426.byte 2f-1f
24271: to_r
24282:
2429
2430s_r_from:
2431.byte 2f-1f
24321: r_from
24332:
2434
2435s_r_at:
2436.byte 2f-1f
24371: r_at
24382:
2439
2440.p2align 2
2441_ctx: .long dseg
2442.long 0x40240000 // CP
2443.long forth_link
2444.skip ramhere-12
2445
2446ssss:
2447# .ascii "us@ 1+ 1- us@ swap - .x"
2448.ascii "$123456789. 2dup .x .x cr dnegate .x .x"
2449.ascii " "
2450
2451.p2align 2
2452.skip 512
2453dstk:
2454
2455.section .bss
2456dseg: .skip 16384
2457