• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Implementing figFORTH on SH3 assembler


コミットメタ情報

リビジョンe3d3fdd0c266ab07f87ee1d11898005423c0b6e7 (tree)
日時2014-03-11 23:10:21
作者Joel Matthew Rees <reiisi@user...>
コミッターJoel Matthew Rees

ログメッセージ

Up through about definition 60, some of the compiling words (shimmed) and the first few CONSTANTS.

変更サマリ

差分

--- /dev/null
+++ b/compiler.inc
@@ -0,0 +1,161 @@
1+ .list ON, EXP
2+
3+; Compiling definitions and their primitives for fig-FORTH for SH-3
4+; Joel Matthew Rees, Hyougo Polytec Center
5+; 2014.03.11
6+
7+; Licensed extended under GPL v. 2 or 3, or per the following:
8+; ------------------------------------LICENSE-------------------------------------
9+;
10+; Copyright (c) 2009, 2010, 2011 Joel Matthew Rees
11+;
12+; Permission is hereby granted, free of charge, to any person obtaining a copy
13+; of this software and associated documentation files (the "Software"), to deal
14+; in the Software without restriction, including without limitation the rights
15+; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16+; copies of the Software, and to permit persons to whom the Software is
17+; furnished to do so, subject to the following conditions:
18+;
19+; The above copyright notice and this permission notice shall be included in
20+; all copies or substantial portions of the Software.
21+;
22+; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23+; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24+; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25+; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26+; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27+; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28+; THE SOFTWARE.
29+;
30+; --------------------------------END-OF-LICENSE----------------------------------
31+
32+; Monolithic, not separate assembly:
33+; context.inc must be included before this file.
34+; .include "context.inc"
35+;
36+; .section compiler, code
37+
38+
39+; : ( --- ) P
40+; { : name sundry-stuff ; } typical input
41+;
42+; If executing, record the data stack mark in CSP, CREATE a
43+; header, compile a call to DOCOL, and set state to compile.
44+;
45+; The interpreter will remain in a compiling state,
46+; compiling as literals the characteristic addresses
47+; of all non-IMMEDIATE symbols (words) it scans,
48+; until it scans a terminating (IMMEDIATE) symbol such as
49+; ";" or ";CODE".
50+;
51+; CONTEXT (interpretation) vocabulary is set to CURRENT.
52+;
53+; DOCOL ( *** IP )
54+; Characteristic of a colon (:) definition. Begins execution of a
55+; high-level definition, i. e., nests the definition and begins
56+; processing icodes.
57+;
58+; In the low-level description, it pushes the IP
59+; and loads the Parameter Field Address of the definition which
60+; called it into the IP.
61+;
62+; SEMIS un-nests out of list interpretation.
63+; DOCOL nests in.
64+; This is the way that lists get interpreted.
65+;
66+; Should DOCOL have a header?
67+; -- The fig model for 6800 does not give it one.
68+;
69+; See NEXT loop.
70+;
71+ HIHEADER ":", COLON, DOCOL, MIMM
72+ .data.l QEXEC,SCSP,CURENT,AT,CONTXT,STORE
73+ .data.l CREATE,RBRAK
74+ .data.l PSCODE
75+DOCOL:
76+_fDOCOL:
77+ mov.l fIP, @-fRP ; Remember where we were.
78+ mov fW, fIP ; fW is still pointing at the characteristic (CFA).
79+ rts
80+ add #NATURAL_SIZE, fIP ; bump it before we start
81+
82+
83+; ; ( --- ) P
84+; { : name sundry-stuff ; } typical input
85+; ERROR check data stack against mark in CSP, compile ;S, unSMUDGE
86+; LATEST definition, and set state to interpretation.
87+;
88+ HIHEADER ";", SEMI, DOCOL
89+ .data.l QCSP,COMPIL,SEMIS,SMUDGE,LBRAK
90+ .data.l SEMIS
91+
92+
93+; CONSTANT ( n --- )
94+; { value CONSTANT name } typical input
95+; CREATE a header, compile a call to DOCON,
96+; compile the constant value.
97+;
98+; DOCON ( --- n )
99+; Characteristic of a CONSTANT. A CONSTANT simply loads its value
100+; from its parameter field and pushes it on the stack.
101+;
102+ HIHEADER CONSTANT, CON, DOCOL
103+ .data.l CREATE,SMUDGE,COMMA,PSCODE
104+DOCON:
105+_fDOCON:
106+ mov.l @(NATURAL_SIZE,fW), r0
107+ rts
108+ mov.l r0, @-fSP
109+
110+
111+; VARIABLE ( init --- )
112+; { init VARIABLE name } typical input
113+; CREATE a header, compile a call to XVAR, compile the initial
114+; value init.
115+;
116+; DOVAR ( --- vadr ) jsr <XVAR (bif.m, bifdp.a)
117+; Characteristic of a VARIABLE. A VARIABLE pushes its PFA address
118+; on the stack. The parameter field of a VARIABLE is the actual
119+; allocation of the variable, so that pushing its address allows
120+; its contents to be @ed (fetched). Ordinary arrays and strings
121+; that do not subscript themselves may be allocated by defining a
122+; variable and immediately ALLOTting the remaining space.
123+; VARIABLES are global to all users, and thus should have been
124+; hidden in resource monitors, but aren't.
125+;
126+ HIHEADER VARIABLE, VAR, DOCOL
127+ .data.l CON,PSCODE
128+DOVAR:
129+_fDOVAR:
130+ add #NATURAL_SIZE, fW
131+ rts
132+ mov.l fW, @-fSP
133+
134+
135+; USER ( u --- )
136+; { uoffset USER name } typical input
137+; CREATE a header, compile a call to DOUSER,
138+; compile the unsigned offset.
139+; The offset is treated by DOUSER as an offset into the
140+; per-user variable table.
141+;
142+; The HUMAN user is entirely responsible for maintaining allocation!
143+;
144+; DOUSER ( --- vadr )
145+; Characteristic of a per-USER variable. USER variables are
146+; similiar to VARIABLEs, but are allocated (by hand!) in the
147+; per-user table. A USER variable's parameter field contains its
148+; offset in the per-user table.
149+;
150+; DOUSER adds the compiled offset to the base of the per-user table
151+; and pushes the resulting address.
152+;
153+ HIHEADER USER, USER, DOCOL
154+ .data.l CON,PSCODE
155+DOUSER:
156+_fDOUSER:
157+ mov.l @(NATURAL_SIZE,fW), r0
158+ add fUP, r0
159+ rts
160+ mov.l r0, @-fSP
161+
--- a/context.inc
+++ b/context.inc
@@ -33,9 +33,14 @@
3333
3434 .cpu sh3
3535
36-; For huge things, like U/ (USLASH)
36+; For huge things, like U/ (USLASH) might be cut in half and repeated or something.
3737 PRIORITY_SIZE: .DEFINE "1"
3838
39+; Comment this out when all forward references are resolved,
40+; and test stuff is no longer needed.
41+SHIMMED: .DEFINE "1"
42+TESTING: .DEFINE "1"
43+
3944
4045 NATURAL_SIZE: .equ 4 ; 4 byte word
4146 HALF_SIZE: .equ ( NATURAL_SIZE / 2 )
@@ -248,23 +253,23 @@ TAILMASK: .equ ( H'FF & ~TAILFLAG ) ; Expose the tail character.
248253
249254 _PREVNAME: .assign 0 ; allocation/dictionary link (terminated by zero)
250255
251- .macro HEADER name, characteristic, mode=0
256+ .macro HIHEADER name, characteristic, inherited, mode=0
252257 ; Symbol name length and mode (Too much stuff in one byte, really.)
253258 .data.b (.len("\name")&H'1f)|\mode|H'80
254259 ; Symbol name
255260 _s\characteristic: .sdata .substr("\name", 0, .len("\name")-1)
256261 ; Terminate the name with high bit set (bad news for multi-byte names).
257262 .data.b .substr("\name", .len("\name")-1, 1)+H'80
258-; Symbol names float, yes this is a bit awkward.
263+; Symbol names float a little, yes this is a little awkward.
259264 .align NATURAL_SIZE
260-; Link to previously defined symbol's header.
265+; (Allocation) link to previously defined symbol's header.
261266 .data.l _PREVNAME
262267 ; Use the SH-3 assembler to track the last symbol.
263268 ; (This is not always a good idea.)
264269 _PREVNAME: .assign _s\characteristic
265270 ; Point to the characteristic code for this Word (symbol) to execute.
266271 \characteristic .equ $
267- .data.l _f\characteristic
272+ .data.l _f\inherited
268273 ; Point to the "parameter" area of the symbol.
269274 _f\characteristic .equ $
270275 ; This area will contain executable code for primitive (leaf) definitions.
@@ -274,6 +279,10 @@ _f\characteristic .equ $
274279 ; And so (ahem) forth.
275280 .endm
276281
282+ .macro HEADER name, characteristic, mode=0
283+ HIHEADER "\name", \characteristic, \characteristic, \mode
284+ .endm
285+
277286
278287 ; More as an example than to be actually used:
279288 .macro fSAFECALL cfa
--- a/driver.inc
+++ b/driver.inc
@@ -2,83 +2,83 @@
22
33 ; Actual driver definitions for fig-FORTH for SH-3
44 ; Joel Matthew Rees, Hyougo Polytec Center
5-; 2014.03.05
6-
7-; Licensed extended under GPL v. 2 or 3, or per the following:
8-; ------------------------------------LICENSE-------------------------------------
9-;
10-; Copyright (c) 2009, 2010, 2011 Joel Matthew Rees
11-;
12-; Permission is hereby granted, free of charge, to any person obtaining a copy
13-; of this software and associated documentation files (the "Software"), to deal
14-; in the Software without restriction, including without limitation the rights
15-; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16-; copies of the Software, and to permit persons to whom the Software is
17-; furnished to do so, subject to the following conditions:
18-;
19-; The above copyright notice and this permission notice shall be included in
20-; all copies or substantial portions of the Software.
21-;
22-; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23-; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24-; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25-; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26-; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27-; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28-; THE SOFTWARE.
29-;
30-; --------------------------------END-OF-LICENSE----------------------------------
31-
5+; 2014.03.05
6+
7+; Licensed extended under GPL v. 2 or 3, or per the following:
8+; ------------------------------------LICENSE-------------------------------------
9+;
10+; Copyright (c) 2009, 2010, 2011 Joel Matthew Rees
11+;
12+; Permission is hereby granted, free of charge, to any person obtaining a copy
13+; of this software and associated documentation files (the "Software"), to deal
14+; in the Software without restriction, including without limitation the rights
15+; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16+; copies of the Software, and to permit persons to whom the Software is
17+; furnished to do so, subject to the following conditions:
18+;
19+; The above copyright notice and this permission notice shall be included in
20+; all copies or substantial portions of the Software.
21+;
22+; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23+; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24+; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25+; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26+; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27+; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28+; THE SOFTWARE.
29+;
30+; --------------------------------END-OF-LICENSE----------------------------------
31+
3232 ; This is where you put the drivers for your hardware.
33-
34-; Monolithic, not separate assembly:
35-; context.inc must be included before this file.
36-; .include "context.inc"
37-;
33+
34+; Monolithic, not separate assembly:
35+; context.inc must be included before this file.
36+; .include "context.inc"
37+;
3838 ; .section driver, code
39-
40-
41-; Not sure whether to make headers for these.
42-; See screens 21 and around 63 in the fig model.
43-
44-
45-; (EMIT) ( c --- )
46-; Low level details of outputting a character
47-; to the current output device.
48-;
49- HEADER (EMIT), PEMIT
50- mov.l @fSP+, r0
51- rts
52- nop
53-
54-
55-; (KEY) ( --- c )
56-; Low level details of getting a key
57-; from the current input device.
58-;
59- HEADER (KEY), PKEY
60- mov.l r0, @-fSP
61- rts
62- nop
63-
64-
65-; (?TERMINAL) ( --- f )
66-; Low level details of checking the break key.
67-;
68- HEADER (?TERMINAL), PQTER
69- mov #6, r0
70- mov.l r0, @-fSP
71- rts
72- nop
73-
74-
75-; (CR) ( --- )
76-; Low level details of performing carriage return/line feed
77-; on the current output device.
78-;
79- HEADER (CR), PCR
80- mov.l @fSP+, r0
81- rts
82- nop
83-
84-
39+
40+
41+; Not sure whether to make headers for these.
42+; See screens 21 and around 63 in the fig model.
43+
44+
45+; (EMIT) ( c --- )
46+; Low level details of outputting a character
47+; to the current output device.
48+;
49+ HEADER "(EMIT)", PEMIT
50+ mov.l @fSP+, r0
51+ rts
52+ nop
53+
54+
55+; (KEY) ( --- c )
56+; Low level details of getting a key
57+; from the current input device.
58+;
59+ HEADER "(KEY)", PKEY
60+ mov.l r0, @-fSP
61+ rts
62+ nop
63+
64+
65+; (?TERMINAL) ( --- f )
66+; Low level details of checking the break key.
67+;
68+ HEADER "(?TERMINAL)", PQTER
69+ mov #6, r0
70+ mov.l r0, @-fSP
71+ rts
72+ nop
73+
74+
75+; (CR) ( --- )
76+; Low level details of performing carriage return/line feed
77+; on the current output device.
78+;
79+ HEADER "(CR)", PCR
80+ mov.l @fSP+, r0
81+ rts
82+ nop
83+
84+
--- a/evaluator.inc
+++ b/evaluator.inc
@@ -3,271 +3,570 @@
33 ; Expression evaluator definitions for fig-FORTH for SH-3
44 ; Joel Matthew Rees, Hyougo Polytec Center
55 ; 2014.03.01
6+
7+; Licensed extended under GPL v. 2 or 3, or per the following:
8+; ------------------------------------LICENSE-------------------------------------
9+;
10+; Copyright (c) 2009, 2010, 2011 Joel Matthew Rees
11+;
12+; Permission is hereby granted, free of charge, to any person obtaining a copy
13+; of this software and associated documentation files (the "Software"), to deal
14+; in the Software without restriction, including without limitation the rights
15+; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16+; copies of the Software, and to permit persons to whom the Software is
17+; furnished to do so, subject to the following conditions:
18+;
19+; The above copyright notice and this permission notice shall be included in
20+; all copies or substantial portions of the Software.
21+;
22+; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23+; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24+; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25+; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26+; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27+; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28+; THE SOFTWARE.
29+;
30+; --------------------------------END-OF-LICENSE----------------------------------
31+
632
7-; Licensed extended under GPL v. 2 or 3, or per the following:
8-; ------------------------------------LICENSE-------------------------------------
9-;
10-; Copyright (c) 2009, 2010, 2011 Joel Matthew Rees
11-;
12-; Permission is hereby granted, free of charge, to any person obtaining a copy
13-; of this software and associated documentation files (the "Software"), to deal
14-; in the Software without restriction, including without limitation the rights
15-; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16-; copies of the Software, and to permit persons to whom the Software is
17-; furnished to do so, subject to the following conditions:
18-;
19-; The above copyright notice and this permission notice shall be included in
20-; all copies or substantial portions of the Software.
21-;
22-; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23-; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24-; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25-; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26-; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27-; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28-; THE SOFTWARE.
29-;
30-; --------------------------------END-OF-LICENSE----------------------------------
31-
32-
33-; Monolithic, not separate assembly:
34-; context.inc must be included before this file.
35-; .include "context.inc"
36-;
33+; Monolithic, not separate assembly:
34+; context.inc must be included before this file.
35+; .include "context.inc"
36+;
3737 ; .section evaluator, code
3838
39+
40+; Not in the 6800 fig model, I've just re-factored it for fun.
41+; (ALIGN) ( ptr1 --- ptr2 )
42+; Adjust ptr1 to the nearest aligned address not lower.
43+; In other words, if ptr1 is aligned at a NATURAL_SIZE boundary, do nothing.
44+; Otherwise, adjust it up until it is aligned.
45+;
46+ HEADER ALIGN, xPALIGN
47+ mov.l @fSP, r0
48+ mALIGNr0
49+ rts
50+ mov.l r0, @fSP
51+
52+
3953
40-; Not in the 6800 fig model, I've just re-factored it for fun.
41-; (ALIGN) ( ptr1 --- ptr2 )
42-; Adjust ptr1 to the nearest aligned address not lower.
43-; In other words, if ptr1 is aligned at a NATURAL_SIZE boundary, do nothing.
44-; Otherwise, adjust it up until it is aligned.
45-;
46- HEADER ALIGN, xPALIGN
47- mov.l @fSP, r0
48- mALIGNr0
49- rts
50- mov.l r0, @fSP
51-
52-
53-
54-; It's tempting to put I in a dedicated register,
55-; but we don't want to optimize too early.
56-;
57-; I ( --- index ) ( limit index *** limit index )
58-; Copy the loop index from the return stack. Synonym for R, here.
54+; It's tempting to put I in a dedicated register,
55+; but we don't want to optimize too early.
5956 ;
57+; I ( --- index ) ( limit index *** limit index )
58+; Copy the loop index from the return stack. Synonym for R, here.
59+;
60+; It's convenient to have the current return address
61+; out-of-the-way in PR
62+;
6063 HEADER I, I
6164 mov.l @fRP, r0 ; I (loop counter)
6265 rts
6366 mov.l r0, @-fSP
64-
65-
66-; U* ( u1 u2 --- ud )
67-; Multiplies the top two unsigned integers, yielding a double
68-; integer product.
69-;
70-; Rejoice, there is a double unsigned multiply!
71-;
72-; ***** FORTH order for double wide is most-significant-first!
73-;
74- HEADER U*, USTAR
75- mov.l @fSP+, r1
76- mov.l @fSP+, r0
77- dmulu.l r1, r0
78- sts.l macl, @-fSP
79- rts
80- sts.l mach, @-fSP
67+
68+
69+; U* ( u1 u2 --- ud )
70+; Multiplies the top two unsigned integers, yielding a double
71+; integer product.
72+;
73+; Rejoice, there is a double unsigned multiply!
74+;
75+; ***** FORTH order for double wide is most-significant-first!
76+;
77+ HEADER "U*", USTAR
78+ mov.l @fSP+, r1
79+ mov.l @fSP+, r0
80+ dmulu.l r1, r0
81+ sts.l macl, @-fSP
82+ rts
83+ sts.l mach, @-fSP
84+
85+
86+; Put this close to the test, so that we don't worry about the .AREPEAT length
87+PUDIVover:
88+ mov.b #-1, r0 ; Or we could trap this, if we take the time to define traps.
89+ mov.l r0, @fSP
90+ rts
91+ mov.l r0, @(NATURAL_SIZE,fSP)
92+;
93+; (UDIV) ( ud u --- uquotient )
94+; Divides the top unsigned integer into the second and third words
95+; on the stack as a single unsigned double integer,
96+; leaving only the quotient as an unsigned integer.
97+;
98+; The smaller the divisor, the more likely dropping the high word
99+; of the quotient loses significant bits.
100+;
101+; The SH3 manual seems to indicate that we can't trust the remainder
102+; to remain a true remainder to the end.
103+; It strongly recommends using multiply-subtract instead,
104+; to get the remainder.
105+;
106+; ***** FORTH order for double wide is most-significant-first!
107+;
108+; Using a loop that messes with the carry won't work.
109+; .AIFDEF PRIORITY_SIZE
110+;DIVIDELENGTH: .DEFINE "16" ; repeat count * 2 cycles * count in r3
111+; .AELSE
112+DIVIDELENGTH: .DEFINE "32" ; repeat count * 2 cycles
113+; .AENDI
114+;
115+ HEADER "(UDIV)", PUDIV
116+ mov.l @fSP+, r2 ; divisor
117+ mov.l @fSP+, r0 ; dividend high part
118+ cmp/hs r2, r0 ; zero divide or overflow?
119+ bt PUDIVover
120+ mov.l @fSP, r1 ; dividend low part
121+; .AIFDEF PRIORITY_SIZE
122+; mov.b #2, r3 ; Trade speed for size
123+; .AENDI
124+ div0u ; Get the flags ready
125+;PUDIVloop:
126+ .AREPEAT DIVIDELENGTH
127+ rotcl r1
128+ div1 r2, r0
129+ .AENDR
130+; .AIFDEF PRIORITY_SIZE
131+; dt r3 ; + 4 cycles * count in r3
132+; bf PUDIVloop
133+; .AENDI
134+ rotcl r1
135+ rts
136+ mov.l r1, @fSP
137+
138+
139+; U/ ( ud u --- uremainder uquotient )
140+; Divides the top unsigned integer into the second and third words
141+; on the stack as a single unsigned double integer, leaving the
142+; remainder and quotient (quotient on top) as unsigned integers.
143+;
144+; The smaller the divisor, the more likely dropping the high word
145+; of the quotient loses significant bits.
146+;
147+; ***** FORTH order for double wide is most-significant-first!
148+;
149+ HEADER "U/", USLASH
150+ sts.l pr, @-fRP
151+ mov.l @(2*NATURAL_SIZE,fSP), r0
152+ mov.l r0, @-fSP
153+ mov.l @(2*NATURAL_SIZE,fSP), r0
154+ mov.l r0, @-fSP
155+ mov.l @(2*NATURAL_SIZE,fSP), r0
156+ bsr _fPUDIV
157+ mov.l r0, @-fSP ; Push the divisor as we go.
158+;
159+ mov.l @fSP+, r0 ; grab the quotient
160+ mov.l @fSP+, r1 ; grab the divisor (unsigned double dividend still on stack)
161+ mov r0, fW ; hold the quotient
162+ and r1, r0
163+ cmp/eq #-1, r0 ; both max unsigned? (fW == r0 == max unsigned)
164+ bf USLASHremainder
165+ bra USLASHexitstore
166+ mov.l r0, @(NATURAL_SIZE,fSP) ; remainder (max) as we go
167+;
168+; The SH-3 manual recommends this approach
169+USLASHremainder:
170+ mov fW, r0
171+ dmulu.l r1, r0 ; multiply quotient by divisor
172+ sts.l macl, @-fSP
173+ bsr _fDSUB
174+ sts.l mach, @-fSP ; Store most significant as we go.
175+; The low part is in the right place for the remainder.
176+;
177+USLASHexitstore:
178+ lds.l @fRP+, pr
179+ rts
180+ mov.l fW, @fSP ; Store the quotient as we go
181+
182+
183+; AND ( n1 n2 --- n )
184+; Bitwise and the top two integers.
185+;
186+ HEADER AND, AND
187+ mov.l @fSP+, r1
188+ mov.l @fSP, r0
189+ and r1, r0
190+ rts
191+ mov.l r0, @fSP
192+
193+
194+; OR ( n1 n2 --- n )
195+; Bitwise or.
196+;
197+ HEADER OR, OR
198+ mov.l @fSP+, r1
199+ mov.l @fSP, r0
200+ or r1, r0
201+ rts
202+ mov.l r0, @fSP
203+
204+
205+; XOR ( n1 n2 --- n )
206+; Bitwise exclusive or.
207+;
208+ HEADER XOR, XOR
209+ mov.l @fSP+, r1
210+ mov.l @fSP, r0
211+ xor r1, r0
212+ rts
213+ mov.l r0, @fSP
214+
215+
216+; LEAVE ( limit index *** index index )
217+; Force the terminating condition for the innermost loop by
218+; copying its index to its limit. Termination is postponed until
219+; the next LOOP or +LOOP instruction is executed. The index
220+; remains available for use until the LOOP or +LOOP instruction is
221+; encountered.
222+;
223+; It's convenient to have the current return address
224+; out-of-the-way in PR
225+;
226+ HEADER LEAVE, LEAVE
227+ mov.l @fSP, r0
228+ rts
229+ mov.l r0, @(NATURAL_SIZE,fSP)
230+
231+
232+; >R ( n --- ) ( *** n ) C
233+; Move top of parameter stack to top of return stack.
234+;
235+; It's convenient to have the current return address
236+; out-of-the-way in PR
237+;
238+ HEADER ">R", TOR
239+ mov.l @fSP+, r0
240+ rts
241+ mov.l r0, @-fRP
242+
243+
244+; R> ( --- n ) (n *** ) C
245+; Move top of return stack to top of parameter stack.
246+;
247+; It's convenient to have the current return address
248+; out-of-the-way in PR
249+;
250+ HEADER "R>", FROMR
251+ mov.l @fRP+, r0
252+ rts
253+ mov.l r0, @-fSP
254+
255+
256+; R ( --- n ) ( n *** n )
257+; Copy the top of return stack to top of parameter stack. A
258+; synonym for I.
259+;
260+; It's convenient to have the current return address
261+; out-of-the-way in PR
262+;
263+ HIHEADER R, R, I
264+; mov.l @fRP, r0
265+; rts
266+; mov.l r0, @-fSP
267+
268+
269+; 0= ( n --- n=0 )
270+; Logically invert top of stack; or flag true if top is zero,
271+; otherwise false.
272+;
273+ HEADER "0=", ZEQU
274+ mov.l @fSP, r0
275+ cmp/eq #0, r0 ; Bit inversion leaves an incomplete flag.
276+ bt ZEQUequal
277+ mov #0, r0
278+ rts
279+ mov.l r0, @fSP
280+ZEQUequal:
281+ mov #-1, r0 ; not r0, r0 would also work, but why bother?
282+ rts
283+ mov.l r0, @fSP
284+
285+
286+;0< ( n --- n<0 )
287+; Flag true if top is negative (MSbit set), otherwise false.
288+;
289+ HEADER "0<", ZLESS
290+ mov.l @fSP, r0
291+ shal r0 ; Sign bit to T (and why are shal and shll different opcodes?)
292+ bt ZLESSneg
293+ mov #0, r0
294+ rts
295+ mov.l r0, @fSP
296+ZLESSneg:
297+ mov #-1, r0 ; not r0, r0 would also work, but why bother?
298+ rts
299+ mov.l r0, @fSP
300+
301+
302+; + ( n1 n2 --- n1+n2 )
303+; Add top two words.
304+;
305+ HEADER "+", PLUS
306+ mov.l @fSP+, r1
307+ mov.l @fSP, r0
308+ add r1, r0
309+ rts
310+ mov.l r0, @fSP
81311
82312
83-; Put this close to the test, so that we don't worry about the .AREPEAT length
84-PUDIVover:
85- mov.b #-1, r0 ; Or we could trap this, if we take the time to define traps.
86- mov.l r0, @fSP
87- rts
88- mov.l r0, @(NATURAL_SIZE,fSP)
89-;
90-; (UDIV) ( ud u --- uquotient )
91-; Divides the top unsigned integer into the second and third words
92-; on the stack as a single unsigned double integer,
93-; leaving only the quotient as an unsigned integer.
94-;
95-; The smaller the divisor, the more likely dropping the high word
96-; of the quotient loses significant bits.
97-;
98-; The SH3 manual seems to indicate that we can't trust the remainder
99-; to remain a true remainder to the end.
100-; It strongly recommends using multiply-subtract instead,
101-; to get the remainder.
102-;
103-; ***** FORTH order for double wide is most-significant-first!
104-;
105-; Using a loop that messes with the carry won't work.
106-; .AIFDEF PRIORITY_SIZE
107-;DIVIDELENGTH: .DEFINE "16" ; repeat count * 2 cycles * count in r3
108-; .AELSE
109-DIVIDELENGTH: .DEFINE "32" ; repeat count * 2 cycles
110-; .AENDI
111-;
112- HEADER (UDIV), PUDIV
113- mov.l @fSP+, r2 ; divisor
114- mov.l @fSP+, r0 ; dividend high part
115- cmp/hs r2, r0 ; zero divide or overflow?
116- bt PUDIVover
117- mov.l @fSP, r1 ; dividend low part
118-; .AIFDEF PRIORITY_SIZE
119-; mov.b #2, r3 ; Trade speed for size
120-; .AENDI
121- div0u ; Get the flags ready
122-;PUDIVloop:
123- .AREPEAT DIVIDELENGTH
124- rotcl r1
125- div1 r2, r0
126- .AENDR
127-; .AIFDEF PRIORITY_SIZE
128-; dt r3 ; + 4 cycles * count in r3
129-; bf PUDIVloop
130-; .AENDI
131- rotcl r1
132- rts
133- mov.l r1, @fSP
134-
135-
136-; U/ ( ud u --- uremainder uquotient )
137-; Divides the top unsigned integer into the second and third words
138-; on the stack as a single unsigned double integer, leaving the
139-; remainder and quotient (quotient on top) as unsigned integers.
140-;
141-; The smaller the divisor, the more likely dropping the high word
142-; of the quotient loses significant bits.
143-;
144-; ***** FORTH order for double wide is most-significant-first!
145-;
146- HEADER U/, USLASH
147- sts.l pr, @-fRP
148- mov.l @(2*NATURAL_SIZE,fSP), r0
149- mov.l r0, @-fSP
150- mov.l @(2*NATURAL_SIZE,fSP), r0
151- mov.l r0, @-fSP
152- mov.l @(2*NATURAL_SIZE,fSP), r0
153- bsr _fPUDIV
154- mov.l r0, @-fSP ; Push the divisor as we go.
155-;
156- mov.l @fSP+, r0 ; grab the quotient
157- mov.l @fSP+, r1 ; grab the divisor (unsigned double dividend still on stack)
158- mov r0, fW ; hold the quotient
159- and r1, r0
160- cmp/eq #-1, r0 ; both max unsigned? (fW == r0 == max unsigned)
161- bf USLASHremainder
162- bra USLASHexitstore
163- mov.l r0, @(NATURAL_SIZE,fSP) ; remainder (max) as we go
164-;
165-; The SH-3 manual recommends this approach
166-USLASHremainder:
167- mov fW, r0
168- dmulu.l r1, r0 ; multiply quotient by divisor
169- sts.l macl, @-fSP
170- bsr _fDSUB
171- sts.l mach, @-fSP ; Store most significant as we go.
172-; The low part is in the right place for the remainder.
173-;
174-USLASHexitstore:
175- lds.l @fRP+, pr
176- rts
177- mov.l fW, @fSP ; Store the quotient as we go
178-
179-
180-; AND ( n1 n2 --- n )
181-; Bitwise and the top two integers.
182-;
183- HEADER AND, AND
184- mov.l @fSP+, r1
185- mov.l @fSP, r0
186- and r1, r0
187- rts
188- mov.l r0, @fSP
189-
190-
191-; OR ( n1 n2 --- n )
192-; Bitwise or.
193-;
194- HEADER OR, OR
195- mov.l @fSP+, r1
196- mov.l @fSP, r0
197- or r1, r0
198- rts
199- mov.l r0, @fSP
200-
201-
202-; XOR ( n1 n2 --- n )
203-; Bitwise exclusive or.
204-;
205- HEADER XOR, XOR
206- mov.l @fSP+, r1
207- mov.l @fSP, r0
208- xor r1, r0
209- rts
210- mov.l r0, @fSP
211-
313+; D+ ( d1 d2 --- d1+d2 )
314+; Add top two double words, leaving the double sum.
315+;
316+; ***** FORTH order for double wide is most-significant-first!
317+;
318+ HEADER "D+", DPLUS
319+ mov.l @fSP+, r2 ; high part
320+ mov.l @fSP+, r3 ; low part
321+ mov.l @(NATURAL_SIZE,fSP), r1 ; high part
322+ mov.l @fSP, r0 ; low part
323+ clrt
324+ addc r3, r1
325+ addc r2, r0
326+ mov.l r1, @(NATURAL_SIZE,fSP)
327+ rts
328+ mov.l r0, @fSP
329+
212330
331+;MINUS ( n --- -n )
332+; Negate (two's complement) top of stack.
333+; (NOT the the opposite of PLUS!)
334+;
335+ HEADER MINUS, MINUS
336+ mov.l @fSP, r0
337+ neg r0, r0
338+ rts
339+ mov.l r0, @fSP
340+
341+
342+;DMINUS ( d --- -d )
343+; Negate (two's complement) top two words on stack as a double
344+; integer.
345+; (NOT the the opposite of DPLUS!)
346+;
347+ HEADER DMINUS, DMINUS
348+ mov.l @(NATURAL_SIZE,fSP), r1
349+ mov.l @fSP, r0
350+ clrt
351+ negc r1, r1
352+ negc r0, r0
353+ mov.l r1, @(NATURAL_SIZE,fSP)
354+ rts
355+ mov.l r0, @fSP
356+
357+
358+; OVER ( n1 n2 --- n1 n2 n1 )
359+; Push a copy of the second word on stack.
360+;
361+ HEADER OVER, OVER
362+ mov.l @(NATURAL_SIZE,fSP), r0
363+ rts
364+ mov.l r0, @-fSP
365+
366+
367+; DROP ( n --- )
368+; Discard the top word on stack.
369+;
370+ HEADER DROP, DROP
371+ rts
372+ add #NATURAL_SIZE, fSP
373+
374+
375+; SWAP ( n1 n2 --- n2 n1 )
376+; Swap the top two words on stack.
377+;
378+ HEADER SWAP, SWAP
379+ mov.l @(NATURAL_SIZE,fSP), r0
380+ mov.l @fSP, r1
381+ mov.l r1, @(NATURAL_SIZE,fSP)
382+ rts
383+ mov.l r0, @fSP
384+
213385
386+; DUP ( n1 --- n1 n1 )
387+; Push a copy of the top word on stack.
388+;
389+ HEADER DUP, DUP
390+ mov.l @fSP, r0
391+ rts
392+ mov.l r0, @-fSP
393+
394+
395+; +! ( n adr --- )
396+; Add the second word on stack to the word at the adr on top of
397+; stack.
398+;
399+ HEADER "+!", PSTORE
400+ mov.l @fSP+, r2
401+ mov.l @r2, r0
402+ mov.l @fSP+, r1
403+ add r1, r0
404+ rts
405+ mov.l r0, @r2
406+
407+
408+myTOGGLE: .DEFINE "1"
214409
215-; + ( n1 n2 --- n1+n2 )
216-; Add top two words.
217-;
218- HEADER +, PLUS
219- mov.l @fSP+, r1
220- mov.l @fSP, r0
221- add r1, r0
222- rts
223- mov.l r0, @fSP
224-
410+; TOGGLE ( adr b --- )
411+; Exclusive or byte at adr with low byte of top word.
412+;
413+ .AIFDEF myTOGGLE
414+ HEADER TOGGLE, TOGGLE
415+ mov.l @fSP+, r1
416+ mov.l @fSP+, r2
417+ mov.b @r2, r0
418+ xor r1, r0
419+ rts
420+ mov.b r0, @r2
421+ .AELSE ; It makes a good example, so I'll keep it here.
422+ HIHEADER TOGGLE, TOGGLE, DOCOL
423+ .data.l OVER,CAT,XOR,SWAP,CSTORE
424+ .data.l SEMIS
425+ .AENDI
426+
427+
428+; @ ( adr --- n )
429+; Replace address on stack with the word at the address.
430+;
431+ HEADER "@", AT
432+ mov.l @fSP, r1
433+ mov.l @r1, r0 ; Would mov.l @r0, r0 cause a stall?
434+ rts
435+ mov.l r0, @fSP
436+
225437
226-; D+ ( d1 d2 --- d1+d2 )
227-; Add top two double words, leaving the double sum.
228-;
229-; ***** FORTH order for double wide is most-significant-first!
230-;
231- HEADER D+, DPLUS
232- mov.l @fSP+, r2 ; high part
233- mov.l @fSP+, r3 ; low part
234- mov.l @(NATURAL_SIZE,fSP), r1 ; high part
235- mov.l @fSP, r0 ; low part
236- clrt
237- addc r3, r1
238- addc r2, r0
239- mov.l r1, @(NATURAL_SIZE,fSP)
240- rts
241- mov.l r0, @fSP
242-
438+; C@ ( adr --- b )
439+; CFEH Replace address on top of stack with the byte at the address.
440+; High byte of result is clear.
441+;
442+ HEADER "C@", CAT
443+ mov.l @fSP, r1
444+ mov.b @r1, r0 ; Would mov.b @r0, r0 cause a stall?
445+ rts
446+ mov.l r0, @fSP
447+
448+
449+; ! ( n adr --- )
450+; Store second word on stack at address on top of stack.
451+;
452+ HEADER "!", STORE
453+ mov.l @fSP+, r1
454+ mov.l @fSP+, r0
455+ rts
456+ mov.l r0, @r1
457+
243458
244-; - ( n1 n2 --- n1-n2 )
245-; Subtract top word from second, leaving the difference.
246-;
247- HEADER -, SUB
248- mov.l @fSP+, r1
249- mov.l @fSP, r0
250- sub r1, r0
251- rts
252- mov.l r0, @fSP
459+; C! ( b adr --- )
460+; CSTO Store low byte of second word on stack at address on top of
461+; stack. High byte is ignored.
462+;
463+ HEADER "C!", CSTORE
464+ mov.l @fSP+, r1
465+ mov.l @fSP+, r0
466+ rts
467+ mov.b r0, @r1
468+
469+
470+; Numeric constants mapping to themselves is primarily for speed.
471+;
472+; 0 ( --- 0 )
473+ HIHEADER "0", ZERO, DOCON
474+ .data.l 0
475+
476+; 1 ( --- 1 )
477+ HIHEADER "1", ONE, DOCON
478+ .data.l 1
479+
480+; 2 ( --- 2 )
481+ HIHEADER "2", TWO, DOCON
482+ .data.l 1
483+
484+; 3 ( --- 3 )
485+ HIHEADER "3", THREE, DOCON
486+ .data.l 3
487+
488+; 4 ( --- 4 )
489+; Not part of the fig-FORTH model.
490+ HIHEADER "4", FOUR, DOCON
491+ .data.l 4
492+
493+; NWIDTH ( --- u )
494+; Not part of the fig-FORTH model, should have been.
495+ HIHEADER NWIDTH, NWIDTH, DOCON
496+ .data.l NATURAL_SIZE
497+
498+; PTRWIDTH ( --- u )
499+; Not part of the fig-FORTH model, should have been.
500+ HIHEADER PTRWIDTH, PTRWIDTH, DOCON
501+ .data.l NATURAL_SIZE
502+
503+; BL ( --- u )
504+ HIHEADER BL, BL, DOCON
505+ .data.l " " ; ascii blank
506+
507+
508+
509+
510+; - ( n1 n2 --- n1-n2 )
511+; Subtract top word from second, leaving the difference.
512+;
513+ HEADER "-", SUB
514+ mov.l @fSP+, r1
515+ mov.l @fSP, r0
516+ sub r1, r0
517+ rts
518+ mov.l r0, @fSP
253519
254520
255-; D- ( d1 d2 --- d1+d2 )
256-; Subtract top double from second, leaving the double difference.
257-;
258-; ***** FORTH order for double wide is most-significant-first!
259-;
260- HEADER D-, DSUB
261- mov.l @fSP+, r2 ; high part
262- mov.l @fSP+, r3 ; low part
263- mov.l @(NATURAL_SIZE,fSP), r1 ; high part
264- mov.l @fSP, r0 ; low part
265- clrt
266- subc r3, r1
267- subc r2, r0
268- mov.l r1, @(NATURAL_SIZE,fSP)
269- rts
270- mov.l r0, @fSP
271-
272-
521+; D- ( d1 d2 --- d1+d2 )
522+; Subtract top double from second, leaving the double difference.
523+;
524+; ***** FORTH order for double wide is most-significant-first!
525+;
526+ HEADER "D-", DSUB
527+ mov.l @fSP+, r2 ; high part
528+ mov.l @fSP+, r3 ; low part
529+ mov.l @(NATURAL_SIZE,fSP), r1 ; high part
530+ mov.l @fSP, r0 ; low part
531+ clrt
532+ subc r3, r1
533+ subc r2, r0
534+ mov.l r1, @(NATURAL_SIZE,fSP)
535+ rts
536+ mov.l r0, @fSP
537+
538+
539+
540+
541+
542+
543+;= ( n1 n2 --- n1=n2 )
544+; Flag true if n1 and n2 are equal, otherwise false.
545+;
546+ HEADER "=", EQU
547+ mov.l @fSP+, r1
548+ mov.l @fSP, r0
549+ cmp/eq r1, r0 ; Subtraction leaves an incomplete flag.
550+ bt EQUequal
551+ mov #0, r0
552+ rts
553+ mov.l r0, @fSP
554+EQUequal:
555+ mov #-1, r0
556+ rts
557+ mov.l r0, @fSP
558+
559+
560+;< ( n1 n2 --- n1<n2 )
561+; Flag true if n1 is less than n2, otherwise false.
562+;
563+
564+
565+
566+
567+;> ( n1 n2 --- n1>n2 )
568+; Flag true if n1 is greater than n2, false otherwise.
569+;
570+
571+
273572
--- a/initialize.inc
+++ b/initialize.inc
@@ -59,56 +59,56 @@ WENT:
5959
6060
6161
62-;COLD FDB *+2
63-;CENT LDS #REND-1 top of destination
64-; LDX #ERAM top of stuff to move
65-;COLD2 DEX
66-; LDA A 0,X
67-; PSH A move TASK & FORTH to ram
68-; CPX #RAM
69-; BNE COLD2
70-;*
71-; LDS #XFENCE-1 put stack at a safe place for now
72-; LDX COLINT
73-; STX XCOLUM
74-; LDX DELINT
75-; STX XDELAY
76-; LDX VOCINT
77-; STX XVOCL
78-; LDX DPINIT
79-; STX XDP
80-; LDX FENCIN
81-; STX XFENCE
82-;
83-;
84-;WENT LDS #XFENCE-1 top of destination
85-; LDX #FENCIN top of stuff to move
86-;WARM2 DEX
87-; LDA A 0,X
88-; PSH A
89-; CPX #SINIT
90-; BNE WARM2
91-;*
92-; LDS SINIT
93-; LDX UPINIT
94-; STX UP init user ram pointer
95-; LDX #ABORT
96-; STX IP
97-; NOP Here is a place to jump to special user
98-; NOP initializations such as I/0 interrups
99-; NOP
100-;*
101-;* For systems with TRACE:
102-; LDX #00
103-; STX TRLIM clear trace mode
104-; LDX #0
105-; STX BRKPT clear breakpoint address
106-; JMP RPSTOR+2 start the virtual machine running !
107-;*
108-;* Here is the stuff that gets copied to ram :
109-;* at address $140:
110-;*
111-;* Thus, MAGIC numbers that initialize USE and PREV, magically! (JMR)
112-;* RAM FDB $3000,$3000,0,0
113-;RAM FDB $4000+132,$4000+132,0,0
114-;
62+;COLD FDB *+2
63+;CENT LDS #REND-1 top of destination
64+; LDX #ERAM top of stuff to move
65+;COLD2 DEX
66+; LDA A 0,X
67+; PSH A move TASK & FORTH to ram
68+; CPX #RAM
69+; BNE COLD2
70+;*
71+; LDS #XFENCE-1 put stack at a safe place for now
72+; LDX COLINT
73+; STX XCOLUM
74+; LDX DELINT
75+; STX XDELAY
76+; LDX VOCINT
77+; STX XVOCL
78+; LDX DPINIT
79+; STX XDP
80+; LDX FENCIN
81+; STX XFENCE
82+;
83+;
84+;WENT LDS #XFENCE-1 top of destination
85+; LDX #FENCIN top of stuff to move
86+;WARM2 DEX
87+; LDA A 0,X
88+; PSH A
89+; CPX #SINIT
90+; BNE WARM2
91+;*
92+; LDS SINIT
93+; LDX UPINIT
94+; STX UP init user ram pointer
95+; LDX #ABORT
96+; STX IP
97+; NOP Here is a place to jump to special user
98+; NOP initializations such as I/0 interrups
99+; NOP
100+;*
101+;* For systems with TRACE:
102+; LDX #00
103+; STX TRLIM clear trace mode
104+; LDX #0
105+; STX BRKPT clear breakpoint address
106+; JMP RPSTOR+2 start the virtual machine running !
107+;*
108+;* Here is the stuff that gets copied to ram :
109+;* at address $140:
110+;*
111+;* Thus, MAGIC numbers that initialize USE and PREV, magically! (JMR)
112+;* RAM FDB $3000,$3000,0,0
113+;RAM FDB $4000+132,$4000+132,0,0
114+;
--- a/inout.inc
+++ b/inout.inc
@@ -3,116 +3,116 @@
33 ; FORTH input/output definitions for fig-FORTH for SH-3
44 ; Joel Matthew Rees, Hyougo Polytec Center
55 ; 2014.03.05
6-
7-; Licensed extended under GPL v. 2 or 3, or per the following:
8-; ------------------------------------LICENSE-------------------------------------
9-;
10-; Copyright (c) 2009, 2010, 2011 Joel Matthew Rees
11-;
12-; Permission is hereby granted, free of charge, to any person obtaining a copy
13-; of this software and associated documentation files (the "Software"), to deal
14-; in the Software without restriction, including without limitation the rights
15-; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16-; copies of the Software, and to permit persons to whom the Software is
17-; furnished to do so, subject to the following conditions:
18-;
19-; The above copyright notice and this permission notice shall be included in
20-; all copies or substantial portions of the Software.
21-;
22-; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23-; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24-; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25-; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26-; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27-; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28-; THE SOFTWARE.
29-;
30-; --------------------------------END-OF-LICENSE----------------------------------
31-
32-; Monolithic, not separate assembly:
33-; context.inc must be included before this file.
34-; .include "context.inc"
35-;
6+
7+; Licensed extended under GPL v. 2 or 3, or per the following:
8+; ------------------------------------LICENSE-------------------------------------
9+;
10+; Copyright (c) 2009, 2010, 2011 Joel Matthew Rees
11+;
12+; Permission is hereby granted, free of charge, to any person obtaining a copy
13+; of this software and associated documentation files (the "Software"), to deal
14+; in the Software without restriction, including without limitation the rights
15+; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16+; copies of the Software, and to permit persons to whom the Software is
17+; furnished to do so, subject to the following conditions:
18+;
19+; The above copyright notice and this permission notice shall be included in
20+; all copies or substantial portions of the Software.
21+;
22+; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23+; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24+; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25+; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26+; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27+; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28+; THE SOFTWARE.
29+;
30+; --------------------------------END-OF-LICENSE----------------------------------
31+
32+; Monolithic, not separate assembly:
33+; context.inc must be included before this file.
34+; .include "context.inc"
35+;
3636 ; .section inputoutput, code
37-
38-
39-; EMIT, KEY, QTERM, and CR are assumed to be the focus
40-; of porting to new hardware.
41-
42-; These are stubs which call real drivers defined in driver.inc
43-; In the fig-FORTH model, you see the stubs around screen 21.
44-; And you see the drivers around screen 63.
45-
46-; Contrary to usual practice, I am assuming the drivers
47-; use the stack instead of registers to pass results.
48-; No particular reason not use the registers, of course.
49-
50-
51-; EMIT ( c --- )
52-; Write c to the terminal device, whatever that may be.
53-; Increment the OUT per USER variable.
54-;
55- HEADER EMIT, EMIT
56- sts.l PR, @-fRP
57- mov.l #_fPEMIT, r1 ; May be within range of absolute call?
58- jsr @r1
59- nop
60- mov.l #XOUT, r0 ; We defined XOUT as the offset itself.
61- mov.l @(r0,fUP), r1
62- add #1, r1
63- lds.l @fRP+, PR
64- rts
65- mov.l r1, @(r0,fUP)
66-
67-
68-; KEY ( --- c )
37+
38+
39+; EMIT, KEY, QTERM, and CR are assumed to be the focus
40+; of porting to new hardware.
41+
42+; These are stubs which call real drivers defined in driver.inc
43+; In the fig-FORTH model, you see the stubs around screen 21.
44+; And you see the drivers around screen 63.
45+
46+; Contrary to usual practice, I am assuming the drivers
47+; use the stack instead of registers to pass results.
48+; No particular reason not use the registers, of course.
49+
50+
51+; EMIT ( c --- )
52+; Write c to the terminal device, whatever that may be.
53+; Increment the OUT per USER variable.
54+;
55+ HEADER EMIT, EMIT
56+ sts.l PR, @-fRP
57+ mov.l #_fPEMIT, r1 ; May be within range of absolute call?
58+ jsr @r1
59+ nop
60+ mov.l #XOUT, r0 ; We defined XOUT as the offset itself.
61+ mov.l @(r0,fUP), r1
62+ add #1, r1
63+ lds.l @fRP+, PR
64+ rts
65+ mov.l r1, @(r0,fUP)
66+
67+
68+; KEY ( --- c )
6969 ; Leave the ascii value of the next terminal key struck.
70-;
71- HEADER KEY, KEY
72- sts.l PR, @-fRP
73- mov.l #_fPKEY, r1 ; May be within range of absolute call?
74- jsr @r1
75- nop
76- mov.l @fSP, r1
77- mov.l #H'000000ff, r0
78- and r1, r0
79- lds.l @fRP+, PR
80- rts
81- mov.l r0, @fSP
82-
83-
70+;
71+ HEADER KEY, KEY
72+ sts.l PR, @-fRP
73+ mov.l #_fPKEY, r1 ; May be within range of absolute call?
74+ jsr @r1
75+ nop
76+ mov.l @fSP, r1
77+ mov.l #H'000000ff, r0
78+ and r1, r0
79+ lds.l @fRP+, PR
80+ rts
81+ mov.l r0, @fSP
82+
83+
8484 ; ?TERMINAL ( --- f )
8585 ; Perform a test of the terminal keyboard for actuation of the break
8686 ; key. A true flag indicates actuation.
87-; In other words, scan keyboard, but do not wait.
88-; Return true if break key currently pressed, 0 otherwise.
89-; Ignores any keys buffered up, in theory.
90-; But this definition is installation dependent,
87+; In other words, scan keyboard, but do not wait.
88+; Return true if break key currently pressed, 0 otherwise.
89+; Ignores any keys buffered up, in theory.
90+; But this definition is installation dependent,
9191 ; and may not give exactly these results.
92-;
93- HEADER ?TERMINAL, QTERM
94- sts.l PR, @-fRP
95- mov.l #_fPQTER, r1 ; May be within range of absolute call?
96- jsr @r1
97- nop ; Might need to filter results?
98- lds.l @fRP+, PR
99- rts
100- nop
101-
102-
103-; CR ( --- )
92+;
93+ HEADER "?TERMINAL", QTERM
94+ sts.l PR, @-fRP
95+ mov.l #_fPQTER, r1 ; May be within range of absolute call?
96+ jsr @r1
97+ nop ; Might need to filter results?
98+ lds.l @fRP+, PR
99+ rts
100+ nop
101+
102+
103+; CR ( --- )
104104 ; Transmit a carriage return and line feed to the selected output
105105 ; device.
106-;
107- HEADER CR, CR
108- sts.l PR, @-fRP
109- mov.l #_fPCR, r1 ; May be within range of absolute call?
110- jsr @r1
111- nop ; Might push a CR and EMIT, then a LF and EMIT?
112- lds.l @fRP+, PR
113- rts
114- nop
115-
116-
117-
118-
106+;
107+ HEADER CR, CR
108+ sts.l PR, @-fRP
109+ mov.l #_fPCR, r1 ; May be within range of absolute call?
110+ jsr @r1
111+ nop ; Might push a CR and EMIT, then a LF and EMIT?
112+ lds.l @fRP+, PR
113+ rts
114+ nop
115+
116+
117+
118+
--- a/main.src
+++ b/main.src
@@ -1,4 +1,4 @@
1-; Assembly language sourcec code text for SH3 version of fig-FORTH.
1+; Assembly language source code text for SH3 version of fig-FORTH.
22 .list ON, EXP
33
44 ; Primitive (kernel) definitions for fig-FORTH for SH-3
@@ -37,126 +37,65 @@
3737
3838 .org $
3939
40+;***************************
41+;** C O L D E N T R Y **
4042 ;***************************
41-;** C O L D E N T R Y **
42-;***************************
43-; 0 offset into the ROMmable code
44-ORIG:
43+; 0 offset into the ROMmable code
44+ORIG:
4545 mov.l #_fCENT, r0
46- jmp @r0
47-;***************************
48-;** W A R M E N T R Y **
46+ jmp @r0
47+;***************************
48+;** W A R M E N T R Y **
4949 ;***************************
5050 ;
51-; 4 offset into the ROMmable code
52- nop ; Conveniently left over from the COLD entry point.
51+; 4 offset into the ROMmable code
52+ nop ; Conveniently left over from the COLD entry point.
5353 mov.l #WENT, r0 ; warm-start code, keeps current dictionary intact
5454 jmp @r0
55- nop
56-;
57-;*
58-;******* startup parmeters **************************
55+ nop
56+;
57+;*
58+;******* startup parmeters **************************
5959 ;*
6060 ; All of this is essentially place-holder values:
61-COLD_PARAMETERS:
61+COLD_PARAMETERS:
6262 .data.l "SH-3" ; cpu
6363 .data.l 0 ; revision
64- .data.l 0 ; topmost word in FORTH vocabulary
64+ .data.l 0 ; topmost word in FORTH vocabulary
6565 BACKSP:
66- .data.l h'7f ; backspace character for editing
66+ .data.l h'7f ; backspace character for editing
6767 UPINIT:
68- .data.l PER_USER ; UORIG ; initial user area
68+ .data.l PER_USER ; UORIG ; initial user area
6969 SINIT:
70- .data.l fSP_BASE ; ORIG-$210 ; initial top of data stack
70+ .data.l fSP_BASE ; ORIG-$210 ; initial top of data stack
7171 RINIT:
72- .data.l fRP_BASE ; ORIG-$10 ; initial top of return stack
73- .data.l fSP_LIMIT-h'200 ; ORIG-$200 ; terminal input buffer
74- .data.l 31 ; initial name field width
75- .data.l 0 ; initial warning mode (0 = no disc)
72+ .data.l fRP_BASE ; ORIG-$10 ; initial top of return stack
73+ .data.l fSP_LIMIT-h'200 ; ORIG-$200 ; terminal input buffer
74+ .data.l 31 ; initial name field width
75+ .data.l 0 ; initial warning mode (0 = no disc)
7676 FENCIN:
77- .data.l fSP_LIMIT-h'400 ; REND ; initial fence
77+ .data.l fSP_LIMIT-h'400 ; REND ; initial fence
7878 DPINIT:
79- .data.l fSP_LIMIT-h'400 ; REND ; cold start value for DP
79+ .data.l fSP_LIMIT-h'400 ; REND ; cold start value for DP
8080 VOCINT:
81- .data.l fSP_LIMIT-h'400 ; FORTH+8
81+ .data.l fSP_LIMIT-h'400 ; FORTH+8
8282 COLINT:
83- .data.l 132 ; initial terminal carriage width
83+ .data.l 132 ; initial terminal carriage width
8484 DELINT:
8585 .data.l 4 ; initial carriage return delay
86-;****************************************************
87-;*
88-
86+;*
87+;****************************************************
88+;*
8989
9090
91-
92-TEST_THINGY:
93- .data.l LIT, 1
94- .data.l LIT, -1
95- .data.l BRAN
96- mTARGET BRAN_THINGY
97- .data.l 4, 3, 2, 1, 0 ; should branch over these
98-BRAN_THINGY:
99- .data.l PLUS
100- .data.l ZBRAN
101- mTARGET ZBRAN_THINGY0
102- .data.l 0, 1, 2, 3 ; should branch over these
103-ZBRAN_THINGY0:
104- .data.l LIT, 20
105- .data.l LIT, 19
106- .data.l SUB
107- .data.l ZBRAN
108- mTARGET ZBRAN_THINGY0
109- .data.l LIT, 15
110- .data.l LIT, 10
111- .data.l XDO
112-LOOP_THINGY:
113- .data.l LIT, "*"
114- .data.l EMIT
115- .data.l XLOOP
116- mTARGET LOOP_THINGY
117- .data.l LIT, h'f0f0f0f0
118- .data.l LIT, h'0f0f0f0f
119- .data.l USTAR
120- .data.l LIT, h'6A4C2E10, LIT, h'E2C4A68, DSUB, OR
121- .data.l ZBRAN
122- mTARGET UPRODUCTOK
123- .data.l -5
124-UPRODUCTOK:
125- .data.l LIT, h'10010000
126- .data.l LIT, h'10011001
127- .data.l LIT, h'10010
128- .data.l USLASH
129- .data.l AND, LIT, -1, SUB
130- .data.l ZBRAN
131- mTARGET UOVERFLOWOK
132- .data.l -1
133-UOVERFLOWOK:
134- .data.l LIT, h'1000fe76
135- .data.l LIT, h'00000100
136- .data.l LIT, h'00010010
137- .data.l USLASH
138- .data.l LIT, H'01000000
139- .data.l SUB
140- .data.l ZBRAN
141- mTARGET UQUOTIENTOK
142- .data.l 1
143-UQUOTIENTOK:
144- .data.l LIT, H'fe76
145- .data.l SUB
146- .data.l ZBRAN
147- mTARGET UREMAINDEROK
148- .data.l 3
149-UREMAINDEROK:
150- .data.l BRAN
151- mTARGET TEST_THINGY
152-
153-
15491 ; For various reasons, including the above "locate" declaration,
15592 ; this will be assembled monolithically, rather than separately.
15693 ; Thus:
15794 ;
95+ .include "teststuff.inc"
15896 .include "initialize.inc"
15997 .include "primitive.inc"
98+ .include "compiler.inc"
16099 .include "parser.inc"
161100 .include "evaluator.inc"
162101 .include "symbol.inc"
@@ -187,4 +126,4 @@ OUTERSPACE: .equ $
187126
188127
189128
190- .end
129+ .end
\ No newline at end of file
--- a/parser.inc
+++ b/parser.inc
@@ -3,124 +3,125 @@
33 ; Parser definitions for fig-FORTH for SH-3
44 ; Joel Matthew Rees, Hyougo Polytec Center
55 ; 2014.03.01
6+
7+; Licensed extended under GPL v. 2 or 3, or per the following:
8+; ------------------------------------LICENSE-------------------------------------
9+;
10+; Copyright (c) 2009, 2010, 2011 Joel Matthew Rees
11+;
12+; Permission is hereby granted, free of charge, to any person obtaining a copy
13+; of this software and associated documentation files (the "Software"), to deal
14+; in the Software without restriction, including without limitation the rights
15+; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16+; copies of the Software, and to permit persons to whom the Software is
17+; furnished to do so, subject to the following conditions:
18+;
19+; The above copyright notice and this permission notice shall be included in
20+; all copies or substantial portions of the Software.
21+;
22+; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23+; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24+; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25+; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26+; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27+; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28+; THE SOFTWARE.
29+;
30+; --------------------------------END-OF-LICENSE----------------------------------
31+
632
7-; Licensed extended under GPL v. 2 or 3, or per the following:
8-; ------------------------------------LICENSE-------------------------------------
9-;
10-; Copyright (c) 2009, 2010, 2011 Joel Matthew Rees
11-;
12-; Permission is hereby granted, free of charge, to any person obtaining a copy
13-; of this software and associated documentation files (the "Software"), to deal
14-; in the Software without restriction, including without limitation the rights
15-; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16-; copies of the Software, and to permit persons to whom the Software is
17-; furnished to do so, subject to the following conditions:
18-;
19-; The above copyright notice and this permission notice shall be included in
20-; all copies or substantial portions of the Software.
21-;
22-; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23-; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24-; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25-; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26-; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27-; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28-; THE SOFTWARE.
29-;
30-; --------------------------------END-OF-LICENSE----------------------------------
31-
32-; Monolithic, not separate assembly:
33-; context.inc must be included before this file.
34-; .include "context.inc"
35-;
33+; Monolithic, not separate assembly:
34+; context.inc must be included before this file.
35+; .include "context.inc"
36+;
3637 ; .section parser, code
3738
3839
39-; DIGIT ( c base --- ff )
40-; ( c base --- n tf )
41-; Translate C in base, yielding a translation valid flag. If the
42-; translation is not valid in the specified base, only the false
43-; flag is returned.
44-;
40+; DIGIT ( c base --- ff )
41+; ( c base --- n tf )
42+; Translate C in base, yielding a translation valid flag. If the
43+; translation is not valid in the specified base, only the false
44+; flag is returned.
45+;
4546 HEADER DIGIT, DIGIT
46- mov.l @(NATURAL_SIZE,fSP), r0 ; 7ビット文字
47+ mov.l @(NATURAL_SIZE,fSP), r0 ; 7ビット文字
4748 mov.b #"0", r1
48- cmp/ge r1, r0 ; character (r0) >= "0"
49- bf DIGITno
50- add #-"0", r0
51- mov.b #9, r1
52- cmp/gt r1, r0 ; digit (r0) > 9
53- bf DIGITbase
54- mov.b #"A"-"0", r1
55- cmp/ge r1, r0 ; was it between "9" and "A"?
56- bf DIGITno
57- add #"9"-"A"+1, r0
58-DIGITbase:
59- mov.l @fSP, r1
60- cmp/ge r1, r0 ; digit (r0) >= base
61- bt DIGITno
62- mov.l r0, @(NATURAL_SIZE,fSP)
63- mov.b #-1, r0 ; store the converted digit
64- rts
49+ cmp/ge r1, r0 ; character (r0) >= "0"
50+ bf DIGITno
51+ add #-"0", r0
52+ mov.b #9, r1
53+ cmp/gt r1, r0 ; digit (r0) > 9
54+ bf DIGITbase
55+ mov.b #"A"-"0", r1
56+ cmp/ge r1, r0 ; was it between "9" and "A"?
57+ bf DIGITno
58+ add #"9"-"A"+1, r0
59+DIGITbase:
60+ mov.l @fSP, r1
61+ cmp/ge r1, r0 ; digit (r0) >= base
62+ bt DIGITno
63+ mov.l r0, @(NATURAL_SIZE,fSP)
64+ mov.b #-1, r0 ; store the converted digit
65+ rts
6566 mov.l r0, @fSP ; set the flag on our way out
6667 ;
67-DIGITno:
68- mov.b #0, r0
69- add #NATURAL_SIZE, fSP
70- rts
71- mov.l r0, @fSP ; set the flag on our way out
72-
73-
74-; ENCLOSE ( buffer c --- buffer off1 off2 off3 )
75-; Scan buffer for a symbol delimited by c or ASCII NUL;
76-; return the offsets to the first character of the symbol,
77-; the last character of the symbol,
78-; and the next character after the symbol.
79-; Walks all over r0-r3 and fW.
80-;
81- HEADER ENCLOSE, ENCLOS
82- mov.l @fSP, r2 ; delimiter
83- mov.l @(NATURAL_SIZE,fSP), r1 ; point to start in the buffer
84- mov #0, r3 ; count
85-ENCLOSleadloop:
86- mov.b @r1+, r0
87- cmp/eq #0, r0 ; NUL character before symbol?
88- bt ENCLOSnone
89- cmp/eq r2, r0 ; leading delimiter? (Usually SPACE.)
90- bt ENCLOSword
91- bra ENCLOSleadloop
92- add #1, r1 ; Count it as we go.
93-;
94-ENCLOSword:
95- mov.l r3, @fSP ; Save offset to symbol or NUL.
96- mov.l @r1+, r0 ; get the next one
97-ENCLOSwordloop:
98- cmp/eq #0, r0 ; NUL?
99- bt/s ENCLOSnulterm
100- add #1, r3 ; count the one before
101- cmp/eq r2, r0 ; delimiter
102- bf/s ENCLOSwordloop
103- mov.l @r1+, r0 ; Get the next one, but not beyond NUL.
104-;
105-; The pointer and character don't matter, just the count.
106- mov.l r3, @-fSP ; Count to non-NUL delimiter.
107- add #1, r3 ; Next character that might be part of a symbol.
108- rts
109- mov.l r3, @-fSP ; Save it as we go.
110-
68+DIGITno:
69+ mov.b #0, r0
70+ add #NATURAL_SIZE, fSP
71+ rts
72+ mov.l r0, @fSP ; set the flag on our way out
73+
74+
75+; ENCLOSE ( buffer c --- buffer off1 off2 off3 )
76+; Scan buffer for a symbol delimited by c or ASCII NUL;
77+; return the offsets to the first character of the symbol,
78+; the last character of the symbol,
79+; and the next character after the symbol.
80+; Walks all over r0-r3 and fW.
81+;
82+ HEADER ENCLOSE, ENCLOS
83+ mov.l @fSP, r2 ; delimiter
84+ mov.l @(NATURAL_SIZE,fSP), r1 ; point to start in the buffer
85+ mov #0, r3 ; count
86+ENCLOSleadloop:
87+ mov.b @r1+, r0
88+ cmp/eq #0, r0 ; NUL character before symbol?
89+ bt ENCLOSnone
90+ cmp/eq r2, r0 ; leading delimiter? (Usually SPACE.)
91+ bt ENCLOSword
92+ bra ENCLOSleadloop
93+ add #1, r1 ; Count it as we go.
94+;
95+ENCLOSword:
96+ mov.l r3, @fSP ; Save offset to symbol or NUL.
97+ mov.l @r1+, r0 ; get the next one
98+ENCLOSwordloop:
99+ cmp/eq #0, r0 ; NUL?
100+ bt/s ENCLOSnulterm
101+ add #1, r3 ; count the one before
102+ cmp/eq r2, r0 ; delimiter
103+ bf/s ENCLOSwordloop
104+ mov.l @r1+, r0 ; Get the next one, but not beyond NUL.
105+;
106+; The pointer and character don't matter, just the count.
107+ mov.l r3, @-fSP ; Count to non-NUL delimiter.
108+ add #1, r3 ; Next character that might be part of a symbol.
109+ rts
110+ mov.l r3, @-fSP ; Save it as we go.
111+
111112 ; found NUL before non-delimiter, therefore there is no word
112-ENCLOSnone:
113- mov.l r3, @fSP ; Save offset to NUL.
114- add #1, r3
115- mov.l r3, @-fSP ; Make the symbol at least one char long.
116- add #-1, r3
117- rts
118- mov.l r3, @-fSP ; But keep us stopped at the NUL.
119-; delimited by NUL
120-ENCLOSnulterm:
121- mov.l r3, @-fSP ; Delimiter is NUL.
122- rts
123- mov.l r3, @-fSP ; No next character included, keep us at the NUL.
124-
125-
113+ENCLOSnone:
114+ mov.l r3, @fSP ; Save offset to NUL.
115+ add #1, r3
116+ mov.l r3, @-fSP ; Make the symbol at least one char long.
117+ add #-1, r3
118+ rts
119+ mov.l r3, @-fSP ; But keep us stopped at the NUL.
120+; delimited by NUL
121+ENCLOSnulterm:
122+ mov.l r3, @-fSP ; Delimiter is NUL.
123+ rts
124+ mov.l r3, @-fSP ; No next character included, keep us at the NUL.
125+
126+
126127
--- a/primitive.inc
+++ b/primitive.inc
@@ -50,13 +50,15 @@ NEXTloop:
5050 ; 3 cycles to get back to the top of the loop.
5151 nop
5252 bra NEXTloop
53- mov.l @fIP+, fW ; grab the next pointer as we go.
53+ mov.l @fIP+, fW ; grab the next pointer as we loop back.
5454 ; Note that, since jumps to absolute addresses have limits in constant-width instruction sets,
5555 ; using the subroutine call mode for the virtual machine is not as much a penalty as it might seem.
5656 ; It also has the advantage of being more compatible with more conventional code.
5757 ; Ways to make an absolute jump work might include
5858 ; * the address of next in a table of constants (and reserving a register for the table base), or
5959 ; * reserving a register for the address of next.
60+;
61+; See DOCOL ( _fDOCOL ).
6062
6163
6264 ; LIT ( --- n ) C
@@ -98,7 +100,7 @@ BRANCHgo:
98100 ; 0BRANCH ( f --- ) C
99101 ; BRANCH if flag is zero.
100102 ;
101- HEADER 0BRANCH, ZBRAN
103+ HEADER "0BRANCH", ZBRAN
102104 mov.l @fSP+, r0
103105 cmp/eq #0, r0
104106 bt/s BRANCHgo
@@ -124,7 +126,7 @@ BRANCHgo:
124126 ; does not occur, and the index and limit are dropped from the
125127 ; return stack.
126128 ;
127- HEADER (LOOP), XLOOP
129+ HEADER "(LOOP)", XLOOP
128130 mov.l @fRP, r0 ; I (loop counter)
129131 add #1, r0
130132 mov.l r0, @fRP ; update I
@@ -144,7 +146,7 @@ BRANCHgo:
144146 ; limit. A negative n must cause the index to become less than
145147 ; the limit to cause loop termination.
146148 ;
147- HEADER (+LOOP), XPLOOP
149+ HEADER "(+LOOP)", XPLOOP
148150 mov.l @fSP+, r1 ; increment
149151 mov.l @fRP, r0 ; I (loop counter)
150152 add r1, r0
@@ -176,7 +178,7 @@ XPLOOPminus:
176178 ; (DO) ( limit index --- ) ( *** limit index )
177179 ; Move the loop parameters to the return stack. Synonym for D>R, here.
178180 ;
179- HEADER (DO), XDO
181+ HEADER "(DO)", XDO
180182 mov.l @fSP+, r0
181183 mov.l @fSP+, r1
182184 add #-2*NATURAL_SIZE, fRP
@@ -211,7 +213,7 @@ CMOVEdone:
211213 rts
212214 add #3*NATURAL_SIZE, fSP ; Drop the parameters as we go.
213215
214-
216+
215217 ; SP@ ( --- adr )
216218 ; SPAT Fetch the parameter stack pointer (before it is pushed).
217219 ;
@@ -224,7 +226,7 @@ CMOVEdone:
224226 ; SPSTOR Initialize the parameter stack pointer from the USER variable
225227 ; S0. Effectively clears the stack.
226228 ;
227- HEADER SP!, SPSTOR
229+ HEADER "SP!", SPSTOR
228230 mov.l @(XSPZER,fUP), r0
229231 rts
230232 mov.l r0, fSP
@@ -238,7 +240,7 @@ CMOVEdone:
238240 ; Deferring to the glossary, rather than the 6800 model,
239241 ; and getting the initializer from the PER_USER table.
240242 ;
241- HEADER RP!, RPSTOR
243+ HEADER "RP!", RPSTOR
242244 mov.l @(XRZERO,fUP), r0
243245 rts
244246 mov.l r0, fSP
@@ -254,3 +256,16 @@ CMOVEdone:
254256
255257
256258
259+
260+
261+; NOOP ( --- )
262+; For stuffing no-operation placeholders into code.
263+; Useful for temporarily resolving forward definitions, among other things.
264+;
265+; This is part of the 6800 model, but not in the fig-FORTH glossary.
266+;
267+ HEADER NOOP, NOOP
268+ rts
269+ nop
270+
271+
--- a/symbol.inc
+++ b/symbol.inc
@@ -3,145 +3,145 @@
33 ; Symbol table definitions for fig-FORTH for SH-3
44 ; Joel Matthew Rees, Hyougo Polytec Center
55 ; 2014.03.01
6-
7-; Licensed extended under GPL v. 2 or 3, or per the following:
8-; ------------------------------------LICENSE-------------------------------------
9-;
10-; Copyright (c) 2009, 2010, 2011 Joel Matthew Rees
11-;
12-; Permission is hereby granted, free of charge, to any person obtaining a copy
13-; of this software and associated documentation files (the "Software"), to deal
14-; in the Software without restriction, including without limitation the rights
15-; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16-; copies of the Software, and to permit persons to whom the Software is
17-; furnished to do so, subject to the following conditions:
18-;
19-; The above copyright notice and this permission notice shall be included in
20-; all copies or substantial portions of the Software.
21-;
22-; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23-; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24-; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25-; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26-; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27-; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28-; THE SOFTWARE.
29-;
30-; --------------------------------END-OF-LICENSE----------------------------------
31-
32-; Monolithic, not separate assembly:
33-; context.inc must be included before this file.
34-; .include "context.inc"
35-;
36-; .section evaluator, code
37-
38-
39-; Not in the 6800 fig model, I've just re-factored it for fun.
40-; (NAME-SCAN) ( ptr1 --- ptr2 )
41-; Scan ptr1 to a byte with the high bit set,
42-; leave ptr2 pointing to the next byte.
43-; Walks all over r0 and r1. Must leave fW untouched.
44-;
45- HEADER (NAME-SCAN), PNAMESCAN
46- mov.l @fSP, r1
47- mov.b @r1+, r0
48-PNAMESCANloop:
49- and #CTFLAG, r0
50- cmp/eq #CTFLAG, r0
51- bf/s PNAMESCANloop
52- mov.b @r1+, r0
53-;
54- add #-1, r1
55- mov r1, r0
56- mALIGNr0
57- rts
58- mov.l r0, @fSP
6+
7+; Licensed extended under GPL v. 2 or 3, or per the following:
8+; ------------------------------------LICENSE-------------------------------------
9+;
10+; Copyright (c) 2009, 2010, 2011 Joel Matthew Rees
11+;
12+; Permission is hereby granted, free of charge, to any person obtaining a copy
13+; of this software and associated documentation files (the "Software"), to deal
14+; in the Software without restriction, including without limitation the rights
15+; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16+; copies of the Software, and to permit persons to whom the Software is
17+; furnished to do so, subject to the following conditions:
18+;
19+; The above copyright notice and this permission notice shall be included in
20+; all copies or substantial portions of the Software.
21+;
22+; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23+; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24+; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25+; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26+; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27+; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28+; THE SOFTWARE.
29+;
30+; --------------------------------END-OF-LICENSE----------------------------------
31+
32+; Monolithic, not separate assembly:
33+; context.inc must be included before this file.
34+; .include "context.inc"
35+;
36+; .section symbol, code
37+
38+
39+; Not in the 6800 fig model, I've just re-factored it for fun.
40+; (NAME-SCAN) ( ptr1 --- ptr2 )
41+; Scan ptr1 to a byte with the high bit set,
42+; leave ptr2 pointing to the next byte.
43+; Walks all over r0 and r1. Must leave fW untouched.
44+;
45+ HEADER "(NAME-SCAN)", PNAMESCAN
46+ mov.l @fSP, r1
47+ mov.b @r1+, r0
48+PNAMESCANloop:
49+ and #CTFLAG, r0
50+ cmp/eq #CTFLAG, r0
51+ bf/s PNAMESCANloop
52+ mov.b @r1+, r0
53+;
54+ add #-1, r1
55+ mov r1, r0
56+ mALIGNr0
57+ rts
58+ mov.l r0, @fSP
59+
60+
61+
62+; Not in the 6800 fig model, I've just re-factored it for fun.
63+; (CHK-NAME) ( name nfa --- name link f )
64+; Compare a name in a buffer to a name in the symbol table.
65+; Leave an equality flag and a pointer to the link field for the next name.
66+; Names in the dictionary are terminated with the high bit set.
67+; (Names only save 3 significant characters in some FORTHs.)
68+; Walks all over r0 - r3. Must leave fW untouched.
69+;
70+ HEADER "(CHK-NAME)", PCHKNAME
71+ sts.l pr, @-fRP ; so we can call stuff
72+ mov.l @fSP, r2 ; name in dictionary
73+ mov.l @(NATURAL_SIZE, fSP), r3 ; name in buffer
74+ mov.b @r2+, r0 ; count byte in dictionary, plus flags
75+ and #CTMASK, r0 ; Extract the actual count.
76+ mov.b @r3+, r1 ; count byte in buffer
77+ cmp/eq r0, r1
78+ bf PCHKNAMEno
79+PCHKNAMEloop:
80+ mov.b @r2+, r0 ; character in dictionary
81+ tst #TAILFLAG, r0
82+ bt PCHKNAMElast
83+ mov.b @r3+, r1 ; character in buffer
84+ cmp/eq r0, r1
85+ bt PCHKNAMEloop
86+;
87+PCHKNAMEno:
88+ mov #0, r3 ; r3 is not touched by xNAMESCAN
89+PCHKNAMEret:
90+ bsr _fPNAMESCAN
91+ mov.l r2, @fSP ; save it as we go
92+ lds.l @fRP+, pr ; Gotta have that return address!
93+ rts
94+ mov.l r3, @-fSP ; flag it as we go
95+;
96+PCHKNAMElast:
97+ mov.b @r3+, r1 ; last character in buffer
98+ and #TAILMASK, r0
99+ cmp/eq r0, r1
100+ bf PCHKNAMEno
101+;
102+ bra PCHKNAMEret
103+ mov #ALL_BITS8, r3 ; Set the flag as we go.
104+
59105
60-
61-
62-; Not in the 6800 fig model, I've just re-factored it for fun.
63-; (CHK-NAME) ( name nfa --- name link f )
64-; Compare a name in a buffer to a name in the symbol table.
65-; Leave an equality flag and a pointer to the link field for the next name.
66-; Names in the dictionary are terminated with the high bit set.
67-; (Names only save 3 significant characters in some FORTHs.)
68-; Walks all over r0 - r3. Must leave fW untouched.
69-;
70- HEADER (CHK-NAME), PCHKNAME
71- sts.l pr, @-fRP ; so we can call stuff
72- mov.l @fSP, r2 ; name in dictionary
73- mov.l @(NATURAL_SIZE, fSP), r3 ; name in buffer
74- mov.b @r2+, r0 ; count byte in dictionary, plus flags
75- and #CTMASK, r0 ; Extract the actual count.
76- mov.b @r3+, r1 ; count byte in buffer
77- cmp/eq r0, r1
78- bf PCHKNAMEno
79-PCHKNAMEloop:
80- mov.b @r2+, r0 ; character in dictionary
81- tst #TAILFLAG, r0
82- bt PCHKNAMElast
83- mov.b @r3+, r1 ; character in buffer
84- cmp/eq r0, r1
85- bt PCHKNAMEloop
86-;
87-PCHKNAMEno:
88- mov #0, r3 ; r3 is not touched by xNAMESCAN
89-PCHKNAMEret:
90- bsr _fPNAMESCAN
91- mov.l r2, @fSP ; save it as we go
92- lds.l @fRP+, pr ; Gotta have that return address!
93- rts
94- mov.l r3, @-fSP ; flag it as we go
95-;
96-PCHKNAMElast:
97- mov.b @r3+, r1 ; last character in buffer
98- and #TAILMASK, r0
99- cmp/eq r0, r1
100- bf PCHKNAMEno
101-;
102- bra PCHKNAMEret
103- mov #ALL_BITS8, r3 ; Set the flag as we go.
104-
105-
106-; (FIND) ( name nfa --- pfa b tf )
107-; ( name nfa --- ff )
108-; Search vocabulary for a symbol called name.
109-; name is a pointer to a counted string.
110-; nfa is the NFA of the last entry in the vocabulary to be searched.
111-; Walks all over r0 - r3, and fW.
112-;
113- HEADER (FIND), PFIND
114- sts.l pr, @-fRP ; so we can call stuff
115- mov.l @fSP, r0
116-PFINDloop:
117- mov.b @r0, fW ; We aren't using fW anyway, and it doesn't get walked in.
118- bsr _fPCHKNAME
119- mov.l @fSP+, r0 ; Did we find it?
120- cmp/eq #0, r0
121- bf/s PFINDfound ; Use the true flag in r0
122- mov.l @fSP, r1 ; LFA needed either way
123-;
124- mov.l @r1, r0
125- cmp/eq #0, r0
126- bt PFINDnot
127- bra PFINDloop
128- mov.l r0, @fSP ; Store the next one to check as we go.
129-;
130-PFINDnot:
131-; mov #0, r0 ; use the NULL pointer as a false flag
132- bra PFINDret
133- add #2*NATURAL_SIZE, fSP ; bump as we go
134-;
135-PFINDfound:
136- add #2*NATURAL_SIZE, r1 ; pfa
137- mov.l r1, @(NATURAL_SIZE,fSP)
138- mov.l fW, @fSP ; Store the saved count byte, with mode bits.
139-; mov #ALL_BITS8, r0 ; We can reuse the flag that sent us here.
140-PFINDret:
141- lds.l @fRP+, pr ; Gotta have that return address!
142- rts
143- mov.l r0, @-fSP ; Flag it as we go.
144-
145-
146-; *** Sometime check whether there are extra (unused) instructions in the 6800 code about here.
147-
106+; (FIND) ( name nfa --- pfa b tf )
107+; ( name nfa --- ff )
108+; Search vocabulary for a symbol called name.
109+; name is a pointer to a counted string.
110+; nfa is the NFA of the last entry in the vocabulary to be searched.
111+; Walks all over r0 - r3, and fW.
112+;
113+ HEADER "(FIND)", PFIND
114+ sts.l pr, @-fRP ; so we can call stuff
115+ mov.l @fSP, r0
116+PFINDloop:
117+ mov.b @r0, fW ; We aren't using fW anyway, and it doesn't get walked in.
118+ bsr _fPCHKNAME
119+ mov.l @fSP+, r0 ; Did we find it?
120+ cmp/eq #0, r0
121+ bf/s PFINDfound ; Use the true flag in r0
122+ mov.l @fSP, r1 ; LFA needed either way
123+;
124+ mov.l @r1, r0
125+ cmp/eq #0, r0
126+ bt PFINDnot
127+ bra PFINDloop
128+ mov.l r0, @fSP ; Store the next one to check as we go.
129+;
130+PFINDnot:
131+; mov #0, r0 ; use the NULL pointer as a false flag
132+ bra PFINDret
133+ add #2*NATURAL_SIZE, fSP ; bump as we go
134+;
135+PFINDfound:
136+ add #2*NATURAL_SIZE, r1 ; pfa
137+ mov.l r1, @(NATURAL_SIZE,fSP)
138+ mov.l fW, @fSP ; Store the saved count byte, with mode bits.
139+; mov #ALL_BITS8, r0 ; We can reuse the flag that sent us here.
140+PFINDret:
141+ lds.l @fRP+, pr ; Gotta have that return address!
142+ rts
143+ mov.l r0, @-fSP ; Flag it as we go.
144+
145+
146+; *** Sometime check whether there are extra (unused) instructions in the 6800 code about here.
147+
--- /dev/null
+++ b/teststuff.inc
@@ -0,0 +1,132 @@
1+ .list ON, EXP
2+
3+; Temporary test stuff for fig-FORTH for SH-3
4+; Joel Matthew Rees, Hyougo Polytec Center
5+; 2014.03.11
6+
7+; Licensed extended under GPL v. 2 or 3, or per the following:
8+; ------------------------------------LICENSE-------------------------------------
9+;
10+; Copyright (c) 2009, 2010, 2011 Joel Matthew Rees
11+;
12+; Permission is hereby granted, free of charge, to any person obtaining a copy
13+; of this software and associated documentation files (the "Software"), to deal
14+; in the Software without restriction, including without limitation the rights
15+; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16+; copies of the Software, and to permit persons to whom the Software is
17+; furnished to do so, subject to the following conditions:
18+;
19+; The above copyright notice and this permission notice shall be included in
20+; all copies or substantial portions of the Software.
21+;
22+; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23+; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24+; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25+; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26+; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27+; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28+; THE SOFTWARE.
29+;
30+; --------------------------------END-OF-LICENSE----------------------------------
31+
32+; Monolithic, not separate assembly:
33+; context.inc must be included before this file.
34+; .include "context.inc"
35+;
36+; .section test, code
37+
38+
39+ .AIFDEF SHIMMED
40+
41+; Temporary forward definitions --
42+; Added here as they are used,
43+; commented out as they are defined.
44+;
45+; These aren't magic, just shims for the assembler.
46+;
47+QEXEC: .define "NOOP" ; used in COLON
48+SCSP: .define "NOOP" ; used in COLON
49+CURENT: .define "NOOP" ; used in COLON
50+CONTXT: .define "NOOP" ; used in COLON
51+CREATE: .define "NOOP" ; used in COLON
52+RBRAK: .define "NOOP" ; used in COLON
53+PSCODE: .define "NOOP" ; used in COLON
54+QCSP: .define "NOOP" ; used in SEMI
55+COMPIL: .define "NOOP" ; used in SEMI
56+SMUDGE: .define "NOOP" ; used in SEMI
57+LBRAK: .define "NOOP" ; used in SEMI
58+COMMA: .define "NOOP" ; used in CONSTANT
59+; : .define "NOOP"
60+
61+
62+
63+ .AENDI
64+
65+
66+ .AIFDEF TESTING
67+
68+; test code
69+;
70+TEST_THINGY:
71+ .data.l LIT, 1
72+ .data.l LIT, -1
73+ .data.l BRAN
74+ mTARGET BRAN_THINGY
75+ .data.l 4, 3, 2, 1, 0 ; should branch over these
76+BRAN_THINGY:
77+ .data.l PLUS
78+ .data.l ZBRAN
79+ mTARGET ZBRAN_THINGY0
80+ .data.l 0, 1, 2, 3 ; should branch over these
81+ZBRAN_THINGY0:
82+ .data.l LIT, 20
83+ .data.l LIT, 19
84+ .data.l SUB
85+ .data.l ZBRAN
86+ mTARGET ZBRAN_THINGY0
87+ .data.l LIT, 15
88+ .data.l LIT, 10
89+ .data.l XDO
90+LOOP_THINGY:
91+ .data.l LIT, "*"
92+ .data.l EMIT
93+ .data.l XLOOP
94+ mTARGET LOOP_THINGY
95+ .data.l LIT, h'f0f0f0f0
96+ .data.l LIT, h'0f0f0f0f
97+ .data.l USTAR
98+ .data.l LIT, h'6A4C2E10, LIT, h'E2C4A68, DSUB, OR
99+ .data.l ZBRAN
100+ mTARGET UPRODUCTOK
101+ .data.l -5
102+UPRODUCTOK:
103+ .data.l LIT, h'10010000
104+ .data.l LIT, h'10011001
105+ .data.l LIT, h'10010
106+ .data.l USLASH
107+ .data.l AND, LIT, -1, SUB
108+ .data.l ZBRAN
109+ mTARGET UOVERFLOWOK
110+ .data.l -1
111+UOVERFLOWOK:
112+ .data.l LIT, h'1000fe76
113+ .data.l LIT, h'00000100
114+ .data.l LIT, h'00010010
115+ .data.l USLASH
116+ .data.l LIT, H'01000000
117+ .data.l SUB
118+ .data.l ZBRAN
119+ mTARGET UQUOTIENTOK
120+ .data.l 1
121+UQUOTIENTOK:
122+ .data.l LIT, H'fe76
123+ .data.l SUB
124+ .data.l ZBRAN
125+ mTARGET UREMAINDEROK
126+ .data.l 3
127+UREMAINDEROK:
128+ .data.l BRAN
129+ mTARGET TEST_THINGY
130+
131+ .AENDI
132+