-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
329 lines (238 loc) · 11 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
88 88 88888888888
88 88 88
88 88 88
88 88 88aaaaa
88 88 88"""""
88 88 88
Y8a. .a8P 88
`"Y8888Y"' 88
Version: 9
I. Introduction
This is a traditional Forth system for the "uxn/varvara"[1] virtual
computer. "UF" is written in Tal[2] and Forth and provides an
interactive text interface and screen editor. The system is not
threaded, it compiles to native UXN code, but currently only minimal
optimizations are performed. The mapping of Forth source code to
VM instructions is nevertheless relatively direct, so performance
should be more than sufficient in all but the most speed-critical
situations. Cells are 16 bits, the full system uses around 25K of
memory, with another 4K needed for screen memory and buffers.
II. Building UF
To build the .rom files, you need to first assemble the kernel and
then use it to generate additional .rom files with more functionality:
$ uxnasm kernel.tal kernel.rom
...
$ uxncli kernel.rom <uf.f
This will produce the following files:
kernel.rom
The kernel, containing minimal functionality to define new
words.
uf0.rom
The kernel and core words.
uf.rom
The functionality of "uf0.rom" together with words to access
"varvara" device ports in a more convenient matter, and some
basic tools (like `dump`).
ufx.rom
The full graphical Forth system, including the block editor.
III. Using UF
Run "uf0.rom" and "uf.rom" with "uxncli" as a normal terminal
application. "ufx.rom" should be executed with "uxnemu":
uxnemu ufx.rom <arguments ...>
Additional command line arguments or console input will be redirected
to the graphical input prompt and can be used to perform initialization,
etc.
In the graphical interface the following key sequences have a special
meaning ("^" meaning the Control key, "Sh" the Shift key):
^a Jump to beginning of line
^e Jump to end of line
^c Terminate Forth (unless a modified block is open in the
editor)
^d Delete next char
^k Kill to end of line or marked region (and write to
".snarf" file)
^u Kill to beginning of line or marked region (and snarf)
^x Copy line or marked region to ".snarf" file
^v, ^y Paste contents of ".snarf" file
^f Find next occurrence of word below cursor
^s Save changes in currently edited block
^l Clear screen (unless in editor)
^g Read digits and jump to indicated block on ENTER
(abort on ESC)
^r Read digits and copy current block to new one on ENTER
^m Read digits and move current block to new one on ENTER
(and delete the old block)
^ENTER Toggle region mark on/off in editor
Sh-Up Recall the last entered line or jump to previous block
Sh-Down Jump to next block
Sh-Left/Right Jump between code and documentation ("shadow")
block
The arrow keys have the usual meaning. Pressing ENTER will execute
the current line (marked by the cursor). Pressing ^ENTER will
toggle "mark" mode, all lines between the start of the mark and
the current row are copied and written to a file named ".snarf"
in the current directory once you press ENTER or ^x.
Pressing the first mouse button will reposition the cursor. Pressing
the third button will execute the word below the mouse pointer.
Moving the scroll wheel will jump to the previous or next block,
when currently editing an unmodified block.
File system access is provided by "block" files, where each block
is named by a natural number and contains 2496 bytes (39 lines with
64 columns). To edit a block, enter
<blocknumber> edit
The ESC key will exit or enter editing (unless the current block
is modified). The bottom row contains counters indicating current
row, column, block number, the length of the most recently copied
text, the amount of dictionary space left and a marker indicating
whether the current block is modified. Blocks can be loaded using
`load` and `thru`. Note that block-loading is done by temporarily
changing the word for reading user-input (`query`) and takes effect
when the current input line has been fully processed. That implies
that loading words can not be invoked recursively.
You can also edit a block by clicking with button 3 on a string of
the form "#nnnn" where "nnnn" is a decimal integer.
If a 6 byte file named ".theme" is found in the current directory,
then it will be used to initialize the color scheme during startup.
The colors are used as follows: #0 background, #1 text, #2 status
line text, #3 selection.
The current state of the system can be conveniently stored as a
.rom file on disk by entering
save <filename>
The saved rom has the exact same state (but with cleared stacks)
as when it was created. During startup, the deferred word `boot`
is invoked, you can redefine it to replace it with custom startup
code.
You are also heavily encouraged to consult the source code in "uf.f".
IV. Compatibility to other Forths
Consult the "GLOSSARY" file for a list of supported Forth words
and the extensively commented source files "kernel.tal" and "uf.f"
for more information. The dialect implemented in UF is mostly compatible
to the Forth 2012 Standard[3]. Notable differences include:
- The system is case-sensitive (`Abc` and `abc` name two different
words)
- `do` and `?do` treat the index and range as unsigned quantities.
- Numeric conversion in `<# ... #>` exclusively deals with single
cell numbers.
- Double-word maths are currently not implemented.
- Words that produce boolean results may not always generate -1
(`true`) but some other non-zero value.
- Multiple `while` forms in a `begin` ... `repeat` loop are not
supported.
The dictionary can be inspected with the `words`, `order` and `.vocs`
words. To decompile built-in or user words, use `see`.
V. The integrated Assembler
You can define words containing a simplifed form of Uxntal using the
`code` and `end-code` words. Inside such a definition, the following
words have a special meaning:
BRK INC ... assemble uxn op-instruction
" k r add modifier bit to previous instruction
$ ( u -- ) pad by number of bytes on stack
# ( c -- ) assemble byte literal
#" ( x -- ) assemble short literal
& ( u -- ) define label
, ( u -- ) reference previously defined label as relative
branch distance
` ( | <word> -- ) Compile immediate call of Forth word
! ( | <word> -- ) Compile immediate jump to Forth word
? ( | <word> -- ) Compile immediate conditional jump to Forth word
Currently only 16 labels can be defined. You can insert absolute
references to other Forth words using the sequence `' <word> #"`
or by using the syntax
` <word`
to encode an immediate (JSI) call to a Forth word.
Note that the stack is required to be aligned to shorts and that
code-words should perform the equivalent of a "JMP2r" to return to
the caller.
An example:
code bitcount8 ( x^ -- n^ )
0 # SWP ( n x )
1 &
DUP 0 # EQU ( n x x=0 )
2 , JCN ( n x )
1 # SFT ( n x>>1 )
SWP INC SWP ( n+1 x>>1 )
1 , JMP
2 &
POP ( n )
JMP " r
end-code
VI. Memory Map
FFFF +----------------------------+
| Screen buffer |
F600 +----------------------------+
| Block load buffer |
ec40 +----------------------------+
| |
| Unused space |
| |
+----------------------------+ < `here`
| User defined words |
+----------------------------+
| Kernel |
0100 +----------------------------+
| Unused |
0000 +----------------------------+
Uf allows up to 4 vocabularies to be active at the same time. You
can see the currently available words by executing `words` and
inspect the vocabulary stack with `.vocs`. Predefined vocabularies
are `forth` (the default), `compiler` (words only available during
compilation of colon words), `assembler`, `decompiler` and `editor`.
VIII. Uxn VM implementation Issues
UF has been tested on SDL uxn[4] and uxn11[5].
In the graphical interface the controller, console and mouse device
vectors are modified to receive input events. During evaluation of
code the vectors are temporarily cleared and a BRK or machine halt
will abort with an error and return to the Forth prompt. If you
want to modify any of these vectors permanently, make sure your
code does not return to the interactive prompt or use `wait`, which
invokes the deferred word `tick`, which you can modify to perform
custom processing (the default implementation just blinks the
cursor).
The graphical system sets the screen size to the default 512x320
resolution which must be supported by the underlying uxn implementation.
A number of words are defined to access "varvara" devices, consult
the GLOSSARY for more details:
System:
colors reset clear depth evector
Console:
cin cout ctype cvector
Screen:
screensize@ screensize! position pixel auto spritedata
sprite svector
Audio:
sample play adsr volume output avector
Controller:
jkey jbutton jvector
Mouse:
mouse mscroll mstate mvector
File:
filename filewrite fileappend fileread filedelete
Datetime:
year month day hour minute second dotw doty isdst
Note that the file words only use the first file device (a0).
Console input in the graphical interface is redirected to the
screen, so the line-length limit of the screen applies here.
Input lines that exceed the screen width are silently cut off,
with the text preceding the exceeding part being ignored.
Due to limitations of the "varvara" file-system interface files
loaded with `include` (or `included`) may not exceed the
currently available dictionary space divided by two as the
file has to be loaded into memory completely before it can be
interpreted. Moreover, file-inclusion can not be nested.
IX. License
This software was written by Felix L. Winkelmann and has been
released into the public domain. Do with it whatever you want.
X. Contact Information
This software will have many bugs and shortcomings. In case you
need help, have suggestions or ideas, please do not hesitate to
contact the author at
felix AT call-with-current-continuation DOT org
A git repository can be found at [6], if you want to follow the
development of the system more closely.
XI. References
[1] https://100r.co/site/uxn.html
[2] https://wiki.xxiivv.com/site/uxntal.html
[3] https://forth-standard.org/
[4] https://git.sr.ht/~rabbits/uxn
[5] https://git.sr.ht/~rabbits/uxn11
[6] https://gitlab.com/b2495/uf