Implementing figFORTH on SH3 assembler
Revision | e3d3fdd0c266ab07f87ee1d11898005423c0b6e7 (tree) |
---|---|
Zeit | 2014-03-11 23:10:21 |
Autor | Joel Matthew Rees <reiisi@user...> |
Commiter | Joel Matthew Rees |
Up through about definition 60, some of the compiling words (shimmed) and the first few CONSTANTS.
@@ -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 | + |
@@ -33,9 +33,14 @@ | ||
33 | 33 | |
34 | 34 | .cpu sh3 |
35 | 35 | |
36 | -; For huge things, like U/ (USLASH) | |
36 | +; For huge things, like U/ (USLASH) might be cut in half and repeated or something. | |
37 | 37 | PRIORITY_SIZE: .DEFINE "1" |
38 | 38 | |
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 | + | |
39 | 44 | |
40 | 45 | NATURAL_SIZE: .equ 4 ; 4 byte word |
41 | 46 | HALF_SIZE: .equ ( NATURAL_SIZE / 2 ) |
@@ -248,23 +253,23 @@ TAILMASK: .equ ( H'FF & ~TAILFLAG ) ; Expose the tail character. | ||
248 | 253 | |
249 | 254 | _PREVNAME: .assign 0 ; allocation/dictionary link (terminated by zero) |
250 | 255 | |
251 | - .macro HEADER name, characteristic, mode=0 | |
256 | + .macro HIHEADER name, characteristic, inherited, mode=0 | |
252 | 257 | ; Symbol name length and mode (Too much stuff in one byte, really.) |
253 | 258 | .data.b (.len("\name")&H'1f)|\mode|H'80 |
254 | 259 | ; Symbol name |
255 | 260 | _s\characteristic: .sdata .substr("\name", 0, .len("\name")-1) |
256 | 261 | ; Terminate the name with high bit set (bad news for multi-byte names). |
257 | 262 | .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. | |
259 | 264 | .align NATURAL_SIZE |
260 | -; Link to previously defined symbol's header. | |
265 | +; (Allocation) link to previously defined symbol's header. | |
261 | 266 | .data.l _PREVNAME |
262 | 267 | ; Use the SH-3 assembler to track the last symbol. |
263 | 268 | ; (This is not always a good idea.) |
264 | 269 | _PREVNAME: .assign _s\characteristic |
265 | 270 | ; Point to the characteristic code for this Word (symbol) to execute. |
266 | 271 | \characteristic .equ $ |
267 | - .data.l _f\characteristic | |
272 | + .data.l _f\inherited | |
268 | 273 | ; Point to the "parameter" area of the symbol. |
269 | 274 | _f\characteristic .equ $ |
270 | 275 | ; This area will contain executable code for primitive (leaf) definitions. |
@@ -274,6 +279,10 @@ _f\characteristic .equ $ | ||
274 | 279 | ; And so (ahem) forth. |
275 | 280 | .endm |
276 | 281 | |
282 | + .macro HEADER name, characteristic, mode=0 | |
283 | + HIHEADER "\name", \characteristic, \characteristic, \mode | |
284 | + .endm | |
285 | + | |
277 | 286 | |
278 | 287 | ; More as an example than to be actually used: |
279 | 288 | .macro fSAFECALL cfa |
@@ -2,83 +2,83 @@ | ||
2 | 2 | |
3 | 3 | ; Actual driver definitions for fig-FORTH for SH-3 |
4 | 4 | ; 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 | + | |
32 | 32 | ; 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 | +; | |
38 | 38 | ; .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 | + |
@@ -3,271 +3,570 @@ | ||
3 | 3 | ; Expression evaluator definitions for fig-FORTH for SH-3 |
4 | 4 | ; Joel Matthew Rees, Hyougo Polytec Center |
5 | 5 | ; 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 | + | |
6 | 32 | |
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 | +; | |
37 | 37 | ; .section evaluator, code |
38 | 38 | |
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 | + | |
39 | 53 | |
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. | |
59 | 56 | ; |
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 | +; | |
60 | 63 | HEADER I, I |
61 | 64 | mov.l @fRP, r0 ; I (loop counter) |
62 | 65 | rts |
63 | 66 | 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 | |
81 | 311 | |
82 | 312 | |
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 | + | |
212 | 330 | |
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 | + | |
213 | 385 | |
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" | |
214 | 409 | |
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 | + | |
225 | 437 | |
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 | + | |
243 | 458 | |
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 | |
253 | 519 | |
254 | 520 | |
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 | + | |
273 | 572 |
@@ -59,56 +59,56 @@ WENT: | ||
59 | 59 | |
60 | 60 | |
61 | 61 | |
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 | +; |
@@ -3,116 +3,116 @@ | ||
3 | 3 | ; FORTH input/output definitions for fig-FORTH for SH-3 |
4 | 4 | ; Joel Matthew Rees, Hyougo Polytec Center |
5 | 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 | - | |
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 | +; | |
36 | 36 | ; .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 ) | |
69 | 69 | ; 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 | + | |
84 | 84 | ; ?TERMINAL ( --- f ) |
85 | 85 | ; Perform a test of the terminal keyboard for actuation of the break |
86 | 86 | ; 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, | |
91 | 91 | ; 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 ( --- ) | |
104 | 104 | ; Transmit a carriage return and line feed to the selected output |
105 | 105 | ; 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 | + |
@@ -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. | |
2 | 2 | .list ON, EXP |
3 | 3 | |
4 | 4 | ; Primitive (kernel) definitions for fig-FORTH for SH-3 |
@@ -37,126 +37,65 @@ | ||
37 | 37 | |
38 | 38 | .org $ |
39 | 39 | |
40 | +;*************************** | |
41 | +;** C O L D E N T R Y ** | |
40 | 42 | ;*************************** |
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: | |
45 | 45 | 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 ** | |
49 | 49 | ;*************************** |
50 | 50 | ; |
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. | |
53 | 53 | mov.l #WENT, r0 ; warm-start code, keeps current dictionary intact |
54 | 54 | jmp @r0 |
55 | - nop | |
56 | -; | |
57 | -;* | |
58 | -;******* startup parmeters ************************** | |
55 | + nop | |
56 | +; | |
57 | +;* | |
58 | +;******* startup parmeters ************************** | |
59 | 59 | ;* |
60 | 60 | ; All of this is essentially place-holder values: |
61 | -COLD_PARAMETERS: | |
61 | +COLD_PARAMETERS: | |
62 | 62 | .data.l "SH-3" ; cpu |
63 | 63 | .data.l 0 ; revision |
64 | - .data.l 0 ; topmost word in FORTH vocabulary | |
64 | + .data.l 0 ; topmost word in FORTH vocabulary | |
65 | 65 | BACKSP: |
66 | - .data.l h'7f ; backspace character for editing | |
66 | + .data.l h'7f ; backspace character for editing | |
67 | 67 | UPINIT: |
68 | - .data.l PER_USER ; UORIG ; initial user area | |
68 | + .data.l PER_USER ; UORIG ; initial user area | |
69 | 69 | 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 | |
71 | 71 | 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) | |
76 | 76 | FENCIN: |
77 | - .data.l fSP_LIMIT-h'400 ; REND ; initial fence | |
77 | + .data.l fSP_LIMIT-h'400 ; REND ; initial fence | |
78 | 78 | 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 | |
80 | 80 | VOCINT: |
81 | - .data.l fSP_LIMIT-h'400 ; FORTH+8 | |
81 | + .data.l fSP_LIMIT-h'400 ; FORTH+8 | |
82 | 82 | COLINT: |
83 | - .data.l 132 ; initial terminal carriage width | |
83 | + .data.l 132 ; initial terminal carriage width | |
84 | 84 | DELINT: |
85 | 85 | .data.l 4 ; initial carriage return delay |
86 | -;**************************************************** | |
87 | -;* | |
88 | - | |
86 | +;* | |
87 | +;**************************************************** | |
88 | +;* | |
89 | 89 | |
90 | 90 | |
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 | - | |
154 | 91 | ; For various reasons, including the above "locate" declaration, |
155 | 92 | ; this will be assembled monolithically, rather than separately. |
156 | 93 | ; Thus: |
157 | 94 | ; |
95 | + .include "teststuff.inc" | |
158 | 96 | .include "initialize.inc" |
159 | 97 | .include "primitive.inc" |
98 | + .include "compiler.inc" | |
160 | 99 | .include "parser.inc" |
161 | 100 | .include "evaluator.inc" |
162 | 101 | .include "symbol.inc" |
@@ -187,4 +126,4 @@ OUTERSPACE: .equ $ | ||
187 | 126 | |
188 | 127 | |
189 | 128 | |
190 | - .end | |
129 | + .end | |
\ No newline at end of file |
@@ -3,124 +3,125 @@ | ||
3 | 3 | ; Parser definitions for fig-FORTH for SH-3 |
4 | 4 | ; Joel Matthew Rees, Hyougo Polytec Center |
5 | 5 | ; 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 | + | |
6 | 32 | |
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 | +; | |
36 | 37 | ; .section parser, code |
37 | 38 | |
38 | 39 | |
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 | +; | |
45 | 46 | HEADER DIGIT, DIGIT |
46 | - mov.l @(NATURAL_SIZE,fSP), r0 ; 7ビット文字 | |
47 | + mov.l @(NATURAL_SIZE,fSP), r0 ; 7ビット文字 | |
47 | 48 | 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 | |
65 | 66 | mov.l r0, @fSP ; set the flag on our way out |
66 | 67 | ; |
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 | + | |
111 | 112 | ; 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 | + | |
126 | 127 |
@@ -50,13 +50,15 @@ NEXTloop: | ||
50 | 50 | ; 3 cycles to get back to the top of the loop. |
51 | 51 | nop |
52 | 52 | 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. | |
54 | 54 | ; Note that, since jumps to absolute addresses have limits in constant-width instruction sets, |
55 | 55 | ; using the subroutine call mode for the virtual machine is not as much a penalty as it might seem. |
56 | 56 | ; It also has the advantage of being more compatible with more conventional code. |
57 | 57 | ; Ways to make an absolute jump work might include |
58 | 58 | ; * the address of next in a table of constants (and reserving a register for the table base), or |
59 | 59 | ; * reserving a register for the address of next. |
60 | +; | |
61 | +; See DOCOL ( _fDOCOL ). | |
60 | 62 | |
61 | 63 | |
62 | 64 | ; LIT ( --- n ) C |
@@ -98,7 +100,7 @@ BRANCHgo: | ||
98 | 100 | ; 0BRANCH ( f --- ) C |
99 | 101 | ; BRANCH if flag is zero. |
100 | 102 | ; |
101 | - HEADER 0BRANCH, ZBRAN | |
103 | + HEADER "0BRANCH", ZBRAN | |
102 | 104 | mov.l @fSP+, r0 |
103 | 105 | cmp/eq #0, r0 |
104 | 106 | bt/s BRANCHgo |
@@ -124,7 +126,7 @@ BRANCHgo: | ||
124 | 126 | ; does not occur, and the index and limit are dropped from the |
125 | 127 | ; return stack. |
126 | 128 | ; |
127 | - HEADER (LOOP), XLOOP | |
129 | + HEADER "(LOOP)", XLOOP | |
128 | 130 | mov.l @fRP, r0 ; I (loop counter) |
129 | 131 | add #1, r0 |
130 | 132 | mov.l r0, @fRP ; update I |
@@ -144,7 +146,7 @@ BRANCHgo: | ||
144 | 146 | ; limit. A negative n must cause the index to become less than |
145 | 147 | ; the limit to cause loop termination. |
146 | 148 | ; |
147 | - HEADER (+LOOP), XPLOOP | |
149 | + HEADER "(+LOOP)", XPLOOP | |
148 | 150 | mov.l @fSP+, r1 ; increment |
149 | 151 | mov.l @fRP, r0 ; I (loop counter) |
150 | 152 | add r1, r0 |
@@ -176,7 +178,7 @@ XPLOOPminus: | ||
176 | 178 | ; (DO) ( limit index --- ) ( *** limit index ) |
177 | 179 | ; Move the loop parameters to the return stack. Synonym for D>R, here. |
178 | 180 | ; |
179 | - HEADER (DO), XDO | |
181 | + HEADER "(DO)", XDO | |
180 | 182 | mov.l @fSP+, r0 |
181 | 183 | mov.l @fSP+, r1 |
182 | 184 | add #-2*NATURAL_SIZE, fRP |
@@ -211,7 +213,7 @@ CMOVEdone: | ||
211 | 213 | rts |
212 | 214 | add #3*NATURAL_SIZE, fSP ; Drop the parameters as we go. |
213 | 215 | |
214 | - | |
216 | + | |
215 | 217 | ; SP@ ( --- adr ) |
216 | 218 | ; SPAT Fetch the parameter stack pointer (before it is pushed). |
217 | 219 | ; |
@@ -224,7 +226,7 @@ CMOVEdone: | ||
224 | 226 | ; SPSTOR Initialize the parameter stack pointer from the USER variable |
225 | 227 | ; S0. Effectively clears the stack. |
226 | 228 | ; |
227 | - HEADER SP!, SPSTOR | |
229 | + HEADER "SP!", SPSTOR | |
228 | 230 | mov.l @(XSPZER,fUP), r0 |
229 | 231 | rts |
230 | 232 | mov.l r0, fSP |
@@ -238,7 +240,7 @@ CMOVEdone: | ||
238 | 240 | ; Deferring to the glossary, rather than the 6800 model, |
239 | 241 | ; and getting the initializer from the PER_USER table. |
240 | 242 | ; |
241 | - HEADER RP!, RPSTOR | |
243 | + HEADER "RP!", RPSTOR | |
242 | 244 | mov.l @(XRZERO,fUP), r0 |
243 | 245 | rts |
244 | 246 | mov.l r0, fSP |
@@ -254,3 +256,16 @@ CMOVEdone: | ||
254 | 256 | |
255 | 257 | |
256 | 258 | |
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 | + |
@@ -3,145 +3,145 @@ | ||
3 | 3 | ; Symbol table definitions for fig-FORTH for SH-3 |
4 | 4 | ; Joel Matthew Rees, Hyougo Polytec Center |
5 | 5 | ; 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 | + | |
59 | 105 | |
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 | + |
@@ -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 | + |