commit 192cc07
chld
·
2026-10-27 12:40:04 +0000 UTC
parent 50819bf
init uxn38
+23,
-0
1@@ -0,0 +1,23 @@
2+environment:
3+ BUILD_SUBMITTER: git.sr.ht
4+ SITE: rabbits.srht.site/uxn2
5+image: debian/stable
6+packages:
7+- curl
8+- libsdl2-dev
9+shell: false
10+oauth: pages.sr.ht/PAGES:RW
11+sources:
12+- https://git.sr.ht/~rabbits/uxn2
13+tasks:
14+- build: |
15+ mkdir bin/
16+ cc -I/usr/include/SDL2 -DNDEBUG -O2 -g0 -s -lSDL2 uxn2/src/uxn2.c -o bin/uxn2 $(sdl2-config --cflags --libs)
17+- upload: |
18+ tar -czf out.tar.gz bin/
19+ acurl() {
20+ set +x
21+ curl -H "Authorization: Bearer ${OAUTH2_TOKEN}" "${@}"
22+ set -x
23+ }
24+ acurl -fsS "https://pages.sr.ht/publish/${SITE}" -Fcontent=@out.tar.gz
+22,
-0
1@@ -0,0 +1,22 @@
2+AlignAfterOpenBracket: DontAlign
3+AlignEscapedNewlines: DontAlign
4+AlignOperands: DontAlign
5+AllowShortBlocksOnASingleLine: Always
6+AllowShortCaseLabelsOnASingleLine: true
7+AllowShortEnumsOnASingleLine: true
8+AllowShortIfStatementsOnASingleLine: true
9+AllowShortLoopsOnASingleLine: true
10+AlwaysBreakAfterDefinitionReturnType: TopLevel
11+BreakBeforeTernaryOperators: false
12+BinPackArguments: false
13+BinPackParameters: false
14+BreakBeforeBraces: WebKit
15+IndentCaseLabels: false
16+TabWidth: 4
17+IndentWidth: 4
18+ContinuationIndentWidth: 4
19+UseTab: ForContinuationAndIndentation
20+ColumnLimit: 0
21+ReflowComments: false
22+SortIncludes: false
23+SpaceBeforeParens: false
+16,
-0
1@@ -0,0 +1,16 @@
2+.DS*
3+*jpg~
4+*png~
5+*gif~
6+*bmp~
7+/bin
8+*io.bit
9+*.bak
10+/*-test
11+/screenshot-*.bmp
12+
13+*snarf
14+*theme
15+
16+bios.rom
17+bios.rom.sym
A
LICENSE
+21,
-0
1@@ -0,0 +1,21 @@
2+MIT License
3+
4+Copyright (c) Devine Lu Linvega
5+
6+Permission is hereby granted, free of charge, to any person obtaining a copy
7+of this software and associated documentation files (the "Software"), to deal
8+in the Software without restriction, including without limitation the rights
9+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+copies of the Software, and to permit persons to whom the Software is
11+furnished to do so, subject to the following conditions:
12+
13+The above copyright notice and this permission notice shall be included in all
14+copies or substantial portions of the Software.
15+
16+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+SOFTWARE.
+112,
-0
1@@ -0,0 +1,112 @@
2+# Uxn2
3+
4+A graphical emulator for the [Varvara Computer](https://wiki.xxiivv.com/site/varvara.html), written in C99(SDL2).
5+
6+## Building
7+
8+You must have [SDL2](https://www.libsdl.org/) installed.
9+
10+```sh
11+cc -I/usr/include/SDL2 -DNDEBUG -O2 -g0 -s -lSDL2 src/uxn2.c -o bin/uxn2
12+```
13+
14+For your convenience a [Makefile](https://en.wikipedia.org/wiki/Make_(software)#Makefile) is provided.
15+
16+```sh
17+make run
18+```
19+
20+You can run `make install` to build and install the files. By default, files are installed into `~/.local` but this can be overridden using `PREFIX`:
21+
22+```sh
23+# installs files into /opt/uxn/bin
24+$ make PREFIX=/opt/uxn install
25+```
26+
27+### Plan 9
28+
29+If you're on plan 9.
30+
31+```sh
32+cd src/
33+cc -p -I/sys/include/npe -I /sys/include/npe/SDL2/ uxn2.c
34+6l -o uxn2 uxn2.6
35+```
36+
37+If do not wish to build it yourself, you can [download linux binaries](https://rabbits.srht.site/uxn2/bin/uxn2).
38+
39+[](https://builds.sr.ht/~rabbits/uxn2?)
40+
41+## Usage
42+
43+The first parameter is the rom file, the subsequent arguments will be accessible to the rom, via the [Console vector](https://wiki.xxiivv.com/site/varvara.html#console).
44+
45+```sh
46+bin/uxn2 bin/example.rom arg1 arg2
47+```
48+
49+- `-f` to start in fullscreen
50+- `-2` to start in zoomed x2
51+
52+## Assembler
53+
54+This repository comes with a copy of the compiled [Drifblim](https://git.sr.ht/~rabbits/drifblim) assembler.
55+
56+```sh
57+cat etc/utils/drifblim.rom.txt | bin/uxn2 etc/utils/xh.rom > bin/drifblim.rom
58+bin/uxn2 bin/drifblim.rom etc/tests/opctest.tal bin/opctest.rom
59+```
60+
61+## Devices
62+
63+The file device is _not_ sandboxed, it is able read or write outside of the working directory.
64+
65+- `00` system
66+- `10` console
67+- `20` screen
68+- `40` audio
69+- `50` audio
70+- `60` audio
71+- `70` audio
72+- `80` controller
73+- `90` mouse
74+- `a0` file(a)
75+- `b0` file(b)
76+- `c0` datetime
77+
78+## Emulator Controls
79+
80+- `F1` toggle zoom
81+- `F2` toggle debugger
82+- `F4` reboot
83+- `F5` reboot(soft)
84+
85+### Buttons
86+
87+- `LCTRL` A
88+- `LALT` B
89+- `LSHIFT` SEL
90+- `HOME` START
91+
92+## SDL2
93+
94+To build this emulator, you must install [SDL2](https://wiki.libsdl.org/) for your distro. If you are using a package manager:
95+
96+```sh
97+sudo pacman -Sy sdl2 # Arch
98+sudo apt install libsdl2-dev # Ubuntu
99+sudo xbps-install SDL2-devel # Void Linux
100+brew install sdl2 # OS X
101+```
102+
103+## Need a hand?
104+
105+The following resources are a good place to start:
106+
107+* [XXIIVV — uxntal](https://wiki.xxiivv.com/site/uxntal.html)
108+* [XXIIVV — uxntal reference](https://wiki.xxiivv.com/site/uxntal_reference.html)
109+* [compudanzas — uxn tutorial](https://compudanzas.net/uxn_tutorial.html)
110+
111+## Contributing
112+
113+Submit patches using [`git send-email`](https://git-send-email.io/) to the [~rabbits/public-inbox mailing list](https://lists.sr.ht/~rabbits/public-inbox).
+347,
-0
1@@ -0,0 +1,347 @@
2+.\" Manpage reference for uxntal.
3+.\" by Eiríkr Åsheim
4+.\" Contact d_m@plastic-idolatry.com to correct errors or typos.
5+.TH uxntal 7 "12 Aug 2026" "1.0" "Uxntal Reference Guide"
6+.SH NAME
7+uxntal \- assembly language for Varvara virtual machine
8+.SH DESCRIPTION
9+Uxntal is an 8-bit instruction set for programming the Varvara virtual machine.
10+It uses the lower 5-bits to specify an opcode, and the upper 3-bits to specify
11+optional modes.
12+
13+ROMs consist of a 16-bit address space of bytes. Any byte can be interpreted as either data or an instruction. A 2-byte program counter (\fIpc\fP) determines the address of the next instruction to decode and run.
14+
15+Instructions manipulate data using two stacks: a working stack (\fBwst\fP) and a return stack (\fBrst\fP). Each stack consists of 256 bytes, and in the case of overflow or underflow the stack pointer will wrap (the stacks are circular).
16+
17+There are also 256 bytes of device memory, which are used to interact with the virtual machine and its devices.
18+
19+Instructions deal with unsigned 8-bit values (\fIbytes\fP) and unsigned 16-bit values (\fIshorts\fP). There are no other built-in data types. Occasionally values are treated as signed, such as when loading, storing, or jumping with a relative address.
20+
21+Short values are stored on the stack in big-endian byte order: the least significant byte will be on the top of the stack. This makes \fB#abcd\fP equivalent to \fB#ab #cd\fP.
22+
23+.SH INSTRUCTION LAYOUT
24+
25+ 0x01 ----
26+ 0x02 \\
27+ 0x04 +- \fIopcode\fP
28+ 0x08 /
29+ 0x10 ----
30+ 0x20 ---- 2: \fIshort mode\fP
31+ 0x40 ---- r: \fIreturn mode\fP
32+ 0x80 ---- k: \fIkeep mode\fP
33+
34+.SH OPCODE LAYOUT
35+
36+There are 32 base values for opcodes:
37+
38+ 0x00 \fBBRK*\fP 0x08 \fBEQU\fP 0x10 \fBLDZ\fP 0x18 \fBADD\fP
39+ 0x01 \fBINC\fP 0x09 \fBNEQ\fP 0x11 \fBSTZ\fP 0x19 \fBSUB\fP
40+ 0x02 \fBPOP\fP 0x0a \fBGTH\fP 0x12 \fBLDR\fP 0x1a \fBMUL\fP
41+ 0x03 \fBNIP\fP 0x0b \fBLTH\fP 0x13 \fBSTR\fP 0x1b \fBDIV\fP
42+ 0x04 \fBSWP\fP 0x0c \fBJMP\fP 0x14 \fBLDA\fP 0x1c \fBAND\fP
43+ 0x05 \fBROT\fP 0x0d \fBJCN\fP 0x15 \fBSTA\fP 0x1d \fBORA\fP
44+ 0x06 \fBDUP\fP 0x0e \fBJSR\fP 0x16 \fBDEI\fP 0x1e \fBEOR\fP
45+ 0x07 \fBOVR\fP 0x0f \fBSTH\fP 0x17 \fBDEO\fP 0x1f \fBSFT\fP
46+
47+The "complete" opcode's value can be derived by combining the base value with its flags.
48+
49+For example, \fBADD2k\fP is \fB(ADD | 2 | k)\fP = \fB(0x18 | 0x20 | 0x80)\fP = \fB0xb8\fP.
50+
51+Unlike other opcodes, \fB0x00\fP (\fBBRK*\fP) is contextual: its meaning depends on the \fImode\fP bits provided:
52+
53+ 0x00 \fBBRK\fP 0x80 \fBLIT\fP
54+ 0x20 \fBJCI\fP 0xa0 \fBLIT2\fP
55+ 0x40 \fBJMI\fP 0xc0 \fBLITr\fP
56+ 0x60 \fBJSI\fP 0xe0 \fBLIT2r\fP
57+
58+.SH STACK EFFECTS
59+
60+.BR
61+
62+.SS NOTATION
63+
64+Given a stack effect \fB( a^ b^ c^ -- c^ a^ b^ )\fP here is what each symbol means:
65+
66+ \fB(\fP and \fB)\fP are comment delimiters
67+ \fBa^\fP, \fBb^\fP, and \fBc^\fP are values on the stack
68+ \fB^\fP indicates that each value is a \fIbyte\fP (\fB*\fP would indicate \fIshort\fP)
69+ \fB--\fP separates the "before" and "after" of the stack effect
70+
71+The effect here is to move the top byte of the stack below the next two bytes, which could be achieved with \fBROT ROT\fP.
72+
73+By default stack effects describe the effect on \fBwst\fP. When \fBrst\fP is involved we use \fB[]\fP to differentiate the stacks. For example \fB( a* [b*] -- a+1* [b+1*] )\fP will increment the top short of both \fBwst\fP and \fBrst\fP.
74+
75+.SS EFFECTS AND MODES
76+
77+Regular instructions have a single stack effect which is modified in a predictable way by any additional modes.
78+
79+For example the generic effect for \fBADD\fP is ( x y -- x+y ). The eight combinations of modes have the following effects:
80+
81+.nf
82+
83+ \fBADD\fP ( x^ y^ -- x+y^ ) sum bytes from \fBwst\fP
84+ \fBADDr\fP ( [x^ y^] -- [x+y^] ) sum bytes from \fBrst\fP
85+ \fBADD2\fP ( x* y* -- x+y* ) sum shorts from \fBwst\fP
86+ \fBADD2r\fP ( [x* y*] -- [x+y*] ) sum shorts from \fBrst\fP
87+ \fBADDk\fP ( x^ y^ -- x^ y^ x+y^ ) sum and keep bytes from \fBwst\fP
88+ \fBADDkr\fP ( [x^ y^] -- [x^ y^ x+y^] ) sum and keep bytes from \fBrst\fP
89+ \fBADD2k\fP ( x* y* -- x* y* x+y* ) sum and keep shorts from \fBwst\fP
90+ \fBADD2kr\fP ( [x* y*] -- [x* y* x+y*] ) sum and keep shorts from \fBrst\fP
91+
92+.fi
93+
94+Thus for regular instructions writing a "generic" effect (leaving sigils off values whose size depends on \fIshort mode\fP) is sufficient to describe its behavior across all eight variations. Note that some instructions always read values of a fixed size. For example the boolean condition read by \fBJCN\fP is always one byte, no matter what modes are used.
95+
96+In \fIreturn mode\fP the stacks are reversed. Effects on \fBwst\fP will instead affect \fBrst\fP, and effects on \fBrst\fP will instead affect \fBwst\fP. For example, \fBSTH\fP reads a byte from \fBwst\fP and writes it to \fBrst\fP, but \fBSTHr\fP reads a byte from \fBrst\fP and writes it to \fBwst\fP.
97+
98+In \fIkeep mode\fP all the values on the left-hand side of the stack effect will also appear on the right-hand side before the outputs. For example, \fBSWP\fP is \fB(x y -- y x)\fP but \fBSWPk\fP is \fB(x y -- x y y x)\fP.
99+
100+.SS TERMINOLOGY
101+
102+We consider the top of the stack to be the first value of the stack, and count back from there. For example, given the stack effect \fB( a b c -- )\fP we would say that \fBc\fP is the top of the stack, \fBb\fP is the second value (second from the top), and \fBa\fP is the third value (third from the top).
103+
104+.SH REGULAR INSTRUCTIONS
105+
106+.BR
107+
108+.SS INC ( x -- x+1 )
109+
110+Increment the top value of the stack by 1.
111+
112+Overflow will be truncated, so \fB#ff INC\fP will evaluate to \fB0x00\fP.
113+
114+.SS POP ( x -- )
115+
116+Remove the top value of the stack.
117+
118+\fBPOPk\fP is guaranteed to have no effect (it will not change the stack).
119+
120+.SS NIP ( x y -- y )
121+
122+Remove the second value of the stack.
123+
124+Note that \fBNIPk\fP is identical to \fBDUP\fP.
125+
126+.SS SWP ( x y -- y x )
127+
128+Swap the top two values of the stack.
129+
130+.SS ROT ( x y z -- y z x )
131+
132+Rotate the top three values of the stack. The lowest becomes the top and the others are each shifted down one place.
133+
134+.SS DUP ( x -- x x )
135+
136+Place a copy of the top value of the stack on top of the stack.
137+
138+.SS OVR ( x y -- x y x )
139+
140+Place a copy of the second value of the stack on top of the stack.
141+
142+.SS EQU ( x y -- x==y^ )
143+
144+Test whether the top two values of the stack are equal.
145+
146+Result is guaranteed to be boolean (\fB0x00\fP or \fB0x01\fP).
147+
148+.SS NEQ ( x y -- x!=y^ )
149+
150+Test whether the top two values of the stack are not equal.
151+
152+Result is guaranteed to be boolean (\fB0x00\fP or \fB0x01\fP).
153+
154+.SS GTH ( x y -- x>y^ )
155+
156+Test whether the second value of the stack is greater than the top.
157+
158+Result is guaranteed to be boolean (\fB0x00\fP or \fB0x01\fP).
159+
160+.SS LTH ( x y -- x<y^ )
161+
162+Test whether the second value of the stack is less than the top.
163+
164+Result is guaranteed to be boolean (\fB0x00\fP or \fB0x01\fP).
165+
166+.SS JMP ( x -- ; pc <- x )
167+
168+Jump to a location.
169+
170+The program counter (\fIpc\fP) is unconditionally updated. When \fIx\fP is a byte, it is treated as relative (\fBpc += x\fP) and when \fIx\fP is a short it is treated as absolute (\fBpc = x\fP).
171+
172+It is common to \fBJMP\fP with boolean bytes (0-1) to handle simple conditionals. For example:
173+
174+ \fB@max ( x^ y^ -- max^ ) GTHk JMP SWP POP JMP2r\fP
175+
176+.SS JCN ( bool^ x -- ; pc <- x if bool )
177+
178+Jump to a location when a condition is true.
179+
180+The program counter (\fIpc\fP) is updated when \fIbool\fP is non-zero. When \fIx\fP is a byte, it is treated as relative (\fBpc += x\fP) and when \fIx\fP is a short it is treated as absolute (\fBpc = x\fP).
181+
182+.SS JSR ( x -- [pc+1*] )
183+
184+Jump to a location, saving a reference to return to.
185+
186+Stores the next address to execute before unconditionally updating the program counter (\fIpc\fP). This instruction is usually used to invoke subroutines, which use the \fBJMP2r\fP to return. When \fIx\fP is a byte, it is treated as relative (\fBpc += x\fP) and when \fIx\fP is a short it is treated as absolute (\fBpc = x\fP).
187+
188+The saved address will always be a short regardless of \fIshort mode\fP.
189+
190+.SS STH ( x -- [x] )
191+
192+Move the top value of the stack to the return stack.
193+
194+.SS LDZ ( zp^ -- x )
195+
196+Load data from a zero-page address (\fB0x00 - 0xff\fP).
197+
198+.SS STZ ( x zp^ -- )
199+
200+Store data at a zero-page address (\fB0x00 - 0xff\fP).
201+
202+.SS LDR ( rel^ -- x )
203+
204+Load data from a relative address (\fBpc + x\fP).
205+
206+Note that unlike \fBLDZk\fP and \fBLDAk\fP the \fBLDRk\fP instruction is not very useful, since a relative address is usually only meaningful when run from a particular address (i.e. for a particular \fIpc\fP value).
207+
208+.SS STR ( x rel^ -- )
209+
210+Store data at a relative address (\fBpc + x\fP).
211+
212+Note that unlike \fBSTZk\fP and \fBSTAk\fP the \fBSTRk\fP instruction is not very useful, since a relative address is usually only meaningful when run from a particular address (i.e. for a particular \fIpc\fP value).
213+
214+.SS LDA ( abs* -- x )
215+
216+Load data from an absolute address (\fB0x0000 - 0xffff\fP).
217+
218+.SS STA ( x abs* -- )
219+
220+Store data at an absolute address (\fB0x0000 - 0xffff\fP).
221+
222+.SS DEI ( dev^ -- x )
223+
224+Read data from a device port (\fB0x00 - 0xff\fP).
225+
226+Reading from some ports may have an effect on the underlying VM; in other cases it will simply read values from device memory. For two-byte device ports the effect (if any) is triggered by reading the higher byte (the most significant byte).
227+
228+See Varvara device documentation for more details.
229+
230+.SS DEO ( x dev^ -- )
231+
232+Write data to a device port (\fB0x00 - 0xff\fP).
233+
234+Writing to some ports may have an effect on the underlying VM; in other cases it will simply write values to device memory. For two-byte device ports the effect (if any) is triggered by writing the lower byte (the least significant byte).
235+
236+See Varvara device documentation for more details.
237+
238+.SS ADD ( x y -- x+y )
239+
240+Add the top two values of the stack.
241+
242+Overflow will be truncated, so \fB#ff #03 ADD\fP will evaluate to \fB0x02\fP.
243+
244+.SS SUB ( x y -- x-y )
245+
246+Subtract the top of the stack from the second value of the stack.
247+
248+Underflow will be truncated, so \fB#01 #03 SUB\fP will evaluate to \fB0xfe\fP.
249+
250+.SS MUL ( x y -- xy )
251+
252+Multiply the top two values of the stack.
253+
254+Overflow will be truncated, so \fB#11 #11 MUL\fP will evaluate to \fB0x21\fP.
255+
256+.SS DIV ( x y -- x/y )
257+
258+Divide the second value of the stack by the top of the stack.
259+
260+\fBDIV\fP implements \fIEuclidean division\fP, which is also known as \fIinteger division\fP. It returns whole numbers, so \fB#08 #09 DIV\fP evaluates to \fB0x00\fP.
261+
262+Division by zero will return zero (instead of signaling an error).
263+
264+Unlike \fBADD\fP, \fBSUB\fP, and \fBMUL\fP, \fBDIV\fP does not behave correctly for numbers which should be treated as signed. For example, the signed byte representation of \fB-2\fP is \fB0xfe\fP, but \fB#06 #fe DIV\fP evaluates to \fB0x00\fP (\fB6 / 254 = 0\fP). For signed values the correct result should instead be \fB0xfd\fP (\fB6 / -2 = -3\fP).
265+
266+There is no \fIremainder\fP instruction, but the phrase \fBDIVk MUL SUB\fP can be used to compute the remainder.
267+
268+.SS AND ( x y -- x&y )
269+
270+Compute the bitwise intersection of the top two values of the stack.
271+
272+.SS ORA ( x y -- x|y )
273+
274+Compute the bitwise union of the top two values of the stack.
275+
276+.SS EOR ( x y -- x^y )
277+
278+Compute the bitwise exclusive-or (\fIxor\fP) of the top two values of the stack.
279+
280+.SS SFT ( x rl^ -- (x>>l)<<r )
281+
282+Compute a bit shift of the second value of the stack; the directions and distances of the shift are determined by the top value of the stack.
283+
284+Given a byte \fIrl\fP consisting of a low nibble (\fIl\fP) and a high nibble (\fIr\fP), this instruction shifts \fIx\fP left by \fIl\fP and then right by \fIr\fP.
285+
286+Right shifts are unsigned (they introduce zero bits). There are no signed shifts.
287+
288+For 16-bit (and 8-bit) values, one nibble (\fB0x0 - 0xf\fP) is sufficient to express all useful left or right shifts.
289+
290+ Right: \fB#ff #03 SFT\fP evaluates to \fB0x1f\fP
291+ Left: \fB#ff #20 SFT\fP evaluates to \fB0xfc\fP
292+ Both: \fB#ff #23 SFT\fP evaluates to \fB0x7c\fP
293+
294+There is no rotation instruction but one-byte rotations can be accomplished with \fBDUP\fP and \fBSFT2\fP:
295+
296+ \fB#87 DUP #03 SFT2 NIP\fP ( 0x87 rotated right by 3 is 0xf0 )
297+ \fB#87 DUP #20 SFT2 POP\fP ( 0x87 rotated left by 2 is 0x1e )
298+
299+.SH SPECIAL INSTRUCTIONS
300+
301+These instructions do not accept all mode flags (some do not accept any).
302+
303+.SS BRK
304+
305+The break instruction is used to end a vector call and return control to the virtual machine.
306+
307+.SS JCI, JMI, and JSI
308+
309+The "immediate jump" instructions are produced by the assembler. They interpret the next 2 bytes of the ROM as a relative address (\fIaddr\fP) and have the following effects:
310+
311+ \fBJMI\fP ( -- ) jump to \fIaddr\fP unconditionally
312+ \fBJCI\fP ( bool^ -- ) jump to \fIaddr\fP if \fIbool\fP is non-zero
313+ \fBJSI\fP ( -- [pc*] ) jump to \fIaddr\fP saving the current address (\fIpc\fP) on \fIrst\fP
314+
315+(The instruction pointer will be moved forward 2 bytes, past the relative address.)
316+
317+These instructions are created by the assembler from special syntax:
318+
319+ \fB!dest\fP produces \fBJMI wx yz\fP
320+ \fB?dest\fP produces \fBJCI wx yz\fP
321+ \fBdest\fP produces \fBJSI wx yz\fP (assuming \fBdest\fP is not a macro or reserved)
322+
323+.SS LIT, LIT2, LITr, and LIT2r
324+
325+Push a literal value on the stack.
326+
327+The "literal" instructions are used to push new data onto the stacks. They interpret the next 1-2 bytes of the ROM (\fIwx\fP, \fIwxyz\fP) as data and push it onto the corresponding stack:
328+
329+ \fBLIT\fP ( -- wx^ ) push literal byte \fIwx\fP onto the \fBwst\fP
330+ \fBLITr\fP ( -- [wx^] ) push literal byte \fIwx\fP onto the \fBrst\fP
331+ \fBLIT2\fP ( -- wxyz* ) push literal short \fIwxyz\fP (2 bytes) onto the \fBwst\fP
332+ \fBLIT2r\fP ( -- [wxyz*] ) push literal short \fIwxyz\fP (2 bytes) onto the \fBrst\fP
333+
334+(The instruction pointer will be moved forward 1-2 bytes, past the literal data.)
335+
336+Literal values can be updated dynamically using store instructions:
337+
338+ #abcd ;x STA2
339+ ( later on... )
340+ LIT2 [ @x $2 ]
341+
342+.SH SEE ALSO
343+
344+ https://wiki.xxiivv.com/site/uxntal_opcodes.html \fIUxntal Opcodes\fP
345+ https://wiki.xxiivv.com/site/uxntal_syntax.html \fIUxntal Syntax\fP
346+ https://wiki.xxiivv.com/site/uxntal_modes.html \fIUxntal Modes\fP
347+ https://wiki.xxiivv.com/site/uxntal_immediate.html \fIImmediate opcodes\fP
348+ https://wiki.xxiivv.com/site/varvara.html \fIVarvara\fP
+177,
-0
1@@ -0,0 +1,177 @@
2+( dev/audio )
3+
4+%GET-NOTE { #00 SWP ;melody ADD2 LDA }
5+%GET-HEXCHAR { #00 SWP #30 SFT2 ;font-hex ADD2 .Screen/addr DEO2 }
6+
7+( devices )
8+
9+|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
10+|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
11+|30 @Audio0 [ &vector $2 &position $2 &output $1 &pad $3 &adsr $2 &length $2 &addr $2 &volume $1 &pitch $1 ]
12+|80 @Controller [ &vector $2 &button $1 &key $1 ]
13+
14+( variables )
15+
16+|0000
17+
18+@timer $1
19+@progress $1
20+@selection $1
21+@offset
22+ &x $2 &y $2
23+
24+|0100 ( -> )
25+
26+ ( theme )
27+ #0f8f .System/r DEO2
28+ #0f8f .System/g DEO2
29+ #0f80 .System/b DEO2
30+
31+ ( vectors )
32+ ;on-frame .Screen/vector DEO2
33+ ;on-button .Controller/vector DEO2
34+
35+ ( setup synth )
36+ #0208 .Audio0/adsr DEO2
37+ ;saw .Audio0/addr DEO2
38+ #0100 .Audio0/length DEO2
39+ #dd .Audio0/volume DEO ( TODO: turn ON )
40+
41+ ( center )
42+ .Screen/width DEI2 #01 SFT2 #0080 SUB2 .offset/x STZ2
43+ .Screen/height DEI2 #01 SFT2 #0040 SUB2 .offset/y STZ2
44+
45+ ;draw JSR2
46+ #02 ;draw-selector JSR2
47+
48+BRK
49+
50+@on-button ( -> )
51+
52+ .Controller/button DEI #04 SFT
53+ [ #01 ] NEQk NIP ,&no-up JCN
54+ .selection LDZ STHk
55+ #00 ;draw-note JSR2
56+ [ STHkr GET-NOTE INC ] #00 STHkr ;melody ADD2 STA
57+ STHr #01 ;draw-note JSR2
58+ #02 ;draw-selector JSR2
59+ &no-up
60+ [ #02 ] NEQk NIP ,&no-down JCN
61+ .selection LDZ STHk
62+ #00 ;draw-note JSR2
63+ [ STHkr GET-NOTE #01 SUB ] #00 STHkr ;melody ADD2 STA
64+ STHr #01 ;draw-note JSR2
65+ #02 ;draw-selector JSR2
66+ &no-down
67+ [ #04 ] NEQk NIP ,&no-left JCN
68+ #00 ;draw-selector JSR2
69+ .selection LDZ #01 SUB #1f AND .selection STZ
70+ #02 ;draw-selector JSR2
71+ &no-left
72+ [ #08 ] NEQk NIP ,&no-right JCN
73+ #00 ;draw-selector JSR2
74+ .selection LDZ INC #1f AND .selection STZ
75+ #02 ;draw-selector JSR2
76+ &no-right
77+ POP
78+
79+BRK
80+
81+@on-frame ( -> )
82+
83+ ( incr ) .timer LDZ INC .timer STZ
84+ ( skip ) .timer LDZ #10 EQU #01 JCN [ BRK ]
85+ .progress LDZ
86+ ( play note ) DUP GET-NOTE .Audio0/pitch DEO
87+ ( erase last ) DUP #01 SUB #1f AND #01 ,draw-note JSR
88+ ( draw current ) #01 ,draw-note JSR
89+ ( incr ) .progress LDZ INC #1f AND .progress STZ
90+ #00 .timer STZ
91+
92+BRK
93+
94+@draw ( -- )
95+
96+ #20 #00
97+ &loop
98+ DUP #01 ,draw-note JSR
99+ INC GTHk ,&loop JCN
100+ POP2
101+
102+JMP2r
103+
104+@draw-note ( id color -- )
105+
106+ STH STH
107+ ( set x ) [ #00 STHkr ] #30 SFT2 .offset/x LDZ2 ADD2 .Screen/x DEO2
108+ ( set y ) [ #00 #00 STHkr ;melody ADD2 LDA ] #20 SFT2 #0100 SWP2 SUB2 .offset/y LDZ2 ADD2 #0080 ADD2 .Screen/y DEO2
109+ ( set addr ) ;marker-icn [ #00 .progress LDZ STHr EQU #08 MUL ADD2 ] .Screen/addr DEO2
110+ ( draw ) STHr .Screen/sprite DEO
111+
112+JMP2r
113+
114+@draw-selector ( color -- )
115+
116+ STH
117+ [ #00 .selection LDZ ] #30 SFT2 .offset/x LDZ2 ADD2 .Screen/x DEO2
118+ #0070 .offset/y LDZ2 ADD2 .Screen/y DEO2
119+ ;selector-icn .Screen/addr DEO2
120+ STHkr .Screen/sprite DEO
121+
122+ .Screen/y DEI2k #0008 ADD2 ROT DEO2
123+ .selection LDZ GET-NOTE STHr ,draw-byte JSR
124+
125+JMP2r
126+
127+@draw-byte ( byte color -- )
128+
129+ STH
130+ DUP
131+ #04 SFT GET-HEXCHAR
132+ ( draw ) STHkr .Screen/sprite DEO
133+ .Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
134+ #0f AND GET-HEXCHAR
135+ ( draw ) STHr .Screen/sprite DEO
136+
137+JMP2r
138+
139+@melody
140+ 54 52 54 4f 4b 4f 48 ff
141+ 54 52 54 4f 4b 4f 48 ff
142+ 54 56 57 56 57 54 56 54
143+ 56 52 54 52 54 50 54 ff
144+
145+@selector-icn
146+ 0000 0010 387c 0000
147+
148+@marker-icn
149+ 3844 8282 8244 3800
150+ 387c fefe fe7c 3800
151+
152+@saw
153+ 0003 0609 0c0f 1215 181b 1e21 2427 2a2d
154+ 3033 3639 3b3e 4143 4649 4b4e 5052 5557
155+ 595b 5e60 6264 6667 696b 6c6e 7071 7274
156+ 7576 7778 797a 7b7b 7c7d 7d7e 7e7e 7e7e
157+ 7f7e 7e7e 7e7e 7d7d 7c7b 7b7a 7978 7776
158+ 7574 7271 706e 6c6b 6967 6664 6260 5e5b
159+ 5957 5552 504e 4b49 4643 413e 3b39 3633
160+ 302d 2a27 2421 1e1b 1815 120f 0c09 0603
161+ 00fd faf7 f4f1 eeeb e8e5 e2df dcd9 d6d3
162+ d0cd cac7 c5c2 bfbd bab7 b5b2 b0ae aba9
163+ a7a5 a2a0 9e9c 9a99 9795 9492 908f 8e8c
164+ 8b8a 8988 8786 8585 8483 8382 8282 8282
165+ 8182 8282 8282 8383 8485 8586 8788 898a
166+ 8b8c 8e8f 9092 9495 9799 9a9c 9ea0 a2a5
167+ a7a9 abae b0b2 b5b7 babd bfc2 c5c7 cacd
168+ d0d3 d6d9 dcdf e2e5 e8eb eef1 f4f7 fafd
169+
170+@font-hex ( 0-F )
171+ 007c 8282 8282 827c 0030 1010 1010 1010
172+ 007c 8202 7c80 80fe 007c 8202 1c02 827c
173+ 000c 1424 4484 fe04 00fe 8080 7c02 827c
174+ 007c 8280 fc82 827c 007c 8202 1e02 0202
175+ 007c 8282 7c82 827c 007c 8282 7e02 827c
176+ 007c 8202 7e82 827e 00fc 8282 fc82 82fc
177+ 007c 8280 8080 827c 00fc 8282 8282 82fc
178+ 007c 8280 f080 827c 007c 8280 f080 8080
+59,
-0
1@@ -0,0 +1,59 @@
2+( 54K . Console Test
3+| arguments "abc" "def"
4+| stream "ghi" )
5+
6+|10 @Console/vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1
7+|0050 @Varvara/version
8+
9+|100
10+
11+@on-reset ( -> )
12+ ;meta #06 DEO2
13+ ;on-console .Console/vector DEO2
14+ [ LIT2 01 -Console/type ] DEI NEQ ?fail
15+ BRK
16+
17+@meta 00
18+ ( name ) "Console 20 "Device 20 "Test(80K) 0a
19+ ( details ) "Testing 20 "Program 0a
20+ ( author ) "By 20 "Devine 20 "Lu 20 "Linvega 0a
21+ ( date ) "23 20 "Jul 20 "2026 00
22+ ( . ) 01
23+ ( - ) 56 =Varvara/version
24+
25+@on-console ( -> )
26+ .Console/type DEI .Console/read DEI
27+ ( inc ) [ LIT2 &ptr =expect ] INC2k INC2 ,&ptr STR2
28+ LDA2 NEQ2 ?fail
29+ ,&ptr LDR2 ;expect/end EQU2 ?pass
30+ BRK
31+
32+@fail ( -> )
33+ ;dict/fail str/<print>
34+ #010f DEO
35+ BRK
36+
37+@pass ( type read ptr* -> )
38+ ;dict/pass str/<print>
39+ #800f DEO
40+ BRK
41+
42+(
43+@|Utils )
44+
45+@str/<print> ( str* -- )
46+ LDAk DUP ?{ POP POP2 JMP2r }
47+ #18 DEO
48+ INC2 !/<print>
49+
50+(
51+@|Data )
52+
53+@expect ( . )
54+ ( arg1 ) [ 02 "a 02 "b 02 "c 03 0a ]
55+ ( arg2 ) [ 02 "d 02 "e 02 "f 04 0a ]
56+ ( strm ) [ 01 "g 01 "h 01 "i 04 0a ] &end
57+
58+@dict/pass "Console: 20 "pass 0a $1
59+ &fail "Console: 20 "fail 0a $1
60+
+87,
-0
1@@ -0,0 +1,87 @@
2+( 54K . Datetime Test )
3+
4+|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1
5+|c0 @DateTime &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1
6+|0050 @Varvara/version
7+
8+|100
9+
10+@on-reset ( -> )
11+ ;meta #06 DEO2
12+ .DateTime/year DEI2k dec/<print>
13+ [ LIT "- ] .Console/write DEO
14+ INC INC DEIk INC <print-dec-pad>
15+ [ LIT "- ] .Console/write DEO
16+ INC DEI <print-dec-pad>
17+ #0a18 DEO
18+ ( | .. )
19+ ;dict/date str/<print>
20+ [ LIT2 00 -DateTime/dotw ] DEI #20 SFT ;dict/days ADD2 str/<print>
21+ [ LIT2 ", 18 ] DEO
22+ #2018 DEO
23+ [ LIT2 00 -DateTime/month ] DEI #20 SFT ;dict/months ADD2 str/<print>
24+ #2018 DEO
25+ [ LIT2 00 -DateTime/day ] DEI dec/<print>
26+ [ LIT2 ", 18 ] DEO
27+ #2018 DEO
28+ .DateTime/year DEI2 dec/<print>
29+ #0a18 DEO
30+ ( | .. )
31+ ;dict/time str/<print>
32+ .DateTime/hour DEIk <print-dec-pad>
33+ [ LIT2 ": 18 ] DEO
34+ INC DEIk <print-dec-pad>
35+ [ LIT2 ": 18 ] DEO
36+ INC DEI <print-dec-pad>
37+ #0a18 DEO
38+ ( | .. )
39+ ;dict/doty str/<print>
40+ .DateTime/doty DEI2 dec/<print>
41+ #0a18 DEO
42+ #800f DEO
43+ BRK
44+
45+@meta 00
46+ ( name ) "Datetime 20 "Device 20 "Test(80K) 0a
47+ ( details ) "Testing 20 "Program 0a
48+ ( author ) "By 20 "Devine 20 "Lu 20 "Linvega 0a
49+ ( date ) "24 20 "Jun 20 "2026 00
50+ ( . ) 01
51+ ( - ) 56 =Varvara/version
52+
53+@<print-dec-pad> ( byte -- )
54+ #0a DIVk dec/<emit>
55+ DIVk MUL SUB
56+ ( >> )
57+
58+@dec/<emit> ( byte -- )
59+ LIT "0 ADD #18 DEO
60+ JMP2r
61+
62+@str/<print> ( str* -- )
63+ LDAk DUP ?{ POP POP2 JMP2r }
64+ #18 DEO
65+ INC2 !/<print>
66+
67+@dec/<print> ( short* -- )
68+ #2710 [ LIT2r 00fb ]
69+ &>w
70+ DIV2k #000a DIV2k MUL2 SUB2 SWPr EQUk OVR STHkr EQU AND ?{ DUP dec/<emit>
71+ INCr }
72+ POP2 #000a DIV2 SWPr INCr STHkr ?&>w
73+ POP2r POP2 POP2 JMP2r
74+
75+(
76+@|assets )
77+
78+@dict/date "The 20 "date 20 "is: 20 $1
79+ &time "The 20 "time 20 "is: 20 $1
80+ &doty "The 20 "day 20 "of 20 "the 20 "year 20 "is: 20 $1
81+ &months [
82+ "Jan $1 "Feb $1 "Mar $1 "Apr $1
83+ "May $1 "Jun $1 "Jul $1 "Aug $1
84+ "Sep $1 "Oct $1 "Nov $1 "Dec $1 ]
85+ &days [
86+ "Sun $1 "Mon $1 "Tue $1 "Wed $1
87+ "Thu $1 "Fri $1 "Sat $1 ]
88+
+229,
-0
1@@ -0,0 +1,229 @@
2+( 54K . File Test )
3+
4+|10 @Console/vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1
5+|a0 @File/vector $2 &success $1 &success-lb $1 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2
6+|004f @Varvara/version
7+
8+|100
9+
10+@on-reset ( -> )
11+ ;meta #06 DEO2
12+ #800f DEO
13+ ;dict/write file/test-write <test>
14+ ;dict/append file/test-append <test>
15+ ;dict/read file/test-read <test>
16+ ;dict/read-of file/test-read-of <test>
17+ ;dict/stat file/test-stat <test>
18+ ;dict/stat-oversize file/test-stat-oversize <test>
19+ ;dict/stat-of file/test-stat-of <test>
20+ ;dict/write-of file/test-write-of <test>
21+ ;dict/delete file/test-delete <test>
22+ ;dict/success file/test-success <test>
23+ ( | Dir )
24+ ;dict/dir-spacer file/test-dir-spacer <test>
25+ ;dict/dir-partial file/test-dir-partial <test>
26+ ( ;dict/dir-nostream file/test-dir-nostream <test> ) ( | cleanup )
27+ ;file/name .File/name DEO2
28+ #01 .File/delete DEO
29+ BRK
30+
31+@meta 00
32+ ( name ) "File 20 "Device 20 "Test(80K) 0a
33+ ( details ) "Testing 20 "Program 0a
34+ ( author ) "By 20 "Devine 20 "Lu 20 "Linvega 0a
35+ ( date ) "24 20 "Jun 20 "2026 00
36+ ( . ) 01
37+ ( - ) 56 =Varvara/version
38+
39+(
40+@|Tests )
41+
42+@file/test-write ( -- pass )
43+ ;&name .File/name DEO2
44+ #0002 .File/length DEO2
45+ ;&a1 .File/write DEO2
46+ .File/success DEI2 #0002 EQU2 JMP2r
47+
48+@file/test-append ( -- pass )
49+ ;&name .File/name DEO2
50+ #0002 .File/length DEO2
51+ #01 .File/append DEO
52+ ;&b1 .File/write DEO2
53+ .File/success DEI2 #0002 EQU2 JMP2r
54+
55+@file/test-read ( -- pass )
56+ ;&name .File/name DEO2
57+ ( 4+2 ) #0006 .File/length DEO2
58+ ;&read-buf .File/read DEO2
59+ ( success ) .File/success DEI2 #0004 EQU2
60+ ( a ) ;&a1 LDA2 ;&a2 LDA2 EQU2 AND
61+ ( b ) ;&b1 LDA2 ;&b2 LDA2 EQU2 AND JMP2r
62+
63+@file/test-stat ( -- pass )
64+ ;&name .File/name DEO2
65+ #0004 .File/length DEO2
66+ ;&stat-buf .File/stat DEO2
67+ ( success ) .File/success DEI2 #0004 EQU2
68+ ( a ) ;&stat-hs LDA2 LIT2 "00 EQU2 AND
69+ ( b ) ;&stat-ls LDA2 LIT2 "04 EQU2 AND
70+ ( | try missing file )
71+ ;&unknown-name .File/name DEO2
72+ #0002 .File/length DEO2
73+ ;&stat-buf .File/stat DEO2
74+ ;&stat-buf LDA2 LIT2 "!! EQU2 AND JMP2r
75+
76+@file/test-stat-of ( -- pass )
77+ ;&name .File/name DEO2
78+ #0004 .File/length DEO2
79+ #fffe .File/stat DEO2
80+ .File/success DEI2 #0002 EQU2 JMP2r
81+
82+@file/test-stat-oversize ( -- pass )
83+ ;&name .File/name DEO2
84+ #0020 .File/length DEO2
85+ #00 .File/append DEO
86+ #f000 .File/write DEO2
87+ ( | Read stat too small )
88+ ;&name .File/name DEO2
89+ #0000 .File/length DEO2
90+ ;&sobuf .File/stat DEO2
91+ ;&sobuf LDA #00 EQU ?{ #00 JMP2r }
92+ #0001 .File/length DEO2
93+ ;&sobuf .File/stat DEO2
94+ ;&sobuf LDA LIT "? EQU ?{ #00 JMP2r }
95+ #0002 .File/length DEO2
96+ ;&sobuf .File/stat DEO2
97+ ;&sobuf LDA2 LIT2 "20 EQU2 ?{ #00 JMP2r }
98+ #0003 .File/length DEO2
99+ ;&sobuf .File/stat DEO2
100+ ;&sobuf LDA2 LIT2 "02 EQU2 JMP2r
101+ &sobuf $4
102+
103+@file/test-delete ( -- pass )
104+ ;&name .File/name DEO2
105+ #01 .File/delete DEO
106+ .File/success DEI2 #0001 EQU2
107+ ( | stat )
108+ ;&name .File/name DEO2
109+ #0002 .File/length DEO2
110+ ;&null-buf .File/stat DEO2
111+ ;&null-buf LDA2 LIT2 "!! EQU2 AND
112+ ( | try failure )
113+ #01 .File/delete DEO
114+ .File/success DEI2 #0000 EQU2 AND JMP2r
115+
116+@file/test-write-of ( -- pass )
117+ ;&name .File/name DEO2
118+ #0004 .File/length DEO2
119+ #fffe .File/write DEO2
120+ .File/success DEI2 #0002 EQU2 JMP2r
121+
122+@file/test-read-of ( -- pass )
123+ ;&name .File/name DEO2
124+ #0002 .File/length DEO2
125+ #ffff .File/read DEO2
126+ .File/success DEI2 #0001 EQU2 JMP2r
127+
128+@file/test-dir-spacer ( -- pass )
129+ ;&dirpath .File/name DEO2
130+ #0200 .File/length DEO2
131+ ;&dirbuf .File/read DEO2
132+ ;&dirbuf #0004 ADD2 LDA #09 EQU JMP2r
133+
134+ &dirpath ". 00
135+
136+@file/test-dir-partial ( -- pass )
137+ ( a ) LIT "~ ;&dirbuf #0007 ADD2 STA
138+ ( b ) LIT "~ ;&dirbuf #0009 ADD2 STA
139+ ;&dirpath .File/name DEO2
140+ #0008 .File/length DEO2
141+ ;&dirbuf .File/read DEO2
142+ ( b ) LIT "~ ;&dirbuf #0009 ADD2 LDA EQU
143+ ( a ) LIT "~ ;&dirbuf #0007 ADD2 LDA NEQ AND JMP2r
144+
145+@file/test-dir-nostream ( -- pass )
146+ ;&dirpath .File/name DEO2
147+ #0008 .File/length DEO2
148+ ;&bufa .File/read DEO2
149+ ;&bufb .File/read DEO2
150+ ;&bufa ;&bufb !str/cmp
151+
152+@file/test-success ( -- pass )
153+ ;&name .File/name DEO2
154+ #01 .File/delete DEO
155+ #00 .File/success-lb DEI EQU ?{ #00 JMP2r }
156+ ( | Make file )
157+ #0003 .File/length DEO2
158+ ;&string .File/write DEO2
159+ .File/success DEI2 #0003 EQU2 ?{ #00 JMP2r }
160+ ( | Zero load )
161+ #0000 .File/length DEO2
162+ ;&sz .File/read DEO2
163+ #00 .File/success-lb DEI EQU ?{ #00 JMP2r }
164+ ( | Each letter )
165+ #0001 .File/length DEO2
166+ ;&sa .File/read DEO2
167+ .File/success-lb DEI ?{ #00 JMP2r }
168+ [ LIT2 &sa $1 "a ] EQU ?{ #00 JMP2r }
169+ ;&sb .File/read DEO2
170+ .File/success-lb DEI ?{ #00 JMP2r }
171+ [ LIT2 &sb $1 "b ] EQU ?{ #00 JMP2r }
172+ ;&sc .File/read DEO2
173+ .File/success-lb DEI ?{ #00 JMP2r }
174+ [ LIT2 &sc $1 "c ] EQU ?{ #00 JMP2r }
175+ ;&sz .File/read DEO2
176+ .File/success-lb DEI ?{ #01 JMP2r }
177+ #00 JMP2r
178+
179+ &string "abc 00 &sz $1
180+
181+(
182+@|Helpers )
183+
184+@<test> ( name* f -- )
185+ ?{
186+ str/<print>
187+ #010f DEO
188+ ;dict/fail !str/<print> }
189+ str/<print>
190+ ;dict/pass
191+ ( >> )
192+
193+@str/<print> ( str* -- )
194+ LDAk DUP ?{ POP POP2 JMP2r }
195+ .Console/write DEO
196+ INC2 !/<print>
197+
198+@str/cmp ( a* b* -- f )
199+ STH2
200+ &>wc
201+ LDAk ?{ &d LDA LDAr STHr EQU JMP2r }
202+ LDAk LDAkr STHr NEQ ?&d
203+ INC2 INC2r !&>wc
204+
205+(
206+@|Assets )
207+
208+@dict/write "File/write: 20 $1
209+ &append "File/append: 20 $1
210+ &read "File/read: 20 $1
211+ &stat "File/stat: 20 $1
212+ &stat-oversize "File/stat(oversize): 20 $1
213+ &stat-of "File/stat(overflow): 20 $1
214+ &delete "File/delete: 20 $1
215+ &write-of "File/write(overflow): 20 $1
216+ &read-of "File/read(overflow): 20 $1
217+ &dir-spacer "File/dir(spacer): 20 $1
218+ &dir-nostream "File/dir(nostream): 20 $1
219+ &dir-partial "File/dir(partial): 20 $1
220+ &success "File/success: 20 $1
221+ &fail "fail 0a $1
222+ &pass "pass 0a $1
223+
224+@file/a1 1234 &b1 5678
225+ ( read buf ) &read-buf &a2 $2 &b2 $2
226+ ( stat buf ) &stat-buf &stat-hs $2 &stat-ls $2
227+ ( null buf ) &null-buf $4
228+ &name "test.txt $1
229+ &unknown-name "abcdefghj $1 &dirbuf $200 &bufa $8 &bufb $8
230+
+1470,
-0
1@@ -0,0 +1,1470 @@
2+( 54K . Opcode Tester )
3+
4+|100
5+
6+@on-reset ( -> )
7+ ( | PART 1:
8+ | LIT2: Puts a short on the stack
9+ | LIT: Puts a byte on the stack
10+ | #06 DEO: Write to metadata ports
11+ | #18 DEO: Write a letter in terminal )
12+ ;meta #06 DEO2
13+ [ LIT2 "kO ] #18 DEO
14+ #18 DEO
15+ #2018 DEO
16+ ( | PART 2:
17+ | LITr: Put a byte on return stack
18+ | STH: Move a byte from working stack to return stack
19+ | STH2r: Move a short from return stack to working stack )
20+ [ LITr "k ] [ LIT "O ] STH
21+ STH2r #18 DEO
22+ #18 DEO
23+ #2018 DEO
24+ ( | PART 3:
25+ | LIT2r: Put a short on return stack
26+ | DUP: Duplicate byte
27+ | ADDr: Add bytes on return stack )
28+ [ LIT2r "k 4d ] #01 DUP STH
29+ ADDr STH
30+ ADDr STH2r #18 DEO
31+ #18 DEO
32+ #2018 DEO
33+ ( | PART 4:
34+ | JSI: Subroutine to relative short address
35+ | JMP2r: Jumps to absolute address on return stack )
36+ tests/<print-ok>
37+ #2018 DEO
38+ ( | PART 5:
39+ | POP2: Removes a short from the stack
40+ | INC2: Increments short on stack
41+ | DUP2: Duplicate short
42+ | LDA: load byte from absolute address
43+ | JCI: Conditional subroutine to relative short address )
44+ ;dict/ok str/<print>
45+ #2018 DEO
46+ ( | PART 6:
47+ | JSR2: Jump to subroutine from short pointer
48+ | LDAk: Non-destructive load byte from absolute address )
49+ { "Ok $1 }
50+ STH2r ;str/<print> JSR2 #2018 DEO
51+ ( | PART 7:
52+ | Relative distance bytes )
53+ tests/<rel>
54+ SWP #18 DEO
55+ #18 DEO
56+ ( | PART 8:
57+ | Test every opcode )
58+ #1234 #00 STZ2
59+ ( sentinel ) #1234 LIT2r 5678
60+ ( run tests ) tests/<run>
61+ ( sentinel ) #1234 EQU2 LIT2r 5678 EQU2r STHr AND ;dict/sentinel tests/<print>
62+ ( | PART 9:
63+ | Testing that stacks are circular and wrapping )
64+ POP #12 #34 ADD #46 EQU STH
65+ POP #1234 ADD #46 EQU STH
66+ POP2 #1111 #2222 ADD2 #3333 EQU2 STHr AND STHr AND ;dict/stack-wrap tests/<print>
67+ ( restore stack ) #0000 #0000
68+ ( | PART 10:
69+ | Testing that zero-page is wrapping )
70+ #5678 #ff STZ2
71+ ( LDZ ) #00 LDZ #ff LDZ ADD #ce EQU
72+ ( LDZ2 ) #ff LDZ2 ADD #ce EQU AND ;dict/zp-wrap tests/<print>
73+ ( | PART 11:
74+ | Testing that device page is wrapping )
75+ #1234 #ff DEO2
76+ ( DEI ) #00 DEI #ff DEI ADD #46 EQU
77+ ( DEI2 ) #ff DEI2 ADD #46 EQU AND ;dict/dev-wrap tests/<print>
78+ #0000 DEO
79+ #00ff DEO
80+ ( | PART 12: Requires 0x10000 ram
81+ | Testing RAM wrapping
82+ | Storing 12 in 0xffff, and 34 in 0x0000 )
83+ #1234 #ffff STA2
84+ ( LDA ) #0000 LDA #ffff LDA ADD #46 EQU
85+ ( LDA2 ) #ffff LDA2 ADD #46 EQU AND ;dict/ram-wrap tests/<print>
86+ ( | PART 13: Requires 0x10000 ram
87+ | Testing PC wrapping: split instruction
88+ | Storing 80[LIT] in 0xffff, and 55[val8] in 0x0000
89+ | Storing 6c[JMP2r] in 0x0001 )
90+ #8055 #ffff STA2
91+ #6c #01 STZ
92+ #ffff JSR2 #55 EQU ;dict/pc-wrap tests/<print>
93+ ( | PART 14: Requires 0x10000 ram
94+ | Testing PC wrapping: split value after instruction
95+ | Storing a0[LIT2] in 0xfffe,
96+ | and 0x55[hi-byte] in 0xffff, and 0xaa[lo-byte] in 0x0000
97+ | Storing 6c[JMP2r] in 0x0001 )
98+ #a055 #fffe STA2
99+ #aa6c #0000 STA2
100+ #fffe JSR2 #55aa EQU2 ;dict/pc2-wrap tests/<print>
101+ ( | PART 15: Requires 0x10000 ram
102+ | Testing that LIT is wrapping )
103+ #80 #ffff STA ( LIT ) #d6 #0000 STA ( <d6> )
104+ #a0 #0001 STA ( LIT2 ) ;<1-return #0002 STA2 ( <hi>,<lo> )
105+ #2c #0004 STA ( JMP2 )
106+ #ffff JMP2 <1-return #d6 EQU ;dict/lt1-wrap tests/<print>
107+ ( | PART 16: Requires 0x10000 ram
108+ | Testing that LIT2 is wrapping )
109+ #a0 #fffe STA ( LIT2 ) #a1 #ffff STA ( <d6> ) #23 #0000 STA ( <76> )
110+ #a0 #0001 STA ( LIT2 ) ;<2-return #0002 STA2 ( <hi>,<lo> )
111+ #2c #0004 STA ( JMP2 )
112+ #fffe JMP2 <2-return #a123 EQU2 ;dict/lt2-wrap tests/<print>
113+ ( | PART 17: Requires 0x10000 ram
114+ | Testing that JMI is wrapping )
115+ #c8 ;dict/jmi-wrap str/<print>
116+ #40 #fffe STA ( JMI ) #00 #ffff STA ( <00> ) #01 #0000 STA ( <01> )
117+ #01 #0001 STA ( INC )
118+ #a0 #0002 STA ( LIT2 ) ;&jmi-return #0003 STA2 ( <hi>,<lo> )
119+ #2c #0005 STA ( JMP2 )
120+ #fffe JMP2 &jmi-return #c8 EQU tests/<outcome>
121+ ( | PART 18: Requires 0x10000 ram
122+ | Testing that JSI is wrapping )
123+ #ea ;dict/jsi-wrap str/<print>
124+ #60 #fffe STA ( JSI ) #00 #ffff STA ( <00> ) #01 #0000 STA ( <01> )
125+ #01 #0001 STA ( INC )
126+ #a0 #0002 STA ( LIT2 ) ;&jsi-return #0003 STA2 ( <hi>,<lo> )
127+ #2c #0005 STA ( JMP2 )
128+ #fffe JMP2 &jsi-return POP2r #ea EQU tests/<outcome>
129+ ( | PART 19:
130+ | Testing that JSI is wrapping )
131+ #8b #01 ;dict/jci-wrap str/<print>
132+ #20 #fffe STA ( JCI ) #00 #ffff STA ( <00> ) #01 #0000 STA ( <01> )
133+ #01 #0001 STA ( INC )
134+ #a0 #0002 STA ( LIT2 ) ;&jci-return #0003 STA2 ( <hi>,<lo> )
135+ #2c #0005 STA ( JMP2 )
136+ #fffe JMP2 &jci-return POP2r #8b EQU tests/<outcome>
137+ ( | You have a working uxn! )
138+ #800f DEO
139+ BRK
140+
141+
142+@str/<print> ( str* -- )
143+ LDAk DUP ?{ POP POP2 JMP2r }
144+ #18 DEO
145+ INC2 !/<print>
146+
147+@dict/ok "Ok 00
148+ &fail "fail 0a 00
149+ &pass "pass 0a 00
150+ &stack-wrap "Stk-wrap: 20 $1
151+ &ram-wrap "Ram-wrap: 20 $1
152+ &pc-wrap "Pc1-wrap: 20 $1
153+ &pc2-wrap "Pc2-wrap: 20 $1
154+ &zp-wrap "Zer-wrap: 20 $1
155+ &dev-wrap "Dev-wrap: 20 $1
156+ &opc-test "Opc-test: 20 $1
157+ &sentinel "Sentinel: 20 $1
158+ <1-wrap "Lt1-wrap: 20 $1
159+ <2-wrap "Lt2-wrap: 20 $1
160+ &jci-wrap "Jci-wrap: 20 $1
161+ &jmi-wrap "Jmi-wrap: 20 $1
162+ &jsi-wrap "Jsi-wrap: 20 $1
163+
164+(
165+@|Relative Distance Bytes )
166+
167+@meta 00
168+ ( name ) "Opctest 0a
169+ ( details ) "A 20 "Testing 20 "Program 0a
170+ ( author ) "By 20 "Devine 20 "Lu 20 "Linvega 0a
171+ ( date ) "9 20 "Jun 20 "2026 $2
172+
173+(
174+@|Tests )
175+
176+@tests/<run> ( -- )
177+ [ LITr 00 ] ;&lut-end ;&lut
178+ &>l
179+ STHkr #0f AND ?{ #0a18 DEO }
180+ STHkr u8/<print>
181+ #2018 DEO
182+ LDA2k JSR2 #01 EQU ?{ #010f DEO
183+ BRK }
184+ INC2 INC2 INCr GTH2k ?&>l
185+ POP2 POP2 POPr #0a18 DEO
186+ #01 ;dict/opc-test !tests/<print>
187+
188+@tests/<print> ( f name* -- )
189+ str/<print> &<outcome>
190+ ?{ #010f DEO
191+ ;dict/fail !str/<print> }
192+ ;dict/pass !str/<print>
193+
194+@tests/back "O $7c &<rel> ,&back LDR ,&forw LDR JMP2r
195+ $7e
196+ &forw "k
197+
198+@tests/<print-ok> ( -- )
199+ [ LIT2 "kO ] #18 DEO
200+ #18 DEO
201+ JMP2r
202+
203+@u8/<print> ( byte -- )
204+ DUP #04 SFT /<print-nibble>
205+ ( >> )
206+ &<print-nibble> ( byte -- )
207+ #0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD #18 DEO
208+ JMP2r
209+
210+(
211+@|imm )
212+
213+@op-brk ( -- pass )
214+ ( skip ) #01 JMP2r
215+
216+@op-jci ( -- pass )
217+ ( - ) #12 #01 ?{ INC }
218+ #12 EQU
219+ ( - ) #34 #00 ?{ INC }
220+ #35 EQU AND
221+ ( - ) #34 #ff ?{ INC }
222+ #34 EQU AND JMP2r
223+
224+@op-jmi ( -- pass )
225+ ( - ) #12 !{
226+ INC }
227+ #12 EQU JMP2r
228+
229+@op-jsi ( -- pass )
230+ #12 /t #24 EQU JMP2r
231+ &t DUP ADD JMP2r
232+
233+@op-lit ( -- pass )
234+ LIT 12 #12 EQU JMP2r
235+
236+@op-lit2 ( -- pass )
237+ LIT2 1234 #12 #34 EQU2 JMP2r
238+
239+@op-litr ( -- pass )
240+ LITr 12 STHr #12 EQU JMP2r
241+
242+@op-lit2r ( -- pass )
243+ LIT2r 1234 STH2r #1234 EQU2 JMP2r
244+
245+(
246+@|m )
247+
248+@op-inc ( -- pass )
249+ ( - ) #01 INC [ #02 ] EQU
250+ ( - ) #ff INC #00 EQU AND
251+ ( - ) #fe INC #ff EQU AND
252+ ( - ) #00 INC #01 EQU AND JMP2r
253+
254+@op-pop ( -- pass )
255+ ( - ) #0a #0b POP [ #0a ] EQU
256+ ( - ) #0a #0b #0c POP POP [ #0a ] EQU AND
257+ ( - ) #0a #0b #0c ADD POP [ #0a ] EQU AND
258+ ( - ) #0a #0b #0c POP ADD [ #15 ] EQU AND JMP2r
259+
260+@op-nip ( -- pass )
261+ ( - ) #12 #34 #56 NIP ADD [ #68 ] EQU JMP2r
262+
263+@op-swp ( -- pass )
264+ ( - ) #02 #10 SWP DIV [ #08 ] EQU JMP2r
265+
266+@op-rot ( -- pass )
267+ ( - ) #02 #04 #10 ROT DIV ADD [ #0c ] EQU JMP2r
268+
269+@op-dup ( -- pass )
270+ ( - ) #0a #0b DUP ADD ADD [ #20 ] EQU JMP2r
271+
272+@op-ovr ( -- pass )
273+ ( - ) #02 #10 OVR DIV ADD [ #0a ] EQU JMP2r
274+
275+@op-equ ( -- pass )
276+ ( - ) #f8 #f8 EQU #01 EQU
277+ ( - ) #01 #01 EQU #01 EQU AND
278+ ( - ) #f8 #01 EQU #00 EQU AND
279+ ( - ) #00 #ff EQU #00 EQU AND JMP2r
280+
281+@op-neq ( -- pass )
282+ ( - ) #f8 #f8 NEQ #00 EQU
283+ ( - ) #01 #01 NEQ #00 EQU AND
284+ ( - ) #f8 #01 NEQ #01 EQU AND
285+ ( - ) #01 #f8 NEQ #01 EQU AND JMP2r
286+
287+@op-gth ( -- pass )
288+ ( - ) #f8 #f8 GTH #00 EQU
289+ ( - ) #01 #01 GTH #00 EQU AND
290+ ( - ) #f8 #01 GTH #01 EQU AND
291+ ( - ) #01 #f8 GTH #00 EQU AND JMP2r
292+
293+@op-lth ( -- pass )
294+ ( - ) #f8 #f8 LTH #00 EQU
295+ ( - ) #01 #01 LTH #00 EQU AND
296+ ( - ) #f8 #01 LTH #00 EQU AND
297+ ( - ) #01 #ff LTH #01 EQU AND JMP2r
298+
299+@op-jmp ( -- pass )
300+ ( - ) #12 #34 ,&x [ JMP SWP &x ] POP [ #12 ] EQU
301+ ( - ) #12 #34 ,&t [ JMP &back ] POP [ #34 ] EQU AND JMP2r
302+ &t SWP ,&back JMP
303+
304+@op-jcn ( -- pass )
305+ ( - ) #23 #03 ,&x [ JCN INC &x ] [ #23 ] EQU
306+ ( - ) #23 #00 ,&y [ JCN INC &y ] [ #24 ] EQU AND
307+ ( - ) #12 #34 #ff ,&t [ JCN &back ] POP [ #34 ] EQU AND
308+ ( - ) #12 #34 #00 ,&t [ JCN ] POP [ #12 ] EQU AND JMP2r
309+ &t SWP ,&back JMP
310+
311+@op-jsr ( -- pass )
312+ ( - ) #12 #34 ,&routine JSR [ #46 ] EQU JMP2r
313+ &routine ADD JMP2r
314+
315+@op-sth ( -- pass )
316+ ( - ) #0a [ STH ] #0b [ STH ] ADDr STHr [ #15 ] EQU JMP2r
317+
318+@op-ldz ( -- pass )
319+ ( - ) #00 LDZ #12 EQU JMP2r
320+
321+@op-stz ( -- pass )
322+ #ff03 STZ
323+ #5602 STZ
324+ ( ) #5602 LDZ EQU #ff03 LDZ EQU AND JMP2r
325+
326+@op-ldr ( -- pass )
327+ ( advance ) [ !{ &a 12 ( -128 ) $6e &u 34 } ]
328+ ( - ) ,&t LDR #12 EQU
329+ ( - ) ,&u LDR #34 EQU AND
330+ ( -128 ) ,&a LDR #12 EQU AND
331+ ( +127 ) ,&b LDR #56 EQU AND [ !{ &t 12 ( +127 ) $77 &b 56 } ] JMP2r
332+
333+@op-str ( -- pass )
334+ ( advance ) [ !{ &a $1 ( -128 ) $63 &u $1 ] }
335+ ( - ) #34 ,&t [ STR ] ,&t LDR #34 EQU
336+ ( - ) #12 ,&u [ STR ] ,&u LDR #12 EQU AND
337+ ( -128 ) [ LIT2 56 _&a ] STR
338+ ( +127 ) [ LIT2 56 _&b ] STR
339+ [ !{ &t $1 ( +127 ) $7b &b $1 } ]
340+ ( - check ) ;&a LDA #56 EQU AND ;&b LDA #56 EQU AND JMP2r
341+
342+@op-lda ( -- pass )
343+ ( - ) ;&value LDA #ef EQU JMP2r
344+ &value ef
345+
346+@op-sta ( -- pass )
347+ #34 ;&b STA
348+ #12 ;&a STA
349+ ;&a LDA #12 EQU ;&b LDA #34 EQU AND JMP2r
350+ &a 00 &b 00
351+
352+@op-dei ( -- pass )
353+ ( skip ) #01 JMP2r
354+
355+@op-deo ( -- pass )
356+ ( skip ) #01 JMP2r
357+
358+@op-add ( -- pass )
359+ ( - ) #ff #00 ADD #ff EQU
360+ ( - ) #01 #ff ADD #00 EQU AND
361+ ( - ) #ff #ff ADD [ #fe ] EQU AND JMP2r
362+
363+@op-sub ( -- pass )
364+ ( - ) #ff #00 SUB #ff EQU
365+ ( - ) #01 #ff SUB [ #02 ] EQU AND
366+ ( - ) #ff #ff SUB #00 EQU AND
367+ ( - ) #fe #ff SUB #ff EQU AND JMP2r
368+
369+@op-mul ( -- pass )
370+ ( - ) #00 #01 MUL #00 EQU
371+ ( - ) #3f #e7 MUL [ #d9 ] EQU AND
372+ ( - ) #37 #3f MUL [ #89 ] EQU AND
373+ ( - ) #10 #02 MUL [ #20 ] EQU AND JMP2r
374+
375+@op-div ( -- pass )
376+ ( - ) #10 #06 DIV [ #02 ] EQU
377+ ( - ) #20 #20 DIV #01 EQU AND
378+ ( - ) #34 #01 DIV [ #34 ] EQU AND
379+ ( - ) #02 #ef DIV #00 EQU AND
380+ ( - ) #02 #00 DIV #00 EQU AND
381+ ( - ) #00 #00 DIV #00 EQU AND
382+ ( - ) #fe #02 DIV #7f EQU AND
383+ ( - ) #03 #fd DIV #00 EQU AND JMP2r
384+
385+@op-and ( -- pass )
386+ ( - ) #fc #3f AND [ #3c ] EQU
387+ ( - ) #f0 #0f AND #00 EQU AND
388+ ( - ) #ff #3c AND [ #3c ] EQU AND
389+ ( - ) #02 #03 AND [ #02 ] EQU AND JMP2r
390+
391+@op-ora ( -- pass )
392+ ( - ) #0f #f0 ORA #ff EQU
393+ ( - ) #ab #cd ORA [ #ef ] EQU AND
394+ ( - ) #12 #34 ORA [ #36 ] EQU AND
395+ ( - ) #88 #10 ORA [ #98 ] EQU AND JMP2r
396+
397+@op-eor ( -- pass )
398+ ( - ) #00 #00 EOR #00 EQU
399+ ( - ) #ff #00 EOR #ff EQU AND
400+ ( - ) #aa #55 EOR #ff EQU AND
401+ ( - ) #ff #ff EOR #00 EQU AND JMP2r
402+
403+@op-sft ( -- pass )
404+ ( - ) #ff #08 SFT #00 EQU
405+ ( - ) #ff #e0 SFT #00 EQU AND
406+ ( - ) #ff #11 SFT [ #fe ] EQU AND
407+ ( - ) #ff #12 SFT [ #7e ] EQU AND
408+ ( - ) #ff #00 SFT [ #ff ] EQU AND
409+ ( - ) #ff #77 SFT [ #80 ] EQU AND
410+ ( - ) #ff #88 SFT [ #00 ] EQU AND
411+ ( - ) #ff #ff SFT [ #00 ] EQU AND JMP2r
412+
413+(
414+@|m2 )
415+
416+@op-inc2 ( -- pass )
417+ ( - ) #00ff INC2 [ #0100 ] EQU2
418+ ( - ) #ffff INC2 [ #0000 ] EQU2 AND
419+ ( - ) #fffe INC2 [ #ffff ] EQU2 AND
420+ ( - ) #0000 INC2 [ #0001 ] EQU2 AND JMP2r
421+
422+@op-pop2 ( -- pass )
423+ ( - ) #0a0b #0c0d POP2 [ #0a0b ] EQU2
424+ ( - ) #0a0b #0c0d #0e0f POP2 POP2 #0a0b EQU2 AND
425+ ( - ) #0a0b #0c0d #0e0f ADD2 POP2 #0a0b EQU2 AND
426+ ( - ) #0a0b #0c0d #0e0f POP2 ADD2 #1618 EQU2 AND JMP2r
427+
428+@op-nip2 ( -- pass )
429+ ( - ) #1234 #5678 #9abc NIP2 ADD2 #acf0 EQU2 JMP2r
430+
431+@op-swp2 ( -- pass )
432+ ( - ) #0a0b #0c0d SWP2 NIP2 #0a0b EQU2 JMP2r
433+
434+@op-rot2 ( -- pass )
435+ ( - ) #0a0b #0c0d #0c0f ROT2 ADD2 NIP2 #161a EQU2 JMP2r
436+
437+@op-dup2 ( -- pass )
438+ ( - ) #0a0b DUP2 ADD2 #1416 EQU2 JMP2r
439+
440+@op-ovr2 ( -- pass )
441+ ( - ) #0a0b #0c0d OVR2 NIP2 ADD2 #1416 EQU2 JMP2r
442+
443+@op-equ2 ( -- pass )
444+ ( - ) #f801 #f801 EQU2 #01 EQU
445+ ( - ) #01f8 #01f8 EQU2 #01 EQU AND
446+ ( - ) #f801 #01f9 EQU2 #00 EQU AND
447+ ( - ) #01f8 #f802 EQU2 #00 EQU AND JMP2r
448+
449+@op-neq2 ( -- pass )
450+ ( - ) #f801 #f801 NEQ2 #00 EQU
451+ ( - ) #01f8 #01f8 NEQ2 #00 EQU AND
452+ ( - ) #f802 #01f9 NEQ2 #01 EQU AND
453+ ( - ) #01f9 #f802 NEQ2 #01 EQU AND JMP2r
454+
455+@op-gth2 ( -- pass )
456+ ( - ) #f801 #f802 GTH2 #00 EQU
457+ ( - ) #01f8 #01f9 GTH2 #00 EQU AND
458+ ( - ) #f801 #01f9 GTH2 #01 EQU AND
459+ ( - ) #01f8 #f802 GTH2 #00 EQU AND JMP2r
460+
461+@op-lth2 ( -- pass )
462+ ( - ) #f801 #f802 LTH2 #01 EQU
463+ ( - ) #01f8 #01f9 LTH2 #01 EQU AND
464+ ( - ) #f801 #01f9 LTH2 #00 EQU AND
465+ ( - ) #01f8 #f802 LTH2 #01 EQU AND JMP2r
466+
467+@op-jmp2 ( -- pass )
468+ ( - ) #56 #78 ;&t [ JMP2 SWP &t ] POP #56 EQU JMP2r
469+
470+@op-jcn2 ( -- pass )
471+ ( - ) #23 #10 ;&abs-x [ JCN2 INC &abs-x ] #23 EQU
472+ ( - ) #23 #00 ;&abs-y [ JCN2 INC &abs-y ] #24 EQU AND JMP2r
473+
474+@op-jsr2 ( -- pass )
475+ ( - ) #12 ;&t JSR2 #24 EQU JMP2r
476+ &t DUP ADD JMP2r
477+
478+@op-sth2 ( -- pass )
479+ ( - ) #1234 [ STH2 ] ADDr STHr #46 EQU JMP2r
480+
481+@op-ldz2 ( -- pass )
482+ ( - ) #00 LDZ2 #1234 EQU2 JMP2r
483+
484+@op-stz2 ( -- pass )
485+ ( - ) #5678 #04 [ STZ2 ] #04 LDZ2 #5678 EQU2 JMP2r
486+
487+@op-ldr2 ( -- pass )
488+ ( advance ) [ !{ &a 1234 ( -128 ) $6a &u 3456 } ]
489+ ( - ) ,&t LDR2 #1234 EQU2
490+ ( - ) ,&u LDR2 #3456 EQU2 AND
491+ ( -128 ) ,&a LDR2 #1234 EQU2 AND
492+ ( +127 ) ,&b LDR2 #5678 EQU2 AND [ !{ &t 1234 ( +127 ) $75 &b 5678 } ] JMP2r
493+
494+@op-str2 ( -- pass )
495+ ( advance ) [ !{ &a $2 ( -128 ) $5b &u $2 ] }
496+ ( - ) #1234 ,&t [ STR2 ] ,&t LDR2 #1234 EQU2
497+ ( - ) #1234 ,&u [ STR2 ] ,&u LDR2 #1234 EQU2 AND
498+ ( -128 ) #1234 ,&a STR2
499+ ( +127 ) #1234 ,&b STR2
500+ [ !{ &t $2 ( +127 ) $7a &b $2 } ]
501+ ( - check ) ;&a LDA2 #1234 EQU2 AND ;&b LDA2 #1234 EQU2 AND JMP2r
502+
503+@op-lda2 ( -- pass )
504+ ( - ) ;&t LDA2 #1234 EQU2 JMP2r
505+ &t 1234
506+
507+@op-sta2 ( -- pass )
508+ ( - ) #1234 ;&t [ STA2 ] ;&t LDA2 #1234 EQU2 JMP2r
509+ &t $2
510+
511+@op-dei2 ( -- pass )
512+ ( skip ) #01 JMP2r
513+
514+@op-deo2 ( -- pass )
515+ ( skip ) #01 JMP2r
516+
517+@op-add2 ( -- pass )
518+ ( - ) #ffff #0000 ADD2 [ #ffff ] EQU2
519+ ( - ) #0001 #ffff ADD2 [ #0000 ] EQU2 AND
520+ ( - ) #ffff #ffff ADD2 [ #fffe ] EQU2 AND
521+ ( - ) #fffe #ffff ADD2 [ #fffd ] EQU2 AND JMP2r
522+
523+@op-sub2 ( -- pass )
524+ ( - ) #ffff #0000 SUB2 [ #ffff ] EQU2
525+ ( - ) #0001 #ffff SUB2 [ #0002 ] EQU2 AND
526+ ( - ) #ffff #ffff SUB2 [ #0000 ] EQU2 AND
527+ ( - ) #fffe #ffff SUB2 [ #ffff ] EQU2 AND JMP2r
528+
529+@op-mul2 ( -- pass )
530+ ( - ) #1000 #0003 MUL2 [ #3000 ] EQU2
531+ ( - ) #abcd #1234 MUL2 [ #4fa4 ] EQU2 AND
532+ ( - ) #8000 #0200 MUL2 [ #0000 ] EQU2 AND
533+ ( - ) #2222 #0003 MUL2 [ #6666 ] EQU2 AND JMP2r
534+
535+@op-div2 ( -- pass )
536+ ( - ) #03e8 #0006 DIV2 [ #00a6 ] EQU2
537+ ( - ) #abcd #1234 DIV2 [ #0009 ] EQU2 AND
538+ ( - ) #8000 #0200 DIV2 [ #0040 ] EQU2 AND
539+ ( - ) #2222 #0003 DIV2 [ #0b60 ] EQU2 AND
540+ ( - ) #0202 #0000 DIV2 [ #0000 ] EQU2 AND
541+ ( - ) #0000 #0000 DIV2 #0000 EQU2 AND
542+ ( - ) #fffe #0002 DIV2 #7fff EQU2 AND
543+ ( - ) #0003 #fffd DIV2 #0000 EQU2 AND JMP2r
544+
545+@op-and2 ( -- pass )
546+ ( - ) #f0f0 #00f0 AND2 [ #00f0 ] EQU2
547+ ( - ) #aaaa #5555 AND2 [ #0000 ] EQU2 AND
548+ ( - ) #ffff #1234 AND2 [ #1234 ] EQU2 AND
549+ ( - ) #abcd #0a0c AND2 [ #0a0c ] EQU2 AND JMP2r
550+
551+@op-ora2 ( -- pass )
552+ ( - ) #0f0f #f0f0 ORA2 [ #ffff ] EQU2
553+ ( - ) #abab #cdcd ORA2 [ #efef ] EQU2 AND
554+ ( - ) #1122 #1234 ORA2 [ #1336 ] EQU2 AND
555+ ( - ) #8888 #1000 ORA2 [ #9888 ] EQU2 AND JMP2r
556+
557+@op-eor2 ( -- pass )
558+ ( - ) #ffff #ff00 EOR2 [ #00ff ] EQU2
559+ ( - ) #aaaa #5555 EOR2 [ #ffff ] EQU2 AND
560+ ( - ) #1122 #1234 EOR2 [ #0316 ] EQU2 AND
561+ ( - ) #8888 #1000 EOR2 [ #9888 ] EQU2 AND JMP2r
562+
563+@op-sft2 ( -- pass )
564+ ( - ) #ffff #01 SFT2 [ #7fff ] EQU2
565+ ( - ) #ffff #70 SFT2 [ #ff80 ] EQU2 AND
566+ ( - ) #ffff #7e SFT2 [ #0180 ] EQU2 AND
567+ ( - ) #ffff #00 SFT2 [ #ffff ] EQU2 AND
568+ ( - ) #ffff #ff SFT2 [ #8000 ] EQU2 AND
569+ ( - ) #ffff #e3 SFT2 [ #c000 ] EQU2 AND JMP2r
570+
571+(
572+@|mr )
573+
574+@op-incr ( -- pass )
575+ ( - ) LITr 01 INCr STHr #02 EQU JMP2r
576+
577+@op-popr ( -- pass )
578+ ( - ) LITr 0a LITr 0b POPr STHr #0a EQU JMP2r
579+
580+@op-nipr ( -- pass )
581+ ( - ) LITr 12 LITr 34 LITr 56 NIPr ADDr STHr #68 EQU JMP2r
582+
583+@op-swpr ( -- pass )
584+ ( - ) LITr 02 LITr 03 SWPr POPr STHr #03 EQU JMP2r
585+
586+@op-rotr ( -- pass )
587+ ( - ) LITr 0a LITr 0b LITr 0c ROTr POPr POPr STHr #0b EQU JMP2r
588+
589+@op-dupr ( -- pass )
590+ ( - ) LITr 0a DUPr STHr STHr #0a0a EQU2 JMP2r
591+
592+@op-ovrr ( -- pass )
593+ ( - ) LITr 0a LITr 0b OVRr STHr POPr POPr #0a EQU JMP2r
594+
595+@op-equr ( -- pass )
596+ ( - ) LITr f8 LITr f8 EQUr STHr #01 EQU JMP2r
597+
598+@op-neqr ( -- pass )
599+ ( - ) LITr f8 LITr f8 NEQr STHr #00 EQU JMP2r
600+
601+@op-gthr ( -- pass )
602+ ( - ) LITr f8 LITr f8 GTHr STHr #00 EQU JMP2r
603+
604+@op-lthr ( -- pass )
605+ ( - ) LITr f8 LITr f8 LTHr STHr #00 EQU JMP2r
606+
607+@op-jmpr ( -- pass )
608+ ( - ) LITr _&t [ JMPr ] #01 EQU JMP2r
609+ &t #01 JMP2r
610+
611+@op-jcnr ( -- pass )
612+ ( - ) #23 LIT2r 02 _&x [ JCNr INC &x ] [ #23 ] EQU
613+ ( - ) #23 LIT2r 00 _&y [ JCNr INC &y ] [ #24 ] EQU AND
614+ ( - ) #1234 LIT2r f0 _&t [ JCNr &back ] POP [ #34 ] EQU AND
615+ ( - ) #1234 LIT2r 00 _&t [ JCNr ] POP [ #12 ] EQU AND JMP2r
616+ &t SWP ,&back JMP
617+
618+@op-jsrr ( -- pass )
619+ LITr 0a LITr _&t JSRr STHr #14 EQU JMP2r
620+ &t DUPr ADDr JMP2
621+
622+@op-sthr ( -- pass )
623+ ( - ) LITr 55 [ STHr ] #55 EQU JMP2r
624+
625+@op-ldzr ( -- pass )
626+ ( - ) LITr 00 LDZr STHr #12 EQU JMP2r
627+
628+@op-stzr ( -- pass )
629+ ( - ) LIT2r 5606 [ STZr ] #06 LDZ #56 EQU JMP2r
630+
631+@op-ldrr ( -- pass )
632+ ( advance ) [ !{ &u 34 ] }
633+ ( - ) LITr _&t LDRr STHr #12 EQU
634+ ( - ) LITr _&u LDRr STHr #34 EQU AND JMP2r
635+ &t 12
636+
637+@op-strr ( -- pass )
638+ ( advance ) [ !{ &u $1 ] }
639+ ( - ) LITr 34 LITr _&t [ STRr ] ,&t LDR #34 EQU
640+ ( - ) LITr 12 LITr _&u [ STRr ] ,&u LDR #12 EQU AND JMP2r
641+ &t $1
642+
643+@op-ldar ( -- pass )
644+ ( - ) LIT2r =&value LDAr STHr #ef EQU JMP2r
645+ &value ef
646+
647+@op-star ( -- pass )
648+ ( - ) LITr 12 LIT2r =&value [ STAr ] ;&value LDA #12 EQU JMP2r
649+ &value 00
650+
651+@op-deir ( -- pass )
652+ ( skip ) #01 JMP2r
653+
654+@op-deor ( -- pass )
655+ ( skip ) #01 JMP2r
656+
657+@op-addr ( -- pass )
658+ ( - ) LITr ff LITr 00 ADDr STHr #ff EQU JMP2r
659+
660+@op-subr ( -- pass )
661+ ( - ) LITr ff LITr 00 SUBr STHr #ff EQU JMP2r
662+
663+@op-mulr ( -- pass )
664+ ( - ) LITr 00 LITr 01 MULr STHr #00 EQU JMP2r
665+
666+@op-divr ( -- pass )
667+ ( - ) LITr 10 LITr 06 DIVr STHr [ #02 ] EQU JMP2r
668+
669+@op-andr ( -- pass )
670+ ( - ) LITr fc LITr 3f ANDr STHr [ #3c ] EQU JMP2r
671+
672+@op-orar ( -- pass )
673+ ( - ) LITr 0f LITr f0 ORAr STHr #ff EQU JMP2r
674+
675+@op-eorr ( -- pass )
676+ ( - ) LITr 00 LITr 00 EORr STHr #00 EQU JMP2r
677+
678+@op-sftr ( -- pass )
679+ ( - ) LITr ff LITr 08 SFTr STHr #00 EQU JMP2r
680+
681+(
682+@|m2r )
683+
684+@op-inc2r ( -- pass )
685+ ( - ) LIT2r 00ff INC2r
686+ ( . ) STH2r [ #0100 ] EQU2 JMP2r
687+
688+@op-pop2r ( -- pass )
689+ ( - ) LIT2r 0a0b LIT2r 0c0d POP2r
690+ ( . ) STH2r [ #0a0b ] EQU2 JMP2r
691+
692+@op-nip2r ( -- pass )
693+ ( - ) LIT2r 1234 LIT2r 5678 NIP2r
694+ ( . ) STH2r #5678 EQU2 JMP2r
695+
696+@op-swp2r ( -- pass )
697+ ( - ) LIT2r 0a0b LIT2r 0c0d SWP2r
698+ ( . ) STH2r POP2r #0a0b EQU2 JMP2r
699+
700+@op-rot2r ( -- pass )
701+ ( - ) LIT2r 0a0b LIT2r 0c0d LIT2r 0c0f ROT2r POP2r POP2r
702+ ( . ) STH2r #0c0d EQU2 JMP2r
703+
704+@op-dup2r ( -- pass )
705+ ( - ) LIT2r 0a0b DUP2r
706+ ( . ) STH2r STH2r ADD2 #1416 EQU2 JMP2r
707+
708+@op-ovr2r ( -- pass )
709+ ( - ) LIT2r 0a0b LIT2r 0c0d OVR2r
710+ ( . ) STH2r STH2r
711+ ( . ) STH2r ADD2 ADD2 #2023 EQU2 JMP2r
712+
713+@op-equ2r ( -- pass )
714+ ( - ) LIT2r 0a0b LIT2r 0a0b EQU2r STHr #01 EQU
715+ ( - ) LIT2r 0a0b LIT2r 0c0d EQU2r STHr #00 EQU AND JMP2r
716+
717+@op-neq2r ( -- pass )
718+ ( - ) LIT2r 0a0b LIT2r 0a0b NEQ2r STHr #00 EQU
719+ ( - ) LIT2r 0a0b LIT2r 0c0d NEQ2r STHr #01 EQU AND JMP2r
720+
721+@op-gth2r ( -- pass )
722+ ( - ) LIT2r f801 LIT2r f801 GTH2r STHr #00 EQU
723+ ( - ) LIT2r f801 LIT2r 01f8 GTH2r STHr #01 EQU AND JMP2r
724+
725+@op-lth2r ( -- pass )
726+ ( - ) LIT2r f801 LIT2r f801 LTH2r STHr #00 EQU
727+ ( - ) LIT2r 01f8 LIT2r f801 LTH2r STHr #01 EQU AND JMP2r
728+
729+@op-jmp2r ( -- pass )
730+ ( - ) #5678 LIT2r =&t [ JMP2r ] SWP &t POP #56 EQU JMP2r
731+
732+@op-jcn2r ( -- pass )
733+ ( - ) #23 LITr f0 LIT2r =&x [ JCN2r INC &x ] #23 EQU
734+ ( - ) #23 LITr 00 LIT2r =&y [ JCN2r INC &y ] #24 EQU AND JMP2r
735+
736+@op-jsr2r ( -- pass )
737+ ( - ) LITr 12 LIT2r =&t JSR2r STHr #24 EQU JMP2r
738+ &t DUPr ADDr JMP2
739+
740+@op-sth2r ( -- pass )
741+ ( - ) LIT2r 0a0b
742+ ( . ) STH2r #0a0b EQU2 JMP2r
743+
744+@op-ldz2r ( -- pass )
745+ ( - ) LITr 00 [ LDZ2r ]
746+ ( . ) STH2r #1234 EQU2 JMP2r
747+
748+@op-stz2r ( -- pass )
749+ ( - ) LIT2r 5678 LITr 08 [ STZ2r ] #08 LDZ2 #5678 EQU2 JMP2r
750+
751+@op-ldr2r ( -- pass )
752+ ( advance ) [ !{ &u 1234 ] }
753+ ( - ) LITr _&t [ LDR2r ] STH2r #1234 EQU2
754+ ( - ) LITr _&u [ LDR2r ] STH2r #1234 EQU2 AND JMP2r
755+ &t 1234
756+
757+@op-str2r ( -- pass )
758+ ( advance ) [ !{ &u $2 ] }
759+ ( - ) LIT2r 1234 LITr _&t [ STR2r ] ,&t LDR2 #1234 EQU2
760+ ( - ) LIT2r 1234 LITr _&u [ STR2r ] ,&u LDR2 #1234 EQU2 AND JMP2r
761+ &t $2
762+
763+@op-lda2r ( -- pass )
764+ ( - ) LIT2r =&t [ LDA2r ]
765+ ( . ) STH2r #1234 EQU2 JMP2r
766+ &t 1234
767+
768+@op-sta2r ( -- pass )
769+ ( - ) LIT2r 1234 LIT2r =&t [ STA2r ] ;&t LDA2 #1234 EQU2 JMP2r
770+ &t $2
771+
772+@op-dei2r ( -- pass )
773+ ( skip ) #01 JMP2r
774+
775+@op-deo2r ( -- pass )
776+ ( skip ) #01 JMP2r
777+
778+@op-add2r ( -- pass )
779+ ( - ) LIT2r ffff LIT2r 0000 ADD2r STH2r [ #ffff ] EQU2
780+ ( - ) LIT2r 0001 LIT2r ffff ADD2r STH2r [ #0000 ] EQU2 AND
781+ ( - ) LIT2r ffff LIT2r ffff ADD2r STH2r [ #fffe ] EQU2 AND
782+ ( - ) LIT2r fffe LIT2r ffff ADD2r STH2r [ #fffd ] EQU2 AND JMP2r
783+
784+@op-sub2r ( -- pass )
785+ ( - ) LIT2r ffff LIT2r 0000 SUB2r STH2r [ #ffff ] EQU2
786+ ( - ) LIT2r 0001 LIT2r ffff SUB2r STH2r [ #0002 ] EQU2 AND
787+ ( - ) LIT2r ffff LIT2r ffff SUB2r STH2r [ #0000 ] EQU2 AND
788+ ( - ) LIT2r fffe LIT2r ffff SUB2r STH2r [ #ffff ] EQU2 AND JMP2r
789+
790+@op-mul2r ( -- pass )
791+ ( - ) LIT2r 1000 LIT2r 0003 MUL2r STH2r [ #3000 ] EQU2
792+ ( - ) LIT2r abcd LIT2r 1234 MUL2r STH2r [ #4fa4 ] EQU2 AND
793+ ( - ) LIT2r 8000 LIT2r 0200 MUL2r STH2r [ #0000 ] EQU2 AND
794+ ( - ) LIT2r 2222 LIT2r 0003 MUL2r STH2r [ #6666 ] EQU2 AND JMP2r
795+
796+@op-div2r ( -- pass )
797+ ( - ) LIT2r 03e8 LIT2r 0006 DIV2r STH2r [ #00a6 ] EQU2
798+ ( - ) LIT2r abcd LIT2r 1234 DIV2r STH2r [ #0009 ] EQU2 AND
799+ ( - ) LIT2r 8000 LIT2r 0200 DIV2r STH2r [ #0040 ] EQU2 AND
800+ ( - ) LIT2r 2222 LIT2r 0003 DIV2r STH2r [ #0b60 ] EQU2 AND
801+ ( - ) LIT2r 0202 LIT2r 0000 DIV2r STH2r [ #0000 ] EQU2 AND JMP2r
802+
803+@op-and2r ( -- pass )
804+ ( - ) LIT2r f0f0 LIT2r 00f0 AND2r STH2r [ #00f0 ] EQU2
805+ ( - ) LIT2r aaaa LIT2r 5555 AND2r STH2r [ #0000 ] EQU2 AND
806+ ( - ) LIT2r ffff LIT2r 1234 AND2r STH2r [ #1234 ] EQU2 AND
807+ ( - ) LIT2r abcd LIT2r 0a0c AND2r STH2r [ #0a0c ] EQU2 AND JMP2r
808+
809+@op-ora2r ( -- pass )
810+ ( - ) LIT2r 0f0f LIT2r f0f0 ORA2r STH2r [ #ffff ] EQU2
811+ ( - ) LIT2r abab LIT2r cdcd ORA2r STH2r [ #efef ] EQU2 AND
812+ ( - ) LIT2r 1122 LIT2r 1234 ORA2r STH2r [ #1336 ] EQU2 AND
813+ ( - ) LIT2r 8888 LIT2r 1000 ORA2r STH2r [ #9888 ] EQU2 AND JMP2r
814+
815+@op-eor2r ( -- pass )
816+ ( - ) LIT2r ffff LIT2r ff00 EOR2r STH2r [ #00ff ] EQU2
817+ ( - ) LIT2r aaaa LIT2r 5555 EOR2r STH2r [ #ffff ] EQU2 AND
818+ ( - ) LIT2r 1122 LIT2r 1234 EOR2r STH2r [ #0316 ] EQU2 AND
819+ ( - ) LIT2r 8888 LIT2r 1000 EOR2r STH2r [ #9888 ] EQU2 AND JMP2r
820+
821+@op-sft2r ( -- pass )
822+ ( - ) LIT2r ffff LITr 01 SFT2r STH2r [ #7fff ] EQU2
823+ ( - ) LIT2r ffff LITr 70 SFT2r STH2r [ #ff80 ] EQU2 AND
824+ ( - ) LIT2r ffff LITr 7e SFT2r STH2r [ #0180 ] EQU2 AND
825+ ( - ) LIT2r ffff LITr e3 SFT2r STH2r [ #c000 ] EQU2 AND JMP2r
826+
827+(
828+@|mk )
829+
830+@op-inck ( -- pass )
831+ ( - ) #01 INCk #0102 EQU2
832+ ( - ) #ff INCk #ff00 EQU2 AND JMP2r
833+
834+@op-popk ( -- pass )
835+ ( - ) #0a #0b POPk #0a0b EQU2 JMP2r
836+
837+@op-nipk ( -- pass )
838+ ( - ) #12 #34 NIPk NIP NIP #34 EQU
839+ ( - ) #12 #34 NIPk NIP #1234 EQU2 AND JMP2r
840+
841+@op-swpk ( -- pass )
842+ ( - ) #12 #34 SWPk NIP2 #3412 EQU2
843+ ( - ) #12 #34 SWPk POP2 #1234 EQU2 AND JMP2r
844+
845+@op-rotk ( -- pass )
846+ ( - ) #02 #04 #10 ROTk POP POP POP ROT DIV ADD #0c EQU
847+ ( - ) #02 #04 #10 ROTk [ STH STH STH ] POP POP POP STHr STHr STHr DIV ADD [ #0c ] EQU AND JMP2r
848+
849+@op-dupk ( -- pass )
850+ ( - ) #0a DUPk EQU SWP [ #0a ] EQU AND
851+ ( - ) #ff DUPk EQU SWP #ff EQU AND AND JMP2r
852+
853+@op-ovrk ( -- pass )
854+ ( - ) #02 #10 OVRk POP POP POP #0210 EQU2
855+ ( check result ) #02 #10 OVRk NIP NIP DIV ADD [ #0a ] EQU AND JMP2r
856+
857+@op-equk ( -- pass )
858+ ( - ) #0a #0a EQUk ROT [ #0a ] EQU ROT [ #0a ] EQU AND SWP #01 EQU AND
859+ ( - ) #0a #0b EQUk ROT [ #0a ] EQU ROT [ #0b ] EQU AND SWP #00 EQU AND AND JMP2r
860+
861+@op-neqk ( -- pass )
862+ ( - ) #0a #0b NEQk ROT [ #0a ] EQU ROT [ #0b ] EQU AND SWP #01 EQU AND
863+ ( - ) #0a #0a NEQk ROT [ #0a ] EQU ROT [ #0a ] EQU AND SWP #00 EQU AND AND JMP2r
864+
865+@op-gthk ( -- pass )
866+ ( - ) #f8 #01 GTHk ROT [ #f8 ] EQU ROT #01 EQU AND SWP #01 EQU AND
867+ ( - ) #01 #f8 GTHk ROT #01 EQU ROT [ #f8 ] EQU AND SWP #00 EQU AND AND JMP2r
868+
869+@op-lthk ( -- pass )
870+ ( - ) #01 #ff LTHk ROT #01 EQU ROT #ff EQU AND SWP #01 EQU AND
871+ ( - ) #f8 #01 LTHk ROT [ #f8 ] EQU ROT #01 EQU AND SWP #00 EQU AND AND JMP2r
872+
873+@op-jmpk ( -- pass )
874+ ( - ) #1234 ,&x [ JMPk SWP &x ] POP2 [ #12 ] EQU
875+ ( - ) #1234 ,&t [ JMPk &back ] POP2 [ #34 ] EQU AND JMP2r
876+ &t POP SWP ,&back JMPk
877+
878+@op-jcnk ( -- pass )
879+ ( - ) LITr 0a #00 ,&x JCNk INCr &x POP2 STHr #0b EQU
880+ ( - ) LITr 0a #81 ,&y JCNk INCr &y POP2 STHr #0a EQU AND JMP2r
881+
882+@op-jsrk ( -- pass )
883+ ( - ) #0a ,&t JSRk #0b EQU JMP2r
884+ &t POP INC JMP2r
885+
886+@op-sthk ( -- pass )
887+ ( - ) #08 STHk STHr ADD #10 EQU JMP2r
888+
889+@op-ldzk ( -- pass )
890+ ( - ) #00 LDZk [ #12 ] EQU SWP #00 EQU AND JMP2r
891+
892+@op-stzk ( -- pass )
893+ ( - ) #56 #0a STZk POP2 #0a LDZ [ #56 ] EQU
894+ ( - ) #ab #0b STZk #ab0b EQU2 AND JMP2r
895+
896+@op-ldrk ( -- pass )
897+ ( - ) ,&t LDRk [ #12 ] EQU NIP JMP2r
898+ &t 12
899+
900+@op-strk ( -- pass )
901+ ( - ) #34 ,&t STRk POP2 ,&t LDR [ #34 ] EQU
902+ ( - ) #34 ,&t STRk SWP [ #34 ] EQU NIP AND JMP2r
903+ &t $1
904+
905+@op-ldak ( -- pass )
906+ ( - ) ;&t LDAk [ STH ] ;&t EQU2 STHr [ #ef ] EQU AND JMP2r
907+ &t ef
908+
909+@op-stak ( -- pass )
910+ ( - ) #12 ;&t STAk POP2 POP ;&t LDA [ #12 ] EQU
911+ ( - ) #34 ;&t STAk [ STH2 ] [ #34 ] EQU STH2r ;&t EQU2 AND AND JMP2r
912+ &t 00
913+
914+@op-deik ( -- pass )
915+ ( skip ) #01 JMP2r
916+
917+@op-deok ( -- pass )
918+ ( skip ) #01 JMP2r
919+
920+@op-addk ( -- pass )
921+ ( - ) #03 #05 ADDk ROT [ #03 ] EQU ROT [ #05 ] EQU AND SWP [ #08 ] EQU AND
922+ ( - ) #ff #01 ADDk ROT #ff EQU ROT #01 EQU AND SWP #00 EQU AND AND JMP2r
923+
924+@op-subk ( -- pass )
925+ ( - ) #ff #00 SUBk ROT #ff EQU ROT #00 EQU AND SWP #ff EQU AND
926+ ( - ) #01 #ff SUBk ROT #01 EQU ROT #ff EQU AND SWP [ #02 ] EQU AND AND JMP2r
927+
928+@op-mulk ( -- pass )
929+ ( - ) #03 #04 MULk ROT [ #03 ] EQU ROT [ #04 ] EQU AND SWP [ #0c ] EQU AND
930+ ( - ) #10 #02 MULk ROT [ #10 ] EQU ROT [ #02 ] EQU AND SWP [ #20 ] EQU AND AND JMP2r
931+
932+@op-divk ( -- pass )
933+ ( - ) #10 #02 DIVk ROT [ #10 ] EQU ROT [ #02 ] EQU AND SWP [ #08 ] EQU AND
934+ ( - ) #34 #01 DIVk ROT [ #34 ] EQU ROT #01 EQU AND SWP [ #34 ] EQU AND AND JMP2r
935+
936+@op-andk ( -- pass )
937+ ( - ) #fc #3f ANDk ROT [ #fc ] EQU ROT [ #3f ] EQU AND SWP [ #3c ] EQU AND
938+ ( - ) #ff #aa ANDk ROT #ff EQU ROT [ #aa ] EQU AND SWP [ #aa ] EQU AND AND JMP2r
939+
940+@op-orak ( -- pass )
941+ ( - ) #0f #f0 ORAk ROT [ #0f ] EQU ROT [ #f0 ] EQU AND SWP #ff EQU AND
942+ ( - ) #12 #34 ORAk ROT [ #12 ] EQU ROT [ #34 ] EQU AND SWP [ #36 ] EQU AND AND JMP2r
943+
944+@op-eork ( -- pass )
945+ ( - ) #aa #55 EORk ROT [ #aa ] EQU ROT [ #55 ] EQU AND SWP #ff EQU AND
946+ ( - ) #ff #ff EORk ROT #ff EQU ROT #ff EQU AND SWP #00 EQU AND AND JMP2r
947+
948+@op-sftk ( -- pass )
949+ ( - ) #ff #11 SFTk ROT #ff EQU ROT [ #11 ] EQU AND SWP [ #fe ] EQU AND
950+ ( - ) #ff #12 SFTk ROT #ff EQU ROT [ #12 ] EQU AND SWP [ #7e ] EQU AND AND JMP2r
951+
952+(
953+@|m2k )
954+
955+@op-inc2k ( -- pass )
956+ ( - ) #00ff INC2k ADD2 #01ff EQU2 JMP2r
957+
958+@op-pop2k ( -- pass )
959+ ( - ) #0a0b POP2k #0a0b EQU2 JMP2r
960+
961+@op-nip2k ( -- pass )
962+ ( - ) #1234 #5678 NIP2k #5678 EQU2 STH
963+ ( - ) #5678 EQU2 STH
964+ ANDr
965+ ( - ) #1234 EQU2 STHr AND JMP2r
966+
967+@op-swp2k ( -- pass )
968+ ( - ) #1234 #5678 SWP2k
969+ ( | tests )
970+ #1234 EQU2 STH
971+ #5678 EQU2 STH
972+ #5678 EQU2 STH
973+ #1234 EQU2 STH
974+ ANDr ANDr ANDr STHr JMP2r
975+
976+@op-rot2k ( -- pass )
977+ ( - ) #000a #000b #000c ROT2k
978+ ( | tests )
979+ #000a EQU2 STH
980+ #000c EQU2 STH
981+ #000b EQU2 STH
982+ #000c EQU2 STH
983+ #000b EQU2 STH
984+ #000a EQU2 STH
985+ ANDr ANDr ANDr ANDr ANDr STHr JMP2r
986+
987+@op-dup2k ( -- pass )
988+ ( - ) #0a0b DUP2k
989+ ( | tests )
990+ #0a0b EQU2 STH
991+ #0a0b EQU2 STH
992+ #0a0b EQU2 STH
993+ ANDr ANDr STHr JMP2r
994+
995+@op-ovr2k ( -- pass )
996+ ( - ) #0a0b #0c0d OVR2k
997+ ( | tests )
998+ #0a0b EQU2 STH
999+ #0c0d EQU2 STH
1000+ #0a0b EQU2 STH
1001+ #0c0d EQU2 STH
1002+ #0a0b EQU2 STH
1003+ ANDr ANDr ANDr ANDr STHr JMP2r
1004+
1005+@op-equ2k ( -- pass )
1006+ ( - ) #0a0b #0a0b EQU2k STH
1007+ EQU2 STHr AND
1008+ ( - ) #0a0b #0e0f EQU2k #00 EQU STH
1009+ EQU2 #00 EQU STHr AND AND JMP2r
1010+
1011+@op-neq2k ( -- pass )
1012+ ( - ) #0a0b #0a0b NEQ2k #00 EQU STH
1013+ NEQ2 #00 EQU STHr AND
1014+ ( - ) #0a0b #0e0f NEQ2k STH
1015+ NEQ2 STHr AND AND JMP2r
1016+
1017+@op-gth2k ( -- pass )
1018+ ( - ) #000a #000b GTH2k #00 EQU STH
1019+ GTH2 #00 EQU STHr AND
1020+ ( - ) #000b #000a GTH2k STH
1021+ GTH2 STHr AND AND JMP2r
1022+
1023+@op-lth2k ( -- pass )
1024+ ( - ) #000b #000a LTH2k #00 EQU STH
1025+ LTH2 #00 EQU STHr AND
1026+ ( - ) #000a #000b LTH2k STH
1027+ LTH2 STHr AND AND JMP2r
1028+
1029+@op-jmp2k ( -- pass )
1030+ ( - ) LIT2r 1234 ;&x [ JMP2k SWPr &x ] POP2 STHr POPr #34 EQU
1031+ ( - ) LIT2r 1234 ;&t [ JMP2k &back ] POP2 POPr STHr #34 EQU AND JMP2r
1032+ &t POP2 SWPr ;&back JMP2k
1033+
1034+@op-jcn2k ( -- pass )
1035+ ( - ) LITr 0a #00 ;&x JCN2k INCr &x POP2 POP STHr #0b EQU
1036+ ( - ) LITr 0a #18 ;&y JCN2k INCr &y POP2 POP STHr #0a EQU AND JMP2r
1037+
1038+@op-jsr2k ( -- pass )
1039+ ( - ) #0a ;&t JSR2k #0b EQU JMP2r
1040+ &t POP2 INC JMP2r
1041+
1042+@op-sth2k ( -- pass )
1043+ ( - ) #0a0b STH2k STH2r EQU2 JMP2r
1044+
1045+@op-ldz2k ( -- pass )
1046+ ( - ) #00 LDZ2k #1234 EQU2 SWP #00 EQU AND JMP2r
1047+
1048+@op-stz2k ( -- pass )
1049+ ( - ) #5678 #05 [ STZ2k ] #05 EQU STH
1050+ #5678 EQU2 STHr AND #05 LDZ2 #5678 EQU2 AND JMP2r
1051+
1052+@op-ldr2k ( -- pass )
1053+ ( - ) ,&t LDR2k [ LIT2 &t 1234 ] EQU2 NIP JMP2r
1054+
1055+@op-str2k ( -- pass )
1056+ ( - ) #1234 ,&t STR2k POP [ LIT2 &t $2 ] EQU2 JMP2r
1057+
1058+@op-lda2k ( -- pass )
1059+ ( - ) ;&t LDA2k [ LIT2 &t 1234 ] EQU2 NIP NIP JMP2r
1060+
1061+@op-sta2k ( -- pass )
1062+ ( - ) #1234 ;&t STA2k POP2 [ LIT2 &t $2 ] EQU2 JMP2r
1063+
1064+@op-dei2k ( -- pass )
1065+ ( skip ) #01 JMP2r
1066+
1067+@op-deo2k ( -- pass )
1068+ ( skip ) #01 JMP2r
1069+
1070+@op-add2k ( -- pass )
1071+ #0a0b #0c0d ADD2k
1072+ ( | tests )
1073+ #1618 EQU2 STH
1074+ #0c0d EQU2 STH
1075+ #0a0b EQU2 STH
1076+ ANDr ANDr STHr JMP2r
1077+
1078+@op-sub2k ( -- pass )
1079+ #0a0b #0c0d SUB2k
1080+ ( | tests )
1081+ #fdfe EQU2 STH
1082+ #0c0d EQU2 STH
1083+ #0a0b EQU2 STH
1084+ ANDr ANDr STHr JMP2r
1085+
1086+@op-mul2k ( -- pass )
1087+ #0a0b #0c0d MUL2k
1088+ ( | tests )
1089+ #068f EQU2 STH
1090+ #0c0d EQU2 STH
1091+ #0a0b EQU2 STH
1092+ ANDr ANDr STHr JMP2r
1093+
1094+@op-div2k ( -- pass )
1095+ #0c0d #0003 DIV2k
1096+ ( | tests )
1097+ #0404 EQU2 STH
1098+ #0003 EQU2 STH
1099+ #0c0d EQU2 STH
1100+ ANDr ANDr STHr JMP2r
1101+
1102+@op-and2k ( -- pass )
1103+ #0c0d #a5a5 AND2k
1104+ ( | tests )
1105+ #0405 EQU2 STH
1106+ #a5a5 EQU2 STH
1107+ #0c0d EQU2 STH
1108+ ANDr ANDr STHr JMP2r
1109+
1110+@op-ora2k ( -- pass )
1111+ #0c0d #a5a5 ORA2k
1112+ ( | tests )
1113+ #adad EQU2 STH
1114+ #a5a5 EQU2 STH
1115+ #0c0d EQU2 STH
1116+ ANDr ANDr STHr JMP2r
1117+
1118+@op-eor2k ( -- pass )
1119+ #0c0d #a5a5 EOR2k
1120+ ( | tests )
1121+ #a9a8 EQU2 STH
1122+ #a5a5 EQU2 STH
1123+ #0c0d EQU2 STH
1124+ ANDr ANDr STHr JMP2r
1125+
1126+@op-sft2k ( -- pass )
1127+ ( - ) #1234 #32 SFT2k
1128+ ( | test )
1129+ #2468 EQU2 STH
1130+ #32 EQU STH
1131+ #1234 EQU2 STH
1132+ ANDr ANDr STHr JMP2r
1133+
1134+(
1135+@|mkr )
1136+
1137+@op-inckr ( -- pass )
1138+ ( - ) LITr 01 INCkr LIT2r 0102 EQU2r
1139+ ( - ) LITr ff INCkr LIT2r ff00 EQU2r ANDr STHr JMP2r
1140+
1141+@op-popkr ( -- pass )
1142+ ( - ) LIT2r 0a0b POPkr LIT2r 0a0b EQU2r STHr JMP2r
1143+
1144+@op-nipkr ( -- pass )
1145+ ( - ) LIT2r 1234 NIPkr NIPr NIPr LITr 34 EQUr
1146+ ( - ) LIT2r 1234 NIPkr NIPr LIT2r 1234 EQU2r ANDr STHr JMP2r
1147+
1148+@op-swpkr ( -- pass )
1149+ ( - ) LIT2r 1234 SWPkr NIP2r LIT2r 3412 EQU2r
1150+ ( - ) LIT2r 1234 SWPkr POP2r LIT2r 1234 EQU2r ANDr STHr JMP2r
1151+
1152+@op-rotkr ( -- pass )
1153+ LITr 0a LITr 0b LITr 0c ROTkr STH2r #0c0a EQU2 STH2r #0c0b EQU2 STH2r #0a0b EQU2 AND AND JMP2r
1154+
1155+@op-dupkr ( -- pass )
1156+ ( - ) LITr 0a DUPkr
1157+ ( . ) STH2r #0a0a EQU2
1158+ ( . ) STHr #0a EQU AND JMP2r
1159+
1160+@op-ovrkr ( -- pass )
1161+ ( - ) LIT2r 0a0b OVRkr
1162+ ( . ) STH2r #0b0a EQU2
1163+ ( . ) STH2r #0b0a EQU2 AND
1164+ ( . ) STHr #0a EQU AND JMP2r
1165+
1166+@op-equkr ( -- pass )
1167+ ( - ) LIT2r 0a0a EQUkr ROTr LITr 0a EQUr ROTr LITr 0a EQUr ANDr SWPr LITr 01 EQUr ANDr
1168+ ( - ) LIT2r 0a0b EQUkr ROTr LITr 0a EQUr ROTr LITr 0b EQUr ANDr SWPr LITr 00 EQUr ANDr ANDr STHr JMP2r
1169+
1170+@op-neqkr ( -- pass )
1171+ ( - ) LIT2r 0a0b NEQkr ROTr LITr 0a EQUr ROTr LITr 0b EQUr ANDr SWPr LITr 01 EQUr ANDr
1172+ ( - ) LIT2r 0a0a NEQkr ROTr LITr 0a EQUr ROTr LITr 0a EQUr ANDr SWPr LITr 00 EQUr ANDr ANDr STHr JMP2r
1173+
1174+@op-gthkr ( -- pass )
1175+ ( - ) LIT2r f801 GTHkr ROTr LITr f8 EQUr ROTr LITr 01 EQUr ANDr SWPr LITr 01 EQUr ANDr
1176+ ( - ) LIT2r 01f8 GTHkr ROTr LITr 01 EQUr ROTr LITr f8 EQUr ANDr SWPr LITr 00 EQUr ANDr ANDr STHr JMP2r
1177+
1178+@op-lthkr ( -- pass )
1179+ ( - ) LIT2r 01ff LTHkr ROTr LITr 01 EQUr ROTr LITr ff EQUr ANDr SWPr LITr 01 EQUr ANDr
1180+ ( - ) LIT2r f801 LTHkr ROTr LITr f8 EQUr ROTr LITr 01 EQUr ANDr SWPr LITr 00 EQUr ANDr ANDr STHr JMP2r
1181+
1182+@op-jmpkr ( -- pass )
1183+ ( - ) #1234 LITr _&x [ JMPkr SWP &x ] POP POPr [ #12 ] EQU
1184+ ( - ) #1234 LITr _&t [ JMPkr &back ] POP POPr [ #34 ] EQU AND JMP2r
1185+ &t POPr SWP LITr _&back JMPkr
1186+
1187+@op-jcnkr ( -- pass )
1188+ ( - ) #0a LIT2r 00 _&x JCNkr
1189+ INC &x POP2r #0b EQU
1190+ ( - ) #0a LIT2r 01 _&y JCNkr
1191+ INC &y POP2r #0a EQU AND JMP2r
1192+
1193+@op-jsrkr ( -- pass )
1194+ ( - ) LITr 0a LITr _&t JSRkr STHr #0b EQU JMP2r
1195+ &t POPr INCr JMP2
1196+
1197+@op-sthkr ( -- pass )
1198+ ( - ) LIT2r 0a0b STH2kr STH2r EQU2 JMP2r
1199+
1200+@op-ldzkr ( -- pass )
1201+ ( - ) LITr 00 LDZkr STH2r #0012 EQU2 JMP2r
1202+
1203+@op-stzkr ( -- pass )
1204+ ( - ) LITr 56 LITr 0a STZkr
1205+ POP2r LITr 0a LDZr LITr 56 EQUr
1206+ ( - ) LITr ab LITr 0b STZkr
1207+ LIT2r ab0b EQU2r ANDr STHr JMP2r
1208+
1209+@op-ldrkr ( -- pass )
1210+ ( - ) LITr _&t LDRkr [ LITr 12 ] EQUr NIPr STHr JMP2r
1211+ &t 12
1212+
1213+@op-strkr ( -- pass )
1214+ ( - ) LITr 34 LITr _&t STRkr
1215+ POP2r LITr _&t LDRr [ LITr 34 ] EQUr
1216+ ( - ) LITr 34 LITr _&t STRkr
1217+ SWPr [ LITr 34 ] EQUr NIPr ANDr STHr JMP2r
1218+ &t $1
1219+
1220+@op-ldakr ( -- pass )
1221+ ( - ) LIT2r =&t LDAkr [ STHr ] LIT2r =&t EQU2r STH
1222+ [ LITr ef ] EQUr ANDr STHr JMP2r
1223+ &t ef
1224+
1225+@op-stakr ( -- pass )
1226+ ( - ) LITr 12 LIT2r =&t STAkr
1227+ POP2r POPr LIT2r =&t LDAr [ LITr 12 ] EQUr
1228+ ( - ) LITr 34 LIT2r =&t STAkr
1229+ [ STH2r ] [ LITr 34 ] EQUr STH2
1230+ LIT2r =&t EQU2r ANDr ANDr STHr JMP2r
1231+ &t 00
1232+
1233+@op-deikr ( -- pass )
1234+ ( skip ) #01 JMP2r
1235+
1236+@op-deokr ( -- pass )
1237+ ( skip ) #01 JMP2r
1238+
1239+@op-addkr ( -- pass )
1240+ ( - ) LITr 03 LITr 05 ADDkr ROTr LITr 03 EQUr ROTr LITr 05 EQUr ANDr SWPr LITr 08 EQUr ANDr
1241+ ( - ) LITr ff LITr 01 ADDkr ROTr LITr ff EQUr ROTr LITr 01 EQUr ANDr SWPr LITr 00 EQUr ANDr ANDr STHr JMP2r
1242+
1243+@op-subkr ( -- pass )
1244+ ( - ) LITr ff LITr 00 SUBkr ROTr LITr ff EQUr ROTr LITr 00 EQUr ANDr SWPr LITr ff EQUr ANDr
1245+ ( - ) LITr 01 LITr ff SUBkr ROTr LITr 01 EQUr ROTr LITr ff EQUr ANDr SWPr LITr 02 EQUr ANDr ANDr STHr JMP2r
1246+
1247+@op-mulkr ( -- pass )
1248+ ( - ) LITr 03 LITr 04 MULkr ROTr LITr 03 EQUr ROTr LITr 04 EQUr ANDr SWPr LITr 0c EQUr ANDr
1249+ ( - ) LITr 10 LITr 02 MULkr ROTr LITr 10 EQUr ROTr LITr 02 EQUr ANDr SWPr LITr 20 EQUr ANDr ANDr STHr JMP2r
1250+
1251+@op-divkr ( -- pass )
1252+ ( - ) LITr 10 LITr 02 DIVkr ROTr LITr 10 EQUr ROTr LITr 02 EQUr ANDr SWPr LITr 08 EQUr ANDr
1253+ ( - ) LITr 34 LITr 01 DIVkr ROTr LITr 34 EQUr ROTr LITr 01 EQUr ANDr SWPr LITr 34 EQUr ANDr ANDr STHr JMP2r
1254+
1255+@op-andkr ( -- pass )
1256+ ( - ) LITr fc LITr 3f ANDkr ROTr LITr fc EQUr ROTr LITr 3f EQUr ANDr SWPr LITr 3c EQUr ANDr
1257+ ( - ) LITr ff LITr aa ANDkr ROTr LITr ff EQUr ROTr LITr aa EQUr ANDr SWPr LITr aa EQUr ANDr ANDr STHr JMP2r
1258+
1259+@op-orakr ( -- pass )
1260+ ( - ) LITr 0f LITr f0 ORAkr ROTr LITr 0f EQUr ROTr LITr f0 EQUr ANDr SWPr LITr ff EQUr ANDr
1261+ ( - ) LITr 12 LITr 34 ORAkr ROTr LITr 12 EQUr ROTr LITr 34 EQUr ANDr SWPr LITr 36 EQUr ANDr ANDr STHr JMP2r
1262+
1263+@op-eorkr ( -- pass )
1264+ ( - ) LITr aa LITr 55 EORkr ROTr LITr aa EQUr ROTr LITr 55 EQUr ANDr SWPr LITr ff EQUr ANDr
1265+ ( - ) LITr ff LITr ff EORkr ROTr LITr ff EQUr ROTr LITr ff EQUr ANDr SWPr LITr 00 EQUr ANDr ANDr STHr JMP2r
1266+
1267+@op-sftkr ( -- pass )
1268+ ( - ) LITr ff LITr 11 SFTkr ROTr LITr ff EQUr ROTr LITr 11 EQUr ANDr SWPr LITr fe EQUr ANDr
1269+ ( - ) LITr ff LITr 12 SFTkr ROTr LITr ff EQUr ROTr LITr 12 EQUr ANDr SWPr LITr 7e EQUr ANDr ANDr STHr JMP2r
1270+
1271+(
1272+@|m2kr )
1273+
1274+@op-inc2kr ( -- pass )
1275+ ( - ) LIT2r 00ff INC2kr ADD2r LIT2r 01ff EQU2r STHr JMP2r
1276+
1277+@op-pop2kr ( -- pass )
1278+ ( - ) LIT2r 0a0b POP2kr LIT2r 0a0b EQU2r STHr JMP2r
1279+
1280+@op-nip2kr ( -- pass )
1281+ ( - ) LIT2r 1234 LIT2r 5678 NIP2kr LIT2r 5678 EQU2r STHr
1282+ ( - ) LIT2r 5678 EQU2r STHr AND
1283+ ( - ) LIT2r 1234 EQU2r STH
1284+ ANDr STHr JMP2r
1285+
1286+@op-swp2kr ( -- pass )
1287+ ( - ) LIT2r 1234 LIT2r 5678 SWP2kr
1288+ ( | tests )
1289+ LIT2r 1234 EQU2r STHr LIT2r 5678 EQU2r STHr LIT2r 5678 EQU2r STHr LIT2r 1234 EQU2r STHr AND AND AND JMP2r
1290+
1291+@op-rot2kr ( -- pass )
1292+ ( - ) LIT2r 1234 LIT2r 5678 LIT2r 9abc ROT2kr STH2r #1234 EQU2 STH2r #9abc EQU2 STH2r #5678 EQU2 STH2r #9abc EQU2 STH2r #5678 EQU2 STH2r #1234 EQU2 AND AND AND AND AND JMP2r
1293+
1294+@op-dup2kr ( -- pass )
1295+ ( - ) LIT2r 1234 DUP2kr ADD2r ADD2r STH2r #369c EQU2 JMP2r
1296+
1297+@op-ovr2kr ( -- pass )
1298+ ( - ) LIT2r 0a0b LIT2r 0c0d OVR2kr STH2r #0a0b EQU2 STH2r #0c0d EQU2 STH2r #0a0b EQU2 STH2r #0c0d EQU2 STH2r #0a0b EQU2 AND AND AND AND JMP2r
1299+
1300+@op-equ2kr ( -- pass )
1301+ ( - ) LIT2r 0a0b LIT2r 0a0b EQU2kr STHr EQU2r STH
1302+ ANDr
1303+ ( - ) LIT2r 0a0b LIT2r 0e0f EQU2kr LITr 00 EQUr STHr EQU2r LITr 00 EQUr STH
1304+ ANDr ANDr STHr JMP2r
1305+
1306+@op-neq2kr ( -- pass )
1307+ ( - ) LIT2r 0a0b LIT2r 0a0b NEQ2kr LITr 00 EQUr STHr NEQ2r LITr 00 EQUr STH
1308+ ANDr
1309+ ( - ) LIT2r 0a0b LIT2r 0e0f NEQ2kr STHr NEQ2r STH
1310+ ANDr ANDr STHr JMP2r
1311+
1312+@op-gth2kr ( -- pass )
1313+ ( - ) LIT2r 000a LIT2r 000b GTH2kr LITr 00 EQUr STHr GTH2r LITr 00 EQUr STH
1314+ ANDr
1315+ ( - ) LIT2r 000b LIT2r 000a GTH2kr STHr GTH2r STH
1316+ ANDr ANDr STHr JMP2r
1317+
1318+@op-lth2kr ( -- pass )
1319+ ( - ) LIT2r 000b LIT2r 000a LTH2kr LITr 00 EQUr STHr LTH2r LITr 00 EQUr STH
1320+ ANDr
1321+ ( - ) LIT2r 000a LIT2r 000b LTH2kr STHr LTH2r STH
1322+ ANDr ANDr STHr JMP2r
1323+
1324+@op-jmp2kr ( -- pass )
1325+ ( - ) #1234 LIT2r =&x [ JMP2kr SWP &x ] POP2r POP #12 EQU
1326+ ( - ) #1234 LIT2r =&t [ JMP2kr &back ] POP2r POP #34 EQU AND JMP2r
1327+ &t POP2r SWP LIT2r =&back JMP2kr
1328+
1329+@op-jcn2kr ( -- pass )
1330+ ( - ) #0a LITr 00 LIT2r =&x JCN2kr
1331+ INC &x POP2r POPr #0b EQU
1332+ ( - ) #0a LITr 01 LIT2r =&y JCN2kr
1333+ INC &y POP2r POPr #0a EQU AND JMP2r
1334+
1335+@op-jsr2kr ( -- pass )
1336+ ( - ) LITr 0a LIT2r =&t JSR2kr STHr #0b EQU JMP2r
1337+ &t POP2r INCr JMP2
1338+
1339+@op-sth2kr ( -- pass )
1340+ ( - ) LIT2r 0a0b STH2kr #0a0b EQU2 #0a0b STH2r EQU2 AND JMP2r
1341+
1342+@op-ldz2kr ( -- pass )
1343+ ( - ) LITr 00 LDZ2kr STH2r #1234 EQU2 STHr #00 EQU AND JMP2r
1344+
1345+@op-stz2kr ( -- pass )
1346+ ( - ) LIT2r 5678 LITr 09 [ STZ2kr ] STHr #09 EQU STH2r #5678 EQU2 AND #09 LDZ2 #5678 EQU2 AND JMP2r
1347+
1348+@op-ldr2kr ( -- pass )
1349+ ( - ) LITr _&t LDR2kr [ LIT2r &t 1234 ] EQU2r NIPr STHr JMP2r
1350+
1351+@op-str2kr ( -- pass )
1352+ ( - ) LIT2r 1234 LITr _&t STR2kr
1353+ POPr [ LIT2r &t $2 ] EQU2r STHr JMP2r
1354+
1355+@op-lda2kr ( -- pass )
1356+ ( - ) LIT2r =&t LDA2kr [ LIT2r &t 1234 ] EQU2r NIPr NIPr STHr JMP2r
1357+
1358+@op-sta2kr ( -- pass )
1359+ ( - ) LIT2r 1234 LIT2r =&t STA2kr
1360+ POP2r [ LIT2r &t $2 ] EQU2r STHr JMP2r
1361+
1362+@op-dei2kr ( -- pass )
1363+ ( skip ) #01 JMP2r
1364+
1365+@op-deo2kr ( -- pass )
1366+ ( skip ) #01 JMP2r
1367+
1368+@op-add2kr ( -- pass )
1369+ LIT2r 0a0b LIT2r 0c0d ADD2kr
1370+ ( | tests )
1371+ LIT2r 1618 EQU2r STHr LIT2r 0c0d EQU2r STHr LIT2r 0a0b EQU2r STHr AND AND JMP2r
1372+
1373+@op-sub2kr ( -- pass )
1374+ LIT2r 0a0b LIT2r 0c0d SUB2kr
1375+ ( | tests )
1376+ LIT2r fdfe EQU2r STHr LIT2r 0c0d EQU2r STHr LIT2r 0a0b EQU2r STHr AND AND JMP2r
1377+
1378+@op-mul2kr ( -- pass )
1379+ LIT2r 0a0b LIT2r 0c0d MUL2kr
1380+ ( | tests )
1381+ LIT2r 068f EQU2r STHr LIT2r 0c0d EQU2r STHr LIT2r 0a0b EQU2r STHr AND AND JMP2r
1382+
1383+@op-div2kr ( -- pass )
1384+ LIT2r 0c0d LIT2r 0003 DIV2kr
1385+ ( | tests )
1386+ LIT2r 0404 EQU2r STHr LIT2r 0003 EQU2r STHr LIT2r 0c0d EQU2r STHr AND AND JMP2r
1387+
1388+@op-and2kr ( -- pass )
1389+ LIT2r 0c0d LIT2r a5a5 AND2kr
1390+ ( | tests )
1391+ LIT2r 0405 EQU2r STHr LIT2r a5a5 EQU2r STHr LIT2r 0c0d EQU2r STHr AND AND JMP2r
1392+
1393+@op-ora2kr ( -- pass )
1394+ LIT2r 0c0d LIT2r a5a5 ORA2kr
1395+ ( | tests )
1396+ LIT2r adad EQU2r STHr LIT2r a5a5 EQU2r STHr LIT2r 0c0d EQU2r STHr AND AND JMP2r
1397+
1398+@op-eor2kr ( -- pass )
1399+ LIT2r 0c0d LIT2r a5a5 EOR2kr
1400+ ( | tests )
1401+ LIT2r a9a8 EQU2r STHr LIT2r a5a5 EQU2r STHr LIT2r 0c0d EQU2r STHr AND AND JMP2r
1402+
1403+@op-sft2kr ( -- pass )
1404+ ( - ) LIT2r 1234 LITr 32 SFT2kr LIT2r 2468 EQU2r SWP2r LIT2r 1234 EQU2r ANDr LIT2r 3201 EQU2r STHr JMP2r
1405+
1406+@tests/lut [
1407+ =op-brk =op-inc =op-pop =op-nip
1408+ =op-swp =op-rot =op-dup =op-ovr
1409+ =op-equ =op-neq =op-gth =op-lth
1410+ =op-jmp =op-jcn =op-jsr =op-sth
1411+ =op-ldz =op-stz =op-ldr =op-str
1412+ =op-lda =op-sta =op-dei =op-deo
1413+ =op-add =op-sub =op-mul =op-div
1414+ =op-and =op-ora =op-eor =op-sft
1415+ =op-jci =op-inc2 =op-pop2 =op-nip2
1416+ =op-swp2 =op-rot2 =op-dup2 =op-ovr2
1417+ =op-equ2 =op-neq2 =op-gth2 =op-lth2
1418+ =op-jmp2 =op-jcn2 =op-jsr2 =op-sth2
1419+ =op-ldz2 =op-stz2 =op-ldr2 =op-str2
1420+ =op-lda2 =op-sta2 =op-dei2 =op-deo2
1421+ =op-add2 =op-sub2 =op-mul2 =op-div2
1422+ =op-and2 =op-ora2 =op-eor2 =op-sft2
1423+ =op-jmi =op-incr =op-popr =op-nipr
1424+ =op-swpr =op-rotr =op-dupr =op-ovrr
1425+ =op-equr =op-neqr =op-gthr =op-lthr
1426+ =op-jmpr =op-jcnr =op-jsrr =op-sthr
1427+ =op-ldzr =op-stzr =op-ldrr =op-strr
1428+ =op-ldar =op-star =op-deir =op-deor
1429+ =op-addr =op-subr =op-mulr =op-divr
1430+ =op-andr =op-orar =op-eorr =op-sftr
1431+ =op-jsi =op-inc2r =op-pop2r =op-nip2r
1432+ =op-swp2r =op-rot2r =op-dup2r =op-ovr2r
1433+ =op-equ2r =op-neq2r =op-gth2r =op-lth2r
1434+ =op-jmp2r =op-jcn2r =op-jsr2r =op-sth2r
1435+ =op-ldz2r =op-stz2r =op-ldr2r =op-str2r
1436+ =op-lda2r =op-sta2r =op-dei2r =op-deo2r
1437+ =op-add2r =op-sub2r =op-mul2r =op-div2r
1438+ =op-and2r =op-ora2r =op-eor2r =op-sft2r
1439+ =op-lit =op-inck =op-popk =op-nipk
1440+ =op-swpk =op-rotk =op-dupk =op-ovrk
1441+ =op-equk =op-neqk =op-gthk =op-lthk
1442+ =op-jmpk =op-jcnk =op-jsrk =op-sthk
1443+ =op-ldzk =op-stzk =op-ldrk =op-strk
1444+ =op-ldak =op-stak =op-deik =op-deok
1445+ =op-addk =op-subk =op-mulk =op-divk
1446+ =op-andk =op-orak =op-eork =op-sftk
1447+ =op-lit2 =op-inc2k =op-pop2k =op-nip2k
1448+ =op-swp2k =op-rot2k =op-dup2k =op-ovr2k
1449+ =op-equ2k =op-neq2k =op-gth2k =op-lth2k
1450+ =op-jmp2k =op-jcn2k =op-jsr2k =op-sth2k
1451+ =op-ldz2k =op-stz2k =op-ldr2k =op-str2k
1452+ =op-lda2k =op-sta2k =op-dei2k =op-deo2k
1453+ =op-add2k =op-sub2k =op-mul2k =op-div2k
1454+ =op-and2k =op-ora2k =op-eor2k =op-sft2k
1455+ =op-litr =op-inckr =op-popkr =op-nipkr
1456+ =op-swpkr =op-rotkr =op-dupkr =op-ovrkr
1457+ =op-equkr =op-neqkr =op-gthkr =op-lthkr
1458+ =op-jmpkr =op-jcnkr =op-jsrkr =op-sthkr
1459+ =op-ldzkr =op-stzkr =op-ldrkr =op-strkr
1460+ =op-ldakr =op-stakr =op-deikr =op-deokr
1461+ =op-addkr =op-subkr =op-mulkr =op-divkr
1462+ =op-andkr =op-orakr =op-eorkr =op-sftkr
1463+ =op-lit2r =op-inc2kr =op-pop2kr =op-nip2kr
1464+ =op-swp2kr =op-rot2kr =op-dup2kr =op-ovr2kr
1465+ =op-equ2kr =op-neq2kr =op-gth2kr =op-lth2kr
1466+ =op-jmp2kr =op-jcn2kr =op-jsr2kr =op-sth2kr
1467+ =op-ldz2kr =op-stz2kr =op-ldr2kr =op-str2kr
1468+ =op-lda2kr =op-sta2kr =op-dei2kr =op-deo2kr
1469+ =op-add2kr =op-sub2kr =op-mul2kr =op-div2kr
1470+ =op-and2kr =op-ora2kr =op-eor2kr =op-sft2kr ] &lut-end
1471+
+604,
-0
1@@ -0,0 +1,604 @@
2+( 54K . Perifs
3+| Controller: Buttons should highlight on press and display the button and key bytes.
4+| Mouse: Buttons should highlight on press and display the x and y position. )
5+
6+|00 @System/vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1
7+|20 @Screen/vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
8+|80 @Controller/vector $2 &button $1 &key $1
9+|90 @Mouse/vector $2 &x $2 &y $2 &state $1 &pad $3 &scrollx $2 &scrolly $2
10+|c0 @DateTime/year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1
11+|0050 @Varvara/version
12+
13+|000
14+
15+ @center/x $2 &y $2
16+ @wheel/y $1 &y-lo $1
17+
18+|100
19+
20+@on-reset ( -> )
21+ ;meta #06 DEO2
22+ ( | Set size )
23+ #0180 .Screen/width DEO2
24+ #0180 .Screen/height DEO2
25+ ( | Theme )
26+ #0f0f .System/r DEO2
27+ #00ff .System/g DEO2
28+ #00ff .System/b DEO2
29+ ( | Wipe layers )
30+ #0000 DUP2 .Screen/x DEO2
31+ .Screen/y DEO2
32+ [ LIT2 80 -Screen/pixel ] DEO
33+ [ LIT2 c0 -Screen/pixel ] DEO
34+ ( | Blank vectors )
35+ #0000 #00 &l DEO2k #10 ADD DUP [ ?/l POP POP2 ]
36+ ( | Halt recover )
37+ [ LIT2 80 -System/halt ] DEO
38+ [ LIT2 01 -System/halt ] DEO
39+ [ LIT2 00 -System/halt ] DEO
40+ ( | Distant pixels )
41+ #8000 .Screen/x DEO2
42+ #8000 .Screen/y DEO2
43+ [ LIT2 00 -Screen/pixel ] DEO
44+ [ LIT2 40 -Screen/pixel ] DEO
45+ [ LIT2 80 -Screen/pixel ] DEO
46+ [ LIT2 c0 -Screen/pixel ] DEO
47+ [ LIT2 d0 -Screen/pixel ] DEO
48+ [ LIT2 e0 -Screen/pixel ] DEO
49+ [ LIT2 f0 -Screen/pixel ] DEO
50+ ( | Find center )
51+ .Screen/width DEI2 #01 SFT2 .center/x STZ2
52+ .Screen/height DEI2 #01 SFT2 .center/y STZ2
53+ controller/<draw>
54+ mouse/<draw>
55+ smile/<draw-all>
56+ ;controller/on-event .Controller/vector DEO2
57+ ;mouse/on-event .Mouse/vector DEO2
58+ ;fps/on-frame .Screen/vector DEO2
59+ BRK
60+
61+@meta 00 "Perifs 0a
62+ ( details ) "A 20 "Peripherals 20 "Test 0a
63+ ( author ) "By 20 "Hundred 20 "Rabbits 0a
64+ ( date ) "3 20 "Sep 20 "2026 00
65+ ( . ) 02
66+ ( - ) 56 =Varvara/version
67+ ( - ) 83 =appicon
68+
69+%Screen/<set-pos> ( x* y* -- ) {
70+ .Screen/y DEO2
71+ .Screen/x DEO2 }
72+
73+%Screen/<mod-x> ( x* -- ) {
74+ .Screen/x DEI2 ADD2 .Screen/x DEO2 }
75+
76+%Screen/<mod-y> ( x* -- ) {
77+ .Screen/y DEI2 ADD2 .Screen/y DEO2 }
78+
79+%Screen/<mod> ( x* y* -- ) {
80+ Screen/<mod-y>
81+ Screen/<mod-x> }
82+
83+%u8/mod ( a b -- res ) {
84+ DIVk MUL SUB }
85+
86+(
87+@|Controller )
88+
89+@controller/on-event ( -> )
90+ /<draw>
91+ ( | print stack on start button )
92+ [ LIT2 08 -Controller/button ] DEI
93+ ( | handlers )
94+ DUP ?{ smile/<next> }
95+ NEQ ?{ #010e DEO }
96+ BRK
97+
98+@controller/<draw> ( -- )
99+ .Controller/button DEI2
100+ ( | background )
101+ .center/x LDZ2 #0040 SUB2 .Screen/x DEO2
102+ .center/y LDZ2 #0040 SUB2 .Screen/y DEO2
103+ #03f9 ;&icns #f6 <draw-times>
104+ ( | output )
105+ #0010 #ffb0 Screen/<mod>
106+ DUP2 hex/<draw-short>
107+ ( | A button )
108+ OVR #01 AND #00 EQU ?{
109+ .center/x LDZ2 #0028 ADD2 .Screen/x DEO2
110+ .center/y LDZ2 #0020 SUB2 .Screen/y DEO2
111+ #03fe ;large/icns #16 <draw-times> }
112+ ( | B button )
113+ OVR #02 AND #00 EQU ?{
114+ .center/x LDZ2 #0010 ADD2 .Screen/x DEO2
115+ .center/y LDZ2 #0020 SUB2 .Screen/y DEO2
116+ #03fe ;large/icns #16 <draw-times> }
117+ ( | S button )
118+ OVR #04 AND #00 EQU ?{
119+ .center/x LDZ2 #0018 SUB2 .Screen/x DEO2
120+ .center/y LDZ2 #0018 SUB2 .Screen/y DEO2
121+ #03ff ;small/icn #16 <draw-times> }
122+ ( | Z button )
123+ OVR #08 AND #00 EQU ?{
124+ .center/x LDZ2 #0008 SUB2 .Screen/x DEO2
125+ .center/y LDZ2 #0018 SUB2 .Screen/y DEO2
126+ #03ff ;small/icn #16 <draw-times> }
127+ ( | Up arrow )
128+ OVR #10 AND #00 EQU ?{
129+ .center/x LDZ2 #0030 SUB2 .Screen/x DEO2
130+ .center/y LDZ2 #0028 SUB2 .Screen/y DEO2
131+ #0fff ;arrow/icn #00 <draw-times> }
132+ ( | Down arrow )
133+ OVR #20 AND #00 EQU ?{
134+ .center/x LDZ2 #0030 SUB2 .Screen/x DEO2
135+ .center/y LDZ2 #0018 SUB2 .Screen/y DEO2
136+ #0fff ;arrow/icn #00 <draw-times> }
137+ ( | Left arrow )
138+ OVR #40 AND #00 EQU ?{
139+ .center/x LDZ2 #0038 SUB2 .Screen/x DEO2
140+ .center/y LDZ2 #0020 SUB2 .Screen/y DEO2
141+ #0fff ;arrow/icn #00 <draw-times> }
142+ ( | Right arrow )
143+ OVR #80 AND #00 EQU ?{
144+ .center/x LDZ2 #0028 SUB2 .Screen/x DEO2
145+ .center/y LDZ2 #0020 SUB2 .Screen/y DEO2
146+ #0fff ;arrow/icn #00 <draw-times> }
147+ POP2 JMP2r
148+
149+(
150+@|Mouse )
151+
152+@mouse/on-event ( -> )
153+ [ LIT2 &last $1 -Mouse/state ] DEI DUP ,&last STR
154+ EQUk ?{
155+ DUP #00 EQU ?{ smile/<next> } }
156+ POP2 /<draw>
157+ /<draw-cursor>
158+ BRK
159+
160+@mouse/<draw-cursor> ( -- )
161+ [ LIT2 00 -Screen/auto ] DEO
162+ ;&cursor-icn .Screen/addr DEO2
163+ [ LIT2 &last-x $2 ] .Screen/x DEO2
164+ [ LIT2 &last-y $2 ] .Screen/y DEO2
165+ [ LIT2 40 -Screen/sprite ] DEO
166+ .Mouse/x DEI2 #0003 SUB2 DUP2 ,&last-x STR2
167+ .Screen/x DEO2
168+ .Mouse/y DEI2 #0003 SUB2 DUP2 ,&last-y STR2
169+ .Screen/y DEO2
170+ [ LIT2 43 -Screen/sprite ] DEO
171+ JMP2r
172+
173+@mouse/<draw> ( -- )
174+ .center/x LDZ2 #0040 SUB2 .Screen/x DEO2
175+ .center/y LDZ2 #0020 ADD2 .Screen/y DEO2
176+ #03fc ;&icns #f6 <draw-times>
177+ ( | output )
178+ #0010 #ffd0 Screen/<mod>
179+ [ LIT2 01 -Screen/auto ] DEO
180+ .Mouse/state DEI DUP hex/<draw-byte>
181+ ( | x )
182+ #0018 Screen/<mod-x>
183+ .Mouse/x DEI2 hex/<draw-short>
184+ ( | y )
185+ #0008 Screen/<mod-x>
186+ .Mouse/y DEI2 hex/<draw-short>
187+ ( | mouse 1 )
188+ DUP #01 AND #00 EQU ?{
189+ .center/x LDZ2 #0040 SUB2 .Screen/x DEO2
190+ .center/y LDZ2 #0022 ADD2 .Screen/y DEO2
191+ #0fff ;&tip-icn #16 <draw-times> }
192+ ( | mouse 2 )
193+ DUP #02 AND #00 EQU ?{
194+ .center/x LDZ2 #0028 SUB2 .Screen/x DEO2
195+ .center/y LDZ2 #0022 ADD2 .Screen/y DEO2
196+ #0fff ;small/icn #16 <draw-times> }
197+ ( | mouse 3 )
198+ DUP #04 AND #00 EQU ?{
199+ .center/x LDZ2 #0018 SUB2 .Screen/x DEO2
200+ .center/y LDZ2 #0022 ADD2 .Screen/y DEO2
201+ #0fff ;small/icn #16 <draw-times> }
202+ POP !wheel/<redraw>
203+
204+@wheel/<redraw> ( -- )
205+ .center/x LDZ2 #0047 ADD2 .Screen/x DEO2
206+ .center/y LDZ2 #0010 ADD2 .Screen/y DEO2
207+ [ LIT2 01 -Screen/auto ] DEO
208+ .&y-lo LDZ hex/<draw-byte>
209+ ( | wheel )
210+ .center/x LDZ2 #0048 ADD2 .Screen/x DEO2
211+ .center/y LDZ2 #0020 ADD2 .Screen/y DEO2
212+ #03ff ;&icns #16 <draw-times>
213+ #03ff ;&icns2 #16 <draw-times>
214+ .&y LDZ2k .Mouse/scrolly DEI2 ADD2 ROT STZ2
215+ .&y LDZ2 DUP2 #0010 ADD2 /offset
216+ ( >> )
217+ &offset ( wheelpos* -- )
218+ DUP2 #001f AND2 .center/x LDZ2 #0048 ADD2 /load .Screen/x DEO2
219+ #0018 ADD2 #001f AND2 .center/y LDZ2 #0020 ADD2 /load .Screen/y DEO2
220+ [ LIT2 03 -Screen/pixel ] DEO
221+ JMP2r
222+
223+ &load ( offset* base* -- coord* )
224+ SWP2 ;&offsets ADD2 LDA #00 SWP ADD2 JMP2r
225+
226+(
227+@|Smile )
228+
229+@smile/<next> ( -- )
230+ [ LIT &ptr $1 ] INCk ,&ptr STR
231+ [ LIT2 00 -Screen/auto ] DEO
232+ #0a u8/mod
233+ ( | draw )
234+ #0028 .Screen/x DEO2
235+ .Screen/height DEI2 #0018 SUB2 .Screen/y DEO2
236+ DUP hex/<draw-byte>
237+ /<clear>
238+ #00 SWP DUP ADD ;&lut ADD2 LDA2 JMP2
239+
240+@smile/<draw-all> ( -- )
241+ ;&lut-end ;&lut
242+ &>l
243+ /<clear>
244+ LDA2k JSR2 INC2 INC2 GTH2k ?/>l
245+ POP2 POP2 JMP2r
246+
247+@smile/<set-pos> ( -- )
248+ #0010 .Screen/height DEI2 #0020 SUB2 Screen/<set-pos>
249+ JMP2r
250+
251+@smile/<clear> ( -- )
252+ [ LIT2 11 -Screen/auto ] DEO
253+ ( | bg )
254+ /<set-pos>
255+ ;hash .Screen/addr DEO2
256+ [ LIT2 03 -Screen/sprite ] DEOk DEO
257+ ( | fg )
258+ /<set-pos>
259+ ;fill .Screen/addr DEO2
260+ [ LIT2 40 -Screen/sprite ] DEOk DEO
261+ JMP2r
262+
263+@smile/<draw-0> ( Draw 1bpp four times by moving x,y )
264+ /<set-pos>
265+ [ LIT2 00 -Screen/auto ] DEO
266+ ( a ) ;&hor-a .Screen/addr DEO2
267+ [ LIT2 03 -Screen/sprite ] DEO
268+ #0008 Screen/<mod-x>
269+ ( b ) ;&hor-b .Screen/addr DEO2
270+ [ LIT2 03 -Screen/sprite ] DEO
271+ #fff8 #0008 Screen/<mod>
272+ ( c ) ;&hor-c .Screen/addr DEO2
273+ [ LIT2 03 -Screen/sprite ] DEO
274+ #0008 #0000 Screen/<mod>
275+ ( d ) ;&hor-d .Screen/addr DEO2
276+ [ LIT2 03 -Screen/sprite ] DEO
277+ JMP2r
278+
279+@smile/<draw-1> ( Draw 1bpp two times using addr-y )
280+ /<set-pos>
281+ [ LIT2 16 -Screen/auto ] DEO
282+ ;&hor .Screen/addr DEO2
283+ [ LIT2 03 -Screen/sprite ] DEOk DEO
284+ JMP2r
285+
286+@smile/<draw-2> ( Draw 1bpp two times using addr-x )
287+ /<set-pos>
288+ [ LIT2 15 -Screen/auto ] DEO
289+ ;&ver .Screen/addr DEO2
290+ [ LIT2 03 -Screen/sprite ] DEOk DEO
291+ JMP2r
292+
293+@smile/<draw-3> ( Draw 1bpp-flipx two times using addr-y )
294+ /<set-pos>
295+ #0008 #0000 Screen/<mod>
296+ [ LIT2 16 -Screen/auto ] DEO
297+ ;&horx .Screen/addr DEO2
298+ [ LIT2 13 -Screen/sprite ] DEOk DEO
299+ JMP2r
300+
301+@smile/<draw-4> ( Draw 1bpp-flipy two times using addr-x )
302+ /<set-pos>
303+ #0000 #0008 Screen/<mod>
304+ [ LIT2 15 -Screen/auto ] DEO
305+ ;&very .Screen/addr DEO2
306+ [ LIT2 23 -Screen/sprite ] DEOk DEO
307+ JMP2r
308+
309+@smile/<draw-5> ( Draw 2bpp two times using addr-x )
310+ /<set-pos>
311+ [ LIT2 15 -Screen/auto ] DEO
312+ ;&2bpp .Screen/addr DEO2
313+ [ LIT2 81 -Screen/sprite ] DEOk DEO
314+ JMP2r
315+
316+@smile/<draw-6> ( Draw 1bpp, once for the outline, once for the face )
317+ /<set-pos>
318+ [ LIT2 16 -Screen/auto ] DEO
319+ ;&outline .Screen/addr DEO2
320+ [ LIT2 03 -Screen/sprite ] DEOk DEO
321+ #0000 #fff0 Screen/<mod>
322+ ;&face .Screen/addr DEO2
323+ [ LIT2 0f -Screen/sprite ] DEOk DEO
324+ JMP2r
325+
326+@smile/<draw-7> ( Draw 1bpp, once for the outline, once for the face in fg )
327+ /<set-pos>
328+ [ LIT2 16 -Screen/auto ] DEO
329+ ;&outline .Screen/addr DEO2
330+ [ LIT2 03 -Screen/sprite ] DEOk DEO
331+ #0000 #fff0 Screen/<mod>
332+ ;&face .Screen/addr DEO2
333+ [ LIT2 43 -Screen/sprite ] DEOk DEO
334+ JMP2r
335+
336+@smile/<draw-8> ( Draw using pixels )
337+ /<set-pos>
338+ ;&hor-a icn/<draw-tile>
339+ #0008 #fff8 Screen/<mod>
340+ ;&hor-b icn/<draw-tile>
341+ #fff8 #0000 Screen/<mod>
342+ ;&hor-c icn/<draw-tile>
343+ #0008 #fff8 Screen/<mod>
344+ ;&hor-d !icn/<draw-tile>
345+
346+@smile/<draw-9> ( Draw offscreen origin )
347+ /<set-pos>
348+ .Screen/x DEI2 #0030 SUB2 .Screen/x DEO2
349+ ;&offscreen .Screen/addr DEO2
350+ [ LIT2 76 -Screen/auto ] DEO
351+ [ LIT2 03 -Screen/sprite ] DEOk DEO
352+ JMP2r
353+
354+(
355+@|Fps )
356+
357+@fps/on-frame ( -> )
358+ [ LIT &f $1 ] INCk ,&f STR
359+ [ LIT2 &t $1 -DateTime/second ] DEI DUP ,&t STR
360+ EQU ?{
361+ INCk /<redraw>
362+ [ LIT2 00 _&f ] STR }
363+ POP BRK
364+
365+@fps/<redraw> ( update -- )
366+ DUP [ LIT &last $1 ] NEQ ?{ POP JMP2r }
367+ DUP ,&last STR
368+ [ LIT2 01 -Screen/auto ] DEO
369+ #0010 .Screen/height DEI2 #0030 SUB2 Screen/<set-pos> !dec/<draw-10>
370+
371+(
372+@|Icn )
373+
374+@icn/<draw-tile> ( addr* -- )
375+ [ LIT2 01 -Screen/auto ] DEO
376+ DUP2 #0008 ADD2 SWP2
377+ &>v
378+ LDAk /<draw-row>
379+ #fff8 #0001 Screen/<mod>
380+ INC2 GTH2k ?/>v
381+ POP2 POP2 JMP2r
382+
383+@icn/<draw-row> ( byte -- )
384+ STH
385+ #ff07
386+ &>h
387+ STHkr OVR SFT #01 AND #03 MUL .Screen/pixel DEO
388+ #01 SUB NEQk ?/>h
389+ POP2 POPr JMP2r
390+
391+(
392+@|Generics )
393+
394+@<draw-times> ( color times addr* auto -- )
395+ .Screen/auto DEO
396+ .Screen/addr DEO2
397+ SWP STH
398+ [ LITr -Screen/sprite ]
399+ &>l
400+ DEOkr
401+ INC DUP ?/>l
402+ POP POP2r JMP2r
403+
404+@dec/<draw-10> ( byte -- )
405+ DUP #0a DIV chr/<draw-num>
406+ #0a u8/mod !chr/<draw-num>
407+
408+@hex/<draw-short> ( short* -- )
409+ [ LIT2 01 -Screen/auto ] DEO
410+ SWP /<draw-byte>
411+ ( >> )
412+
413+@hex/<draw-byte> ( byte -- )
414+ DUP #04 SFT chr/<draw-num>
415+ ( >> )
416+
417+@chr/<draw-num> ( char -- )
418+ #00 SWP #0f AND #30 SFT2 ;&icns ADD2 .Screen/addr DEO2
419+ [ LIT2 03 -Screen/sprite ] DEO
420+ JMP2r
421+
422+(
423+@|Assets )
424+
425+@smile/lut [3
426+ =/<draw-0> =/<draw-1> =/<draw-2>
427+ =/<draw-3> =/<draw-4> =/<draw-5>
428+ =/<draw-6> =/<draw-7> =/<draw-8>
429+ =/<draw-9> ] &lut-end
430+
431+@hash [ aa55 aa55 aa55 aa55 ]
432+
433+@fill [ ffff ffff ffff ffff ]
434+
435+@appicon [8
436+ 0000 0000 0000 0102 0000 0000 0000 0001
437+ 0000 0000 3cc3 0000 0000 0000 003c ffff
438+ 0000 0000 0000 8040 0000 0000 0000 0080
439+ 0404 0809 0808 0404 0303 0706 0707 0303
440+ 0000 81c3 8100 423c ffff 7ebc 7eff bdc3
441+ 2020 1090 1010 2020 c0c0 e060 e0e0 c0c0
442+ 0201 0000 0000 0000 0100 0000 0000 0000
443+ 0000 c33c 0000 0000 ffff 3c00 0000 0000
444+ 4080 0000 0000 0000 8000 0000 0000 0000 ]
445+
446+@wheel/offsets [
447+ 07 08 09 0a 0b 0b 0c 0c 0c 0c 0c 0b 0b 0a 09 08
448+ 07 06 05 04 03 03 02 02 02 02 02 03 03 04 05 06 ]
449+ &icns [ 0718 2040 4080 8081 c030 0804 0402 0202 ]
450+ &icns2 [ 8080 4040 2018 0700 0202 0404 0830 c000 ]
451+
452+@arrow/icn [ 187e 7eff ff7e 7e18 ]
453+
454+@small/icn [ 0000 001f 3f3f 3f1f 0000 00f8 fcfc fcf8 ]
455+
456+@large/icns [8
457+ 071f 3f7f 7fff ffff e0f8 fcfe feff ffff
458+ ffff ff7f 7f3f 1f07 ffff fffe fefc f8e0 ]
459+
460+@controller/icns [8
461+ 0000 0f30 4040 8080 0000 ff00 0000 0000
462+ 0042 8100 0000 0000 0000 ff00 0000 0000
463+ 0000 ff00 0000 0000 0000 ff00 0000 0000
464+ 0000 ff00 0000 0000 0000 ff00 0000 0000
465+ 0000 ff00 0000 0000 0000 ff00 0000 0000
466+ 0000 ff00 0000 0000 0000 ff00 0000 0000
467+ 0000 ff00 0000 0000 0000 ff00 0000 0000
468+ 0000 ff00 0000 0000 0000 f00c 0202 0101
469+ 8080 8080 8080 8080 0000 0000 0000 0000
470+ 0000 0000 0000 0000 0000 0000 0000 0000
471+ 0000 0000 0000 0000 0000 0000 0000 0000
472+ 0000 0000 0000 0000 0000 0000 0000 0000
473+ 0000 0000 0000 0000 0000 0000 0000 0000
474+ 0000 0000 0000 0000 0000 0000 0000 0000
475+ 0000 0000 0000 0000 0000 0000 0000 0000
476+ 0000 0000 0000 0000 0101 0101 0101 0101
477+ 8080 8080 8080 8080 0000 0000 0000 0000
478+ 0000 0000 0000 0018 0000 0000 0000 0000
479+ 0000 0000 0000 0000 0000 0000 0000 0000
480+ 0000 0000 0000 0000 0000 0000 0000 0000
481+ 0000 0000 0000 0000 0000 0000 0000 0000
482+ 0000 0000 0000 0302 0000 0000 0000 8040
483+ 0000 0000 0000 0000 0000 0000 0000 0102
484+ 0000 0000 0000 8040 0101 0101 0101 0101
485+ 8080 8080 8080 8080 0000 0001 0101 011f
486+ 6681 8100 0000 0000 0000 0080 8080 80f8
487+ 0000 0000 0000 0000 0000 0000 0000 0000
488+ 0000 0000 0000 0000 0000 0000 0000 0000
489+ 0000 0000 0000 0000 0000 0000 0000 0000
490+ 0203 0202 0300 0000 4080 4040 8000 0000
491+ 0000 0000 0000 0000 0203 0202 0200 0000
492+ 40c0 4040 4000 0000 0101 0101 0101 0101
493+ 8080 8081 8180 8080 6080 8000 0080 8060
494+ 0000 0000 0000 0000 0601 0100 0001 0106
495+ 0000 0080 8000 0000 0001 0202 0100 0201
496+ 0080 4000 8040 4080 0003 0000 0102 0203
497+ 00c0 4040 8000 00c0 0000 0000 0000 0000
498+ 0718 2040 4080 8080 e018 0402 0201 0101
499+ 0000 0000 0000 0000 0718 2040 4080 8080
500+ e018 0402 0201 0101 0101 0101 0101 0101
501+ 8080 8080 8080 8080 1f01 0101 0100 0000
502+ 0000 0000 0081 8166 f880 8080 8000 0000
503+ 0000 0000 0000 0000 0000 001f 2020 201f
504+ 0000 00f8 0404 04f8 0000 001f 2020 201f
505+ 0000 00f8 0404 04f8 0000 0000 0000 0000
506+ 8080 8040 4020 1807 0101 0102 0204 18e0
507+ 0000 0000 0000 0000 8080 8040 4020 1807
508+ 0101 0102 0204 18e0 0101 0101 0101 0101
509+ 8080 8080 4040 300f 0000 0000 0000 00ff
510+ 1800 0000 0000 00ff 0000 0000 0000 00ff
511+ 0000 0000 0000 00ff 0000 0000 0000 00ff
512+ 0000 0000 0000 00ff 0000 0000 0000 00ff
513+ 0000 0000 0000 00ff 0000 0000 0000 00ff
514+ 0000 0000 0000 00ff 0000 0000 0000 00ff
515+ 0000 0000 0000 00ff 0000 0000 0000 00ff
516+ 0000 0000 0000 00ff 0101 0101 0202 0cf0 ]
517+
518+@mouse/icns [8
519+ 0000 0001 0618 6482 0718 6080 0000 0000
520+ e01f 0000 0000 0000 00c0 3f00 001f 2020
521+ 0000 ff00 00f8 0404 0000 ff00 001f 2020
522+ 0000 ff00 00f8 0404 0000 ff00 0000 0000
523+ 0000 ff00 0000 0000 0000 ff00 0000 0000
524+ 0000 ff00 0000 0000 0000 ff00 0000 0000
525+ 0000 ff00 0000 0000 0000 ff00 0000 0000
526+ 0000 ff00 0000 0000 0000 c03e 0101 0101
527+ 6418 0601 0000 0000 0000 0080 6018 0700
528+ 0000 0000 001f e000 201f 0000 3fc0 0000
529+ 04f8 0000 ff00 0000 201f 0000 ff00 0000
530+ 04f8 0000 ff00 0000 0000 0000 ff00 0000
531+ 0000 0000 ff00 0000 0000 0000 ff00 0000
532+ 0000 0000 ff00 0000 0000 0000 ff00 0000
533+ 0000 0000 ff00 0000 0000 0000 ff00 0000
534+ 0000 0000 ff00 0000 0101 013e c000 0000
535+ 0000 6090 90f0 9090 0000 0000 0000 0000
536+ 0000 0000 0000 0000 0000 0302 0203 0202
537+ 0000 8040 4080 4040 0000 0102 0202 0202
538+ 0000 8040 0000 0040 0000 0000 0000 0000
539+ 0000 0000 0000 0000 0000 0000 0000 0000
540+ 0000 0000 0000 0000 0000 0000 0000 0000
541+ 0000 0000 0000 0000 0000 0000 0000 0000
542+ 0000 0000 0000 0000 0000 0000 0000 0000
543+ 9000 0000 0000 0000 0000 0000 0000 0000
544+ 0000 0000 0000 0000 0300 0000 0000 0000
545+ 8000 0000 0000 0000 0100 0000 0000 0000
546+ 8000 0000 0000 0000 0000 0000 0000 0000
547+ 0000 0000 0000 0000 0000 0000 0000 0000
548+ 0000 0000 0000 0000 0000 0000 0000 0000
549+ 0000 0000 0000 0000 0000 0000 0000 0000
550+ 0000 0000 0000 0000 0000 0000 0000 0000 ]
551+ &tip-icn [ 0000 0000 187c 1800 $8 ]
552+ &cursor-icn [ 1010 10ee 1010 1000 ]
553+
554+@chr/icns [8
555+ 0018 2424 2424 2418 0008 1808 0808 0808
556+ 0018 2404 1820 203c 0018 2404 1804 2418
557+ 0024 2424 1c04 0404 003c 2020 1804 2418
558+ 0018 2420 3824 2418 003c 0408 1010 1010
559+ 0018 2424 1824 2418 0018 2424 1c04 2418
560+ 0018 2424 3c24 2424 0038 2424 3824 2438
561+ 0018 2420 2020 2418 0038 2424 2424 2438
562+ 001c 2020 3820 201c 001c 2020 3820 2020 ]
563+
564+@smile/hor
565+ &hor-a [ 030c 1020 4040 889c ]
566+ &hor-b [ c030 0804 0202 1129 ]
567+ &hor-c [ 8880 4443 2010 0c03 ]
568+ &hor-d [ 1101 22c2 0408 30c0 ]
569+
570+@smile/horx [8
571+ 030c 1020 4040 8894 c030 0804 0202 1139
572+ 8880 4443 2010 0c03 1101 22c2 0408 30c0 ]
573+
574+@smile/very [8
575+ 030c 1020 4344 8088 9c88 4040 2010 0c03
576+ c030 0804 c222 0111 2911 0202 0408 30c0 ]
577+
578+@smile/ver [8
579+ 030c 1020 4040 889c 8880 4443 2010 0c03
580+ c030 0804 0202 1129 1101 22c2 0408 30c0 ]
581+
582+@smile/2bpp [8
583+ 030c 1020 4040 889c 030c 1020 4040 889c
584+ 8880 4443 2010 0c03 8880 4443 2010 0c03
585+ c030 0804 0202 1129 c030 0804 0202 1129
586+ 1101 22c2 0408 30c0 1101 22c2 0408 30c0 ]
587+
588+@smile/outline [8
589+ 030c 1020 4040 8080 c030 0804 0202 0101
590+ 8080 4040 2010 0c03 0101 0202 0408 30c0 ]
591+
592+@smile/face [8
593+ 0000 0000 0000 081c 0000 0000 0000 1028
594+ 0800 0403 0000 0000 1000 20c0 0000 0000 ]
595+
596+@smile/offscreen [8
597+ aa55 aa55 aa55 aa55 0000 0000 0000 0000
598+ 0000 0000 0000 0000 0000 0000 0000 0000
599+ 0000 0000 0000 0000 0000 0000 0000 0000
600+ 030c 1020 4040 889c c030 0804 0202 1129
601+ aa55 aa55 aa55 aa55 0000 0000 0000 0000
602+ 0000 0000 0000 0000 0000 0000 0000 0000
603+ 0000 0000 0000 0000 0000 0000 0000 0000
604+ 8880 4443 2010 0c03 1101 22c2 0408 30c0 ]
605+
+152,
-0
1@@ -0,0 +1,152 @@
2+( All five portraits should look right )
3+
4+|00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1
5+|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
6+
7+|0100
8+ ( | size )
9+ #00a0 .Screen/width DEO2
10+ #0020 .Screen/height DEO2
11+ ( | theme )
12+ #05ae .System/r DEO2
13+ #0a9f .System/g DEO2
14+ #097f .System/b DEO2
15+ ( | normal horizontal )
16+ #0000 .Screen/x DEO2
17+ #0000 .Screen/y DEO2
18+ [ LIT2 35 -Screen/auto ] DEO
19+ ;img-hor .Screen/addr DEO2
20+ #85 <draw-4times>
21+ ( | normal vertical )
22+ #0020 .Screen/x DEO2
23+ #0000 .Screen/y DEO2
24+ [ LIT2 36 -Screen/auto ] DEO
25+ ;img-ver .Screen/addr DEO2
26+ #85 <draw-4times>
27+ ( | flipped horizontal )
28+ #0058 .Screen/x DEO2
29+ #0000 .Screen/y DEO2
30+ [ LIT2 36 -Screen/auto ] DEO
31+ ;img-x-flipped .Screen/addr DEO2
32+ #95 <draw-4times>
33+ ( | flipped vertical )
34+ #0060 .Screen/x DEO2
35+ #0018 .Screen/y DEO2
36+ [ LIT2 36 -Screen/auto ] DEO
37+ ;img-y-flipped .Screen/addr DEO2
38+ #a5 <draw-4times>
39+ ( | flipped horizontal/vertical )
40+ #0098 .Screen/x DEO2
41+ #0018 .Screen/y DEO2
42+ [ LIT2 36 -Screen/auto ] DEO
43+ ;img-xy-flipped .Screen/addr DEO2
44+ #b5 <draw-4times>
45+ BRK
46+
47+@<draw-4times> ( color -- )
48+ .Screen/sprite DEOk DEOk DEOk DEO
49+ JMP2r
50+
51+@draw-fast ( w h addr* color -- )
52+ ,&color STR
53+ .Screen/addr DEO2
54+ SWP #01 SUB #40 SFT #06 ORA .Screen/auto DEO
55+ #00 SWP SUB
56+ × ( -- )
57+ [ LIT2 &color $1 -Screen/sprite ] DEO
58+ INC DUP ?×
59+ POP JMP2r
60+
61+(
62+@|assets )
63+
64+@img-ver [
65+ 0000 0008 0404 0501 ffff fff7 fbfa f9f9
66+ 0000 1000 21ff ffff ffff efde 21ff ffff
67+ 2020 0060 f8ff fffc dfdf 9f67 f8ff fffc
68+ 0703 2110 0888 c851 e7fb ddee 76b6 d64d
69+ 0307 0617 172f 080c fbf7 f6e5 e7cf e8ec
70+ ffef 1fff ff1f 0f37 f7ef 1fff 8f07 0733
71+ fbff ffff fcf8 f3f7 fbf7 fff8 f0f0 f1f1
72+ d3d7 c783 0100 0040 8bc7 d79b 1d3e 3e5e
73+ 0e06 0301 0101 0505 eef6 fbfd fdfd f9f9
74+ 7bfb 3fff ffff ffff 3b3b 3fff ffff ffff
75+ f7f7 f7ff fff7 fffb f3ff fff3 fbff ffe3
76+ c0e0 e0e4 e5e3 c7cf feee eeea e9eb f7cf
77+ 3800 0103 c7ff ffff c6fe fd3b c7ff ffff
78+ ff7f 3f0f a0b8 bebf ff7f 3f5f b1bf bfbf
79+ dfbf fefd fb07 0fdf c387 fefd fb07 efdf
80+ bf7f ffff ffff ffff bf7f ffff ffff ffff ]
81+
82+@img-hor [
83+ 0000 0008 0404 0501 ffff fff7 fbfa f9f9
84+ 0307 0617 172f 080c fbf7 f6e5 e7cf e8ec
85+ 0e06 0301 0101 0505 eef6 fbfd fdfd f9f9
86+ 3800 0103 c7ff ffff c6fe fd3b c7ff ffff
87+ 0000 1000 21ff ffff ffff efde 21ff ffff
88+ ffef 1fff ff1f 0f37 f7ef 1fff 8f07 0733
89+ 7bfb 3fff ffff ffff 3b3b 3fff ffff ffff
90+ ff7f 3f0f a0b8 bebf ff7f 3f5f b1bf bfbf
91+ 2020 0060 f8ff fffc dfdf 9f67 f8ff fffc
92+ fbff ffff fcf8 f3f7 fbf7 fff8 f0f0 f1f1
93+ f7f7 f7ff fff7 fffb f3ff fff3 fbff ffe3
94+ dfbf fefd fb07 0fdf c387 fefd fb07 efdf
95+ 0703 2110 0888 c851 e7fb ddee 76b6 d64d
96+ d3d7 c783 0100 0040 8bc7 d79b 1d3e 3e5e
97+ c0e0 e0e4 e5e3 c7cf feee eeea e9eb f7cf
98+ bf7f ffff ffff ffff bf7f ffff ffff ffff ]
99+
100+@img-x-flipped [
101+ e0c0 8408 1011 138a e7df bb77 6e6d 6bb2
102+ 0404 0006 1fff ff3f fbfb f9e6 1fff ff3f
103+ 0000 0800 84ff ffff ffff f77b 84ff ffff
104+ 0000 0010 2020 a080 ffff ffef df5f 9f9f
105+ cbeb e3c1 8000 0002 d1e3 ebd9 b87c 7c7a
106+ dfff ffff 3f1f cfef dfef ff1f 0f0f 8f8f
107+ fff7 f8ff fff8 f0ec eff7 f8ff f1e0 e0cc
108+ c0e0 60e8 e8f4 1030 dfef 6fa7 e7f3 1737
109+ 0307 0727 a7c7 e3f3 7f77 7757 97d7 eff3
110+ efef efff ffef ffdf cfff ffcf dfff ffc7
111+ dedf fcff ffff ffff dcdc fcff ffff ffff
112+ 7060 c080 8080 a0a0 776f dfbf bfbf 9f9f
113+ fdfe ffff ffff ffff fdfe ffff ffff ffff
114+ fbfd 7fbf dfe0 f0fb c3e1 7fbf dfe0 f7fb
115+ fffe fcf0 051d 7dfd fffe fcfa 8dfd fdfd
116+ 1c00 80c0 e3ff ffff 637f bfdc e3ff ffff ]
117+
118+@img-y-flipped [
119+ ffff ffc7 0301 0038 ffff ffc7 3bfd fec6
120+ bfbe b8a0 0f3f 7fff bfbf bfb1 5f3f 7fff
121+ df0f 07fb fdfe bfdf dfef 07fb fdfe 87c3
122+ ffff ffff ffff 7fbf ffff ffff ffff 7fbf
123+ 0505 0101 0103 060e f9f9 fdfd fdfb f6ee
124+ ffff ffff ff3f fb7b ffff ffff ff3f 3b3b
125+ fbff f7ff fff7 f7f7 e3ff fffb f3ff fff3
126+ cfc7 e3e5 e4e0 e0c0 cff7 ebe9 eaee eefe
127+ 0c08 2f17 1706 0703 ece8 cfe7 e5f6 f7fb
128+ 370f 1fff ff1f efff 3307 078f ff1f eff7
129+ f7f3 f8fc ffff fffb f1f1 f0f0 f8ff f7fb
130+ 4000 0001 83c7 d7d3 5e3e 3e1d 9bd7 c78b
131+ 0105 0404 0800 0000 f9f9 fafb f7ff ffff
132+ ffff ff21 0010 0000 ffff ff21 deef ffff
133+ fcff fff8 6000 2020 fcff fff8 679f dfdf
134+ 51c8 8808 1021 0307 4dd6 b676 eedd fbe7 ]
135+
136+@img-xy-flipped [
137+ ffff ffff ffff fefd ffff ffff ffff fefd
138+ fbf0 e0df bf7f fdfb fbf7 e0df bf7f e1c3
139+ fd7d 1d05 f0fc feff fdfd fd8d fafc feff
140+ ffff ffe3 c080 001c ffff ffe3 dcbf 7f63
141+ f3e3 c7a7 2707 0703 f3ef d797 5777 777f
142+ dfff efff ffef efef c7ff ffdf cfff ffcf
143+ ffff ffff fffc dfde ffff ffff fffc dcdc
144+ a0a0 8080 80c0 6070 9f9f bfbf bfdf 6f77
145+ 0200 0080 c1e3 ebcb 7a7c 7cb8 d9eb e3d1
146+ efcf 1f3f ffff ffdf 8f8f 0f0f 1fff efdf
147+ ecf0 f8ff fff8 f7ff cce0 e0f1 fff8 f7ef
148+ 3010 f4e8 e860 e0c0 3717 f3e7 a76f efdf
149+ 8a13 1110 0884 c0e0 b26b 6d6e 77bb dfe7
150+ 3fff ff1f 0600 0404 3fff ff1f e6f9 fbfb
151+ ffff ff84 0008 0000 ffff ff84 7bf7 ffff
152+ 80a0 2020 1000 0000 9f9f 5fdf efff ffff ]
153+
+260,
-0
1@@ -0,0 +1,260 @@
2+( )
3+
4+|00 @System &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1
5+|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
6+|80 @Controller &vector $2 &button $1 &key $1
7+|90 @Mouse &vector $2 &x $2 &y $2 &state $1 &pad $3 &scrollx $2 &scrolly $2
8+
9+|000
10+
11+ @position &x $2 &y $2
12+
13+|100
14+
15+@on-reset ( -> )
16+ #375e .System/r DEO2
17+ #286c .System/g DEO2
18+ #2358 .System/b DEO2
19+ ;on-mouse .Mouse/vector DEO2
20+ ;on-button .Controller/vector DEO2
21+ <draw-guide>
22+ #0028 #0028 <move>
23+ BRK
24+
25+@on-button ( -> )
26+ .Controller/button DEI
27+ ( | handlers )
28+ DUP #10 NEQ ?{
29+ .position/x LDZ2 .position/y LDZ2 #0004 SUB2 <move> }
30+ DUP #20 NEQ ?{
31+ .position/x LDZ2 .position/y LDZ2 #0004 ADD2 <move> }
32+ DUP #40 NEQ ?{
33+ .position/x LDZ2 #0004 SUB2 .position/y LDZ2 <move> }
34+ DUP #80 NEQ ?{
35+ .position/x LDZ2 #0004 ADD2 .position/y LDZ2 <move> }
36+ DUP #14 NEQ ?{
37+ .position/x LDZ2 .position/y LDZ2 #0040 SUB2 <move> }
38+ DUP #24 NEQ ?{
39+ .position/x LDZ2 .position/y LDZ2 #0040 ADD2 <move> }
40+ DUP #44 NEQ ?{
41+ .position/x LDZ2 #0040 SUB2 .position/y LDZ2 <move> }
42+ DUP #84 NEQ ?{
43+ .position/x LDZ2 #0040 ADD2 .position/y LDZ2 <move> }
44+ DUP #01 NEQ ?{ <toggle-size> }
45+ DUP #02 NEQ ?{ <toggle-theme> }
46+ DUP #08 NEQ ?{ <toggle-pos> }
47+ POP <draw-portraits>
48+ BRK
49+
50+@on-mouse ( -> )
51+ .Mouse/x DEI2 .Mouse/y DEI2 <move>
52+ BRK
53+
54+(
55+@|drawing )
56+
57+@<toggle-pos> ( -- )
58+ .position/x LDZ2 #8000 NEQ2 ?{ #0000 DUP2 !<move> }
59+ #8000 DUP2 !<move>
60+
61+@<toggle-size> ( -- )
62+ .Screen/width DEI2 #0200 EQU2 ?{
63+ #0200 .Screen/width DEO2
64+ #0200 .Screen/height DEO2
65+ <draw-guide> !<draw-portraits> }
66+ #0180 .Screen/width DEO2
67+ #0180 .Screen/height DEO2
68+ <draw-guide> !<draw-portraits>
69+
70+@<toggle-theme> ( -- )
71+ #ff00 .System/r DEI2 EQU2 ?{
72+ #ff00 .System/r DEO2
73+ #0ff0 .System/g DEO2
74+ #00ff .System/b DEO2
75+ JMP2r }
76+ #00ff .System/r DEO2
77+ #0ff0 .System/g DEO2
78+ #ff00 .System/b DEO2
79+ JMP2r
80+
81+@<move> ( x* y* -- )
82+ ( | clear )
83+ .position/x LDZ2 #0020 SUB2 .Screen/x DEO2
84+ .position/y LDZ2 #0020 SUB2 .Screen/y DEO2
85+ [ LIT2 71 -Screen/auto ] DEO
86+ ;fill-icn .Screen/addr DEO2
87+ #f8
88+ &>l
89+ #40 .Screen/sprite DEO
90+ INC DUP ?&>l
91+ POP OVR2 <phex>
92+ #2018 DEO
93+ DUP2 <phex>
94+ #0a18 DEO
95+ ( | update )
96+ .position/y STZ2
97+ .position/x STZ2
98+ ( >> )
99+
100+@<draw-portraits> ( -- )
101+ .position/x LDZ2 .Screen/x DEO2
102+ .position/y LDZ2 .Screen/y DEO2
103+ [ LIT2 36 -Screen/auto ] DEO
104+ .Mouse/state DEI .Controller/button DEI #0f AND ORA ?<draw-box>
105+ ( | top-left )
106+ .Screen/x DEI2k #0000 ADD2 ROT DEO2
107+ .Screen/y DEI2k #0020 SUB2 ROT DEO2
108+ #8140 ORA <draw-portrait>
109+ .Screen/x DEI2k #0008 SUB2 ROT DEO2
110+ .Screen/y DEI2k #0020 SUB2 ROT DEO2
111+ #9140 ORA <draw-portrait>
112+ .Screen/x DEI2k #0000 SUB2 ROT DEO2
113+ .Screen/y DEI2k #0018 ADD2 ROT DEO2
114+ #b140 ORA <draw-portrait>
115+ .Screen/x DEI2k #0008 ADD2 ROT DEO2
116+ .Screen/y DEI2k #0020 ADD2 ROT DEO2
117+ #a140 ORA <draw-portrait>
118+ ( | pixels )
119+ [ LIT2 00 -Screen/auto ] DEO
120+ .position/x LDZ2 .Screen/x DEO2
121+ .position/y LDZ2 .Screen/y DEO2
122+ #43 .Screen/pixel DEO
123+ .position/x LDZ2 #001f ADD2 .Screen/x DEO2
124+ .position/y LDZ2 #001f ADD2 .Screen/y DEO2
125+ #43 .Screen/pixel DEO
126+ .position/x LDZ2 #0020 SUB2 .Screen/x DEO2
127+ .position/y LDZ2 #0020 SUB2 .Screen/y DEO2
128+ #43 .Screen/pixel DEO
129+ JMP2r
130+
131+@<draw-portrait> ( color -- )
132+ ;portrait-chr .Screen/addr DEO2
133+ .Screen/sprite DEOk DEOk DEOk DEO
134+ JMP2r
135+
136+@<draw-box> ( -- )
137+ ( | top left )
138+ .Screen/x DEI2k #0020 SUB2 ROT DEO2
139+ .Screen/y DEI2k #0020 SUB2 ROT DEO2
140+ ;box-icn .Screen/addr DEO2
141+ #43 .Screen/sprite DEOk DEOk DEOk DEO
142+ ( | top right )
143+ .Screen/x DEI2k #0038 ADD2 ROT DEO2
144+ .Screen/y DEI2k #0020 SUB2 ROT DEO2
145+ ;box-icn .Screen/addr DEO2
146+ #53 .Screen/sprite DEOk DEOk DEOk DEO
147+ ( | bottom right )
148+ .Screen/x DEI2k #0000 ADD2 ROT DEO2
149+ .Screen/y DEI2k #0018 ADD2 ROT DEO2
150+ ;box-icn .Screen/addr DEO2
151+ #73 .Screen/sprite DEOk DEOk DEOk DEO
152+ ( | bottom left )
153+ .Screen/x DEI2k #0038 SUB2 ROT DEO2
154+ .Screen/y DEI2k #0020 ADD2 ROT DEO2
155+ ;box-icn .Screen/addr DEO2
156+ #63 .Screen/sprite DEOk DEOk DEOk DEO
157+ JMP2r
158+
159+@<draw-circle> ( color -- )
160+ [ LITr -Screen/x ] DEI2r ;circle-chr .Screen/addr DEO2
161+ DUP .Screen/sprite DEO
162+ DUP #10 ORA .Screen/sprite DEO
163+ .Screen/y DEI2k #0008 ADD2 ROT DEO2
164+ DUP #20 ORA .Screen/sprite DEO
165+ #30 ORA .Screen/sprite DEO
166+ .Screen/y DEI2k #0008 SUB2 ROT DEO2
167+ [ LIT2r 0010 ] ADD2r [ LITr -Screen/x ] DEO2r
168+ JMP2r
169+
170+@<draw-guide> ( -- )
171+ #0080 .Screen/x DEO2
172+ #0080 .Screen/y DEO2
173+ #82 .Screen/pixel DEO
174+ #93 .Screen/pixel DEO
175+ #a1 .Screen/pixel DEO
176+ #0008 DUP2 .Screen/x DEO2
177+ .Screen/y DEO2
178+ #e2 .Screen/auto DEO
179+ ;guide-icn .Screen/addr DEO2
180+ #0f00
181+ &>l
182+ #01 .Screen/sprite DEO
183+ INC GTHk ?&>l
184+ POP2
185+ ( | circles 1bpp )
186+ #0088 .Screen/x DEO2
187+ #0008 .Screen/y DEO2
188+ #01 .Screen/auto DEO
189+ #0f00
190+ &>ll
191+ DUP <draw-circle>
192+ INC GTHk ?&>ll
193+ POP2
194+ ( | circles 2bpp )
195+ #0088 .Screen/x DEO2
196+ #0018 .Screen/y DEO2
197+ #01 .Screen/auto DEO
198+ #0f00
199+ &>lll
200+ DUP #80 ORA <draw-circle>
201+ INC GTHk ?&>lll
202+ POP2 JMP2r
203+
204+@<update-cursor> ( color addr* -- )
205+ [ LIT2 00 -Screen/auto ] DEO
206+ ;fill-icn .Screen/addr DEO2
207+ #40 <draw-cursor>
208+ .Mouse/x DEI2 ,<draw-cursor>/x STR2
209+ .Mouse/y DEI2 ,<draw-cursor>/y STR2
210+ .Screen/addr DEO2
211+
212+@<draw-cursor> ( color -- )
213+ [ LIT2 &x $2 ] .Screen/x DEO2
214+ [ LIT2 &y $2 ] .Screen/y DEO2
215+ .Screen/sprite DEO
216+ JMP2r
217+
218+@<phex> ( short* -: )
219+ SWP /b
220+ &b ( byte -: )
221+ DUP #04 SFT /c
222+ &c ( byte -: )
223+ #0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD #18 DEO
224+ JMP2r
225+
226+@guide-icn [ 8000 0000 0000 0000 ]
227+
228+@fill-icn [ ffff ffff ffff ffff ]
229+
230+@cursor-icn [ 80c0 e0f0 f8e0 1000 ]
231+
232+@portrait-chr [
233+ 070f 1e1d 1b3b 3b3b f0e0 c0c0 d08b 8080
234+ f76f cf9f 9f5f 5f5f 0000 0007 1c40 4040
235+ fffb f975 7576 7667 0000 3164 0406 0607
236+ efef efef eddd 9e1e 0060 8000 0000 0000
237+ 3b2b 280d 0105 0506 8080 8081 e1f1 f1f0
238+ 5f6c 639b 0f27 77ab 4060 639b 0f27 67ab
239+ 0dc8 b0e5 cded fdfc 0dc8 b0e4 ccec fcfc
240+ 5e1e 1c9c 9d1d 5d59 4000 0080 8000 4040
241+ 0607 0707 070e 0e0e f0f0 f0f0 f0e0 e0e0
242+ fb73 7fb7 bbbf bfdd f373 7b37 3b3f 3f1c
243+ ffff ffff ffff ffff ffff ffff ffff ff7f
244+ dba7 97f7 f7ed dd9d c080 90f0 f0e0 c080
245+ 1e0e 0000 0000 0000 c0c0 f0ff ffff ffff
246+ ee03 0000 0000 0000 0e12 fcff ffff ffff
247+ fffc f30f 1f1f 1f3f 9f3c f30f dfdf dfbf
248+ 3c80 8080 80c0 c0e0 0003 3fbf bfbf dfef ]
249+
250+@box-icn [
251+ 0000 0000 0001 0204 0000 0f30 c000 0000
252+ 03fc 0000 0000 0000 ff00 0000 0000 0000
253+ 0808 1010 2020 2020 0000 0000 0000 0000
254+ 0000 0000 0000 0000 0000 0000 0000 0000
255+ 4040 4040 4040 8080 0000 0000 0000 0000
256+ 0000 0000 0000 0000 0000 0000 0000 0000
257+ 8080 8080 8080 8080 0000 0000 0000 0000
258+ 0000 0000 0000 0000 0000 0000 0000 0000 ]
259+
260+@circle-chr [ 071f 3c70 60e3 c7c7 0000 030f 1f1f 3f3f ]
261+
+128,
-0
1@@ -0,0 +1,128 @@
2+( Screen.pixel: test rom for screen pixel drawing )
3+
4+|00 @System/vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1
5+|20 @Screen/vector $2 &width $2 &height $2 &auto $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
6+
7+|000
8+
9+ @center &x $2 &y $2
10+
11+|100
12+
13+@on-reset ( -> )
14+ ( | theme )
15+ #f07f .System/r DEO2
16+ #f0d6 .System/g DEO2
17+ #f0b2 .System/b DEO2
18+ ( | resize )
19+ #00c8 DUP2 .Screen/width DEO2
20+ .Screen/height DEO2
21+ ( | find screen center )
22+ .Screen/width DEI2 #01 SFT2 .center/x STZ2
23+ .Screen/height DEI2 #01 SFT2 .center/y STZ2
24+ ( | draw )
25+ <draw-bg-fill>
26+ <draw-bg-corners>
27+ <draw-pixels>
28+ #01 .Screen/auto DEO
29+ <draw-default>
30+ <draw-fg-corners>
31+ <draw-default-flipx>
32+ BRK
33+
34+@<draw-bg-fill> ( -- )
35+ .center/x LDZ2 .Screen/x DEO2
36+ .center/y LDZ2 .Screen/y DEO2
37+ ( | 4-way backgrounds )
38+ #0400
39+ &>l
40+ DUP DUP #40 SFT #80 ADD ORA .Screen/pixel DEO
41+ INC GTHk ?&>l
42+ POP2 JMP2r
43+
44+@<draw-bg-corners> ( -- )
45+ .center/x LDZ2 #01 SFT2 .Screen/x DEO2
46+ .center/y LDZ2 #01 SFT2 .Screen/y DEO2
47+ #b0 .Screen/pixel DEO
48+ .center/x LDZ2 #01 SFT2 #0003 MUL2 .Screen/x DEO2
49+ .center/y LDZ2 #01 SFT2 .Screen/y DEO2
50+ #a1 .Screen/pixel DEO
51+ .center/x LDZ2 #01 SFT2 #0003 MUL2 .Screen/x DEO2
52+ .center/y LDZ2 #01 SFT2 #0003 MUL2 .Screen/y DEO2
53+ #83 .Screen/pixel DEO
54+ .center/x LDZ2 #01 SFT2 .Screen/x DEO2
55+ .center/y LDZ2 #01 SFT2 #0003 MUL2 .Screen/y DEO2
56+ #92 .Screen/pixel DEO
57+ JMP2r
58+
59+@<draw-fg-corners> ( -- )
60+ .center/x LDZ2 #02 SFT2 .Screen/x DEO2
61+ .center/y LDZ2 #02 SFT2 .Screen/y DEO2
62+ #f1 .Screen/pixel DEO
63+ .center/x LDZ2 #02 SFT2 #0007 MUL2 .Screen/x DEO2
64+ .center/y LDZ2 #02 SFT2 .Screen/y DEO2
65+ #e3 .Screen/pixel DEO
66+ ( clear ) #e0 .Screen/pixel DEO
67+ .center/x LDZ2 #02 SFT2 #0007 MUL2 .Screen/x DEO2
68+ .center/y LDZ2 #02 SFT2 #0007 MUL2 .Screen/y DEO2
69+ #c2 .Screen/pixel DEO
70+ .center/x LDZ2 #02 SFT2 .Screen/x DEO2
71+ .center/y LDZ2 #02 SFT2 #0007 MUL2 .Screen/y DEO2
72+ #d0 .Screen/pixel DEO
73+ JMP2r
74+
75+@<draw-pixels> ( -- )
76+ ( | bottom-left, background )
77+ .center/x LDZ2 #0010 SUB2 .Screen/x DEO2
78+ .center/y LDZ2 .Screen/y DEO2
79+ ( auto-x ) #01 .Screen/auto DEO
80+ #00
81+ &>bl
82+ #00 OVR EQU OVR #0f AND ORA ?{
83+ .center/x LDZ2 #0010 SUB2 .Screen/x DEO2
84+ .Screen/y DEI2k INC2 ROT DEO2 }
85+ DUP #04 SFT OVR #0f AND LTH INC .Screen/pixel DEO
86+ INC DUP ?&>bl
87+ POP
88+ ( | bottom-right, foreground )
89+ .center/x LDZ2 .Screen/x DEO2
90+ .center/y LDZ2 #0010 SUB2 .Screen/y DEO2
91+ ( auto-y ) #02 .Screen/auto DEO
92+ #00
93+ &>br
94+ #00 OVR EQU OVR #0f AND ORA ?{
95+ .center/y LDZ2 #0010 SUB2 .Screen/y DEO2
96+ .Screen/x DEI2k INC2 ROT DEO2 }
97+ DUP #04 SFT OVR #0f AND GTH INC #40 ORA .Screen/pixel DEO
98+ INC DUP ?&>br
99+ POP JMP2r
100+
101+
102+@<draw-default> ( -- )
103+ #0010 .Screen/x DEO2
104+ #0008 .Screen/y DEO2
105+ ;bike-bin/end ;bike-bin [ LIT2r 83 00 ]
106+ &>l
107+ LDAk #40 ORA .Screen/pixel DEO
108+ INCr NEQkr STHr ?{
109+ #0010 .Screen/x DEO2
110+ .Screen/y DEI2 INC2 .Screen/y DEO2
111+ POPr LITr 00 }
112+ INC2 GTH2k ?&>l
113+ POP2 POP2 POP2r JMP2r
114+
115+@<draw-default-flipx> ( -- )
116+ #0093 .Screen/x DEO2
117+ #0070 .Screen/y DEO2
118+ ;bike-bin/end ;bike-bin [ LIT2r 83 00 ]
119+ &>l
120+ LDAk #03 MUL #50 ORA .Screen/pixel DEO
121+ INCr NEQkr STHr ?{
122+ #0093 .Screen/x DEO2
123+ .Screen/y DEI2 INC2 .Screen/y DEO2
124+ POPr LITr 00 }
125+ INC2 GTH2k ?&>l
126+ POP2 POP2 POP2r JMP2r
127+
128+@bike-bin [
129+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 01 01 01 01 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 01 01 01 01 01 01 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 00 00 00 01 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 00 00 00 00 00 00 01 01 00 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 00 00 00 00 00 00 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 00 00 00 00 00 00 00 00 01 01 00 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 00 00 00 00 00 00 00 00 00 01 00 01 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 01 00 01 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 00 00 01 00 00 00 00 00 00 00 00 01 01 00 01 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00 01 00 00 00 00 00 00 01 01 01 00 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 01 00 00 01 00 00 00 01 01 01 00 00 01 01 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 01 00 00 00 01 01 01 01 01 01 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 01 01 00 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01 01 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 00 00 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 01 00 00 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 00 01 01 00 00 00 01 01 00 01 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 00 00 01 01 01 01 01 00 01 01 01 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00 01 01 01 00 00 00 01 01 00 01 00 01 01 00 01 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 01 01 01 01 01 01 00 01 00 00 00 00 00 00 00 00 00 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 00 00 00 00 01 01 01 01 01 01 01 01 01 00 00 00 00 01 01 01 01 01 01 01 01 01 00 01 01 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 01 00 01 01 01 01 00 01 00 01 01 01 01 01 01 01 01 01 01 00 00 00 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 01 01 01 00 01 01 01 01 01 00 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 01 00 01 01 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 01 01 01 01 01 01 00 00 00 00 01 00 00 00 00 00 01 01 01 01 01 01 01 00 01 01 01 00 01 00 00 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 01 00 00 01 00 01 01 01 01 00 00 00 00 00 01 00 00 00 00 01 01 01 01 01 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 01 01 01 01 00 00 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 01 01 01 01 00 00 01 01 01 01 00 00 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 01 01 01 01 00 01 01 01 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 00 00 01 01 01 01 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 01 01 01 01 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 01 01 00 01 01 00 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 01 01 01 01 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 01 01 01 00 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 01 01 01 01 00 01 00 00 00 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 01 00 00 01 01 01 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 00 01 01 01 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 01 01 01 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 01 01 01 00 00 01 01 00 00 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 01 00 00 01 01 01 01 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 01 01 01 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 01 01 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 01 00 00 00 01 01 01 01 01 00 00 01 00 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 01 00 00 01 01 01 00 01 01 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 01 01 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01 00 00 01 01 01 00 00 00 00 00 00 01 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 01 00 00 01 01 01 00 01 01 01 00 00 01 00 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 01 01 00 01 01 01 00 00 00 01 00 00 01 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 01 00 00 00 00 00 00 01 01 01 00 00 01 00 00 00 00 00 00 00 00 00 00 01 00 01 01 01 00 01 00 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 01 01 01 00 00 00 01 01 01 00 01 00 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 01 00 01 01 01 00 01 00 00 01 01 00 01 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 01 00 01 01 01 00 01 00 00 00 00 00 00 00 00 00 01 00 01 01 01 00 00 00 01 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 01 01 01 01 00 00 01 00 01 01 01 00 01 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 01 00 01 01 01 00 00 00 01 00 00 01 00 01 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 01 00 00 00 01 01 01 00 01 00 00 00 00 00 00 00 01 00 00 01 01 00 00 00 00 00 01 00 00 00 00 00 01 00 00 01 00 00 00 01 00 00 01 00 00 00 01 00 00 01 01 01 00 00 01 00 00 00 01 01 00 00 01 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 01 01 00 01 01 00 00 00 00 00 01 00 01 00 00 01 00 00 00 00 01 00 00 01 00 00 00 01 00 00 01 00 00 00 00 00 01 00 00 00 00 00 01 01 00 00 01 00 00 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 01 00 00 00 00 01 00 00 00 01 00 00 01 00 00 01 00 00 00 01 00 01 01 01 00 00 01 00 00 00 00 00 01 01 00 01 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 01 01 01 00 01 01 00 00 00 01 00 00 01 00 00 01 00 00 00 01 00 00 00 00 01 00 00 00 00 00 00 00 01 01 00 01 00 00 00 00 00 01 00 00 01 01 00 00 00 00 00 00 00 00 01 00 00 00 00 01 00 00 01 00 00 01 00 00 01 00 00 01 00 01 01 01 00 00 01 00 00 00 00 00 01 01 01 00 00 01 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 00 01 00 00 01 01 00 00 00 00 00 00 00 00 01 01 00 00 01 00 00 00 01 00 00 01 00 00 01 00 00 01 00 00 00 00 01 00 00 00 00 00 00 00 00 01 01 00 00 01 00 00 00 00 01 00 01 01 00 01 01 00 00 00 00 00 00 00 01 00 00 00 01 00 00 01 00 00 01 00 00 01 00 00 01 01 01 01 01 00 01 00 00 00 00 01 01 00 00 01 01 00 01 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 00 00 01 00 01 01 00 00 01 00 00 00 00 00 00 00 01 01 00 01 01 00 00 01 00 00 01 00 00 01 00 00 01 00 00 00 01 00 00 00 00 00 00 00 01 01 00 01 01 00 01 00 00 00 00 01 00 01 01 00 00 00 01 01 00 00 00 00 00 00 01 00 00 00 01 00 00 01 00 01 00 01 00 00 01 00 01 01 01 00 01 00 00 00 00 01 00 00 00 00 01 01 00 01 00 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 00 00 00 01 00 01 01 00 00 00 01 01 00 00 00 00 00 00 01 00 00 01 00 00 00 01 00 01 00 01 00 00 01 00 00 00 01 00 00 00 00 00 00 01 01 00 00 00 01 01 00 01 00 00 00 01 00 01 01 00 00 00 00 00 00 01 01 00 00 00 00 00 01 00 00 00 01 00 01 00 01 00 01 00 00 01 01 01 01 00 01 00 00 00 01 01 00 00 00 00 00 00 01 01 00 01 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 00 00 00 01 00 01 01 00 00 00 00 00 00 01 01 00 00 00 00 01 01 00 01 01 00 00 01 00 01 00 01 00 01 00 00 00 01 00 00 00 00 00 01 01 00 00 00 00 00 00 01 01 00 01 00 00 01 00 01 01 00 00 00 00 00 00 00 00 01 01 00 00 00 00 01 00 00 01 00 01 00 01 00 01 00 01 01 01 01 01 01 00 00 01 01 00 00 00 00 00 00 01 01 01 01 00 01 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 00 01 01 00 00 00 01 00 00 01 01 00 01 00 01 00 01 00 01 00 00 01 00 00 00 00 01 01 00 00 00 00 00 00 00 00 01 01 00 01 00 00 01 00 01 01 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 01 00 00 01 01 00 01 01 01 00 01 01 01 01 00 00 00 01 00 00 00 00 00 01 01 00 00 00 01 01 00 01 01 00 00 01 00 01 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 00 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 00 00 00 01 00 00 01 01 00 01 01 00 01 00 01 00 01 01 00 00 01 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 01 01 00 01 00 01 00 00 01 01 01 01 01 01 00 00 00 00 00 00 00 01 01 00 00 00 01 00 01 00 01 01 01 00 01 01 01 01 00 00 01 01 00 00 01 00 01 00 00 00 01 01 01 00 01 00 01 01 00 00 01 00 01 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 00 00 00 00 00 01 00 00 01 01 00 01 01 01 00 00 00 00 00 00 00 01 01 00 01 01 00 01 01 00 01 00 01 00 01 00 01 00 00 00 01 01 00 00 00 00 00 00 00 01 01 01 01 01 01 00 00 01 01 00 01 01 00 00 00 00 00 01 01 01 01 00 00 00 00 00 01 01 00 00 01 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 01 01 00 01 01 00 00 00 00 00 00 00 00 00 01 00 01 01 00 00 00 00 00 01 01 01 01 00 00 00 00 00 01 01 01 01 00 01 01 01 01 01 01 00 01 00 00 01 01 00 00 00 00 00 01 01 01 01 00 00 00 00 00 01 01 00 01 01 00 01 01 00 00 00 00 00 00 00 00 00 01 01 01 01 00 00 00 01 01 00 01 01 00 00 01 01 01 00 01 01 00 00 00 00 01 01 01 01 00 00 00 00 00 00 00 00 01 01 01 01 00 01 01 01 01 01 01 01 01 01 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 00 00 01 01 01 01 00 00 00 01 01 01 00 01 01 00 01 00 01 00 01 01 00 00 00 01 01 01 01 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 00 00 01 01 00 01 01 01 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 01 01 01 00 01 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 00 00 01 01 00 01 00 00 01 01 01 00 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 00 01 01 01 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 01 01 00 01 00 00 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 01 00 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 01 01 01 00 01 01 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01 01 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 01 00 01 01 01 00 00 01 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 00 00 00 01 01 01 00 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 01 00 01 01 01 01 01 00 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 00 00 00 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 01 01 01 01 00 01 01 01 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 00 00 00 01 01 01 01 01 01 00 01 01 01 00 00 00 00 00 01 01 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 00 01 01 00 00 01 01 01 00 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 01 01 00 00 00 00 00 00 00 00 00 01 01 01 01 00 00 00 00 01 01 01 01 01 00 01 01 01 01 01 00 00 00 01 01 01 01 00 00 00 00 00 00 00 00 01 01 01 01 01 01 01 00 01 01 01 01 01 01 01 00 00 01 01 01 00 00 00 01 01 01 01 01 00 00 00 01 00 01 01 00 00 00 00 00 00 00 00 00 01 01 01 01 00 00 00 00 01 01 00 01 01 01 01 01 01 01 01 00 00 00 00 01 01 01 01 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 01 01 00 00 00 00 00 01 01 01 01 00 00 00 00 00 00 01 01 00 01 01 01 01 01 00 01 00 01 00 00 01 01 00 00 00 00 01 01 01 00 00 00 00 00 01 01 00 01 01 01 01 01 01 01 01 01 01 01 01 01 00 01 01 01 00 01 01 01 01 01 01 01 01 00 00 01 00 01 01 00 00 00 00 00 01 01 01 01 00 00 00 00 00 00 01 01 00 01 01 00 01 00 01 00 01 01 00 01 01 00 00 00 00 00 00 01 01 01 01 00 00 00 00 00 01 01 00 01 01 00 00 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 01 00 00 01 00 01 00 01 01 00 01 01 00 01 00 00 00 01 01 00 00 00 00 00 01 01 01 01 00 01 01 01 00 01 01 01 01 00 00 01 01 01 00 01 01 01 01 01 01 01 01 01 00 01 01 01 01 01 00 00 01 00 00 01 01 00 01 01 01 00 00 00 00 00 00 00 00 00 01 00 00 01 00 01 00 01 01 00 01 01 00 01 00 00 01 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 00 01 01 00 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 01 00 01 01 01 01 01 01 01 01 01 01 01 00 00 00 00 01 01 00 00 00 00 00 00 00 01 01 01 01 00 01 01 01 01 00 00 01 01 00 00 00 01 01 01 01 01 01 00 00 01 01 01 00 01 01 00 00 00 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 00 00 01 00 01 01 00 00 00 00 00 00 00 00 00 01 01 00 00 00 01 00 00 01 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 01 01 01 01 00 00 01 01 00 00 00 00 01 01 01 00 00 00 01 01 00 00 01 01 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 00 00 01 01 00 00 00 01 00 00 01 00 01 00 01 00 01 00 01 00 00 01 00 00 00 01 01 00 00 00 00 00 00 00 00 00 01 01 00 01 00 00 01 00 01 01 00 00 00 00 00 00 00 01 01 00 00 00 00 01 00 00 01 00 00 01 00 01 00 01 00 00 01 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 01 01 01 01 01 00 00 01 01 00 01 01 01 00 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 01 01 00 00 00 00 01 00 00 01 00 00 01 00 01 00 01 00 00 01 00 00 01 00 00 00 00 01 01 00 00 00 00 00 00 00 01 01 01 01 00 00 00 01 00 01 01 00 00 00 00 00 01 00 00 00 00 00 01 00 00 00 01 00 01 00 00 01 00 00 01 00 01 00 00 00 01 00 00 00 00 00 01 01 00 00 01 00 01 01 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 00 01 01 01 01 01 00 00 00 00 00 00 00 01 00 01 01 00 00 00 00 00 01 00 00 00 00 00 01 00 00 00 01 00 01 00 00 01 00 00 01 00 01 00 00 00 01 00 00 00 00 00 01 00 00 00 00 00 01 01 00 01 00 00 00 00 01 00 01 01 00 00 00 01 01 00 00 00 00 00 01 00 00 00 01 00 00 01 00 00 01 00 00 01 00 00 01 00 00 00 01 00 00 00 00 00 00 01 00 00 00 01 01 00 01 00 00 00 00 00 01 01 01 01 01 01 00 00 00 00 00 00 00 01 01 01 00 00 00 00 00 00 00 00 01 00 01 01 00 00 00 01 01 00 00 00 00 00 01 00 00 00 01 00 00 01 00 00 01 00 00 01 00 00 01 00 00 00 01 00 00 00 00 00 01 01 00 00 00 01 01 00 01 00 00 00 00 01 00 00 01 01 01 01 00 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 01 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 01 01 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 01 01 00 01 00 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 01 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 01 01 01 01 00 01 01 00 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 01 00 00 00 00 01 00 00 00 01 00 00 01 00 00 00 01 00 00 01 00 00 00 00 01 00 00 00 00 00 00 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01 01 00 00 00 00 00 00 00 01 00 00 00 00 01 00 00 01 00 00 00 01 00 00 01 00 00 00 01 00 00 00 00 01 00 00 00 00 00 00 00 01 01 00 01 00 00 00 00 00 00 01 01 00 01 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 01 00 01 01 00 00 00 00 00 00 00 01 00 01 01 01 00 00 00 01 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 01 00 00 00 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01 01 01 00 00 00 01 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 00 01 00 00 00 01 01 01 00 01 00 00 00 00 00 00 00 00 00 01 00 01 01 01 00 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 00 01 01 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01 01 01 00 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 00 01 01 01 00 01 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 00 00 00 00 00 01 00 00 00 00 00 01 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 01 00 00 00 00 00 01 00 00 00 00 00 01 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 01 00 00 01 01 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 01 01 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 00 00 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 00 00 01 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 00 00 01 00 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 00 00 01 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 01 00 00 00 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 01 00 01 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 01 00 00 00 00 00 00 01 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 01 00 01 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 01 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 01 01 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 01 01 01 01 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 00 01 00 00 00 00 01 01 01 01 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 01 01 01 01 00 00 01 00 00 00 00 00 01 00 00 00 00 00 01 00 00 01 01 01 01 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 01 01 01 01 00 00 01 00 00 00 00 00 01 00 00 00 00 00 01 00 00 01 01 01 01 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 01 01 01 01 01 01 00 00 00 00 01 00 00 00 00 01 01 01 01 01 01 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 01 01 01 01 01 01 00 00 00 00 01 00 00 00 00 01 01 01 01 01 01 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 01 00 01 01 01 01 01 01 01 01 01 00 01 00 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 01 00 01 01 01 01 01 01 01 01 01 00 01 00 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 01 00 01 00 01 00 01 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 01 00 01 00 01 00 01 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ] &end
+217,
-0
1@@ -0,0 +1,217 @@
2+( Screen:
3+ Draws a table of all possible sprite arrangements. )
4+
5+|00 @System &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1
6+|20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
7+|90 @Mouse &vector $2 &x $2 &y $2 &state $1 &chord $1
8+
9+|0000
10+
11+ @center &x $2 &y $2
12+
13+|0100 ( -> )
14+
15+ ( vector )
16+ ;on-frame .Screen/vector DEO2
17+ ( theme )
18+ #f07f .System/r DEO2
19+ #f0e0 .System/g DEO2
20+ #f0c0 .System/b DEO2
21+ ( gba screen size 00f0 x 00a0 )
22+ ( nds screen size 0100 x 00c0 )
23+ #0100 .Screen/width DEO2
24+ #00b0 .Screen/height DEO2
25+ ( find screen center )
26+ .Screen/width DEI2 #01 SFT2 .center/x STZ2
27+ .Screen/height DEI2 #01 SFT2 .center/y STZ2
28+ ( draw )
29+ draw-size
30+ draw-sprites
31+ draw-1bpp
32+ draw-2bpp
33+
34+BRK
35+
36+(
37+@|vectors )
38+
39+@on-frame ( -> )
40+
41+ ( scroll background )
42+ [ LIT2 &f $2 ] INC2k ,&f STR2
43+ #01 SFT2
44+ #001f AND2
45+ #0040 SUB2
46+ DUP2 .Screen/x DEO2
47+ .Screen/y DEO2
48+ ;patt-icn draw-fill
49+
50+ .center/x LDZ2 #0070 SUB2 .Screen/x DEO2
51+ .center/y LDZ2 #0048 SUB2 .Screen/y DEO2
52+ ;anim-chr ,&f LDR2 #00ff AND2 #02 SFT #07 AND #40 SFT ADD2 .Screen/addr DEO2
53+ #8f .Screen/sprite DEO
54+
55+ draw-size
56+ draw-sprites
57+ draw-1bpp
58+ draw-2bpp
59+
60+BRK
61+
62+(
63+@|drawing )
64+
65+@draw-sprites ( -- )
66+
67+ ( horizontal )
68+ .center/x LDZ2 #0060 SUB2 .Screen/x DEO2
69+ .center/y LDZ2 #0048 SUB2 .Screen/y DEO2
70+ ;font-icn .Screen/addr DEO2
71+ #f6 .Screen/auto DEO
72+ #05 .Screen/sprite DEO
73+ ( vertical )
74+ .center/x LDZ2 #0070 SUB2 .Screen/x DEO2
75+ .center/y LDZ2 #0038 SUB2 .Screen/y DEO2
76+ ;font-icn .Screen/addr DEO2
77+ #f5 .Screen/auto DEO
78+ #05 .Screen/sprite DEO
79+ ( table )
80+ #00 .Screen/auto DEO
81+ ;preview-chr .Screen/addr DEO2
82+ #00
83+ &loop
84+ ( move ) #00 OVR #0f AND #30 SFT
85+ .center/x LDZ2 #0060 SUB2 ADD2 .Screen/x DEO2
86+ ( move ) #00 OVR #f0 AND #01 SFT
87+ .center/y LDZ2 #0038 SUB2 ADD2 .Screen/y DEO2
88+ ( draw ) DUP .Screen/sprite DEO
89+ INC DUP ?&loop
90+ POP
91+
92+JMP2r
93+
94+@draw-1bpp ( -- )
95+
96+ #1000
97+ &loop
98+ ( color ) STHk
99+ ( y ) #00 OVR #42 SFT2
100+ .center/y LDZ2 #0038 SUB2 ADD2 STH2
101+ ( x ) #00 OVR #03 AND #40 SFT2 #0040 ADD2
102+ .center/x LDZ2 #0010 SUB2 ADD2
103+ STH2r STHr #00 draw-circle
104+ INC GTHk ?&loop
105+ POP2
106+
107+JMP2r
108+
109+@draw-2bpp ( -- )
110+
111+ #1000
112+ &loop
113+ ( color ) STHk
114+ ( y ) #00 OVR #42 SFT2
115+ .center/y LDZ2 #0008 ADD2 ADD2 STH2
116+ ( x ) #00 OVR #03 AND #40 SFT2 #0040 ADD2
117+ .center/x LDZ2 #0010 SUB2 ADD2
118+ STH2r STHr #80 draw-circle
119+ INC GTHk ?&loop
120+ POP2
121+
122+JMP2r
123+
124+@draw-circle ( x* y* color depth -- )
125+
126+ ADD STH
127+ ;preview-chr .Screen/addr DEO2
128+ .Screen/y DEO2
129+ .Screen/x DEO2
130+ #01 .Screen/auto DEO
131+ STHr .Screen/sprite DEOk
132+ #02 .Screen/auto DEO
133+ SWP #10 ADD SWP DEOk
134+ .Screen/x DEI2k #0008 SUB2 ROT DEO2
135+ #01 .Screen/auto DEO
136+ SWP #10 ADD SWP DEOk
137+ SWP #10 ADD SWP DEO
138+
139+JMP2r
140+
141+@draw-fill ( patt* color -- )
142+
143+ .Screen/addr DEO2
144+ [ LIT2 01 -Screen/auto ] DEO
145+ .Screen/x DEI2 ,&anchor STR2
146+ .Screen/width DEI2 #03 SFT2 NIP #08 ADD ,&x STR
147+ .Screen/height DEI2 #03 SFT2 NIP #08 ADD #00
148+ &h
149+ DUP #02 SFT STH
150+ [ LIT &x $1 ] #00
151+ &w
152+ DUP #02 SFT STHkr ADD #01 AND .Screen/sprite DEO
153+ INC GTHk ?&w
154+ .Screen/y DEI2k #0008 ADD2 ROT DEO2
155+ [ LIT2 &anchor $2 ] .Screen/x DEO2
156+ POP2 POPr
157+ INC GTHk ?&h
158+ POP2
159+
160+JMP2r
161+
162+@draw-size ( -- )
163+
164+ #01 .Screen/auto DEO
165+ .center/x LDZ2 #0030 ADD2 .Screen/x DEO2
166+ .center/y LDZ2 #0048 SUB2 .Screen/y DEO2
167+ .Screen/width DEI2 draw-dec
168+ ;x-icn .Screen/addr DEO2
169+ #01 .Screen/sprite DEO
170+ .Screen/height DEI2
171+
172+@draw-dec ( short* -- )
173+
174+ #00 ,&z STR
175+ #2710 draw-dec/parse
176+ #03e8 draw-dec/parse
177+ #0064 draw-dec/parse
178+ #000a draw-dec/parse
179+ NIP
180+ &emit
181+ DUP [ LIT &z $1 ] EQU ?&skip
182+ #ff ,&z STR #00 OVR #30 SFT ;font-icn ADD2 .Screen/addr DEO2
183+ #01 .Screen/sprite DEO
184+ &skip
185+ POP
186+
187+JMP2r
188+ &parse DIV2k DUP ,&emit JSR MUL2 SUB2 JMP2r
189+
190+(
191+@|assets )
192+
193+@patt-icn [
194+ aa55 aa55 aa55 aa55 ]
195+@x-icn [
196+ 0000 0018 1800 0000 ]
197+@preview-chr [
198+ 0f38 675f dfbf bfbf 0007 1820 2344 4848 ]
199+@font-icn ( 0-f ) [
200+ 007c 8282 8282 827c 0030 1010 1010 1010
201+ 007c 8202 7c80 80fe 007c 8202 1c02 827c
202+ 000c 1424 4484 fe04 00fe 8080 7c02 827c
203+ 007c 8280 fc82 827c 007c 8202 1e02 0202
204+ 007c 8282 7c82 827c 007c 8282 7e02 827c
205+ 007c 8202 7e82 827e 00fc 8282 fc82 82fc
206+ 007c 8280 8080 827c 00fc 8282 8282 82fc
207+ 007c 8280 f080 827c 007c 8280 f080 8080 [
208+@anim-chr [
209+ 0000 0018 1800 0000 c381 0000 0000 81c3
210+ 0000 183c 3c18 0000 0000 0000 0000 0000
211+ 0018 3c7e 7e3c 1800 0000 0000 0000 0000
212+ 3c7e ffe7 e7ff 7e3c 0000 0018 1800 0000
213+ ffff e7c3 c3e7 ffff 0000 183c 3c18 0000
214+ ffe7 c381 81c3 e7ff 0018 3c7e 7e3c 1800
215+ c381 0000 0000 81c3 3c7e ffe7 e7ff 7e3c
216+ 0000 0000 0000 0000 ffff e7c3 c3e7 ffff
217+ 0000 0000 0000 0000 ffe7 c381 81c3 e7ff ]
218+
+158,
-0
1@@ -0,0 +1,158 @@
2+( 54K . System Device Tests )
3+
4+|00 @System/vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1
5+|10 @Console/vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1
6+|0050 @Varvara/version
7+
8+|100
9+
10+@on-reset ( -> )
11+ ;meta #06 DEO2
12+ ( | Halt recover )
13+ [ LIT2 80 -System/state ] DEO
14+ [ LIT2 01 -System/state ] DEO
15+ [ LIT2 00 -System/state ] DEO
16+ ( | )
17+ #800f DEO
18+ system/test-wst ;dict/wst ROT <test>
19+ system/test-rst ;dict/rst ROT <test>
20+ ;dict/cpyl system/test-copyl <test>
21+ ;dict/cpyr system/test-copyr <test>
22+ ;dict/cpyl2 system/test-copyl2 <test>
23+ ;dict/fill system/test-fill <test>
24+ BRK
25+ ( | boundary check )
26+ ;mmu-over .System/expansion DEO2
27+ ;dict/over #0000 LDA #ffff LDA #8888 EQU2 <test>
28+ BRK
29+
30+@meta 00
31+ ( name ) "System 20 "Device 20 "Test(80K) 0a
32+ ( details ) "Testing 20 "Program 0a
33+ ( author ) "By 20 "Devine 20 "Lu 20 "Linvega 0a
34+ ( date ) "24 20 "Jun 20 "2026 00
35+ ( . ) 01
36+ ( - ) 56 =Varvara/version
37+
38+(
39+@|test )
40+
41+@system/test-wst ( -- pass )
42+ ( 1 ) #12 [ LITr -System/wst ] DEIr POP
43+ ( 2 ) #1234 [ LITr -System/wst ] DEIr POP2
44+ ( ) STH2r #0102 EQU2 JMP2r
45+
46+@system/test-rst ( -- pass )
47+ ( 1 ) LITr 12 .System/rst DEI POPr
48+ ( 2 ) LIT2r 1234 .System/rst DEI POP2r
49+ ( account for return addr+2 ) #0304 EQU2 JMP2r
50+
51+@system/test-fill ( -- pass )
52+ ;buf #0003 ADD2 ;mmu-fill/a STA2
53+ ;mmu-fill .System/expansion DEO2
54+ ;buf #0013 ;res4 mem/cmp
55+ ( | test clamp )
56+ ;mmu-fill-of .System/expansion DEO2
57+ #fffe LDA2 LIT2 "AA EQU2 AND
58+ ( | read overflow )
59+ ;mmu-fill-mov .System/expansion DEO2
60+ ;res LDA2 #0000 EQU2 AND JMP2r
61+
62+@system/test-copyl ( -- pass )
63+ ;buf #0006 ADD2 ;mmu-cpyl/a STA2
64+ ;buf #0003 ADD2 ;mmu-cpyl/b STA2
65+ ;mmu-cpyl .System/expansion DEO2
66+ ;buf #0013 ;res1 mem/cmp
67+ ( | test clamp )
68+ ;mmu-cpyl-of .System/expansion DEO2
69+ #fffe LDA2 LIT2 "BB EQU2 AND
70+ ( | read overflow )
71+ ;mmu-fill-mov .System/expansion DEO2
72+ ;res LDA2 #0000 EQU2 AND JMP2r
73+
74+@system/test-copyr ( -- pass )
75+ ;buf #0003 ADD2 ;mmu-cpyr/a STA2
76+ ;buf #0009 ADD2 ;mmu-cpyr/b STA2
77+ ;mmu-cpyr .System/expansion DEO2
78+ ;buf #0013 ;res2 mem/cmp
79+ ( | test clamp )
80+ ;mmu-cpyr-of .System/expansion DEO2
81+ #fffe LDA2 LIT2 "CC EQU2 AND
82+ ( | read overflow )
83+ ;mmu-fill-mov .System/expansion DEO2
84+ ;res LDA2 #0000 EQU2 AND JMP2r
85+
86+@system/test-copyl2 ( -- pass )
87+ ;buf #0009 ADD2 ;mmu-cpyl/a STA2
88+ ;buf #0006 ADD2 ;mmu-cpyl/b STA2
89+ ;mmu-cpyl .System/expansion DEO2
90+ ;buf #0013 ;res3 !mem/cmp
91+
92+(
93+@|Helpers )
94+
95+@<test> ( name* f -- )
96+ ?{
97+ str/<print>
98+ #010f DEO
99+ ;dict/fail !str/<print> }
100+ str/<print>
101+ ;dict/pass
102+ ( >> )
103+
104+@str/<print> ( str* -- )
105+ LDAk DUP ?{ POP POP2 JMP2r }
106+ .Console/write DEO
107+ INC2 !/<print>
108+
109+@mem/cmp ( a* length* b* -- t )
110+ STH2
111+ OVR2 ADD2 SWP2
112+ &>l
113+ EQU2k ?{
114+ LDAk LDAkr STHr NEQ ?{ INC2 INC2r !&>l } }
115+ POP2r EQU2 JMP2r
116+
117+@dict
118+ &wst "System/wst: 20 $1
119+ &rst "System/rst: 20 $1
120+ &cpyl "System/cpyl: 20 $1
121+ &cpyr "System/cpyr: 20 $1
122+ &cpyl2 "System/cpyl2: 20 $1
123+ &fill "System/fill: 20 $1
124+ &over "System/overflow: 20 $1
125+ &pass "pass 0a $1
126+ &fail "fail 0a $1
127+
128+@buf [ "......[hello]..... $1 ]
129+
130+@res1 [ "...[hello]lo]..... $1 ]
131+
132+@res2 [ "...[hello[hello].. $1 ]
133+
134+@res3 [ "...[he[hello]lo].. $1 ]
135+
136+@res4 [ "...-------------.. $1 ]
137+
138+@fill-b [ "BBBB 00 ]
139+
140+@fill-c [ "CCCC 00 ]
141+
142+@mmu-fill [ 00 000d 0000 &a $2 2d ]
143+
144+@mmu-fill-of [ 00 0004 0000 fffe "A ]
145+
146+@mmu-fill-mov [ 01 0002 0001 0000 =res ]
147+
148+@mmu-cpyl [ 01 0007 0000 &a $2 0000 &b $2 ]
149+
150+@mmu-cpyl-of [ 01 0004 0000 =fill-b 0000 fffe ]
151+
152+@mmu-cpyr [ 02 0007 0000 &a $2 0000 &b $2 ]
153+
154+@mmu-cpyr-of [ 02 0004 0000 =fill-c 0000 fffe ]
155+
156+@mmu-over [ 00 0002 0000 ffff 88 ]
157+
158+@res $2
159+
+195,
-0
1@@ -0,0 +1,195 @@
2+a001 2e80 0637 6001 eb20 0009 a004 1260
3+0b3f 600b 6260 00b8 2000 12a0 018b 8010
4+3780 1716 2000 06a0 0170 600b 2400 0044
5+7269 6662 6c69 6d0a 5578 6e74 616c 2835
6+344b 2920 4173 7365 6d62 6c65 720a 4279
7+2044 6576 696e 6520 4c75 204c 696e 7665
8+6761 0a32 3620 4175 6720 3230 3236 0a0a
9+5573 6167 653a 2069 6e2e 7461 6c20 6f75
10+742e 726f 6d0a 0001 5600 5080 1216 6000
11+13a0 0417 1609 2000 0a60 0ae0 2000 04a0
12+800f 1700 0680 210b 2000 04a0 0211 2c02
13+a000 0008 0680 fa13 2000 0ca0 0211 80eb
14+3360 00c6 4000 38a0 0231 80df 3340 0058
15+a001 f580 b837 a000 0180 ba37 c000 a001
16+ed80 bc37 80b3 1620 0002 4f6c 8000 60ff
17+b341 40ff e92e 6472 6966 626c 696d 00a0
18+0010 13a0 0000 116c 60ff f4a0 0211 4009
19+41a0 0000 0680 3f09 2000 0722 a000 0040
20+01c7 8180 ed13 316c a040 0713 a000 4011
21+6ca0 0040 0680 7f09 2000 0722 a000 4040
22+01a7 8180 ed13 316c a002 3140 0904 a00d
23+26a0 07bd 35a0 0000 a007 b535 6ca0 0e26
24+a005 2235 a000 00a0 0e26 356c a01e 26a0
25+09f6 35a0 0000 a01e 2635 6ca0 4e26 a008
26+b335 a000 00a0 4e26 356c 6000 2d60 ffdc
27+60ff e860 ffb8 60ff c460 01de 6001 8ea0
28+0000 6000 f460 09d4 2000 0a60 0185 6009
29+cb20 0001 6ca0 010f 176c a002 cd80 0237
30+a000 ffa0 0b2d 35a0 0100 4008 8100 ff00
31+0001 0000 0080 1633 a002 e980 0237 8000
32+6c00 0001 0001 0000 0001 0001 0001 0000
33+0000 02df 80d6 06a0 dead af60 0008 ef60
34+ffd3 0880 006f 80dd 3380 dc13 a002 e180
35+0237 6ca0 0c7f 6009 30a0 0040 6009 32a0
36+0c89 6009 2ca0 0b2d 3426 a000 ff39 6009
37+2621 a00c 8e60 0919 a000 4080 a837 a000
38+0180 aa37 a000 ff40 0011 2126 809f 33a0
39+02e9 8002 37a0 02df 80ae 37a9 20ff eb22
40+22a0 040d 60fe e1a0 0040 80a8 37a0 08b3
41+34a0 4e26 a000 0280 aa37 2680 ae37 a000
42+0338 9480 0004 af80 aa37 2126 80ae 376f
43+38aa 20ff df22 226c 2126 a000 0028 2000
44+0426 60fe 6380 a837 a000 0126 80aa 37a0
45+0588 35a0 03bb 80a4 37a0 2100 0920 0006
46+a000 0060 0023 6001 a260 08b0 2000 19a0
47+03e1 80ac 3780 a316 2000 0580 0a40 0194
48+8000 6001 8f40 ffe1 6c60 088b a004 0760
49+085f a00c f960 0859 a00c a060 0853 6008
50+5080 0a80 1917 6c50 6174 6820 002e 7379
51+6d00 4552 524f 523a 2062 616e 6b20 3120
52+756e 7375 7070 6f72 7465 640a 00a0 0d22
53+4001 8d80 4132 a004 b029 2000 09a0 0d1d
54+a00c e060 07d1 802e 32a0 04ef 2920 0009
55+a00d 1da0 0cce 6007 be60 0820 2000 0c60
56+05e2 6008 1720 0003 4004 d86c 8008 336c
57+9020 0002 226c a004 802c a004 8040 ffec
58+6007 2a20 065b 6002 4c20 0640 9060 0163
59+a11d 2000 0d22 6000 a2a1 1d20 00c0 2240
60+01d0 2134 2c22 a001 0913 a004 b040 ffbc
61+3426 c000 a028 0028 0f58 a029 0028 0f59
62+cfc0 ef53 2000 0340 ffb0 6c60 033a 6000
63+4a80 0060 004b a004 dc40 ff90 34a0 7b00
64+2920 000a a001 0a13 a004 ef40 ff7e 6cb4
65+26c0 0080 7b08 0480 7b08 1d0f 58a0 7d00
66+280f 59cf c0eb 5320 0009 2280 0060 0011
67+40ff 6760 0005 8020 4000 06a0 0521 4006
68+31a0 0e26 a126 a01e 262b 2000 09a0 0cf0
69+a00c c760 06e1 80e9 3315 6c60 0307 af80
70+e032 a00e 2626 ef60 067b 2000 0e60 066f
71+6006 6caa 20ff ee22 a0ff ff23 626c 2360
72+0009 6006 5aa0 0574 4005 e7a0 c024 13a0
73+00c0 116c 0680 200a 2000 16a0 00c0 60fe
74+ef80 0a09 20ff e4a0 0001 2180 fa33 40ff
75+daa0 00c0 8106 80ff 0b20 0009 a00c f0a0
76+0cd4 6006 7280 eb13 316c a000 8081 0680
77+bf0b 2000 06a0 0cf0 6006 5980 ee13 316c
78+26a0 80e7 1394 802f 0820 0009 9460 ffda
79+2194 20ff f022 80d3 1280 0513 4002 7c21
80+a000 c813 802f 60ff c1a0 0080 24a0 05aa
81+4005 5f0f a006 9594 cf08 2000 0ca0 0003
82+3894 20ff f222 a0ff ff42 6c22 6c22 4001
83+d040 fe91 6000 6c40 feb1 6000 6660 0305
84+4005 2b60 005d 6002 fc40 051e 6000 5440
85+ff8e 60ff aa40 0223 8080 6004 df60 0043
86+6003 da40 04d6 8080 6004 d160 0035 6003
87+be40 04c8 80a0 6004 c360 0027 6003 b840
88+04b6 6000 1e80 2040 04a8 6000 1680 4040
89+04a0 8060 4004 9b60 0009 4004 5560 0003
90+4004 4321 9480 200a 2000 09a0 0cf9 a00c
91+d440 0583 6c7c 061a 2406 2340 062c 2606
92+322c 0638 5f06 3d2e 0646 2d06 4b3b 0654
93+3d06 5921 066a 3f06 6223 0677 2206 7d7d
94+060d 7e03 9828 0611 2906 0b5b 060b 5d06
95+0b25 0614 0026 6000 0e80 0009 0f26 a007
96+af60 04e1 4f1d 6ce0 1f00 a007 4fa4 a000
97+0324 6004 d920 000f 41a0 0003 3894 20ff
98+ec22 2262 8000 6c22 5cb4 a04c 4928 8070
99+1f0f 5da0 0003 3894 8021 0b20 002e 9480
100+3209 2000 05c0 2040 001d 9480 7209 2000
101+05c0 4040 0011 9480 6b09 2000 05c0 8040
102+0005 2242 8000 6c5d 2140 ffcb 224f 6c4c
103+4954 494e 4350 4f50 4e49 5053 5750 524f
104+5444 5550 4f56 5245 5155 4e45 5147 5448
105+4c54 484a 4d50 4a43 4e4a 5352 5354 484c
106+445a 5354 5a4c 4452 5354 524c 4441 5354
107+4144 4549 4445 4f41 4444 5355 424d 554c
108+4449 5641 4e44 4f52 4145 4f52 5346 5442
109+524b 0022 a000 00a1 80fa 3326 a00d 26a1
110+2180 f933 3560 000e 0560 000a 8034 3380
111+3333 a008 016c 0680 041f 6003 8504 4003
112+8180 d932 26a0 0d26 2920 0006 a00c f960
113+0422 a000 0239 b460 ffcb 6000 5e80 bd33
114+6cce bb2e 2e2e 2e00 6003 a220 0025 9480
115+7b08 2000 1e94 60fd da21 1d20 0015 60fd
116+1a21 1d20 0016 6000 a321 1d20 000e 60fe
117+a40c 6ca0 0cf9 a00c d440 03db a00d 01a0
118+0cd4 4003 d294 807b 0820 ff67 9480 2f08
119+20fd 8c94 8026 0820 fd85 6c60 006e a11d
120+2000 1022 a008 b334 6002 4780 0260 02d6
121+4000 1a23 2660 023a 6001 2a20 0008 6002
122+c527 3540 0130 22a0 0d01 4003 8704 6000
123+2160 001e 6000 1be0 08b3 f480 0060 0012
124+60ff 65a0 08b2 6002 a964 7467 7964 5542
125+8000 a04e 26a1 26a0 9626 2b20 0009 a00c
126+f0a0 0cb8 6003 5080 e933 156c 2680 1c33
127+6002 d101 0f80 db32 a04e 26a8 2000 2326
128+a000 0338 94cf 0920 000a a1a0 0000 6002
129+d420 0015 22a0 0003 3894 8000 0401 3840
130+ffd9 2222 a0ff ff42 6c22 2342 6c60 ffbc
131+a11d 2000 0e22 a008 b334 2480 01a0 ffff
132+40ff 6a23 6c60 0285 2002 6460 ff17 60ff
133+9b60 0069 2000 06a0 0cf9 6002 d760 006c
134+3423 6ca0 08b3 34a0 4e26 a121 1480 011c
135+2000 27b4 a001 0028 2000 1f26 a000 0438
136+9480 4119 801a 0b20 000f a00c 9760 02e1
137+2660 02dd 800a 60fa 8a22 a000 0338 9480
138+0004 0138 aa20 ffc2 2222 40f9 8626 a000
139+8038 0220 0001 6ca0 0d0b 4002 77a1 1d20
140+0003 8000 6ca1 2114 8002 1c6c a121 af14
141+8001 1d6f 156c 2121 af14 8002 1d6f 156c
142+8017 3360 fe7f 60ff 4460 ffd9 2000 1d26
143+6001 7360 001b 6000 18a0 0000 6000 12a0
144+0000 6000 0ca0 0588 3460 0005 60ff bd34
145+6c04 6000 00a0 1e26 a126 a04e 262b 2000
146+09a0 0cf0 a00c a360 020d 80e9 3315 6ca0
147+0a79 60ff ab03 6ca0 0a81 40ff a3a0 0a88
148+60ff 9da1 1d20 0004 2280 006c 6001 1760
149+000e 60ff 5803 6ca0 0a97 60ff 8360 0106
150+2121 396c 80af 32a0 1e26 a820 0013 26a0
151+0bf5 35a6 a000 0438 342e a000 0a38 40ff
152+e922 226c b460 00e6 a121 3460 ff2f 2000
153+06a0 0cf9 4001 6e34 6c60 ffe8 2303 4000
154+9b60 ffe0 2340 0090 60ff d924 3460 ffb0
155+6000 0f03 4000 8560 ffca 2434 60ff a140
156+0076 26a0 0080 3802 2000 016c a00d 0b40
157+0133 26a0 0003 3834 a0ce bb29 2000 0222
158+6ca0 09e0 356c a00b 1c40 0086 60fc 1840
159+004a 6000 cf80 0209 8050 1f80 801d 6000
160+3b60 00c9 8000 0820 001e 6000 b706 8002
161+0920 0008 0260 0097 0340 0020 8004 0920
162+0006 6000 8a40 0010 22a0 0cf9 a00c d940
163+0105 6000 0760 ff1f 0460 0000 8fa0 0100
164+a180 fa33 4f80 0008 2000 0c26 a000 ff2b
165+2000 0426 80f6 3307 20f7 cb22 02a0 0d13
166+a00c e840 00d1 80d5 326c 60ff f938 80cd
167+336c 2f94 0620 0004 0222 626c ef2e 2140
168+fff1 800f 1c80 0a8b 2000 0519 8061 186c
169+0280 3018 6c94 8030 1906 8009 0a0c 6c80
170+2719 0680 0a19 8005 0a0c 6c02 80ff 6ce0
171+0000 c040 7f60 ffdd c000 0f78 2194 20ff
172+f122 6f6c a660 0017 2421 3903 6c26 60ff
173+c401 2000 0514 8000 086c 2140 fff0 2194
174+20ff fb21 6c2f 2660 fff5 2440 0009 2f27
175+3824 4000 0221 61a8 2000 0794 d44f 0820
176+fff3 6228 6ca0 0cae 6000 5e60 0063 a00c
177+a060 005d a000 00a1 2134 a000 0438 6000
178+5026 a000 0838 3424 a000 0638 34a0 0004
179+3840 001c a00c c060 002f 6000 34a0 0ca0
180+6000 2ea0 00c0 6000 28a0 0588 34a0 0080
181+a00c 8960 001b 6000 1880 3a60 f7c5 6000
182+1660 0033 800a 40f7 ba60 0005 8020 40f7
183+b2a0 0403 40fe fbe0 ff00 a000 0abb af3a
184+396f 419d 20ff f322 0380 3018 60f7 9447
185+58cf 20ff f362 6ca0 0102 136c 8000 6c41
186+7373 656d 626c 6564 0020 696e 2000 2062
187+7974 6573 2e0a 002d 2d20 556e 7573 6564
188+3a20 0052 6566 6572 656e 6365 7300 5265
189+6665 7265 6e63 6500 5379 6d62 6f6c 7300
190+5379 6d62 6f6c 004d 6163 726f 7300 4d61
191+6372 6f00 4e61 6d65 004e 756d 6265 7200
192+436f 6d6d 656e 7400 5772 6974 696e 6700
193+6578 6365 6564 6564 0069 6e76 616c 6964
194+0064 7570 6c69 6361 7465 0074 6f6f 2066
195+6172 007a 6572 6f2d 7061 6765 006f 7065
196+6e00 546f 7000
+1918,
-0
1@@ -0,0 +1,1918 @@
2+( 54K . M/PC )
3+
4+|00 @System/vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1
5+|10 @Console/vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1
6+|20 @Screen/vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
7+|80 @Controller/vector $2 &button $1 &key $1
8+|90 @Mouse/vector $2 &x $2 &y $2 &state $1 &chord $1 &pad $4 &scrolly &scrolly-hb $1 &scrolly-lb $1
9+|a0 @File/vector $2 &success $1 &success-lb $1 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2
10+|b0 @File2/vector $2 &success $1 &success-lb $1 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2
11+|c0 @DateTime &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1
12+
13+(
14+@|Enums )
15+
16+|0050 @Varvara/version
17+|00fd @loader/entry
18+|0100 @loader/pagelen
19+|0080 @path/buflen
20+|0200 @bios/buflen
21+|0800 @dir/buflen
22+|0120 @meta/buflen
23+|ff00 @dict/cap
24+|0008 @bios/anchor-x
25+|0028 @bios/anchor-y
26+
27+|000
28+
29+ @input/buf $80
30+ @loader/buf
31+
32+|100
33+
34+@on-reset ( -> )
35+ ;meta #06 DEO2
36+ theme/<load>
37+ ;dict/home-path path/<set>
38+ window/<update>
39+ window/<draw-spacer>
40+ input/<bind>
41+ bios/<welcome>
42+ .Console/type DEI ?{ project/<load>
43+ BRK }
44+ loader/<set-instant>
45+ BRK
46+
47+@meta 00
48+ ( name ) "M/PC 0a
49+ ( details ) "Monitor/Program 20 "Control 0a
50+ ( author ) "By 20 "Devine 20 "Lu 20 "Linvega 0a
51+ ( date ) "15 20 "Aug 20 "2026 00
52+ ( . ) 03
53+ ( - ) 56 =Varvara/version
54+ ( - ) 83 =appicon
55+ ( - ) a0 =manifest/dat
56+
57+@manifest/dat ( . )
58+ _{ =dict/m_pc
59+ ( ) 10 00 =scroll/<up> =dict/scroll-up
60+ ( ) 20 00 =scroll/<down> =dict/scroll-down
61+ ( ) 40 00 =sel/<prev> =dict/sel-prev
62+ ( ) 80 00 =sel/<next> =dict/sel-next
63+ ( ) 01 00 =sel/<use> =dict/sel-pick
64+ ( ) 02 00 =bios/<dir> =dict/directory }
65+ _{ =dict/input
66+ ( ) 00 0d =input/<eval> =dict/eval
67+ ( ) 04 0d =input/<eval-partial> =dict/eval-partial
68+ ( ) 00 1b =input/<blank> =dict/clear }
69+ 00
70+
71+%Screen/<set-pos> ( x* y* -- ) {
72+ .Screen/y DEO2
73+ .Screen/x DEO2 }
74+
75+(
76+@|Project )
77+
78+@project/<load> ( -- )
79+ ;&path .File2/name DEO2
80+ #0001 .File2/length DEO2
81+ &>w
82+ ;&c .File2/read DEO2
83+ .File2/success-lb DEI ?{ JMP2r }
84+ [ LIT &c $1 ] input/<handle-input> !/>w
85+
86+ &path ".m_pc 00
87+
88+(
89+@|Input )
90+
91+@input/on-controller ( -> )
92+ .Controller/button DEI2 DUP2 manifest/scan INC2k ORA ?{
93+ POP2
94+ ( key ) /<handle-input>
95+ ( button ) POP BRK }
96+ ( * ) JSR2 POP2 BRK
97+
98+@input/on-console ( -> )
99+ .Console/read DEI
100+ ( | mute arg spacers )
101+ [ LIT2 03 -Console/type ] DEI NEQ ?{ POP #20 }
102+ DUP LIT "\ NEQ ?{
103+ POP ;&on-console-escape .Console/vector DEO2
104+ BRK }
105+ /<handle-input>
106+ BRK
107+
108+@input/on-console-escape ( -> )
109+ .Console/read ] DEI DUP #0a EQU ?{
110+ LIT "\ /<handle-input>
111+ DUP /<handle-input> }
112+ ;&on-console .Console/vector DEO2
113+ BRK
114+
115+@input/<bind> ( -- )
116+ ;&on-controller .Controller/vector DEO2
117+ ;&on-console .Console/vector DEO2 !/<redraw>
118+
119+@input/<handle-input> ( c -- )
120+ DUP ?{ POP JMP2r }
121+ DUP #08 EQU ?/on-bs
122+ DUP #09 EQU ?/on-tab
123+ DUP #0a EQU ?/on-enter
124+ DUP #7f EQU ?/on-del
125+ DUP #20 GTH ?{ POP #20 }
126+ sel/<reset-draw>
127+ /<push>
128+ autocomplete/<update> !/<redraw>
129+
130+ &on-bs ( c -- )
131+ POP /<pop>
132+ autocomplete/<reset> !/<redraw>
133+
134+ &on-tab ( c -- )
135+ POP autocomplete/get INC2k ORA ?{ POP2 JMP2r }
136+ /<push-str> !/<redraw>
137+
138+ &on-enter ( c -- )
139+ POP autocomplete/<reset> !/<eval>
140+
141+ &on-del ( c -- )
142+ POP !/<blank>
143+
144+@input/is-active ( -- t )
145+ [ LIT2 -&buf _&+ptr ] LDR NEQ JMP2r
146+
147+@input/get-length ( -- length* )
148+ [ LIT2 00 _&+ptr ] LDR .&buf SUB JMP2r
149+
150+@input/<reset> ( -- )
151+ #0000 .&buf STZ2
152+ [ LIT2 -&buf _&+ptr ] STR !autocomplete/<reset>
153+
154+@input/<push-str-quoted> ( str* -- )
155+ DUP2 str/is-word ?/<push-str>
156+ LIT "" /<push>
157+ /<push-str>
158+ LIT "" !/<push>
159+
160+@input/<push-str> ( str* -- )
161+ &>w
162+ LDAk DUP ?{ POP POP2 !/<redraw> }
163+ str/escape /<push>
164+ INC2 !/>w
165+
166+@input/<push> ( c -- )
167+ [ LIT2 00 &+ptr -&buf ] INCk ,&+ptr STR
168+ STZ2
169+ JMP2r
170+
171+@input/<pop> ( -- )
172+ ,&+ptr LDR
173+ ( cap ) DUP .&buf NEQ ?{ POP JMP2r }
174+ #01 SUB #00 OVR STZ
175+ ,&+ptr STR
176+ JMP2r
177+
178+@input/<eval-partial> ( -- )
179+ ;&buf LDAk ?{ POP2 !bios/<welcome> }
180+ bios/<parse-partial> !/<reset-draw>
181+
182+@input/<eval> ( -- )
183+ sel/is-active ?sel/<pick>
184+ ( >> )
185+
186+@input/<eval-force> ( -- )
187+ ;&buf LDAk ?{ POP2 !bios/<welcome> }
188+ bios/<parse> !/<reset-draw>
189+
190+@input/<blank> ( -- )
191+ sel/is-active ?sel/<reset-draw>
192+ bios/<redraw>
193+ ( >> )
194+
195+@input/<reset-draw> ( -- )
196+ /<reset>
197+ ( >> )
198+
199+@input/<redraw> ( -- )
200+ ;bios/anchor-x #0018 Screen/<set-pos>
201+ [ LIT2 e0 -Screen/pixel ] DEO
202+ #0008 .Screen/y DEO2
203+ path/<draw>
204+ /get-origin #45 font/<draw-str-color>
205+ autocomplete/<draw>
206+ ;&caret !font/<draw-sprite>
207+
208+@input/get-origin ( -- buf* )
209+ /get-length window/get-margin #03 SFT2 #0002 SUB2 LTH2k ?{
210+ ( follow cursor ) SUB2 ;&buf ADD2 JMP2r }
211+ POP2 POP2 ;&buf JMP2r
212+
213+@autocomplete/get ( -- str* )
214+ ,&addr LDR2 INC2k ORA ?{ JMP2r }
215+ ;input/buf str/len ADD2 JMP2r
216+
217+@autocomplete/<reset> ( -- )
218+ #ffff ,&addr STR2
219+ JMP2r
220+
221+@autocomplete/<update> ( -- )
222+ ;input/buf bios/find-seg INC2k ORA ?{ POP2 !/<reset> }
223+ LDA2 ,&addr STR2
224+ JMP2r
225+
226+@autocomplete/<draw> ( -- )
227+ [ LIT2 &addr $2 ] INC2k ORA ?{ POP2 JMP2r }
228+ input/get-length ADD2 #43 !font/<draw-str-color>
229+
230+(
231+@|Bios )
232+
233+@bios/<parse> ( str* -- )
234+ /<reset>
235+ dict/<reset>
236+ ( >> )
237+
238+@bios/<parse-partial> ( str* -- )
239+ sel/<reset>
240+ str/walk-ws banner/<request>
241+ &>w
242+ /parse-symbol str/walk-ws LDAk ?/>w
243+ POP2 reader/is-bound ?{ !/<redraw> }
244+ JMP2r
245+
246+@bios/parse-symbol ( addr* -- next* )
247+ LDAk LIT "~ EQU ?/parse-include
248+ dict/alloc !/<push>
249+
250+@bios/parse-include ( addr* -- next* )
251+ INC2 dict/alloc path/make dir/load-temp !/<parse-partial>
252+
253+@bios/<welcome> ( -- )
254+ /<reset>
255+ banner/<request>
256+ now/<eval>
257+ ;dict/ready2 /<push> !/<redraw>
258+
259+@bios/<dir> ( -- )
260+ sel/is-active ?sel/<reset-draw>
261+ input/is-active ?input/<reset-draw>
262+ /<reset>
263+ dir/<eval> !/<redraw>
264+
265+@bios/find-seg ( str* -- <res>* )
266+ ,&t STR2
267+ ;&+ptr LDA2 ;&buf
268+ &>lfs
269+ NEQ2k ?{
270+ POP2 #ffff &end NIP2 JMP2r }
271+ LDA2k [ LIT2 &t $2 ] str/seg ?/end
272+ INC2 INC2 !/>lfs
273+
274+@bios/get-symbol ( id -- sym* )
275+ #00 SWP DUP ADD ;&buf ADD2 LDA2 JMP2r
276+
277+@bios/get-depth ( -- depth* )
278+ ,&+ptr LDR2 ;&buf SUB2 #01 SFT2 JMP2r
279+
280+@bios/is-empty ( -- fail )
281+ ,&+ptr LDR2 ;&buf EQU2 JMP2r
282+
283+@bios/is-thtwo ( -- fail )
284+ /get-depth #0002 LTH2 JMP2r
285+
286+@bios/is-ththree ( -- fail )
287+ /get-depth #0003 LTH2 JMP2r
288+
289+@bios/<reset> ( -- )
290+ ;&buf ,&+ptr STR2 !scroll/<reset>
291+
292+@bios/<run> ( str* cmd* -- )
293+ NIP2
294+ ( get cmd ) LDA2
295+ ( get eval ) INC2 INC2 LDA2
296+ ( apply ) JMP2
297+
298+@bios/<push-bool> ( bool -- )
299+ ?{ ;dict/f !/<push> }
300+ ;dict/t
301+ ( >> )
302+
303+@bios/<push> ( str* -- )
304+ DUP2 cmds/find INC2k ORA ?/<run>
305+ POP2
306+ ( >> )
307+
308+@bios/<push-raw> ( str* -- )
309+ ( | put on stack )
310+ [ LIT2 &+ptr =&buf ]
311+ ( clamp ) DUP2 ;&cap NEQ2 ?{ POP2 POP2 JMP2r }
312+ INC2k INC2 ,&+ptr STR2
313+ STA2
314+ JMP2r
315+
316+@bios/pop ( -- addr* )
317+ ,&+ptr LDR2 #0002 SUB2 LDA2k SWP2 ,&+ptr STR2
318+ JMP2r
319+
320+@bios/<push-err-underflow> ( -- )
321+ ;dict/err-underflow !/<push>
322+
323+@bios/<push-err-missing> ( -- )
324+ ;dict/err-missing !/<push>
325+
326+@bios/<push-err-binary> ( -- )
327+ ;dict/err-binary !/<push>
328+
329+@bios/<redraw> ( -- )
330+ #0000 ;&anchor-y Screen/<set-pos>
331+ [ LIT2 c0 -Screen/pixel ] DEO
332+ ;&anchor-y .Screen/y DEO2
333+ ,&+ptr LDR2 ;&buf scroll/get STHk DUP2 ADD2 ADD2
334+ ( | Draw scroll )
335+ scroll/<draw>
336+ &>l
337+ NEQ2k ?{ POP2 POP2 POPr !banner/<draw> }
338+ LDA2k symbol/make DUP2 /<draw-spacer>
339+ STHkr sel/is-unselected symbol/<draw>
340+ INCr INC2 INC2 !/>l
341+
342+@bios/<draw-spacer> ( symbol* -- )
343+ font/get-width .Screen/x DEI2 ADD2 window/get-margin LTH2 ?{ !font/<draw-lb> }
344+ .Screen/x DEI2k #0008 ADD2 ROT DEO2
345+ JMP2r
346+
347+@bios/<use> ( id -- )
348+ /get-symbol
349+ ( | handlers )
350+ DUP2 str/is-dir ?/<use-mov>
351+ DUP2 str/is-icn ?/<use-icn>
352+ DUP2 str/is-rom ?/<use-run>
353+ DUP2 path/make file/is-text ?/<use-txt>
354+ POP2 JMP2r
355+
356+@bios/<use-mov> ( str* -- )
357+ input/<push-str>
358+ ;&cmd-mov !input/<push-str>
359+
360+ &cmd-mov 20 "mov 00
361+
362+@bios/<use-icn> ( str* -- )
363+ input/<push-str>
364+ ;&cmd-icn !input/<push-str>
365+
366+ &cmd-icn 20 "1 20 "icn 00
367+
368+@bios/<use-run> ( str* -- )
369+ input/<push-str>
370+ ;&cmd-run !input/<push-str>
371+
372+ &cmd-run 20 "run 00
373+
374+@bios/<use-txt> ( name* -- )
375+ input/<push-str>
376+ ;&cmd-txt !input/<push-str>
377+
378+ &cmd-txt 20 "0 20 "txt 00
379+
380+@symbol/<draw> ( str* unsel -- )
381+ ?{
382+ DUP2 str/is-dir ?/<draw-dir>
383+ DUP2 str/is-rom ?/<draw-use>
384+ ( selected ) #49 !font/<draw-str-color> }
385+ ( unselected ) #45 !font/<draw-str-color>
386+
387+@symbol/<draw-dir> ( str* -- )
388+ #4d !font/<draw-str-color>
389+
390+@symbol/<draw-use> ( str* -- )
391+ #44 !font/<draw-str-color>
392+
393+@symbol/make ( str* -- sym* )
394+ ;&buf DUP2 ,&+ptr STR2
395+ SWP2 [ LIT2r 1c00 ]
396+ &>w
397+ NEQkr STHr ?{
398+ [ LIT2 ".. ] /<push>
399+ /<push> !/end }
400+ LDAk DUP ?{
401+ POP &end POP2r POP2 #00 !/<push> }
402+ DUP #0a NEQ ?{ POP #20 }
403+ /<push>
404+ INCr INC2 !/>w
405+
406+@symbol/<push> ( c -- )
407+ #00 [ LIT2 &+ptr =&buf ] INC2k ,&+ptr STR2
408+ STA2
409+ JMP2r
410+
411+(
412+@|Path )
413+
414+@path/<move> ( str* -- )
415+ DUP2 ;dict/out-path str/cmp ?/<pop>
416+ ( | Check if file is a folder )
417+ LITr _&+ptr LDR2r /<push-str>
418+ ;&buf file/is-dir ?{
419+ #00 STH2kr STA
420+ LITr _&+ptr STR2r
421+ JMP2r }
422+ POP2r
423+ ( | Add missing slash )
424+ /is-dir ?{ LIT "/ /<push> }
425+ JMP2r
426+
427+@path/is-home ( -- t )
428+ ;&buf str/len #0002 EQU2 JMP2r
429+
430+@path/is-dir ( -- t )
431+ ,&+ptr LDR2 #0001 SUB2 LDA LIT "/ EQU JMP2r
432+
433+@path/<pop> ( str* -- )
434+ POP2
435+ ( | find last slash )
436+ ;&buf ,&+ptr LDR2 #0001 SUB2
437+ &>lp
438+ #0001 SUB2 LDAk LIT "/ EQU ?{ LTH2k ?/>lp }
439+ INC2 #0000 OVR2 STA2
440+ ,&+ptr STR2
441+ POP2 JMP2r
442+
443+@path/<set> ( str* -- )
444+ ;&buf ,&+ptr STR2
445+ ( >> )
446+
447+@path/<push-str> ( str* -- )
448+ &>w
449+ LDAk DUP ?{ POP POP2 JMP2r }
450+ /<push>
451+ INC2 !/>w
452+
453+@path/<push> ( str* -- )
454+ #00 [ LIT2 &+ptr =&buf ]
455+ ( clamp ) DUP2 ;&cap NEQ2 ?{ POP2 POP POP2 JMP2r }
456+ INC2k ,&+ptr STR2
457+ STA2
458+ JMP2r
459+
460+@path/<draw> ( -- )
461+ ;&buf #45 !font/<draw-str-color>
462+
463+@path/make ( str* -- path* )
464+ ;&buf !dict/alloc-cat
465+
466+(
467+@|Selection )
468+
469+@sel/<use> ( -- )
470+ input/is-active ?input/<eval-force>
471+ ,&id LDR INCk ?bios/<use>
472+ POP JMP2r
473+
474+@sel/<prev> ( -- )
475+ ,&id LDR
476+ ( clamp ) INCk ?{ POP JMP2r }
477+ #01 SUB #00 OVR scroll/<follow> !/<set>
478+
479+@sel/<next> ( -- )
480+ ,&id LDR INC
481+ ( clamp ) DUP bios/get-depth NIP LTH ?/<set>
482+ POP JMP2r
483+
484+@sel/has-meta ( -- t )
485+ ,&id LDR INCk ?{ POP #00 JMP2r }
486+ bios/get-symbol DUP2 str/is-rom ?{ POP2 #00 JMP2r }
487+ path/make file/get-meta ORAk ?{ POP2 #00 JMP2r }
488+ meta/<load>
489+ #01 JMP2r
490+
491+@sel/is-active ( -- bool )
492+ #ff
493+ ( >> )
494+
495+@sel/is-unselected ( id -- bool )
496+ [ LIT &id ff ] NEQ JMP2r
497+
498+@sel/<activate> ( -- )
499+ #00
500+ ( >> )
501+
502+@sel/<set> ( id -- )
503+ DUP ,&id LDR NEQ ?{ POP JMP2r }
504+ ,&id STR !bios/<redraw>
505+
506+@sel/<pick> ( -- )
507+ ,&id LDR INCk ?{ POP JMP2r }
508+ bios/get-symbol
509+ ( clamp ) DUP2 str/len #0040 LTH2 ?{ POP2 !input/<redraw> }
510+ input/<push-str-quoted>
511+ #20 input/<push> !input/<redraw>
512+
513+@sel/<reset> ( -- )
514+ [ LIT2 ff _&id ] STR
515+ JMP2r
516+
517+@sel/<reset-draw> ( -- )
518+ scroll/<reset>
519+ ,&id LDR /<reset>
520+ ,&id LDR NEQ ?bios/<redraw>
521+ JMP2r
522+
523+@sel/<follow> ( id -- )
524+ ,&id LDR GTHk ?{ POP2 JMP2r }
525+ POP ,&id STR
526+ JMP2r
527+
528+(
529+@|Scroll )
530+
531+@scroll/<up> ( -- )
532+ ,&+pos LDR2
533+ ( clamp ) ORAk ?{ POP2 JMP2r }
534+ #0001 SUB2 /<set> !bios/<redraw>
535+
536+@scroll/<down> ( -- )
537+ sel/is-active ?{ !sel/<activate> }
538+ ,&+pos LDR2
539+ ( clamp ) INC2k bios/get-depth LTH2 ?{ POP2 JMP2r }
540+ INC2 DUP sel/<follow>
541+ /<set> !bios/<redraw>
542+
543+@scroll/<follow> ( id* -- )
544+ ,&+pos LDR2 LTH2k ?{ POP2 POP2 JMP2r }
545+ POP2 !/<set>
546+
547+@scroll/<reset> ( -- )
548+ #0000
549+ ( >> )
550+
551+@scroll/<set> ( id* -- )
552+ ,&+pos STR2
553+ JMP2r
554+
555+@scroll/get ( -- id* )
556+ ,&+pos LDR2 JMP2r
557+
558+@scroll/<draw> ( -- )
559+ [ LIT2 &+pos $2 ] ORAk ?{ POP2 JMP2r }
560+ ;bios/anchor-x .Screen/x DEO2
561+ bios/get-depth SWP2 INC2 SUB2 dec/make #43 font/<draw-str-color>
562+ #09 !font/<draw-glyph>
563+
564+(
565+@|Reader )
566+
567+@reader/on-controller ( -> )
568+ .Controller/button DEI
569+ ( | handlers )
570+ DUP #01 NEQ ?{ /<leave> }
571+ DUP #10 NEQ ?{ /<select-prev> }
572+ DUP #20 NEQ ?{ /<select-next> }
573+ POP .Controller/key DEI DUP ?{ POP BRK }
574+ /<leave>
575+ input/<handle-input>
576+ BRK
577+
578+@reader/<leave> ( -- )
579+ input/<bind> !bios/<redraw>
580+
581+@reader/is-bound ( -- t )
582+ .Controller/vector DEI2 ;&on-controller EQU2 JMP2r
583+
584+@reader/<bind> ( str* -- )
585+ .File/name DEO2
586+ ;&on-controller .Controller/vector DEO2
587+ ( col ) window/get-cols #0001 SUB2 ,&col STR
588+ POP
589+ ( row ) window/get-rows #01 SFT2 #0003 SUB2 ,&row STR
590+ POP #0000 !/<select-line>
591+
592+@reader/<select-prev> ( -- )
593+ ,&line LDR2 ORAk ?{ POP2 JMP2r }
594+ #0001 SUB2 !/<select-line>
595+
596+@reader/<select-next> ( -- )
597+ [ LIT2 &line $2 ] INC2
598+ ( >> )
599+
600+@reader/<select-line> ( line* -- )
601+ DUP2 file/seek-line ?{ POP2 JMP2r }
602+ ;bios/anchor-x ;bios/anchor-y Screen/<set-pos>
603+ [ LIT2 c0 -Screen/pixel ] DEO
604+ [ LIT2 15 -Screen/auto ] DEO
605+ #0001 .File/length DEO2
606+ ( | Draw line number )
607+ [ LITr &col $1 ] DUP2 dec/make
608+ ( store col ) DUP2 str/len #03 ADD STH
609+ POP #43 font/<draw-str-color>
610+ #09 font/<draw-glyph>
611+ #20 font/<draw-glyph>
612+ ,&line STR2
613+ ( | Render )
614+ #41 ;font/color STA
615+ ( | Stream )
616+ [ LIT2 &row $1 00 ]
617+ &>s
618+ ;&b .File/read DEO2
619+ .File/success-lb DEI ?{
620+ POP2 POP2r ;dict/eof #44 !font/<draw-str-color> }
621+ ( | hard-wrap )
622+ GTHkr STHr ?{
623+ ;bios/anchor-x .Screen/y DEI2 #0010 ADD2 Screen/<set-pos>
624+ INC POPr LITr 00 }
625+ [ LIT &b $1 ] DUP #0a NEQ ?{
626+ SWP INC SWP POPr LITr 00 }
627+ font/<draw-glyph>
628+ INCr GTHk ?/>s
629+ POP2 POP2r JMP2r
630+
631+(
632+@|Commands )
633+
634+@cmds/find ( str* -- <cmd>* )
635+ ,&fn STR2
636+ ;&lutend ;&lut
637+ &>l
638+ LDA2k LDA2 [ LIT2 &fn $2 ] str/cmp ?{
639+ INC2 INC2 GTH2k ?/>l
640+ POP2 #ffff }
641+ NIP2 JMP2r
642+
643+@cmds/lut [ =cmd/api ]
644+ &lut-clip [4
645+ =dir/api =mov/api =now/api =run/api
646+ =icn/api =txt/api =len/api =put/api
647+ =get/api =cpy/api =era/api =ren/api
648+ =pop/api =dup/api =ovr/api =swp/api
649+ =rot/api =dec/api =hex/api =cat/api
650+ =add/api =sub/api =cmp/api =and/api
651+ =ora/api =rsz/api =out/api =bye/api
652+ &lutend ]
653+
654+@cmd/<eval> ( -- )
655+ ;cmds/lutend ;cmds/lut-clip
656+ &>l
657+ LDA2k #0004 ADD2 bios/<push-raw>
658+ INC2 INC2 GTH2k ?/>l
659+ POP2 POP2 JMP2r
660+ &api =dict/cmd =&<eval> "<cmd> 20 "( 20 09 20 ") 00
661+
662+@dir/<eval> ( -- )
663+ ;path/buf .File/name DEO2
664+ ;&buflen .File/length DEO2
665+ ;&buf .File/read DEO2
666+ path/is-home ?{ ;dict/out-path bios/<push-raw> }
667+ .File/success DEI2
668+ ( | Handlers )
669+ DUP2 /<push-folders>
670+ DUP2 /<push-files> !/<push-dotfiles>
671+
672+@dir/find-wallpaper ( -- size* )
673+ ;dict/home-path .File/name DEO2
674+ ;&buflen .File/length DEO2
675+ ;&buf .File/read DEO2
676+ /<explode>
677+ ;&buf
678+ &>w
679+ str/is-wallpaper ?{
680+ str/cap INC2 LDAk ?/>w
681+ POP2 #ffff }
682+ JMP2r
683+
684+@dir/<explode> ( -- )
685+ ;&buf
686+ &>we
687+ LDAk DUP ?{ POP POP2 JMP2r }
688+ #1f GTH ?{ LITr 00 STH2k STAr }
689+ INC2 !/>we
690+
691+@dir/<push-folders> ( length* -- )
692+ ;&buf ADD2 ;&buf
693+ &>lfo
694+ LDAk LIT "- NEQ STH
695+ #0005 ADD2 STHr ?{
696+ LDAk LIT ". EQU ?{ dict/alloc-line bios/<push-raw> } }
697+ str/eol INC2 GTH2k ?/>lfo
698+ POP2 POP2 JMP2r
699+
700+@dir/<push-files> ( length* -- )
701+ ;&buf ADD2 ;&buf
702+ &>lfi
703+ LDAk LIT "- EQU STH
704+ #0005 ADD2 STHr ?{
705+ LDAk LIT ". EQU ?{ dict/alloc-line bios/<push-raw> } }
706+ str/eol INC2 GTH2k ?/>lfi
707+ POP2 POP2 JMP2r
708+
709+@dir/<push-dotfiles> ( length* -- )
710+ ;&buf ADD2 ;&buf
711+ &>ldf
712+ #0005 ADD2 LDAk LIT ". NEQ ?{ dict/alloc-line bios/<push-raw> }
713+ str/eol INC2 GTH2k ?/>ldf
714+ POP2 POP2 JMP2r
715+ &api =dict/dir =&<eval> "<dir> 20 "( 20 09 20 "[f] 20 ") 00
716+
717+@dir/load-temp ( addr* -- buf* )
718+ .File/name DEO2
719+ ;&buflen .File/length DEO2
720+ ;&buf DUP2 .File/read DEO2
721+ JMP2r
722+
723+@mov/<eval> ( -- )
724+ bios/is-empty ?bios/<push-err-underflow>
725+ bios/pop path/<move> !dir/<eval>
726+ &api =dict/mov =&<eval> "<mov> 20 "( 20 "path 20 09 20 "[f] 20 ") 00
727+
728+@now/<eval> ( -- )
729+ date/make bios/<push>
730+ time/make !bios/<push>
731+ &api =dict/now =&<eval> "<now> 20 "( 20 09 20 "date 20 "time 20 ") 00
732+
733+@run/<eval> ( -- )
734+ bios/is-empty ?bios/<push-err-underflow>
735+ bios/pop path/make
736+ ( ? ) DUP2 file/exists ?loader/<bind>
737+ POP2 !bios/<push-err-missing>
738+ &api =dict/run =&<eval> "<run> 20 "( 20 "f.rom 20 09 20 "ok 20 ") 00
739+
740+@txt/<eval> ( -- )
741+ bios/is-thtwo ?bios/<push-err-underflow>
742+ ( line* ) bios/pop
743+ ( path* ) bios/pop path/make
744+ ( ? ) DUP2 file/exists ?{ POP2 POP2 !bios/<push-err-missing> }
745+ ( ? ) DUP2 file/is-text ?{ POP2 POP2 !bios/<push-err-binary> }
746+ reader/<bind>
747+ str/dec reader/<select-line>
748+ ;dict/ok !bios/<push>
749+ &api =dict/txt =&<eval> "<txt> 20 "( 20 "f.txt 20 "line 20 09 20 "ok 20 ") 00
750+
751+@icn/<eval> ( -- )
752+ bios/is-empty ?bios/<push-err-underflow>
753+ ( color ) bios/pop str/dec NIP
754+ ( path ) bios/pop path/make
755+ ( ? ) DUP2 file/exists ?{ POP2 POP !bios/<push-err-missing> }
756+ ROT /<draw>
757+ ;dict/ok !bios/<push>
758+
759+@icn/<draw> ( name* blend -- )
760+ #0f AND ,&blend STR
761+ DUP2 .File/name DEO2
762+ ( | depth )
763+ #0008 .File/length DEO2
764+ [ LIT2r &blend 03 -Screen/sprite ] ;&buf .Screen/addr DEO2
765+ ( | size )
766+ /read-size
767+ ( h ) #00 SWP SUBk ,&height STR
768+ ( y ) #31 SFT2 window/get-middle SWP2 SUB2 .Screen/y DEO2
769+ ( w ) #00 SWP SUBk ,&width STR
770+ ( x ) #31 SFT2 window/get-center SWP2 SUB2 ,&anchor STR2
771+ ( | draw )
772+ [ LIT2 01 -Screen/auto ] DEO
773+ [ LIT &height $1 ]
774+ &>v
775+ [ LIT2 &anchor $2 ] .Screen/x DEO2
776+ [ LIT &width $1 ]
777+ &>h
778+ ;&buf .File/read DEO2
779+ DEOkr
780+ INC DUP ?/>h
781+ POP
782+ ( lb ) .Screen/y DEI2k #0008 ADD2 ROT DEO2
783+ INC DUP ?/>v
784+ POP POP2r JMP2r
785+
786+@icn/read-size ( str* -- w h )
787+ str/cap #0009 SUB2
788+ ( no size ) INC2k INC2 LDA [ LIT "x ] EQU ?{ POP2 #1010 JMP2r }
789+ LDA2k str/read-byte STH
790+ #0003 ADD2 LDA2 str/read-byte STHr SWP JMP2r
791+ &api =dict/icn =&<eval> "<icn> 20 "( 20 "f.icn 20 "blend 20 09 20 "ok 20 ") 00
792+
793+@put/<eval> ( -- )
794+ bios/is-thtwo ?bios/<push-err-underflow>
795+ bios/pop path/make .File/name DEO2
796+ bios/pop DUP2 str/len .File/length DEO2
797+ .File/write DEO2
798+ ;dict/ok !bios/<push>
799+ &api =dict/put =&<eval> "<put> 20 "( 20 "body 20 "f 20 09 20 "ok 20 ") 00
800+
801+@get/<eval> ( -- )
802+ bios/is-empty ?bios/<push-err-underflow>
803+ bios/pop path/make
804+ ( ? ) DUP2 file/exists ?{ POP2 !bios/<push-err-missing> }
805+ ( ? ) DUP2 file/is-text ?{ POP2 !bios/<push-err-binary> }
806+ dict/alloc-file !bios/<push>
807+ &api =dict/get =&<eval> "<get> 20 "( 20 "f 20 09 20 "body 20 ") 00
808+
809+@cpy/<eval> ( -- )
810+ bios/is-thtwo ?bios/<push-err-underflow>
811+ ( dst ) bios/pop path/make
812+ ( src ) bios/pop path/make
813+ ( ? ) DUP2 file/exists ?{ POP2 POP2 !bios/<push-err-missing> }
814+ SWP2 file/<cpy>
815+ ;dict/ok !bios/<push>
816+ &api =dict/cpy =&<eval> "<cpy> 20 "( 20 "fsrc 20 "fdst 20 09 20 "ok 20 ") 00
817+
818+@era/<eval> ( -- )
819+ bios/is-empty ?bios/<push-err-underflow>
820+ bios/pop path/make
821+ ( ? ) DUP2 file/exists ?{ POP2 !bios/<push-err-missing> }
822+ .File/name DEO2
823+ [ LIT2 01 -File/delete ] DEO
824+ ;dict/ok !bios/<push>
825+ &api =dict/era =&<eval> "<era> 20 "( 20 "f 20 09 20 "ok 20 ") 00
826+
827+@ren/<eval> ( -- )
828+ bios/is-thtwo ?bios/<push-err-underflow>
829+ ( dst ) bios/pop path/make
830+ ( src ) bios/pop path/make
831+ ( ? ) DUP2 file/exists ?{ POP2 POP2 !bios/<push-err-missing> }
832+ DUP2 ROT2 file/<cpy>
833+ .File/name DEO2
834+ [ LIT2 01 -File/delete ] DEO
835+ ;dict/ok !bios/<push>
836+ &api =dict/ren =&<eval> "<ren> 20 "( 20 "fsrc 20 "fdst 20 09 20 "ok 20 ") 00
837+
838+@len/<eval> ( -- )
839+ bios/is-empty ?bios/<push-err-underflow>
840+ bios/pop path/make
841+ ( ? ) DUP2 file/exists ?{ POP2 ;dict/zero !bios/<push> }
842+ .File/name DEO2
843+ #0004 .File/length DEO2
844+ ;&buf .File/stat DEO2
845+ ;&hb LDA2 str/read-byte ;&lb LDA2 str/read-byte hex/make dict/alloc NIP2 !bios/<push>
846+ &api =dict/len =&<eval> "<len> 20 "( 20 "f 20 09 20 "hex 20 ") 00
847+
848+@dup/<eval> ( -- )
849+ bios/is-empty ?bios/<push-err-underflow>
850+ bios/pop DUP2 bios/<push> !bios/<push>
851+ &api =dict/dup =&<eval> "<dup> 20 "( 20 "a 20 09 20 "a 20 "a 20 ") 00
852+
853+@ovr/<eval> ( -- )
854+ bios/is-thtwo ?bios/<push-err-underflow>
855+ ( b ) bios/pop
856+ ( a ) bios/pop DUP2 bios/<push>
857+ SWP2 bios/<push> !bios/<push>
858+ &api =dict/ovr =&<eval> "<ovr> 20 "( 20 "a 20 "b 20 09 20 "a 20 "b 20 "a 20 ") 00
859+
860+@pop/<eval> ( -- )
861+ bios/is-empty ?bios/<push-err-underflow>
862+ bios/pop POP2 JMP2r
863+ &api =dict/pop =&<eval> "<pop> 20 "( 20 "a 20 09 20 ") 00
864+
865+@swp/<eval> ( -- )
866+ bios/is-thtwo ?bios/<push-err-underflow>
867+ bios/pop bios/pop SWP2 bios/<push> !bios/<push>
868+ &api =dict/swp =&<eval> "<swp> 20 "( 20 "a 20 "b 20 09 20 "b 20 "a 20 ") 00
869+
870+@rot/<eval> ( -- )
871+ bios/is-ththree ?bios/<push-err-underflow>
872+ bios/pop bios/pop bios/pop ROT2 ROT2 bios/<push>
873+ bios/<push> !bios/<push>
874+ &api =dict/rot =&<eval> "<rot> 20 "( 20 "a 20 "b 20 "c 20 09 20 "b 20 "a 20 "c 20 ") 00
875+
876+@cat/<eval> ( -- )
877+ bios/is-thtwo ?bios/<push-err-underflow>
878+ bios/pop bios/pop dict/alloc-cat !bios/<push-raw>
879+ &api =dict/cat =&<eval> "<cat> 20 "( 20 "a 20 "b 20 09 20 "ab 20 ") 00
880+
881+@cmp/<eval> ( -- )
882+ bios/is-thtwo ?bios/<push-err-underflow>
883+ bios/pop bios/pop str/cmp !bios/<push-bool>
884+ &api =&cmd =&<eval> "<cmp> 20 "( 20 "a 20 "b 20 09 20 "bool 20 ") 00
885+ &cmd "cmp 00
886+
887+@and/<eval> ( -- )
888+ bios/is-thtwo ?bios/<push-err-underflow>
889+ ( a ) bios/pop ;dict/t str/cmp
890+ ( b ) bios/pop ;dict/t str/cmp AND !bios/<push-bool>
891+ &api =&cmd =&<eval> "<and> 20 "( 20 "a 20 "b 20 09 20 "bool 20 ") 00
892+ &cmd "and 00
893+
894+@ora/<eval> ( -- )
895+ bios/is-thtwo ?bios/<push-err-underflow>
896+ ( a ) bios/pop ;dict/t str/cmp
897+ ( b ) bios/pop ;dict/t str/cmp ORA !bios/<push-bool>
898+ &api =&cmd =&<eval> "<ora> 20 "( 20 "a 20 "b 20 09 20 "bool 20 ") 00
899+ &cmd "ora 00
900+
901+@add/<eval> ( -- )
902+ bios/is-thtwo ?bios/<push-err-underflow>
903+ ( a ) bios/pop str/dec
904+ ( b ) bios/pop str/dec ADD2 dec/make !bios/<push-raw>
905+ &api =&cmd =&<eval> "<add> 20 "( 20 "a 20 "b 20 09 20 "sum 20 ") 00
906+ &cmd "add 00
907+
908+@sub/<eval> ( -- )
909+ bios/is-thtwo ?bios/<push-err-underflow>
910+ ( a ) bios/pop str/dec
911+ ( b ) bios/pop str/dec SWP2 SUB2 dec/make !bios/<push-raw>
912+ &api =&cmd =&<eval> "<sub> 20 "( 20 "a 20 "b 20 09 20 "dif 20 ") 00
913+ &cmd "sub 00
914+
915+@dec/<eval> ( -- )
916+ bios/is-empty ?bios/<push-err-underflow>
917+ ;&buf ,&+ptr STR2
918+ bios/pop str/hex /make !bios/<push>
919+
920+@dec/make ( value* -- str* )
921+ ORAk ?{ POP2 ;dict/zero JMP2r }
922+ ;&buf ,&+ptr STR2
923+ OVR #80 AND #00 EQU ?/make-pos
924+ [ LIT "- ] /<push>
925+ #7fff AND2 #8000 SWP2 SUB2
926+ ( >> )
927+
928+@dec/make-pos ( value* -- str* )
929+ #2710 [ LIT2r 00fb ]
930+ &>wpd
931+ DIV2k #000a DIV2k MUL2 SUB2 SWPr EQUk OVR STHkr EQU AND ?{
932+ DUP LIT "0 ADD /<push>
933+ INCr }
934+ POP2 #000a DIV2 SWPr INCr STHkr ?/>wpd
935+ POP2r POP2 POP2 ;&buf JMP2r
936+
937+@dec/<push> ( c -- )
938+ #00 [ LIT2 &+ptr =&buf ] INC2k ,&+ptr STR2
939+ STA2
940+ JMP2r
941+ &api =&cmd =&<eval> "<dec> 20 "( 20 "hex 20 09 20 "dec 20 ") 00
942+ &cmd "dec 00
943+
944+@hex/<eval> ( -- )
945+ bios/is-empty ?bios/<push-err-underflow>
946+ bios/pop str/dec /make !bios/<push>
947+
948+@hex/make ( value* -- buf* )
949+ ;&buf ,&+ptr STR2
950+ SWP /<push-byte>
951+ /<push-byte>
952+ ;&buf !str/walk-zero
953+
954+@hex/<push-byte> ( byte -- )
955+ DUP #04 SFT /<push-nibble>
956+ ( >> )
957+ &<push-nibble> ( byte -- )
958+ /chr #00 [ LIT2 &+ptr =&buf ] INC2k ,&+ptr STR2
959+ STA2
960+ JMP2r
961+ &api =&cmd =&<eval> "<hex> 20 "( 20 "dec 20 09 20 "hex 20 ") 00
962+ &cmd "hex 00
963+
964+@hex/chr ( hex -- char )
965+ #0f AND DUP #09 GTH #27 MUL ADD LIT "0 ADD JMP2r
966+
967+@rsz/<eval> ( -- )
968+ bios/is-thtwo ?bios/<push-err-underflow>
969+ ( h* ) bios/pop str/dec
970+ ( w* ) bios/pop str/dec SWP2k window/<set-size>
971+ .Screen/width DEI2 EQU2 ROT ROT .Screen/height DEI2 EQU2 AND !bios/<push-bool>
972+ &api =&cmd =&<eval> "<rsz> 20 "( 20 "w 20 "h 20 09 20 "bool 20 ") 00
973+ &cmd "rsz 00
974+
975+@out/<eval> ( -- )
976+ bios/is-empty ?bios/<push-err-underflow>
977+ bios/pop !str/<print>
978+ &api =&cmd =&<eval> "<out> 20 "( 20 "a 20 09 20 ") 00
979+ &cmd "out 00
980+
981+@bye/<eval> ( -- )
982+ ;&callback !fade-out/<bind>
983+ &api =&cmd =&<eval> "<bye> 20 "( 20 09 20 ") 00
984+ &cmd "bye 00
985+
986+@bye/callback ( -> )
987+ #800f DEO
988+ BRK
989+
990+(
991+@|Dict )
992+
993+@dict/<reset> ( -- )
994+ ;&buf ,&+ptr STR2
995+ JMP2r
996+
997+@dict/<push-escaped> ( addr* -- addr* )
998+ str/escape
999+ ( >> )
1000+
1001+@dict/<push> ( c -- )
1002+ [ LIT2 &+ptr =&buf ]
1003+ ( clamp ) DUP2 ;&cap NEQ2 ?{ POP2 POP JMP2r }
1004+ INC2k ,&+ptr STR2
1005+ STA
1006+ JMP2r
1007+
1008+@dict/alloc ( str* -- str* addr* )
1009+ LDAk LIT "" EQU ?/alloc-string
1010+ LDAk LIT "( EQU ?/alloc-comment
1011+ [ LITr _&+ptr ] LDR2r
1012+ &>w
1013+ LDAk DUP #20 GTH ?{ POP STH2r #00 !/<push> }
1014+ /<push-escaped>
1015+ INC2 !/>w
1016+
1017+@dict/alloc-file ( name* -- addr* )
1018+ .File/name DEO2
1019+ #0001 .File/length DEO2
1020+ [ LITr _&+ptr ] LDR2r
1021+ &>s
1022+ ;&b .File/read DEO2
1023+ .File/success-lb DEI ?{ STH2r #00 !/<push> }
1024+ [ LIT &b $1 ] /<push> !/>s
1025+
1026+@dict/alloc-cat ( a* b* -- addr* )
1027+ [ LIT2r =&+ptr ] LDA2r
1028+ &>wc1
1029+ LDAk DUP ?{
1030+ POP POP2
1031+ &>wc2
1032+ LDAk DUP ?{
1033+ POP POP2 STH2r #00 !/<push> }
1034+ /<push-escaped>
1035+ INC2 !/>wc2 }
1036+ /<push-escaped>
1037+ INC2 !/>wc1
1038+
1039+@dict/alloc-string ( str* -- str* addr* )
1040+ INC2 [ LIT2r =&+ptr ] LDA2r
1041+ &>was
1042+ LDAk DUP ?{ &end-s POP INC2 STH2r #00 !/<push> }
1043+ DUP LIT "" EQU ?/end-s
1044+ /<push-escaped>
1045+ INC2 !/>was
1046+
1047+@dict/alloc-comment ( str* -- str* addr* )
1048+ [ LIT2r =&+ptr ] LDA2r
1049+ &>wac
1050+ LDAk DUP ?{ &end-c /<push>
1051+ INC2 STH2r #00 !/<push> }
1052+ DUP LIT ") EQU ?/end-c
1053+ /<push-escaped>
1054+ INC2 !/>wac
1055+
1056+@dict/alloc-line ( str* -- str* addr* )
1057+ [ LIT2r =&+ptr ] LDA2r
1058+ &>wal
1059+ LDAk DUP #1f GTH ?{ POP STH2r #00 !/<push> }
1060+ /<push-escaped>
1061+ INC2 !/>wal
1062+
1063+(
1064+@|Font )
1065+
1066+@font/<draw-str-color> ( str* color -- )
1067+ ,&color STR
1068+ ( >> )
1069+
1070+@font/<draw-str> ( str* -- )
1071+ [ LIT2 15 -Screen/auto ] DEO
1072+ &>w
1073+ LDAk DUP ?{ POP POP2 JMP2r }
1074+ DUP LIT "< NEQ ?{ POP !kbd/<draw-str> }
1075+ /<draw-glyph>
1076+ INC2 !/>w
1077+
1078+@font/<draw-glyph> ( c -- )
1079+ DUP #0a NEQ ?{ POP !/<draw-lb> }
1080+ DUP #09 NEQ ?{ POP !/<draw-tab> }
1081+ #00 SWP #20 SUB #40 SFT2 ;&glyphs ADD2
1082+ ( >> )
1083+
1084+@font/<draw-sprite> ( addr* -- )
1085+ .Screen/addr DEO2
1086+ [ LIT2 &color 45 -Screen/sprite ] DEO
1087+ JMP2r
1088+
1089+@font/<draw-lb> ( -- )
1090+ [ LIT2 &anchor =bios/anchor-x ] .Screen/y DEI2 #0010 ADD2 Screen/<set-pos>
1091+ JMP2r
1092+
1093+@font/<draw-tab> ( -- )
1094+ ;&tab !/<draw-sprite>
1095+
1096+@font/get-width ( str* -- width* )
1097+ [ LIT2r 0000 ]
1098+ &>wgw
1099+ LDAk ?{ POP2 STH2r JMP2r }
1100+ LIT2r 0008 ADD2r INC2 !/>wgw
1101+
1102+@kbd/<draw-str> ( str* -- )
1103+ INC2 [ LIT2 15 -Screen/auto ] DEO
1104+ ;&a font/<draw-sprite>
1105+ &>w
1106+ LDAk DUP ?{ POP POP2 JMP2r }
1107+ DUP LIT "> NEQ ?{
1108+ POP [ LIT2 15 -Screen/auto ] DEO
1109+ ;&c font/<draw-sprite>
1110+ INC2 !font/<draw-str> }
1111+ /<draw-glyph>
1112+ INC2 !/>w
1113+
1114+@kbd/<draw-glyph> ( c -- )
1115+ [ LIT2 05 -Screen/auto ] DEO
1116+ [ LITr -Screen/x ] DEI2r .Screen/y DEI2 STH2k #0004 ADD2 .Screen/y DEO2
1117+ #00 SWP #20 SUB #30 SFT2 ;&glyphs ADD2 font/<draw-sprite>
1118+ [ LITr -Screen/y ] DEO2r
1119+ [ LITr -Screen/x ] DEO2r
1120+ [ LIT2 15 -Screen/auto ] DEO
1121+ ;&b !font/<draw-sprite>
1122+
1123+(
1124+@|Loader )
1125+
1126+@loader/<load-expansion> ( -- )
1127+ #ff00 file/<seek>
1128+ ;&pagelen .File/length DEO2
1129+ ;&page .File/read DEO2
1130+ #0000
1131+ &>s
1132+ ;&page .File/read DEO2
1133+ .File/success DEI2 ORA ?{ POP2 JMP2r }
1134+ DUP2k #80 SFT2 ,&a STR2
1135+ #08 SFT2 INC2 ,&p STR2
1136+ ;&mmu-mov .System/expansion DEO2
1137+ INC2 !/>s
1138+
1139+ &mmu-mov [ 01 =&pagelen 0000 =&page &p $2 &a $2 ]
1140+
1141+@loader/<bind> ( path* -- )
1142+ ;&buf ,&+ptr STR2
1143+ &>w
1144+ LDAk DUP ?{ POP POP2 !/<launch> }
1145+ #00 [ LIT2 &+ptr =&buf ] INC2k ,&+ptr STR2
1146+ STA2
1147+ INC2 !/>w
1148+
1149+@loader/<set-instant> ( -- )
1150+ [ LIT2 01 _loader/instant ] STR
1151+ JMP2r
1152+
1153+@loader/<launch> ( -- )
1154+ [ LIT &instant $1 ] ?{ ;&callback !fade-out/<bind> }
1155+ ;&callback .Screen/vector DEO2
1156+ JMP2r
1157+
1158+@loader/callback ( -> )
1159+ ;&buf file/is-oversized #00 EQU ?{ /<load-expansion> }
1160+ #0000 DUP2 Screen/<set-pos>
1161+ ( | Clear screen )
1162+ [ LIT2 80 -Screen/pixel ] DEO
1163+ [ LIT2 c0 -Screen/pixel ] DEO
1164+ ( | Blank vectors )
1165+ #0000 #00 &l DEO2k #10 ADD DUP [ ?/l POP POP2 ]
1166+ ( | Blank arguments )
1167+ [ LIT2 00 -Console/type ] DEO
1168+ ( | Setup file )
1169+ ;&buf .File/name DEO2
1170+ #ff00 .File/length DEO2
1171+ ( | Copy loader )
1172+ ;&mmu .System/expansion DEO2
1173+ ( 0pg ) #00f5 .System/expansion
1174+ ( buf ) #0100 .File/read
1175+ ( 1pg ) #00f1 .System/expansion !/entry
1176+
1177+ &mmu [ 01 000f 0000 =&rom 0000 00f1 ]
1178+ &rom [ 00ff 0000 0001 0000 0000 0000 3737 37 ]
1179+
1180+(
1181+@|Fade )
1182+
1183+@fade-out/<bind> ( callback* -- )
1184+ ,&callback STR2
1185+ ;&on-frame .Screen/vector DEO2
1186+ [ LIT2 00 _&f ] STR
1187+ JMP2r
1188+
1189+@fade-out/on-frame ( -> )
1190+ [ LIT &f $1 ] INCk ,&f STR
1191+ DUP #20 LTH ?{
1192+ POP [ LIT2 &callback $2 ] JMP2 }
1193+ ( | Fill )
1194+ ( color ) DUP #04 SFT #60 SFT
1195+ ( addr* ) #00 ROT #0f AND #30 SFT2 ;curtain/out-short ADD2 window/<fill>
1196+ BRK
1197+
1198+@window/<set-size> ( w* h* -- )
1199+ .Screen/height DEO2
1200+ .Screen/width DEO2
1201+ input/<redraw>
1202+ /<update>
1203+ ( >> )
1204+
1205+@window/<draw-spacer> ( -- )
1206+ #0000 #0018 Screen/<set-pos>
1207+ ;&wave .Screen/addr DEO2
1208+ [ LIT2 01 -Screen/auto ] DEO
1209+ /get-cols SUB [ LIT2r 41 -Screen/sprite ]
1210+ &>l
1211+ DEOkr
1212+ INC DUP ?/>l
1213+ POP POP2r JMP2r
1214+
1215+@window/<update> ( -- )
1216+ .Screen/width DEI2 DUP2 #01 SFT2 ,¢er STR2
1217+ DUP2 #0010 SUB2 ,&margin STR2
1218+ #03 SFT2 ,&cols STR2
1219+ .Screen/height DEI2 DUP2 #01 SFT2 ,&middle STR2
1220+ #03 SFT2 ,&rows STR2
1221+ ( | Load wallpaper )
1222+ dir/find-wallpaper INC2k ORA ?{ POP2 JMP2r }
1223+ #0009 ADD2 LDA2k ,&w STR2
1224+ #0003 ADD2 LDA2 ,&h STR2
1225+ ;&path #03 !icn/<draw>
1226+
1227+ &get-center [ LIT2 ¢er $2 ] JMP2r
1228+
1229+ &get-cols [ LIT2 &cols $2 ] JMP2r
1230+
1231+ &get-middle [ LIT2 &middle $2 ] JMP2r
1232+
1233+ &get-rows [ LIT2 &rows $2 ] JMP2r
1234+
1235+ &get-margin [ LIT2 &margin $2 ] JMP2r
1236+
1237+ &path "wallpaper [ &w "00 "x &h "00 ] ".icn 00
1238+
1239+@window/<fill> ( color addr* -- )
1240+ .Screen/addr DEO2
1241+ STH
1242+ [ LITr -Screen/sprite ]
1243+ ( | Draw )
1244+ #0000 DUP2 Screen/<set-pos>
1245+ [ LIT2 01 -Screen/auto ] DEO
1246+ ( h ) /get-cols SUB
1247+ ( v ) /get-rows SUB
1248+ &>v
1249+ OVR
1250+ &>h
1251+ DEOkr
1252+ INC DUP ?/>h
1253+ POP
1254+ ( | eos )
1255+ #0000 .Screen/x DEO2
1256+ .Screen/y DEI2k #0008 ADD2 ROT DEO2
1257+ INC DUP ?/>v
1258+ POP2 POP2r JMP2r
1259+
1260+(
1261+@|Stdlib )
1262+
1263+@manifest/scan ( but key -- fn* )
1264+ ORAk ?{ POP2 #ffff JMP2r }
1265+ ,&bk STR2
1266+ ;&dat
1267+ &>cat
1268+ DUP2 LDAk #00 SWP INC ADD2 SWP2 #0003 ADD2
1269+ &>opt
1270+ LDA2k [ LIT2 &bk $2 ] NEQ2 ?{
1271+ NIP2 INC2 INC2 LDA2 JMP2r }
1272+ #0006 ADD2 GTH2k ?/>opt
1273+ POP2 INC2 LDAk ?/>cat
1274+ POP2 #ffff JMP2r
1275+
1276+@file/get-meta ( path* -- addr* )
1277+ #0000 ,&port-deo2 STR2
1278+ ( | lit2 addr* )
1279+ .File/name DEO2
1280+ #0001 .File/length DEO2
1281+ ;&lit2 .File/read DEO2
1282+ #0002 .File/length DEO2
1283+ ;&addr .File/read DEO2
1284+ .File/success-lb DEI ?{ #0000 JMP2r }
1285+ ( | lit port-deo2* )
1286+ #0001 .File/length DEO2
1287+ ;&lit .File/read DEO2
1288+ #0002 .File/length DEO2
1289+ ;&port-deo2 .File/read DEO2
1290+ .File/success-lb DEI ?{ #0000 JMP2r }
1291+ ( a ) [ LIT2 &lit2 $1 &lit $1 ] #a080 EQU2
1292+ ( b ) [ LIT2 &port-deo2 $2 ] #0637 EQU2 AND ?{ #0000 JMP2r }
1293+ [ LIT2 &addr $2 ] JMP2r
1294+
1295+@file/<seek> ( addr* -- )
1296+ #0100 SUB2 .File/name DEI2k ROT DEO2
1297+ #0000 INC2k .File/length DEO2
1298+ &>lf
1299+ ;&b .File/read DEO2
1300+ INC2 GTH2k ?/>lf
1301+ POP2 POP2 JMP2r
1302+
1303+@file/seek-line ( line* -- not-eof )
1304+ .File/name DEI2k ROT DEO2
1305+ ORAk ?{ POP2 #01 JMP2r }
1306+ #0001 .File/length DEO2
1307+ [ LIT2r =&bs ] [ LITr -File/read ] #0000
1308+ &>l
1309+ DEO2kr
1310+ [ LIT2 00 -File/success-lb ] DEI EQU ?{
1311+ [ LIT2 &bs $1 0a ] NEQ ?{ INC2 }
1312+ GTH2k ?/>l }
1313+ POP2 POP2 POPr POP2r .File/success-lb DEI JMP2r
1314+
1315+@file/is-dir ( path* -- t )
1316+ .File/name DEO2
1317+ #0001 .File/length DEO2
1318+ ;&bf .File/stat DEO2
1319+ [ LIT2 "- &bf $1 ] EQU JMP2r
1320+
1321+@file/is-oversized ( path* -- t )
1322+ .File/name DEO2
1323+ #0004 .File/length DEO2
1324+ ;&bufstat .File/stat DEO2
1325+ ;&bufstat LDA LIT "? EQU JMP2r
1326+ &bufstat $5
1327+
1328+@file/is-text ( path* -- t )
1329+ .File/name DEO2
1330+ #0001 .File/length DEO2
1331+ #00
1332+ &>st
1333+ ;&b .File/read DEO2
1334+ ( | tests )
1335+ .File/success-lb DEI ?{ JMP2r }
1336+ POP #01 [ LIT &b $1 ] chr/is-ascii ?/>st
1337+ POP #00 JMP2r
1338+
1339+@file/exists ( path* -- t )
1340+ .File/name DEO2
1341+ #0001 .File/length DEO2
1342+ ;&e .File/stat DEO2
1343+ [ LIT &e $1 ]
1344+ ( not folder ) DUP LIT "- NEQ
1345+ ( not missing ) SWP LIT "! NEQ AND JMP2r
1346+
1347+@file/<cpy> ( src* dst* -- )
1348+ .File2/name DEO2
1349+ #0001 .File2/length DEO2
1350+ .File/name DEO2
1351+ #0001 .File/length DEO2
1352+ &>s
1353+ ;&b .File/read DEO2
1354+ .File/success-lb DEI ?{ JMP2r }
1355+ ;&b .File2/write DEO2 !/>s
1356+
1357+@chr/hex ( c -- val )
1358+ ( dec ) [ LIT "0 ] SUB DUP #09 GTH [ JMP JMP2r ]
1359+ ( hex ) #27 SUB DUP #0a SUB #05 GTH [ JMP JMP2r ]
1360+ ( nil ) POP #ff JMP2r
1361+
1362+@chr/n-0 ( c -- c )
1363+ POP #00 JMP2r
1364+
1365+@chr/t-tab ( c -- c )
1366+ POP #09 JMP2r
1367+
1368+@chr/n-lb ( c -- c )
1369+ POP #0a JMP2r
1370+
1371+@chr/t-ws ( c -- c )
1372+ POP #20 JMP2r
1373+
1374+@chr/is-ascii ( c -- t )
1375+ DUP #08 GTH SWP #7f LTH AND JMP2r
1376+
1377+@str/read-byte ( a b -- byte )
1378+ chr/hex SWP chr/hex #40 SFT ORA JMP2r
1379+
1380+@str/is-dir ( str* -- t )
1381+ /cap #0001 SUB2 LDA LIT "/ EQU JMP2r
1382+
1383+@str/is-icn ( str* -- t )
1384+ /cap #0004 SUB2 ;dict/icn-ext !/cmp
1385+
1386+@str/is-rom ( str* -- t )
1387+ /cap #0004 SUB2 ;dict/rom-ext !/cmp
1388+
1389+@str/is-wallpaper ( str* -- str* t )
1390+ DUP2 #0009 ;dict/wallpaper mem/cmp ?{ #00 JMP2r }
1391+ DUP2 /is-icn ?{ #00 JMP2r }
1392+ #01 JMP2r
1393+
1394+@str/<print> ( str* -- )
1395+ LDAk DUP ?{ POP POP2 JMP2r }
1396+ #18 DEO
1397+ INC2 !/<print>
1398+
1399+@str/escape ( addr* c -- addr* c )
1400+ DUP [ LIT "\ ] NEQ ?{
1401+ POP INC2 LDAk
1402+ ( | handlers )
1403+ DUP [ LIT "0 ] EQU ?chr/n-0
1404+ DUP [ LIT "t ] EQU ?chr/t-tab
1405+ DUP [ LIT "n ] EQU ?chr/n-lb
1406+ DUP [ LIT "s ] EQU ?chr/t-ws }
1407+ JMP2r
1408+
1409+@str/is-word ( str* -- t )
1410+ &>wiw
1411+ LDAk DUP ?{ POP POP2 #01 JMP2r }
1412+ #20 GTH ?{ POP2 #00 JMP2r }
1413+ INC2 !/>wiw
1414+
1415+@str/eol ( str* -- eol* )
1416+ &>we
1417+ LDAk DUP ?{ POP JMP2r }
1418+ #0a NEQ ?{ JMP2r }
1419+ INC2 !/>we
1420+
1421+@str/cap ( str* -- end* )
1422+ LDAk ?{ JMP2r }
1423+ INC2 !/cap
1424+
1425+@str/len ( str* -- len* )
1426+ STH2k /cap STH2r SUB2 JMP2r
1427+
1428+@str/cmp ( a* b* -- f )
1429+ STH2
1430+ &>wc
1431+ LDAk ?{ &d LDA LDAr STHr EQU JMP2r }
1432+ LDAk LDAkr STHr NEQ ?/d
1433+ INC2 INC2r !/>wc
1434+
1435+@str/hex ( str* -- value* )
1436+ [ LIT2r 0000 ]
1437+ &>wh
1438+ [ LITr 40 ] SFT2r LDAk chr/hex [ LITr 00 ] STH
1439+ ADD2r INC2 LDAk ?/>wh
1440+ POP2 STH2r JMP2r
1441+
1442+@str/dec ( str* -- val* )
1443+ LDAk [ LIT "- ] NEQ ?/dec-unsigned
1444+ INC2 /dec-unsigned #0000 SWP2 SUB2 JMP2r
1445+
1446+@str/dec-unsigned ( str* -- val* )
1447+ [ LIT2r 0000 ] !{
1448+
1449+ &>ldec
1450+ [ LITr 00 ] STH
1451+ MUL2r [ LITr 00 ] STH
1452+ ADD2r INC2 }
1453+ ( str* . val* ) LDAk [ LIT "0 ] SUB #0a LTHk ?/>ldec
1454+ POP2 POP2 STH2r JMP2r
1455+
1456+@str/walk-ws ( str* -- str* )
1457+ &>ws
1458+ LDAk ?{ JMP2r }
1459+ LDAk #20 GTH ?{ INC2 LDAk ?/>ws }
1460+ JMP2r
1461+
1462+@str/walk-zero ( str* -- str* )
1463+ &>wz
1464+ LDAk ?{ JMP2r }
1465+ LDAk LIT "0 NEQ ?{ INC2 LDAk ?/>wz }
1466+ JMP2r
1467+
1468+@str/seg ( str* seg* -- bool )
1469+ DUP2 /len SWP2 !mem/cmp
1470+
1471+@mem/cmp ( a* length* b* -- t )
1472+ STH2
1473+ OVR2 ADD2 SWP2
1474+ &>l
1475+ EQU2k ?{
1476+ LDAk LDAkr STHr NEQ ?{ INC2 INC2r !/>l } }
1477+ POP2r EQU2 JMP2r
1478+
1479+@date/make ( -- str* )
1480+ ;&buf DUP2 ,&+ptr STR2
1481+ ( | Make string )
1482+ [ LIT2 00 -DateTime/dotw ] DEI #20 SFT ;dict/days ADD2 /<push-str>
1483+ [ LIT ", ] /<push>
1484+ #20 /<push>
1485+ [ LIT2 00 -DateTime/day ] DEI /<push-dec>
1486+ #20 /<push>
1487+ [ LIT2 00 -DateTime/month ] DEI #20 SFT ;dict/months ADD2 /<push-str>
1488+ #20 /<push>
1489+ .DateTime/year DEI2 !/<push-dec>
1490+
1491+@date/<push-dec> ( short* -- )
1492+ #2710 [ LIT2r 00fb ]
1493+ &>wpd
1494+ DIV2k #000a DIV2k MUL2 SUB2 SWPr EQUk OVR STHkr EQU AND ?{ DUP /<push-digit>
1495+ INCr }
1496+ POP2 #000a DIV2 SWPr INCr STHkr ?/>wpd
1497+ POP2r POP2 POP2 JMP2r
1498+
1499+@date/<push-digit> ( d -- )
1500+ LIT "0 ADD
1501+ ( >> )
1502+
1503+@date/<push> ( c -- )
1504+ #00 [ LIT2 &+ptr =&buf ] INC2k ,&+ptr STR2
1505+ STA2
1506+ JMP2r
1507+
1508+@date/<push-str> ( str* -- )
1509+ &>w
1510+ LDAk DUP ?{ POP POP2 JMP2r }
1511+ /<push>
1512+ INC2 !/>w
1513+
1514+@time/make ( -- str* )
1515+ ;&buf DUP2 ,&+ptr STR2
1516+ ( | Make string )
1517+ .DateTime/hour DEI /<push-dec>
1518+ LIT ": /<push>
1519+ .DateTime/minute DEI /<push-dec>
1520+ LIT ": /<push>
1521+ .DateTime/second DEI !/<push-dec>
1522+
1523+@time/<push-dec> ( u8 -- )
1524+ DUP #0a DIV /<push-digit>
1525+ #0a DIVk MUL SUB
1526+ ( >> )
1527+
1528+@time/<push-digit> ( d -- )
1529+ LIT "0 ADD
1530+ ( >> )
1531+
1532+@time/<push> ( c -- )
1533+ #00 [ LIT2 &+ptr =&buf ] INC2k ,&+ptr STR2
1534+ STA2
1535+ JMP2r
1536+
1537+@banner/<request> ( -- )
1538+ [ LIT2 00 _&skip ] STR
1539+ JMP2r
1540+
1541+@banner/<draw> ( -- )
1542+ ;bios/anchor-x DUP2 ,&x STR2
1543+ .Screen/y DEI2 #0018 ADD2 DUP2 ,&y STR2
1544+ Screen/<set-pos>
1545+ sel/has-meta ?meta/<draw>
1546+ [ LIT2 66 -Screen/auto ] DEO
1547+ ;&asset .Screen/addr DEO2
1548+ [ LIT2 45 -Screen/sprite ] DEOk DEO
1549+ .Screen/vector DEI2 ORA ?{
1550+ [ LIT &skip 00 ] ?{
1551+ [ LIT2 00 _&f ] STR
1552+ [ LIT2 01 _&skip ] STR
1553+ ;&on-frame .Screen/vector DEO2 } }
1554+ JMP2r
1555+
1556+@banner/on-frame ( -> )
1557+ [ LIT &f $1 ] INCk ,&f STR
1558+ DUP #20 LTH ?{
1559+ POP #0000 .Screen/vector DEO2
1560+ BRK }
1561+ #01 SFT [ LIT2 &x $2 ] [ LIT2 &y $2 ] Screen/<set-pos>
1562+ [ LIT2 66 -Screen/auto ] DEO
1563+ ;&asset .Screen/addr DEO2
1564+ [ LIT2 45 -Screen/sprite ] DEOk DEO
1565+ ( | mask )
1566+ .Screen/y DEI2k #0010 SUB2 ROT DEO2
1567+ [ LIT2 15 -Screen/auto ] DEO
1568+ #0010 ROT SUB #30 SFT2 ;curtain/out ADD2 .Screen/addr DEO2
1569+ [ LIT2 40 -Screen/sprite ] DEOk DEOk DEOk DEOk DEOk DEOk DEO
1570+ BRK
1571+
1572+@banner/<load> ( -- )
1573+ #0070 .File/length DEO2
1574+ ;&asset .File/read DEO2
1575+ JMP2r
1576+
1577+@meta/<load> ( addr* -- )
1578+ file/<seek>
1579+ ;&buflen .File/length DEO2
1580+ ;&buf .File/read DEO2
1581+ ;&body str/cap INC2
1582+ ( | parse fields )
1583+ [ LIT2 00 _&has-icon ] STR
1584+ LDAk #00 SWP #0003 MUL2 OVR2 INC2 ADD2 SWP2 INC2
1585+ &>l
1586+ LDAk #83 NEQ ?{
1587+ ( | Load icon )
1588+ INC2k LDA2 file/<seek>
1589+ #0090 .File/length DEO2
1590+ ;&icon .File/read DEO2
1591+ [ LIT2 90 -File/success-lb ] DEI EQU ,&has-icon STR }
1592+ #0003 ADD2 GTH2k ?/>l
1593+ POP2 POP2 JMP2r
1594+
1595+@meta/<draw> ( -- )
1596+ /<draw-icon>
1597+ .Screen/x DEI2 #0020 ADD2 .Screen/y DEI2 #0018 SUB2 Screen/<set-pos>
1598+ #0028 ;font/anchor STA2
1599+ ;&body #41 font/<draw-str-color>
1600+ ;bios/anchor-x ;font/anchor STA2
1601+ JMP2r
1602+
1603+@meta/<draw-icon> ( -- )
1604+ [ LIT &has-icon $1 ] ?{
1605+ ;&no-icon .Screen/addr DEO2
1606+ [ LIT2 22 -Screen/auto ] DEO
1607+ [ LIT2 c5 -Screen/sprite ] DEOk DEOk DEO
1608+ JMP2r }
1609+ ;&icon .Screen/addr DEO2
1610+ [ LIT2 26 -Screen/auto ] DEO
1611+ [ LIT2 c5 -Screen/sprite ] DEOk DEOk DEO
1612+ JMP2r
1613+
1614+@theme/<reset> ( -- )
1615+ #f0a8 #f0ec #f0b9
1616+ ( >> )
1617+
1618+@theme/<set> ( r* g* b* -- )
1619+ .System/b DEO2
1620+ .System/g DEO2
1621+ .System/r DEO2
1622+ JMP2r
1623+
1624+@theme/<load> ( -- )
1625+ ;&path .File/name DEO2
1626+ #0002 .File/length DEO2
1627+ ;&r .File/read DEO2
1628+ ;&g .File/read DEO2
1629+ ;&b .File/read DEO2
1630+ .File/success-lb DEI ?{ !/<reset> }
1631+ banner/<load>
1632+ [ LIT2 &r $2 ] [ LIT2 &g $2 ] [ LIT2 &b $2 ] !/<set>
1633+
1634+ &path ".theme 00
1635+
1636+(
1637+@|Assets )
1638+
1639+@dict/m_pc "M/PC 00
1640+ &ready2 "Type 20 "<cmd> 20 "to 20 "see 20 "options. 00
1641+ &home-path "./ 00
1642+ &sel-prev "Selection 20 "Previous 00
1643+ &sel-next "Selection 20 "Next 00
1644+ &sel-pick "Pick 20 "Selection 00
1645+ &clear "Clear 20 "Input 00
1646+ &directory "Directory 00
1647+ &wallpaper "wallpaper 00
1648+ &input "Input 00
1649+ &eval "Run 00
1650+ &eof "eof 00
1651+ &scroll-up "Scroll 20 "Up 00
1652+ &scroll-down "Scroll 20 "Down 00
1653+ &eval-partial "Non-Destructive 20 "Run 00
1654+ &out-path "../ 00
1655+ &icn-ext ".icn 00
1656+ &rom-ext ".rom 00
1657+ &dir "dir 00
1658+ &mov "mov 00
1659+ &run "run 00
1660+ &txt "txt 00
1661+ &put "put 00
1662+ &era "era 00
1663+ &ren "ren 00
1664+ &get "get 00
1665+ &cmd "cmd 00
1666+ &len "len 00
1667+ &dup "dup 00
1668+ &ovr "ovr 00
1669+ &swp "swp 00
1670+ &rot "rot 00
1671+ &pop "pop 00
1672+ &now "now 00
1673+ &cat "cat 00
1674+ &icn "icn 00
1675+ &cpy "cpy 00
1676+ &zero "0 00
1677+ &t "<true> 00
1678+ &f "<false> 00
1679+ &ok "<ok> 00
1680+ &err-underflow "<underflow> 00
1681+ &err-missing "<missing> 00
1682+ &err-binary "<binary> 00
1683+ &months [
1684+ "Jan $1 "Feb $1 "Mar $1 "Apr $1 "May $1 "Jun $1 "Jul $1 "Aug $1
1685+ "Sep $1 "Oct $1 "Nov $1 "Dec $1 ]
1686+ &days [
1687+ "Sun $1 "Mon $1 "Tue $1 "Wed $1 "Thu $1 "Fri $1 "Sat $1 ]
1688+
1689+@window/wave [ 0000 0000 0070 8807 ]
1690+
1691+@input/caret [ 0020 2020 2020 2020 2020 2020 2020 0000 ]
1692+
1693+@curtain/out [8
1694+ 0000 0000 0000 0000 0000 0000 0000 0000
1695+ 0000 0000 0000 0000 0000 0000 0000 0000
1696+ 0000 0000 0000 0000 0000 0000 0000 0000
1697+ 0000 0000 0000 0000 0000 0000 0000 0000
1698+ 0000 0000 0000 0000 0000 0000 0000 0000
1699+ 0000 0000 0000 0000 0000 0000 0000 0000
1700+ 0000 0000 0000 0002 0000 0000 0000 0002 ]
1701+ &out-short [8
1702+ 0000 0022 0000 0022 0000 0022 0000 0022
1703+ 0088 0022 0088 0022 0088 0022 0088 0022
1704+ 00aa 00aa 00aa 00aa 00aa 00aa 00aa 00aa
1705+ 44aa 11aa 44aa 11aa 44aa 11aa 44aa 11aa
1706+ aa55 aa55 aa55 aa55 aa55 aa55 aa55 aa55
1707+ aa77 aadd aa77 aadd aa77 aadd aa77 aadd
1708+ aaff aaff aaff aaff aaff aaff aaff aaff
1709+ bbff eeff bbff eeff bbff eeff bbff eeff
1710+ bbff ffff bbff ffff bbff ffff bbff ffff
1711+ ffff ffff ffff ffff ffff ffff ffff ffff ]
1712+
1713+@appicon [8
1714+ 0000 0000 0000 0001 0000 0000 0000 0000
1715+ 0000 0000 0000 0080 0000 0000 0000 0000
1716+ 0000 0000 0000 0038 0000 0000 0000 0000
1717+ 070f 0f1f 1f0f 0f07 0000 0000 0000 0000
1718+ e0f0 f0f8 f8f1 f1e3 0000 0000 0000 0000
1719+ 3870 70e0 e0c0 c080 0000 0000 0000 0000
1720+ 0100 0000 0000 0000 0000 0000 0000 0000
1721+ 8300 0000 0000 0000 0000 0000 0000 0000
1722+ 8000 0000 0000 0000 0000 0000 0000 0000 ]
1723+
1724+@banner/asset [8
1725+ 000f 3f7f 7fff ffff 00c0 f0f8 f8fc fcfc
1726+ 000e 0e1c 1c38 3870 00ff ffff e0e0 e0e0
1727+ 00f0 fcfc 1e0e 0e1e 001f 7f7f f0e0 e0e0
1728+ 00f0 fcfc 1e0e 0e00 ffff ff7f 7f3f 0f00
1729+ fcfc fcf9 f9f3 c300 70e0 e0c0 c080 8000
1730+ ffff ffe0 e0e0 e000 fcfc f000 0000 0000
1731+ e0e0 e0f0 7f7f 1f00 000e 0e1e fcfc f000 ]
1732+
1733+@meta/no-icon [ cccc 3333 cccc 3333 ]
1734+
1735+@font/glyphs [8
1736+ 0000 0000 0000 0000 0000 0000 0000 0000
1737+ 0000 1010 1020 2020 2000 4040 0000 0000
1738+ 0000 0050 5000 0000 0000 0000 0000 0000
1739+ 0000 0024 24fc 4848 fc90 9000 0000 0000
1740+ 0000 083c 4a50 5030 2828 48f0 4000 0000
1741+ 0000 1129 2a14 0810 2854 9488 0000 0000
1742+ 0000 1824 2428 3052 9488 8876 0000 0000
1743+ 0000 0040 4000 0000 0000 0000 0000 0000
1744+ 0004 0808 1010 2020 2020 2010 1000 0000
1745+ 0020 2010 1010 1010 2020 4040 8000 0000
1746+ 0000 0024 187e 1824 0000 0000 0000 0000
1747+ 0000 0000 0010 107c 1010 0000 0000 0000
1748+ 0000 0000 0000 0000 0000 0020 2040 0000
1749+ 0000 0000 0000 007c 0000 0000 0000 0000
1750+ 0000 0000 0000 0000 0000 0010 0000 0000
1751+ 0001 0102 0404 0810 2020 4080 8000 0000
1752+ 0000 1824 4444 8484 8888 9060 0000 0000
1753+ 0000 0818 2810 1010 1020 2070 0000 0000
1754+ 0000 1c22 0204 0810 2040 80f8 0000 0000
1755+ 0000 1c22 0204 1804 0404 8870 0000 0000
1756+ 0000 0408 0810 2848 fc10 1010 0000 0000
1757+ 0000 3e20 2078 4404 0404 8870 0000 0000
1758+ 0000 0c10 2040 58e4 8484 8870 0000 0000
1759+ 0000 3e02 0408 1010 2020 4040 0000 0000
1760+ 0000 1c22 4244 3844 8484 8870 0000 0000
1761+ 0000 1c22 4242 463c 0408 1060 0000 0000
1762+ 0000 0000 0000 4000 0000 0040 0000 0000
1763+ 0000 0000 0000 2000 0000 0020 2040 0000
1764+ 0000 0000 0008 1020 4020 1008 0000 0000
1765+ 0000 0000 0000 007c 0000 7c00 0000 0000
1766+ 0000 0000 0040 2010 0810 2040 0000 0000
1767+ 0000 003c 4242 0408 1010 0010 0000 0000
1768+ 0000 0000 1e21 4e52 524f 201c 0000 0000
1769+ 0000 0c0c 1414 2424 7c44 8484 0000 0000
1770+ 0000 1e11 1122 3c22 2242 4478 0000 0000
1771+ 0000 0e11 2020 4040 4040 4438 0000 0000
1772+ 0000 3c22 2242 4242 4484 88f0 0000 0000
1773+ 0000 1f10 1020 3c20 2040 407c 0000 0000
1774+ 0000 1f10 1020 3c20 2040 4040 0000 0000
1775+ 0000 0e11 2020 404e 4244 443c 0000 0000
1776+ 0000 2121 2142 7e42 4284 8484 0000 0000
1777+ 0000 1f04 0408 0808 0810 107c 0000 0000
1778+ 0000 0702 0204 0404 0488 8870 0000 0000
1779+ 0000 2122 2448 7050 4888 8484 0000 0000
1780+ 0000 1010 1020 2020 2040 407c 0000 0000
1781+ 0000 2121 3356 5a5a 4284 8484 0000 0000
1782+ 0000 2121 3152 524a 4a8c 8484 0000 0000
1783+ 0000 0e11 2121 4141 4242 4438 0000 0000
1784+ 0000 1e11 1121 223c 2040 4040 0000 0000
1785+ 0000 0e11 2121 4141 4252 5438 0600 0000
1786+ 0000 1e11 1122 3c30 2848 4444 0000 0000
1787+ 0000 1e21 2020 1008 0404 8478 0000 0000
1788+ 0000 7f08 0810 1010 1020 2020 0000 0000
1789+ 0000 2121 4142 4242 8284 8478 0000 0000
1790+ 0000 2121 2222 2424 2828 3030 0000 0000
1791+ 0000 2121 2122 2a5a 6a6c 4444 0000 0000
1792+ 0000 2121 1214 1818 2848 8484 0000 0000
1793+ 0000 2121 1212 1408 0810 1010 0000 0000
1794+ 0000 3f01 0204 0810 2040 80fc 0000 0000
1795+ 001e 1010 1020 2020 2040 4040 7800 0000
1796+ 0040 4040 2020 2010 1010 0808 0800 0000
1797+ 0078 0808 0810 1010 1020 2020 e000 0000
1798+ 0000 0020 5000 0000 0000 0000 0000 0000
1799+ 0000 0000 0000 0000 0000 00f8 0000 0000
1800+ 0000 0040 2000 0000 0000 0000 0000 0000
1801+ 0000 0000 001e 2222 4444 4c32 0000 0000
1802+ 0000 3010 102c 3222 2244 4438 0000 0000
1803+ 0000 0000 001c 2220 4040 4438 0000 0000
1804+ 0000 0101 011e 2222 4244 4c32 0000 0000
1805+ 0000 0000 001c 2224 7840 4438 0000 0000
1806+ 0000 0304 0808 3e08 1010 1010 2020 4000
1807+ 0000 0000 001e 2222 4444 4c34 0848 7000
1808+ 0000 3010 102e 3222 2244 4446 0000 0000
1809+ 0000 0404 000c 1808 0810 121c 0000 0000
1810+ 0000 0404 000c 1808 0808 1010 1020 c000
1811+ 0000 1010 102e 3222 3c48 4442 0000 0000
1812+ 0000 0c04 0408 0808 0810 1418 0000 0000
1813+ 0000 0000 00b7 4949 4992 9293 0000 0000
1814+ 0000 0000 006e 3222 2244 4446 0000 0000
1815+ 0000 0000 001c 2222 4244 4438 0000 0000
1816+ 0000 0000 002c 7222 2244 4478 4080 8000
1817+ 0000 0000 001a 2622 4244 4c34 0808 0800
1818+ 0000 0000 0016 3a10 1020 2020 0000 0000
1819+ 0000 0000 001c 2220 1804 4438 0000 0000
1820+ 0000 0008 083e 0810 1010 2418 0000 0000
1821+ 0000 0000 0062 2222 4244 4c32 0000 0000
1822+ 0000 0000 0062 2222 2224 2830 0000 0000
1823+ 0000 0000 0061 2141 495a 6644 0000 0000
1824+ 0000 0000 0031 120c 0818 2446 0000 0000
1825+ 0000 0000 0062 2222 4444 4c34 0848 7000
1826+ 0000 0000 001d 2204 0810 2052 0c00 0000
1827+ 0006 0808 0810 6010 1020 2020 1800 0000
1828+ 0000 1010 1020 2020 2040 4040 0000 0000
1829+ 0030 0808 0810 100c 1020 2020 c000 0000
1830+ 0000 0000 0000 0032 4c00 0000 0000 0000 ]
1831+ &tab [ 0000 0000 0008 0c7e 0c08 0000 0000 0000 ]
1832+
1833+@kbd/glyphs [8
1834+ 0000 0000 0000 0000 0808 1010 1000 2000
1835+ 2448 0000 0000 0000 0a14 7e28 fc50 a000
1836+ 083c 5238 14a8 7020 44a8 4810 242a 4400
1837+ 1824 4862 9c88 7000 1020 0000 0000 0000
1838+ 0408 1020 2020 1008 2010 0808 0810 2040
1839+ 0050 2050 0000 0000 0000 2020 f820 2000
1840+ 0000 0000 0010 1020 0000 0000 7c00 0000
1841+ 0000 0000 0000 1000 0808 1010 2020 4040
1842+ 0c12 2242 4448 3000 0c04 0808 0810 1000
1843+ 0c12 0408 1020 7800 0e02 0418 0448 3000
1844+ 060a 1424 3e08 0800 1e20 3804 0448 3000
1845+ 0c12 2038 4448 3000 3e04 0810 2040 4000
1846+ 0c12 2418 2448 3000 0c12 221c 0448 3000
1847+ 0000 1000 0010 0000 0000 1000 0010 1020
1848+ 0000 0810 2010 0800 0000 7c00 7c00 0000
1849+ 0000 2010 0810 2000 3844 0418 2000 4000
1850+ 0c12 2e54 5844 3000 1c22 2244 7c88 8800
1851+ 3c22 4478 4488 f000 1c22 4040 8088 7000
1852+ 3c22 4244 4488 f000 3e20 4078 4080 f800
1853+ 3e20 4078 4080 8000 1c22 4040 9c88 7000
1854+ 2222 447c 4488 8800 1c08 1010 2020 7000
1855+ 0e04 0808 1090 6000 2224 4870 5090 8800
1856+ 1010 2020 2040 7c00 2236 4c44 4488 8800
1857+ 2222 6454 4c88 8800 1c22 4244 8488 7000
1858+ 3c22 4478 4080 8000 1c22 4244 9488 7400
1859+ 3c22 4478 4488 8800 1c22 4038 0488 7000
1860+ 7c10 2020 2040 4000 2222 4444 8888 7000
1861+ 4444 4448 5020 2000 2222 4454 a8a8 5000
1862+ 2224 2810 2848 8800 4448 5020 2040 4000
1863+ 3e04 0810 2040 f800 0c08 0810 1020 2030
1864+ 2020 2010 1008 0808 1808 1010 1020 2060
1865+ 2050 8800 0000 0000 0000 0000 0000 f800
1866+ 4020 1000 0000 0000 0000 1a24 4448 3400
1867+ 1020 3824 4448 3000 0000 1824 4048 3000
1868+ 0202 1a24 4448 3400 0000 1824 7840 3000
1869+ 0608 3c10 1020 20c0 0000 1a24 4838 9060
1870+ 1020 2834 2448 4800 0400 1808 1028 3000
1871+ 0400 1808 1010 20c0 1020 2834 2850 4800
1872+ 1808 1010 2028 3000 0000 542a 2a54 5400
1873+ 0000 2c32 2244 4400 0000 1824 4448 3000
1874+ 0000 2c12 2458 4040 0000 1a24 4c34 0408
1875+ 0000 2834 2040 4000 0000 1824 1048 3000
1876+ 0810 3c10 2028 3000 0000 2424 4858 2800
1877+ 0000 6424 4850 6000 0000 622a 5454 2800
1878+ 0000 2458 1034 4800 0000 2424 4838 9060
1879+ 0000 3448 1024 5800 0c10 1060 2040 4020
1880+ 1010 1010 1010 1010 0804 0408 0c10 1060
1881+ 0000 0032 4c00 0000 0000 0000 0000 0000 ]
1882+ &a [ 0000 0001 0204 0810 1008 0402 0100 0000 ]
1883+ &b [ 0000 ff00 0000 0000 0000 0000 00ff 0000 ]
1884+ &c [ 0000 0080 4020 1008 0810 2040 8000 0000 ]
1885+
1886+(
1887+@|Buffer )
1888+
1889+@len/buf &hb $2 &lb $2 00
1890+
1891+@dec/buf $6
1892+
1893+@hex/buf $6
1894+
1895+@icn/buf $8
1896+
1897+@date/buf $12
1898+
1899+@time/buf $a
1900+
1901+@symbol/buf $20
1902+
1903+@loader/page $&pagelen
1904+
1905+@meta/buf $1 &body $&buflen
1906+ &cap 0000 &icon $90
1907+
1908+@path/buf $&buflen
1909+ &cap 0000
1910+
1911+@dir/buf $&buflen 0000
1912+
1913+@bios/buf $&buflen
1914+ &cap 0000
1915+
1916+@dict/buf
1917+
1918+
1919+
+0,
-0
+11,
-0
1@@ -0,0 +1,11 @@
2+( cat a.txt | uxncli xh.rom > b.rom )
3+@on-reset ( -> )
4+ ;on-console #10 DEO2 BRK
5+@on-console ( -> )
6+ #0417 DEI EQU ?{
7+ #12 DEI
8+ LIT "0 SUB DUP #0a LTH ?{
9+ #27 SUB DUP #10 LTH ?{ POP BRK } }
10+ LITr 40 EORr STHkr ?{ ORA #18 DEO BRK }
11+ STHkr SFT BRK }
12+ #800f DEO
A
makefile
+47,
-0
1@@ -0,0 +1,47 @@
2+DEBUG = FALSE
3+
4+GCC = nspire-gcc
5+AS = nspire-as
6+GXX = nspire-g++
7+LD = nspire-ld
8+GENZEHN = genzehn
9+
10+GCCFLAGS = -Wall -W -marm -Wno-int-conversion
11+LDFLAGS = -lSDL
12+ZEHNFLAGS = --name "uxn2"
13+
14+ifeq ($(DEBUG),FALSE)
15+ GCCFLAGS += -Os
16+else
17+ GCCFLAGS += -O0 -g
18+endif
19+
20+OBJS = $(patsubst %.c, %.o, $(shell find . -name \*.c))
21+OBJS += $(patsubst %.cpp, %.o, $(shell find . -name \*.cpp))
22+OBJS += $(patsubst %.S, %.o, $(shell find . -name \*.S))
23+EXE = uxn2
24+DISTDIR = .
25+vpath %.tns $(DISTDIR)
26+vpath %.elf $(DISTDIR)
27+
28+all: $(EXE).tns
29+
30+%.o: %.c
31+ $(GCC) $(GCCFLAGS) -c $<
32+
33+%.o: %.cpp
34+ $(GXX) $(GCCFLAGS) -c $<
35+%.o: %.S
36+ $(AS) -c $<
37+
38+$(EXE).elf: $(OBJS)
39+ mkdir -p $(DISTDIR)
40+ $(LD) $^ -o $(DISTDIR)/$@ $(LDFLAGS)
41+
42+$(EXE).tns: $(EXE).elf
43+ $(GENZEHN) --input $(DISTDIR)/$^ --output $(DISTDIR)/$@.zehn $(ZEHNFLAGS)
44+ make-prg $(DISTDIR)/$@.zehn $(DISTDIR)/$@
45+ rm $(DISTDIR)/$@.zehn
46+
47+clean:
48+ rm -f *.o $(DISTDIR)/$(EXE).tns $(DISTDIR)/$(EXE).elf $(DISTDIR)/$(EXE).zehn
A
uxn.c
+2043,
-0
1@@ -0,0 +1,2043 @@
2+#if 0
3+gcc -s -O2 -Wno-unused-result -fwrapv main.c `sdl-config --cflags --libs`
4+exit
5+#endif
6+
7+// This file is public domain.
8+
9+#include "SDL/SDL.h"
10+#include <dirent.h>
11+#include <fcntl.h>
12+#include <stdio.h>
13+#include <stdlib.h>
14+#include <string.h>
15+#include <sys/stat.h>
16+#include <sys/types.h>
17+#include <time.h>
18+#include <unistd.h>
19+
20+// Subprocess support
21+#include <signal.h>
22+#include <sys/wait.h>
23+
24+#ifdef __linux
25+#include <pty.h>
26+#include <sys/prctl.h>
27+#endif
28+
29+#ifdef __NetBSD__
30+#include <sys/ioctl.h>
31+#include <util.h>
32+#endif
33+
34+#include <stdio.h>
35+#include <stdlib.h>
36+#include <string.h>
37+#include <sys/types.h>
38+
39+static ssize_t getline(char **line, size_t *cap, FILE *fp)
40+{
41+ if (!line || !cap || !fp)
42+ return -1;
43+
44+ size_t len = 0;
45+ int c;
46+
47+ if (*line == NULL || *cap == 0) {
48+ *cap = 128;
49+ *line = malloc(*cap);
50+ if (!*line) {
51+ *cap = 0;
52+ return -1;
53+ }
54+ }
55+
56+ while ((c = fgetc(fp)) != EOF) {
57+ if (len + 1 >= *cap) {
58+ size_t newcap = *cap * 2;
59+ char *tmp = realloc(*line, newcap);
60+ if (!tmp)
61+ return -1;
62+ *line = tmp;
63+ *cap = newcap;
64+ }
65+
66+ (*line)[len++] = (char)c;
67+
68+ if (c == '\n')
69+ break;
70+ }
71+
72+ if (len == 0 && c == EOF)
73+ return -1;
74+
75+ (*line)[len] = '\0';
76+ return (ssize_t)len;
77+}
78+
79+void warn(const char *fmt, ...)
80+{
81+ va_list args;
82+ va_start(args, fmt);
83+
84+ vprintf(fmt, args);
85+ printf("\n");
86+
87+ va_end(args);
88+}
89+
90+static void err(int e, char* str){puts(str);exit(1);}
91+
92+static const Uint8 fontdata[]={ // font for built-in menus
93+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00,
94+ 0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00,
95+ 0x30,0x7C,0xC0,0x78,0x0C,0xF8,0x30,0x00,0x00,0xC6,0xCC,0x18,0x30,0x66,0xC6,0x00,
96+ 0x38,0x6C,0x38,0x76,0xDC,0xCC,0x76,0x00,0x60,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,
97+ 0x18,0x30,0x60,0x60,0x60,0x30,0x18,0x00,0x60,0x30,0x18,0x18,0x18,0x30,0x60,0x00,
98+ 0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00,
99+ 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,
100+ 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,
101+ 0x7C,0xC6,0xCE,0xDE,0xF6,0xE6,0x7C,0x00,0x30,0x70,0x30,0x30,0x30,0x30,0xFC,0x00,
102+ 0x78,0xCC,0x0C,0x38,0x60,0xCC,0xFC,0x00,0x78,0xCC,0x0C,0x38,0x0C,0xCC,0x78,0x00,
103+ 0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x1E,0x00,0xFC,0xC0,0xF8,0x0C,0x0C,0xCC,0x78,0x00,
104+ 0x38,0x60,0xC0,0xF8,0xCC,0xCC,0x78,0x00,0xFC,0xCC,0x0C,0x18,0x30,0x30,0x30,0x00,
105+ 0x78,0xCC,0xCC,0x78,0xCC,0xCC,0x78,0x00,0x78,0xCC,0xCC,0x7C,0x0C,0x18,0x70,0x00,
106+ 0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x60,
107+ 0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x00,0x00,0x00,0xFC,0x00,0x00,0xFC,0x00,0x00,
108+ 0x60,0x30,0x18,0x0C,0x18,0x30,0x60,0x00,0x78,0xCC,0x0C,0x18,0x30,0x00,0x30,0x00,
109+ 0x7C,0xC6,0xDE,0xDE,0xDE,0xC0,0x78,0x00,0x30,0x78,0xCC,0xCC,0xFC,0xCC,0xCC,0x00,
110+ 0xFC,0x66,0x66,0x7C,0x66,0x66,0xFC,0x00,0x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00,
111+ 0xF8,0x6C,0x66,0x66,0x66,0x6C,0xF8,0x00,0xFE,0x62,0x68,0x78,0x68,0x62,0xFE,0x00,
112+ 0xFE,0x62,0x68,0x78,0x68,0x60,0xF0,0x00,0x3C,0x66,0xC0,0xC0,0xCE,0x66,0x3E,0x00,
113+ 0xCC,0xCC,0xCC,0xFC,0xCC,0xCC,0xCC,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x78,0x00,
114+ 0x1E,0x0C,0x0C,0x0C,0xCC,0xCC,0x78,0x00,0xE6,0x66,0x6C,0x78,0x6C,0x66,0xE6,0x00,
115+ 0xF0,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00,
116+ 0xC6,0xE6,0xF6,0xDE,0xCE,0xC6,0xC6,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x38,0x00,
117+ 0xFC,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00,0x78,0xCC,0xCC,0xCC,0xDC,0x78,0x1C,0x00,
118+ 0xFC,0x66,0x66,0x7C,0x6C,0x66,0xE6,0x00,0x78,0xCC,0xE0,0x70,0x1C,0xCC,0x78,0x00,
119+ 0xFC,0xB4,0x30,0x30,0x30,0x30,0x78,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xFC,0x00,
120+ 0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x30,0x00,0xC6,0xC6,0xC6,0xD6,0xFE,0xEE,0xC6,0x00,
121+ 0xC6,0xC6,0x6C,0x38,0x38,0x6C,0xC6,0x00,0xCC,0xCC,0xCC,0x78,0x30,0x30,0x78,0x00,
122+ 0xFE,0xC6,0x8C,0x18,0x32,0x66,0xFE,0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x78,0x00,
123+ 0xC0,0x60,0x30,0x18,0x0C,0x06,0x02,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x78,0x00,
124+ 0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
125+ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0x76,0x00,
126+ 0xE0,0x60,0x60,0x7C,0x66,0x66,0xDC,0x00,0x00,0x00,0x78,0xCC,0xC0,0xCC,0x78,0x00,
127+ 0x1C,0x0C,0x0C,0x7C,0xCC,0xCC,0x76,0x00,0x00,0x00,0x78,0xCC,0xFC,0xC0,0x78,0x00,
128+ 0x38,0x6C,0x60,0xF0,0x60,0x60,0xF0,0x00,0x00,0x00,0x76,0xCC,0xCC,0x7C,0x0C,0xF8,
129+ 0xE0,0x60,0x6C,0x76,0x66,0x66,0xE6,0x00,0x30,0x00,0x70,0x30,0x30,0x30,0x78,0x00,
130+ 0x0C,0x00,0x0C,0x0C,0x0C,0xCC,0xCC,0x78,0xE0,0x60,0x66,0x6C,0x78,0x6C,0xE6,0x00,
131+ 0x70,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0xCC,0xFE,0xFE,0xD6,0xC6,0x00,
132+ 0x00,0x00,0xF8,0xCC,0xCC,0xCC,0xCC,0x00,0x00,0x00,0x78,0xCC,0xCC,0xCC,0x78,0x00,
133+ 0x00,0x00,0xDC,0x66,0x66,0x7C,0x60,0xF0,0x00,0x00,0x76,0xCC,0xCC,0x7C,0x0C,0x1E,
134+ 0x00,0x00,0xDC,0x76,0x66,0x60,0xF0,0x00,0x00,0x00,0x7C,0xC0,0x78,0x0C,0xF8,0x00,
135+ 0x10,0x30,0x7C,0x30,0x30,0x34,0x18,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0x76,0x00,
136+ 0x00,0x00,0xCC,0xCC,0xCC,0x78,0x30,0x00,0x00,0x00,0xC6,0xD6,0xFE,0xFE,0x6C,0x00,
137+ 0x00,0x00,0xC6,0x6C,0x38,0x6C,0xC6,0x00,0x00,0x00,0xCC,0xCC,0xCC,0x7C,0x0C,0xF8,
138+ 0x00,0x00,0xFC,0x98,0x30,0x64,0xFC,0x00,0x1C,0x30,0x30,0xE0,0x30,0x30,0x1C,0x00,
139+ 0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0xE0,0x30,0x30,0x1C,0x30,0x30,0xE0,0x00,
140+ 0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,
141+};
142+
143+#define EXPANDED_MEMORY 8
144+#define MEMSIZE ((EXPANDED_MEMORY+1)*0x10000)
145+
146+#define GET16(p) (((p)[0]<<8)|(p)[1])
147+#define PUT16(p,q) ((p)[0]=(q)>>8,(p)[1]=(q))
148+
149+typedef struct {
150+ Uint8 p;
151+ Uint8 d[256];
152+} Stack;
153+
154+typedef struct Device {
155+ Uint8 d[16];
156+ Uint8(*in)(struct Device*,Uint8);
157+ void(*out)(struct Device*,Uint8);
158+ void(*exp)(struct Device*,Uint16);
159+ void*aux;
160+} Device;
161+
162+typedef struct {
163+ FILE*file;
164+ DIR*dir;
165+ char name[4096];
166+ struct dirent*de;
167+ Uint8 mode;
168+} UxnFile;
169+
170+typedef struct {
171+ Uint32 envtime,phase,freq;
172+ Uint32 length,end,pos;
173+ Uint32 env[4];
174+ Uint8 vol[2];
175+} UxnAudio;
176+
177+typedef struct {
178+ Uint8*data;
179+ Uint32 addr;
180+ Uint16 len;
181+ Uint8 kind,stage;
182+} Script;
183+
184+static SDL_Color colors[64]={
185+ // 0
186+ {0xFF,0xFF,0xFF,0},
187+ {0x00,0x00,0x00,0},
188+ {0x00,0xFF,0xFF,0},
189+ {0xFF,0x00,0x00,0},
190+ {0xAA,0xAA,0xAA,0},
191+ {0x43,0x43,0x33,0},
192+ {0x43,0xAA,0xAA,0},
193+ {0xAA,0x43,0x33,0},
194+ // 1
195+ {0x00,0x00,0x00,0},
196+ {0xFF,0xFF,0xFF,0},
197+ {0x00,0xFF,0xFF,0},
198+ {0xFF,0x00,0x00,0},
199+ {0x43,0x43,0x33,0},
200+ {0xAA,0xAA,0xAA,0},
201+ {0x43,0xAA,0xAA,0},
202+ {0xAA,0x43,0x33,0},
203+ // 2
204+ {0x10,0x30,0x10,0},
205+ {0x60,0xE0,0x60,0},
206+ {0x60,0x60,0xE0,0},
207+ {0xE0,0x60,0x60,0},
208+ {0x10,0x80,0x10,0},
209+ {0x38,0xFF,0xF8,0},
210+ {0xF8,0x38,0xFF,0},
211+ {0xFF,0xF8,0x38,0},
212+ // 3
213+ {0x55,0x55,0x55,0},
214+ {0xFF,0x55,0x00,0},
215+ {0x00,0x00,0x00,0},
216+ {0xFF,0xFF,0xFF,0},
217+ {0x55,0x55,0x55,0},
218+ {0xFF,0x55,0x00,0},
219+ {0x00,0x00,0x00,0},
220+ {0xFF,0xFF,0xFF,0},
221+ // 4
222+ {0x55,0x55,0x55,0},
223+ {0xFF,0x55,0x00,0},
224+ {0xFF,0xFF,0xFF,0},
225+ {0x00,0x00,0x00,0},
226+ {0x55,0x55,0x55,0},
227+ {0xFF,0x55,0x00,0},
228+ {0xFF,0xFF,0xFF,0},
229+ {0x00,0x00,0x00,0},
230+ // 5
231+ {0xFF,0xFF,0xFF,0},
232+ {0xAA,0xAA,0xAA,0},
233+ {0x55,0x55,0x55,0},
234+ {0x00,0x00,0x00,0},
235+ {0xFF,0x80,0x00,0},
236+ {0xC6,0x60,0x00,0},
237+ {0x94,0x40,0x00,0},
238+ {0x72,0x20,0x00,0},
239+ // 6
240+ {0xAA,0xAA,0xAA,0},
241+ {0x00,0x00,0x00,0},
242+ {0xAA,0xAA,0xAA,0},
243+ {0x00,0x00,0x00,0},
244+ {0x91,0xAA,0x9A,0},
245+ {0x0D,0x0E,0x0E,0},
246+ {0x91,0xAA,0x9A,0},
247+ {0x19,0x15,0x00,0},
248+ // 7
249+ {0xFF,0xFF,0xFF,0},
250+ {0x00,0x00,0x00,0},
251+ {0x77,0xCC,0xAA,0},
252+ {0x99,0x22,0x44,0},
253+ {0xFF,0xFF,0xFF,0},
254+ {0x00,0x00,0x00,0},
255+ {0x77,0xCC,0xAA,0},
256+ {0x99,0x22,0x44,0},
257+};
258+
259+static Uint8 blend[4][16]={
260+ {4,0,0,0,1,4,1,1,2,2,4,2,3,3,3,4},
261+ {0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3},
262+ {1,2,3,1,1,2,3,1,1,2,3,1,1,2,3,1},
263+ {2,3,1,2,2,3,1,2,2,3,1,2,2,3,1,2},
264+};
265+
266+static const Uint32 notes[12]={
267+ 0x20000000,0x21e71f26,0x23eb3588,0x260dfc14,0x285145f3,0x2ab70212,
268+ 0x2d413ccd,0x2ff221af,0x32cbfd4a,0x35d13f33,0x39047c0f,0x3c686fce,
269+};
270+
271+static Uint8 mem[MEMSIZE];
272+static Stack ds,rs;
273+static Device device[16];
274+static Uint16 scr_w,scr_h;
275+static Uint8*bglayer;
276+static Uint8*fglayer;
277+static UxnFile uxnfile0;
278+static UxnFile uxnfile1;
279+static FILE*inf;
280+static FILE*outf;
281+
282+static const char*rom_name;
283+static Uint8 use_console=1;
284+static Uint8 use_screen=1;
285+static Uint8 use_mouse=1;
286+static Uint8 use_debug=0;
287+static Uint8 use_utc=0;
288+static Uint8 use_extension=0;
289+static Uint8 use_thread=0;
290+static Uint8 hide_cursor=0;
291+static Uint8 allow_write=0;
292+static Uint8 joypad_repeat=0;
293+static Uint16 scroll_size=1;
294+static Uint8 zoom=1;
295+static Uint8 disallow_size_change=0;
296+static Sint16 default_width=512;
297+static Sint16 default_height=320;
298+static Uint32 scrflags=SDL_SWSURFACE;
299+static Uint16 timer_rate=16;
300+static Uint8 paused=0;
301+static Uint8 picture_changed=0;
302+static Uint8 size_changed=0;
303+static volatile Uint8 timer_expired=0;
304+static SDL_Surface*screen;
305+static Uint8 layers;
306+static Uint8 palet=7;
307+static Uint8 touch_mode=0;
308+static SDL_cond*stdin_cond;
309+static Uint8 screencompat=0x03;
310+static int randomfd=-1;
311+
312+static Uint16 scriptc;
313+static Script*scriptv;
314+static FILE*scriptf;
315+
316+static Sint32*audio_option;
317+static SDL_AudioSpec audiospec;
318+
319+static Uint8 joy_mask;
320+static Uint8 joy_player[4];
321+static Uint8 joy_hat,joy_hat_mode;
322+static Uint8 joy_axis_x,joy_axis_y,joy_axis_mode;
323+static Uint8 joy_button_map[128];
324+static Uint16 joy_sensitivity=8192;
325+
326+static Uint8 debugger=0;
327+static Uint16 breakpoint=0;
328+static Uint16 break_pc=0x0100;
329+static Uint8 debug_op=0;
330+
331+static void debug(int i) {
332+ int j;
333+ if(i) fprintf(stderr,"Debug(%02X)\n",i);
334+ fprintf(stderr,"ds:");
335+ for(i=0;i<ds.p;i++) fprintf(stderr," %02X",ds.d[i]);
336+ fputc('\n',stderr);
337+ fprintf(stderr,"rs:");
338+ for(i=0;i<rs.p;i++) fprintf(stderr," %02X",rs.d[i]);
339+ fputc('\n',stderr);
340+ fprintf(stderr," 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. A. B. C. D. E. F.\n");
341+ for(i=0;i<16;i++) {
342+ fprintf(stderr,"%1X:",i);
343+ for(j=0;j<16;j++) fprintf(stderr," %02X",device[i].d[j]);
344+ if(device[i].aux) fprintf(stderr," *");
345+ fputc('\n',stderr);
346+ }
347+}
348+
349+static void uxnerr(int n,int pc) {
350+ if(use_debug) debug(-1);
351+ fflush(outf);
352+ fflush(stderr);
353+ err(2,"Uxn error");
354+}
355+
356+#define Push8(z) ({ s->d[s->p++]=(z); })
357+#define Push16(z) ({ s->d[s->p++]=(z)>>8; s->d[s->p++]=(z); })
358+#define Push(z) ({ if(v&0x20) s->d[s->p++]=(z)>>8; s->d[s->p++]=(z); })
359+#define Pop8(z) ({ z=s->d[0xFF&--k]; if(v<0x80) s->p=k; })
360+#define Pop16(z) ({ z=s->d[0xFF&--k]; z|=s->d[0xFF&--k]<<8; if(v<0x80) s->p=k; })
361+#define Pop(z) ({ if(v&0x20) Pop16(z); else Pop8(z); })
362+
363+static void run(Uint16 pc) {
364+ Stack*s;
365+ Uint8 k,v;
366+ Uint16 x,y,z;
367+ if(!pc) return;
368+ start:
369+ while(v=mem[pc++]) {
370+ if(pc==breakpoint && use_screen) goto stop;
371+ s=(v&0x40?&rs:&ds);
372+ k=s->p;
373+ switch(v&0x1F?:v) {
374+ case 0x01: Pop(x); Push(x+1); break;
375+ case 0x02: Pop(x); break;
376+ case 0x03: Pop(x); Pop(y); Push(x); break;
377+ case 0x04: Pop(x); Pop(y); Push(x); Push(y); break;
378+ case 0x05: Pop(z); Pop(y); Pop(x); Push(y); Push(z); Push(x); break;
379+ case 0x06: Pop(x); Push(x); Push(x); break;
380+ case 0x07: Pop(x); Pop(y); Push(y); Push(x); Push(y); break;
381+ case 0x08: Pop(x); Pop(y); Push8(y==x?1:0); break;
382+ case 0x09: Pop(x); Pop(y); Push8(y!=x?1:0); break;
383+ case 0x0A: Pop(x); Pop(y); Push8(y>x?1:0); break;
384+ case 0x0B: Pop(x); Pop(y); Push8(y<x?1:0); break;
385+ case 0x0C: Pop(x); jump: if(v&0x20) pc=x; else pc+=(Sint8)x; break;
386+ case 0x0D: Pop(x); Pop8(y); if(y) goto jump; break;
387+ case 0x0E: Pop(x); y=pc; goto stash;
388+ case 0x0F: Pop(x); goto stash;
389+ case 0x10: Pop8(x); peek: if(v&0x20) x=GET16(mem+x); else x=mem[x]; Push(x); break;
390+ case 0x11: Pop8(x); Pop(y); poke: if(v&0x20) PUT16(mem+x,y); else mem[x]=y; break;
391+ case 0x12: Pop8(x); x=pc+(Sint8)x; goto peek; break;
392+ case 0x13: Pop8(x); Pop(y); x=pc+(Sint8)x; goto poke; break;
393+ case 0x14: Pop16(x); goto peek; break;
394+ case 0x15: Pop16(x); Pop(y); goto poke; break;
395+ case 0x16:
396+ Pop8(x);
397+ z=(x>>4)&15; x&=15;
398+ y=device[z].in(device+z,x);
399+ if(v&0x20) y=(y<<8)|device[z].in(device+z,x+1);
400+ Push(y);
401+ break;
402+ case 0x17:
403+ Pop8(x); Pop(y);
404+ z=(x>>4)&15; x&=15;
405+ if(v&0x20) {
406+ device[z].d[x]=y>>8;
407+ device[z].d[(x+1)&15]=y;
408+ device[z].out(device+z,x);
409+ device[z].out(device+z,x+1);
410+ } else {
411+ device[z].d[x]=y;
412+ device[z].out(device+z,x);
413+ }
414+ break;
415+ case 0x18: Pop(x); Pop(y); Push(y+x); break;
416+ case 0x19: Pop(x); Pop(y); Push(y-x); break;
417+ case 0x1A: Pop(x); Pop(y); Push(y*x); break;
418+ case 0x1B: Pop(x); Pop(y); Push(x?y/x:0); break;
419+ case 0x1C: Pop(x); Pop(y); Push(y&x); break;
420+ case 0x1D: Pop(x); Pop(y); Push(y|x); break;
421+ case 0x1E: Pop(x); Pop(y); Push(y^x); break;
422+ case 0x1F: Pop8(x); Pop(y); z=x>>4; x&=15; Push((y>>x)<<z); break;
423+ case 0x20: Pop8(x); pc+=x?GET16(mem+pc)+2:2; break;
424+ case 0x40: pc+=GET16(mem+pc)+2; break;
425+ case 0x60: Push16(pc+2); pc+=GET16(mem+pc)+2; break;
426+ case 0x80: case 0xC0: Push8(mem[pc++]); break;
427+ case 0xA0: case 0xE0: Push8(mem[pc++]); Push8(mem[pc++]); break;
428+ }
429+ continue;
430+ stash:
431+ s=(v&0x40?&ds:&rs);
432+ if(v&1) {
433+ Push(x);
434+ } else {
435+ Push16(y);
436+ if(v&0x20) pc=x; else pc+=(Sint8)x;
437+ }
438+ }
439+ if(pc==breakpoint && use_screen) {
440+ stop:
441+ paused=debugger=picture_changed=1;
442+ break_pc=pc-1;
443+ }
444+ fflush(outf);
445+}
446+
447+static void load_rom(void) {
448+ FILE*fp=fopen(rom_name,"r");
449+ if(!fp) err(1,"Cannot load program file");
450+ memset(mem,0,MEMSIZE);
451+ fread(mem+0x0100,1,MEMSIZE-0x0100,fp);
452+ if(ferror(fp)) err(1,"Cannot load program file");
453+ fclose(fp);
454+}
455+
456+static Uint8 default_in(Device*misc1,Uint8 misc2) { return misc1->d[misc2&15]; }
457+static void default_out(Device*misc1,Uint8 misc2) {}
458+static void default_exp(Device*misc1,Uint16 misc2) {}
459+
460+static Uint8 system_in(Device*dev,Uint8 id) {
461+ switch(id) {
462+ case 4: return ds.p;
463+ case 5: return rs.p;
464+ default: return dev->d[id];
465+ }
466+}
467+
468+static void system_out(Device*dev,Uint8 id) {
469+ Uint16 x;
470+ switch(id) {
471+ case 3:
472+ x=GET16(dev->d+2);
473+ device[mem[x]>>4].exp(device+(mem[x]>>4),x);
474+ break;
475+ case 4:
476+ ds.p=dev->d[4];
477+ break;
478+ case 5:
479+ rs.p=dev->d[5];
480+ break;
481+ case 8 ... 13:
482+ colors[070].r=colors[074].r=(dev->d[8]>>4)*0x11;
483+ colors[071].r=colors[075].r=(dev->d[8]&15)*0x11;
484+ colors[072].r=colors[076].r=(dev->d[9]>>4)*0x11;
485+ colors[073].r=colors[077].r=(dev->d[9]&15)*0x11;
486+ colors[070].g=colors[074].g=(dev->d[10]>>4)*0x11;
487+ colors[071].g=colors[075].g=(dev->d[10]&15)*0x11;
488+ colors[072].g=colors[076].g=(dev->d[11]>>4)*0x11;
489+ colors[073].g=colors[077].g=(dev->d[11]&15)*0x11;
490+ colors[070].b=colors[074].b=(dev->d[12]>>4)*0x11;
491+ colors[071].b=colors[075].b=(dev->d[12]&15)*0x11;
492+ colors[072].b=colors[076].b=(dev->d[13]>>4)*0x11;
493+ colors[073].b=colors[077].b=(dev->d[13]&15)*0x11;
494+ if(screen && palet==7) {
495+ SDL_SetColors(screen,colors+palet*8,0,8);
496+ picture_changed=1;
497+ }
498+ break;
499+ case 14: if(dev->d[14] && use_debug) debug(dev->d[14]); break;
500+ case 15: if(dev->d[15]) exit(dev->d[15]&0x7F); break;
501+ }
502+}
503+
504+// Subprocess support
505+
506+static char enable_subprocess=0;
507+static char *fork_args[4] = {"/bin/sh", "-c", "", NULL};
508+static int child_mode;
509+static int to_child_fd[2];
510+static int from_child_fd[2];
511+static int saved_in;
512+static int saved_out;
513+static pid_t child_pid;
514+
515+/* call after we're sure the process has exited */
516+static void console_clean_after_child(void) {
517+ child_pid = 0;
518+ if(child_mode & 0x01) {
519+ close(to_child_fd[1]);
520+ dup2(saved_out, 1);
521+ }
522+ if(child_mode & (0x04 | 0x02)) {
523+ close(from_child_fd[0]);
524+ dup2(saved_in, 0);
525+ }
526+ child_mode = 0;
527+ saved_in = -1;
528+ saved_out = -1;
529+}
530+
531+static void console_start_fork_pipe(Device*dev) {
532+ pid_t pid;
533+ pid_t parent_pid = getpid();
534+ int addr = GET16(dev->d+12);
535+ fflush(stdout);
536+ if(child_mode & 0x08) {
537+ dev->d[6] = dev->d[5] = 0;
538+ return;
539+ }
540+ if(child_mode & 0x01) {
541+ /* parent writes to child's stdin */
542+ if(pipe(to_child_fd) == -1) {
543+ dev->d[6] = dev->d[5] = 255;
544+ fprintf(stderr, "pipe error: to child\n");
545+ return;
546+ }
547+ }
548+ if(child_mode & (0x04 | 0x02)) {
549+ /* parent reads from child's stdout and/or stderr */
550+ if(pipe(from_child_fd) == -1) {
551+ dev->d[6] = dev->d[5] = 255;
552+ fprintf(stderr, "pipe error: from child\n");
553+ return;
554+ }
555+ }
556+
557+ fork_args[2] = (char *)(mem + GET16(dev->d+12));
558+ pid = fork();
559+ if(pid < 0) { /* failure */
560+ dev->d[6] = dev->d[5] = 255;
561+ fprintf(stderr, "fork failure\n");
562+ } else if(pid == 0) { /* child */
563+
564+#ifdef __linux__
565+ int r = prctl(PR_SET_PDEATHSIG, SIGTERM);
566+ if(r == -1) {
567+ perror(0);
568+ exit(6);
569+ }
570+ if(getppid() != parent_pid) exit(13);
571+#endif
572+
573+ if(child_mode & 0x01) {
574+ dup2(to_child_fd[0], 0);
575+ close(to_child_fd[1]);
576+ }
577+ if(child_mode & (0x04 | 0x02)) {
578+ if(child_mode & 0x02) dup2(from_child_fd[1], 1);
579+ if(child_mode & 0x04) dup2(from_child_fd[1], 2);
580+ close(from_child_fd[0]);
581+ }
582+ fflush(stdout);
583+ execvp(fork_args[0], fork_args);
584+ exit(1);
585+ } else { /*parent*/
586+ child_pid = pid;
587+ dev->d[5] = 1;
588+ dev->d[6] = 0;
589+ if(child_mode & 0x01) {
590+ saved_out = dup(1);
591+ dup2(to_child_fd[1], 1);
592+ close(to_child_fd[0]);
593+ }
594+ if(child_mode & (0x04 | 0x02)) {
595+ saved_in = dup(0);
596+ dup2(from_child_fd[0], 0);
597+ close(from_child_fd[1]);
598+ }
599+ }
600+}
601+
602+static void console_check_child(Device*dev) {
603+ int wstatus;
604+ if(child_pid) {
605+ if(waitpid(child_pid, &wstatus, WNOHANG)) {
606+ dev->d[5] = 255;
607+ dev->d[6] = WEXITSTATUS(wstatus);
608+ console_clean_after_child();
609+ } else {
610+ dev->d[5] = 1;
611+ dev->d[6] = 0;
612+ }
613+ }
614+}
615+
616+static void console_kill_child(Device*dev) {
617+ int wstatus;
618+ if(child_pid) {
619+ kill(child_pid, 9);
620+ if(waitpid(child_pid, &wstatus, WNOHANG)) {
621+ dev->d[5] = 255;
622+ dev->d[6] = WEXITSTATUS(wstatus);
623+ console_clean_after_child();
624+ }
625+ }
626+}
627+
628+static void console_start_fork(Device*dev) {
629+ fflush(stderr);
630+ console_kill_child(dev);
631+ child_mode = dev->d[14];
632+ console_start_fork_pipe(dev);
633+}
634+
635+static void close_console(Device*dev) {
636+ console_kill_child(dev);
637+}
638+
639+static Uint8 subprocess_console_in(Device*dev,Uint8 id) {
640+ switch(id) {
641+ case 5: case 6: console_check_child(dev); break;
642+ }
643+ return dev->d[id];
644+}
645+
646+// End of subprocess support
647+
648+static void console_out(Device*dev,Uint8 id) {
649+ switch(id) {
650+ case 8: fputc(dev->d[8],outf); break;
651+ case 9: fputc(dev->d[9],stderr); break;
652+ // Subprocess
653+ case 15: if(enable_subprocess) console_start_fork(dev); break;
654+ }
655+}
656+
657+static Uint16 files_stat(int fd,char*name,Uint16 len,Uint8*out) {
658+ struct stat st;
659+ if(strlen(name)+7>len || fstatat(fd,name,&st,0)) return 0;
660+ if(S_ISDIR(st.st_mode)) return snprintf(out,len,"---- %s\n",name);
661+ else if(st.st_size<0x10000) return snprintf(out,len,"%04x %s\n",(unsigned int)st.st_size,name);
662+ else return snprintf(out,len,"???? %s\n",name);
663+ return 0;
664+}
665+
666+static Uint32 files_seek(UxnFile*uf,Uint8 mode,Uint32 len) {
667+ switch(uf->mode) {
668+ case 1: case 2: case 4:
669+ switch(mode) {
670+ case 0: fseek(uf->file,len,SEEK_SET); break;
671+ case 1: fseek(uf->file,(Sint32)len,SEEK_CUR); break;
672+ case 2: fseek(uf->file,(Sint32)len,SEEK_END); break;
673+ case 3: return ftell(uf->file);
674+ }
675+ break;
676+ case 3:
677+ // if(!mode && !len) rewinddir(uf->dir);
678+ uf->de=0;
679+ break;
680+ }
681+ return 0;
682+}
683+
684+static int files_set(Device*dev,int rw) {
685+ // rw: 0(close) 1(read) 2(write) 3(both)
686+ // return: 1 if file opened, 0 if not opened
687+ Uint8 m=dev->d[7];
688+ UxnFile*uf=dev->aux;
689+ if(uf->file) fclose(uf->file);
690+ if(uf->dir) closedir(uf->dir);
691+ uf->file=0;
692+ uf->dir=0;
693+ uf->de=0;
694+ uf->mode=0;
695+ dev->d[2]=dev->d[3]=0;
696+ if(!uf->name[0]) return 0;
697+ if(rw==1) {
698+ if(uf->dir=opendir(uf->name)) {
699+ uf->mode=3;
700+ return 1;
701+ } else if(uf->file=fopen(uf->name,"r")) {
702+ uf->mode=1;
703+ return 1;
704+ } else {
705+ warn("Cannot open file '%s' for reading",uf->name);
706+ }
707+ } else if(rw==2 && allow_write) {
708+ if(uf->file=fopen(uf->name,m?"a":"w")) {
709+ uf->mode=2;
710+ return 1;
711+ } else {
712+ warn("Cannot open file '%s' for writing",uf->name);
713+ }
714+ } else if(rw==3) {
715+ if(allow_write && (uf->file=fopen(uf->name,"r+"))) {
716+ uf->mode=4;
717+ return 1;
718+ } else if(uf->file=fopen(uf->name,"r")) {
719+ uf->mode=1;
720+ return 1;
721+ } else {
722+ warn("Cannot open file '%s' for reading/writing",uf->name);
723+ }
724+ }
725+ return 0;
726+}
727+
728+static void files_out(Device*dev,Uint8 id) {
729+ UxnFile*uf=dev->aux;
730+ Uint16 len=GET16(dev->d+10);
731+ Uint16 addr,x,y;
732+ int i;
733+ switch(id) {
734+ case 5:
735+ addr=GET16(dev->d+4);
736+ dev->d[2]=dev->d[3]=0;
737+ if(!uf->name[0]) break;
738+ y=files_stat(AT_FDCWD,uf->name,len,mem+addr);
739+ if(y<=len) PUT16(dev->d+2,y);
740+ break;
741+ case 7:
742+ if(use_extension) files_set(dev,0);
743+ break;
744+ case 9:
745+ addr=GET16(dev->d+8);
746+ files_set(dev,0);
747+ x=GET16(dev->d+8);
748+ for(i=0;i<4095;i++) {
749+ if(!(uf->name[i]=mem[x+i])) break;
750+ // if(mem[x+i]=='/') uf->name[i]=0;
751+ }
752+ if(use_debug) fprintf(stderr,"! File: %s\n",uf->name);
753+ break;
754+ case 13:
755+ addr=GET16(dev->d+12);
756+ dev->d[2]=dev->d[3]=0;
757+ read:
758+ if(uf->mode==1 || uf->mode==4) {
759+ if(!len) break;
760+ x=fread(mem+addr,1,len,uf->file);
761+ PUT16(dev->d+2,x);
762+ if(ferror(uf->file)) {
763+ warn("Error reading file '%s'",uf->name);
764+ clearerr(uf->file);
765+ }
766+ } else if(uf->mode==3) {
767+ do {
768+ /*
769+ if(uf->de) {
770+ if(x=files_stat(dirfd(uf->dir),uf->de->d_name,len,mem+addr)) {
771+ addr+=x;
772+ len-=x;
773+ } else {
774+ break;
775+ }
776+ }*/
777+ } while(uf->de=readdir(uf->dir));
778+ PUT16(dev->d+2,addr-GET16(dev->d+12));
779+ } else {
780+ if(files_set(dev,1)) goto read;
781+ }
782+ break;
783+ case 15:
784+ addr=GET16(dev->d+14);
785+ dev->d[2]=dev->d[3]=0;
786+ if(!allow_write) {
787+ disallow:
788+ warn("Not allowed to write to file '%s'.",uf->name);
789+ break;
790+ }
791+ write:
792+ if(uf->mode==2 || uf->mode==4) {
793+ if(!len) break;
794+ x=fwrite(mem+addr,1,len,uf->file);
795+ PUT16(dev->d+2,x);
796+ if(ferror(uf->file)) {
797+ warn("Error writing file '%s'",uf->name);
798+ clearerr(uf->file);
799+ }
800+ } else {
801+ if(files_set(dev,2)) goto write;
802+ }
803+ break;
804+ }
805+}
806+
807+static Uint8 files_in(Device*dev,Uint8 id) {
808+ UxnFile*uf=dev->aux;
809+ int c;
810+ switch(id) {
811+ case 12: case 13:
812+ dev->d[2]=dev->d[3]=0;
813+ read:
814+ if(uf->mode==1 || uf->mode==4) {
815+ c=fgetc(uf->file);
816+ if(c==EOF) {
817+ if(ferror(uf->file)) {
818+ warn("Error reading file '%s'",uf->name);
819+ clearerr(uf->file);
820+ }
821+ c=0;
822+ } else {
823+ dev->d[3]=1;
824+ }
825+ return c;
826+ } else if(uf->mode==3) {
827+ return 0;
828+ } else {
829+ if(files_set(dev,1)) goto read;
830+ }
831+ return 0;
832+ default: return dev->d[id];
833+ }
834+}
835+
836+static void files_exp(Device*dev,Uint16 addr) {
837+ UxnFile*uf=dev->aux;
838+ Uint32 x;
839+ if(use_extension) switch(mem[addr]&15) {
840+ case 0 ... 2:
841+ x=GET16(mem+addr+1)<<16;
842+ x|=GET16(mem+addr+3);
843+ if(!uf->mode) files_set(dev,3);
844+ files_seek(uf,mem[addr]&15,x);
845+ break;
846+ case 3:
847+ x=files_seek(uf,3,0);
848+ PUT16(mem+addr+1,x>>16);
849+ PUT16(mem+addr+3,x);
850+ break;
851+ }
852+}
853+
854+static Uint8 datetime_in(Device*dev,Uint8 id) {
855+ time_t t=time(0);
856+ struct tm r;
857+ if(use_utc) gmtime_r(&t,&r); else localtime_r(&t,&r);
858+ switch(id) {
859+ case 0: return (r.tm_year+1900)>>8;
860+ case 1: return r.tm_year+1900;
861+ case 2: return r.tm_mon;
862+ case 3: return r.tm_mday;
863+ case 4: return r.tm_hour;
864+ case 5: return r.tm_min;
865+ case 6: return r.tm_sec;
866+ case 7: return r.tm_wday;
867+ case 8: return r.tm_yday>>8;
868+ case 9: return r.tm_yday;
869+ case 10: return r.tm_isdst;
870+ default: return dev->d[id];
871+ }
872+}
873+
874+static Uint8 random_in(Device*dev,Uint8 id) {
875+ Uint8 x[1];
876+ if(read(randomfd,x,1)!=1) err(1,"Cannot read random numbers");
877+ return *x;
878+}
879+
880+static void set_cursor(void) {
881+ if(hide_cursor) SDL_ShowCursor(paused || !use_mouse);
882+}
883+
884+static Uint32 timer_callback(Uint32 interval) {
885+ if(!timer_expired) {
886+ SDL_Event e;
887+ timer_expired=1;
888+ e.type=SDL_USEREVENT;
889+ SDL_PushEvent(&e);
890+ timer_expired=1;
891+ }
892+ return interval;
893+}
894+
895+static void set_screen_mode(int w,int h) {
896+ picture_changed=size_changed=0;
897+ free(bglayer);
898+ if(screen) SDL_FreeSurface(screen);
899+ if(w<1) w=1;
900+ if(h<1) h=1;
901+ scr_w=w;
902+ scr_h=h;
903+ screen=SDL_SetVideoMode(w*zoom,h*zoom,8,scrflags);
904+ if(!screen) err(1,"Cannot set screen mode");
905+ if(!bglayer) {
906+ if(timer_rate) SDL_SetTimer(timer_rate,timer_callback);
907+ if(audio_option) {
908+ if(SDL_OpenAudio(&audiospec,0)) err(1,"Cannot initialize SDL audio");
909+ SDL_PauseAudio(0);
910+ }
911+ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);
912+ SDL_WM_SetCaption(rom_name,rom_name);
913+ set_cursor();
914+ SDL_EnableUNICODE(1);
915+ }
916+ SDL_SetColors(screen,colors+palet*8,0,8);
917+ bglayer=calloc(w*h,2);
918+ if(!bglayer) err(1,"Memory allocation error");
919+ fglayer=bglayer+w*h;
920+}
921+
922+static void screen_fill(Uint8*p,Uint8 v,Uint16 x0,Uint16 y0,Uint16 x1,Uint16 y1) {
923+ if(y1>scr_h) y1=scr_h;
924+ if(x1>scr_w) x1=scr_w;
925+ if(y0>=y1 || x0>=x1) return;
926+ p+=y0*scr_w+x0;
927+ x1-=x0;
928+ while(y0++<y1) memset(p,v,x1),p+=scr_w;
929+}
930+
931+static void draw_sprite(Uint16 x,Uint16 y,Uint16 addr,Uint8 v) {
932+ Uint8 b=v&0x80;
933+ Uint8 u;
934+ Uint16 c;
935+ Uint8*p=v&0x40?fglayer:bglayer;
936+ Uint8*m;
937+ if(x+8>scr_w || y+8>scr_h || addr>0x10000-(b?16:8)) return;
938+ p+=y*scr_w+x;
939+ m=mem+addr;
940+ for(y=0;y<8;y++) {
941+ c=m[y]|(b?m[y+8]<<8:0);
942+ for(x=0;x<8;x++) {
943+ u=(c&1)|((c>>7)&2);
944+ c>>=1;
945+ if((u=blend[u][v&0x0F])!=4) p[(y^(v&0x20?7:0))*scr_w+(x^(v&0x10?0:7))]=u;
946+ }
947+ }
948+}
949+
950+static void screen_out(Device*dev,Uint8 id) {
951+ int i,fx,fy;
952+ Uint16 w;
953+ Uint16 x=GET16(dev->d+8);
954+ Uint16 y=GET16(dev->d+10);
955+ Uint8 z=dev->d[id];
956+ if(id<6 && disallow_size_change) {
957+ PUT16(dev->d+2,scr_w);
958+ PUT16(dev->d+4,scr_h);
959+ return;
960+ }
961+ switch(id) {
962+ case 2: case 3:
963+ x=GET16(dev->d+2);
964+ if(x!=scr_w) scr_w=x,size_changed=1;
965+ break;
966+ case 4: case 5:
967+ x=GET16(dev->d+4);
968+ if(x!=scr_h) scr_h=x,size_changed=1;
969+ break;
970+ case 14:
971+ if(size_changed) set_screen_mode(scr_w,scr_h);
972+ picture_changed=1;
973+ if(z<0x80) {
974+ if(x<scr_w && y<scr_h) (z&0x40?fglayer:bglayer)[x+y*scr_w]=z&3;
975+ if(dev->d[6]&0x01) PUT16(dev->d+8,x+1);
976+ if(dev->d[6]&0x02) PUT16(dev->d+10,y+1);
977+ } else {
978+ screen_fill(z&0x40?fglayer:bglayer,z&3,dev->d[14]&0x10?0:x,dev->d[14]&0x20?0:y,dev->d[14]&0x10?x:scr_w,dev->d[14]&0x20?y:scr_h);
979+ }
980+ break;
981+ case 15:
982+ if(size_changed) set_screen_mode(scr_w,scr_h);
983+ picture_changed=1;
984+ w=GET16(dev->d+12);
985+ fx=((z&0x10)&&(screencompat&0x02)?-8:8);
986+ fy=((z&0x20)&&(screencompat&0x02)?-8:8);
987+ for(i=0;i<=(dev->d[6]>>4);i++) {
988+ draw_sprite(x+i*(dev->d[6]&0x02?fx:0),y+i*(dev->d[6]&0x01?fy:0),w,z);
989+ if(dev->d[6]&0x04) w+=z&0x80?16:8;
990+ }
991+ if(dev->d[6]&0x01) PUT16(dev->d+8,x+fx);
992+ if(dev->d[6]&0x02) PUT16(dev->d+10,y+fy);
993+ if(dev->d[6]&0x04) PUT16(dev->d+12,w);
994+ break;
995+ }
996+}
997+
998+static void audio_out(Device*dev,Uint8 id) {
999+ UxnAudio*a;
1000+ Uint32 s,n;
1001+ if(id!=15) return;
1002+ if(use_screen) SDL_LockAudio();
1003+ a=dev->aux;
1004+ a->env[0]=(dev->d[8]>>4)*audio_option['e'-'a'];
1005+ a->env[1]=(dev->d[8]&15)*audio_option['e'-'a'];
1006+ a->env[2]=(dev->d[9]>>4)*audio_option['e'-'a'];
1007+ a->env[3]=(dev->d[9]&15)*audio_option['e'-'a'];
1008+ a->length=n=GET16(dev->d+10);
1009+ a->pos=s=GET16(dev->d+12);
1010+ a->end=s+n;
1011+ if(dev->d[15]&0x80) a->length=0;
1012+ a->envtime=0;
1013+ a->phase=0;
1014+ s=(dev->d[15]&0x7F)+audio_option['n'-'a'];
1015+ s=notes[s%12]>>(10-s/12);
1016+ if(n<256) s=(n*(unsigned long long)s)>>8;
1017+ if(use_extension && (dev->d[6] || dev->d[7])) s=(((unsigned long long)s)*(0x10000+GET16(dev->d+6)))>>16;
1018+ a->freq=s;
1019+ if(audiospec.channels==1) {
1020+ a->vol[0]=a->vol[1]=((dev->d[14]&15)+(dev->d[14]>>4))/2;
1021+ } else {
1022+ a->vol[0]=dev->d[14]>>4;
1023+ a->vol[1]=dev->d[14]&15;
1024+ }
1025+ if(use_screen) SDL_UnlockAudio();
1026+}
1027+
1028+static Uint32 envelope(const UxnAudio*a) {
1029+ // Returns a number from 0 to 64.
1030+ Uint32 t=a->envtime;
1031+ if(!(a->env[0]|a->env[1]|a->env[2]|a->env[3])) return 64;
1032+ if(t<a->env[0]) return ((64*t)/a->env[0])?:1;
1033+ t-=a->env[0];
1034+ if(t<a->env[1]) return 64-((32*t)/a->env[1]);
1035+ t-=a->env[1];
1036+ if(t<a->env[2]) return 32;
1037+ t-=a->env[2];
1038+ if(t<a->env[3]) return 32-((32*t)/a->env[3]);
1039+ return 0;
1040+}
1041+
1042+static void audio_callback(void*userdata,Uint8*stream,int len) {
1043+ Uint8 c=audiospec.channels;
1044+ Uint32 vol=audio_option['m'-'a']?0:audio_option['v'-'a'];
1045+ Sint16*buf=(void*)stream;
1046+ UxnAudio*a;
1047+ Uint32 o0,o1,d,n,e;
1048+ len>>=1;
1049+ for(n=0;n<len;n+=c) {
1050+ o0=o1=0;
1051+ for(d=3;d<7;d++) {
1052+ a=device[d].aux;
1053+ if(a->pos>=a->end && !a->length) continue;
1054+ e=envelope(a);
1055+ if(!e) {
1056+ a->pos=a->length=a->end=0;
1057+ continue;
1058+ }
1059+ a->envtime++;
1060+ e*=(Sint8)(mem[a->pos]^0x80);
1061+ a->phase+=a->freq;
1062+ if(a->phase>=0x1000000) {
1063+ a->pos+=a->phase>>24;
1064+ a->phase&=0xFFFFFF;
1065+ while(a->pos>=a->end && a->length) a->pos-=a->length;
1066+ }
1067+ o0+=e*a->vol[0];
1068+ o1+=e*a->vol[1];
1069+ }
1070+ buf[n]=(o0*vol)>>12;
1071+ if(c==2) buf[n+1]=(o1*vol)>>12;
1072+ }
1073+}
1074+
1075+static void run_audio(void) {
1076+ Uint8 c=audiospec.channels;
1077+ Uint32 vol=audio_option['m'-'a']?0:audio_option['v'-'a'];
1078+ Uint32 fram=(timer_rate*(long long)audiospec.freq)/1000;
1079+ Uint8 q=0;
1080+ Uint32 f=0;
1081+ UxnAudio*a;
1082+ Uint32 o0,o1,d,e;
1083+ for(;;) {
1084+ if(++f==fram) {
1085+ f=0;
1086+ run(GET16(device[2].d));
1087+ }
1088+ if(q) {
1089+ for(d=3;d<7;d++) if(q&(1<<d)) run(GET16(device[d].d));
1090+ q=0;
1091+ }
1092+ //TODO: check for input from stdin
1093+ o0=o1=0;
1094+ for(d=3;d<7;d++) {
1095+ a=device[d].aux;
1096+ if(a->pos>=a->end && !a->length) {
1097+ end:
1098+ if(a->length) q|=1<<d;
1099+ a->pos=a->length=a->end=0;
1100+ continue;
1101+ }
1102+ e=envelope(a);
1103+ if(!e) goto end;
1104+ a->envtime++;
1105+ e*=(Sint8)(mem[a->pos]^0x80);
1106+ a->phase+=a->freq;
1107+ if(a->phase>=0x1000000) {
1108+ a->pos+=a->phase>>24;
1109+ a->phase&=0xFFFFFF;
1110+ while(a->pos>=a->end && a->length) a->pos-=a->length;
1111+ }
1112+ o0+=e*a->vol[0];
1113+ o1+=e*a->vol[1];
1114+ }
1115+ d=(o0*vol)>>12; putchar(d>>8); putchar(d);
1116+ if(c==2) {
1117+ d=(o1*vol)>>12; putchar(d>>8); putchar(d);
1118+ }
1119+ }
1120+}
1121+
1122+static void do_extension_by_uuid(Uint16 addr) {
1123+ static const Uint8 uuid_8color[]="\x80\x17\x51\x32\xE2\x63\x11\xED\xB8\xC9\x00\x26\x18\x74\x54\x16";
1124+ static const Uint8 uuid_screencompat[]="\x97\x0B\x5A\x0C\x2C\x44\x11\xEE\xAC\x3B\x00\x26\x18\x74\x54\x16";
1125+ static const Uint8 uuid_subprocess[]="\x9C\x5F\x13\x56\x6B\xC5\x11\xEF\xA6\xC9\x00\x26\x18\x74\x54\x16";
1126+ static const Uint8 uuid_random[]="\x41\x05\x25\x9C\xE0\x61\x11\xF0\x96\x3F\x00\x26\x18\x74\x54\x16";
1127+ int i;
1128+ if(mem[addr+1]==0x00 && use_screen && !memcmp(mem+addr+2,uuid_8color,16)) {
1129+ for(i=0;i<8;i++) {
1130+ colors[i+070].r=(mem[addr+19+i+i]>>4)*0x11;
1131+ colors[i+070].g=(mem[addr+19+i+i]&15)*0x11;
1132+ colors[i+070].b=(mem[addr+20+i+i]>>4)*0x11;
1133+ }
1134+ if(palet==7) {
1135+ SDL_SetColors(screen,colors+palet*8,0,8);
1136+ picture_changed=1;
1137+ }
1138+ mem[addr+18]=1;
1139+ } else if(mem[addr+1]==0x20 && use_screen && !memcmp(mem+addr+2,uuid_screencompat,16)) {
1140+ screencompat=mem[addr+19];
1141+ blend[0][0]=(screencompat&0x01?4:0);
1142+ mem[addr+18]=1;
1143+ } else if(mem[addr+1]==0x10 && use_thread && use_console && allow_write && !memcmp(mem+addr+2,uuid_subprocess,16)) {
1144+ device[1].in=subprocess_console_in;
1145+ enable_subprocess=mem[addr+18]=1;
1146+ } else if(device[mem[addr+1]>>4].in==default_in && mem[addr+19]<2 && mem[addr+20]>=4 && !memcmp(mem+addr+2,uuid_random,16)) {
1147+ if(randomfd==-1) randomfd=open("/dev/urandom",O_RDONLY|O_NOCTTY|O_CLOEXEC);
1148+ if(randomfd>=0) {
1149+ mem[addr+18]=1;
1150+ device[mem[addr+1]>>4].in=random_in;
1151+ i=(mem[addr+21]<<8)|mem[addr+22];
1152+ mem[i]=0x80;
1153+ mem[i+1]=mem[addr+1];
1154+ mem[i+2]=0x16+(mem[addr+19]<<5);
1155+ mem[i+3]=0x6C;
1156+ } else {
1157+ warn("Cannot open /dev/urandom");
1158+ }
1159+ }
1160+}
1161+
1162+static void system_exp(Device*dev,Uint16 addr) {
1163+ Uint32 src,dst;
1164+ Uint16 len,n;
1165+ switch(mem[addr]) {
1166+ case 0x00:
1167+ len=GET16(mem+addr+1);
1168+ dst=(GET16(mem+addr+3)<<16L)|(GET16(mem+addr+5));
1169+ if(dst<MEMSIZE && dst+len<=MEMSIZE) {
1170+ memset(mem+dst,mem[addr+7],len);
1171+ } else {
1172+ if(use_debug) fprintf(stderr,"! Access expanded memory out of range\n");
1173+ }
1174+ break;
1175+ case 0x01: case 0x02:
1176+ len=GET16(mem+addr+1);
1177+ src=(GET16(mem+addr+3)<<16L)|(GET16(mem+addr+5));
1178+ dst=(GET16(mem+addr+7)<<16L)|(GET16(mem+addr+9));
1179+ if(dst<MEMSIZE && src+len<=MEMSIZE && dst+len<=MEMSIZE) {
1180+ if(mem[addr]==0x01) {
1181+ for(n=0;n<len;n++) mem[dst+n]=mem[src+n];
1182+ } else {
1183+ for(n=len;n;n--) mem[dst+n-1]=mem[src+n-1];
1184+ }
1185+ } else {
1186+ if(use_debug) fprintf(stderr,"! Access expanded memory out of range\n");
1187+ }
1188+ break;
1189+ case 0x03:
1190+ if(!use_extension) break;
1191+ mem[addr+18]=0;
1192+ do_extension_by_uuid(addr);
1193+ break;
1194+ case 0x04:
1195+ if(!use_extension) break;
1196+ PUT16(mem+addr+1,EXPANDED_MEMORY);
1197+ break;
1198+ }
1199+}
1200+
1201+static void debug_screen(Uint8*s,Uint8 k) {
1202+ static Sint8 page=0;
1203+ static Uint8 port=0;
1204+ static Uint8 din;
1205+ static Uint32 addr=0;
1206+ static Uint32 scrol=0;
1207+ static const char opname[]=
1208+ "?IPNSRDOENGLJJJSLSLSLSDDASMDAOES"
1209+ "?NOIWOUVQETTMCSTDTDTDTEEDUUINROF"
1210+ "?CPPPTPRUQHHPNRHZZRRAAIODBLVDART"
1211+ ;
1212+ char buf[81];
1213+ int i,j;
1214+ Stack*z;
1215+ FILE*f;
1216+ UxnFile*u;
1217+ if(s) {
1218+ memset(s,32,80*25);
1219+ show:
1220+ switch(page) {
1221+ case 0:
1222+ memcpy(s+80*0,buf,snprintf(buf,81,"* %s",rom_name));
1223+ memcpy(s+80*1,buf,snprintf(buf,81,"<c> Console: %s",use_console?"On":"Off"));
1224+ memcpy(s+80*2,buf,snprintf(buf,81,"<d> Debug: %s",use_debug?"On":"Off"));
1225+ memcpy(s+80*3,buf,snprintf(buf,81,"<F2> Sound: %s",audio_option?(audio_option['m'-'a']?"Mute":"On"):"N/A"));
1226+ memcpy(s+80*4,buf,snprintf(buf,81,"<F3> Mouse: %s",use_mouse?"On":"Off"));
1227+ memcpy(s+80*5,buf,snprintf(buf,81,"<F4> Layers: %s",layers?(layers==1?"fg":"bg"):"fg/bg"));
1228+ memcpy(s+80*6,buf,snprintf(buf,81,"<F6/F7> Palette: %d",palet));
1229+ memcpy(s+80*7,buf,snprintf(buf,81,"<F9> Restart"));
1230+ memcpy(s+80*8,buf,snprintf(buf,81,"<F10> Quit"));
1231+ if(audio_option) memcpy(s+80*9,buf,snprintf(buf,81,"<-/+> Volume: %d",(int)audio_option['v'-'a']));
1232+ memcpy(s+80*10,buf,snprintf(buf,81,"<PAUSE> Resume"));
1233+ memcpy(s+80*13,buf,snprintf(buf,81,"Pages: CTRL+"));
1234+ memcpy(s+80*14,buf,snprintf(buf,81," A:Stack B:Return C:Device D:Memory E:Files "));
1235+ memcpy(s+80*15,buf,snprintf(buf,81," F:Code G: N: O: P: "));
1236+ memcpy(s+80*16,buf,snprintf(buf,81," Q: R: S: T: U: "));
1237+ memcpy(s+80*17,buf,snprintf(buf,81," V: W: X: Y: Z:Main "));
1238+ break;
1239+ case 1: case 2:
1240+ if(page==1) z=&ds; else z=&rs;
1241+ memcpy(s,buf,snprintf(buf,81,"%s Stack (%02x)",page==1?"Data":"Return",z->p));
1242+ for(i=0;i<256;i++) memcpy(s+80*(i/16+1)+(i&15)*4,buf,snprintf(buf,81,"%c%02x%c",z->p==i?'[':' ',z->d[i],z->p==i?']':' '));
1243+ break;
1244+ case 3:
1245+ memcpy(s,buf,snprintf(buf,81,"-- -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -a -b -c -d -e -f"));
1246+ for(i=0;i<16;i++) memcpy(s+80*(i+1),buf,snprintf(buf,81,"%x0:",i));
1247+ for(i=0;i<256;i++) memcpy(s+80*(i/16+1)+(i&15)*4+4,buf,snprintf(buf,81,"%c%02x%c",port==i?'[':' ',device[i>>4].d[i&15],port==i?']':' '));
1248+ memcpy(s+80*17,buf,snprintf(buf,81,"<i> In=%02x <o> Out <x> Execute",din));
1249+ break;
1250+ case 4:
1251+ if(addr<0) addr=0;
1252+ if(addr>=MEMSIZE) addr=MEMSIZE-1;
1253+ if(scrol<0) scrol=0;
1254+ if(addr>=0x100 && scrol<addr-0xF0) scrol=(addr-0xF0)&~15;
1255+ if(scrol>addr) scrol=addr&~15;
1256+ memcpy(s,buf,snprintf(buf,81,"----- -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -a -b -c -d -e -f"));
1257+ for(i=0;i<16;i++) memcpy(s+80*(i+1),buf,snprintf(buf,81,"%05x:",i*16+scrol));
1258+ for(i=0;i<256;i++) if(i+scrol<MEMSIZE) memcpy(s+80*(i/16+1)+(i&15)*4+7,buf,snprintf(buf,81,"%c%02x%c",addr==i+scrol?'[':' ',mem[i+scrol],addr==i+scrol?']':' '));
1259+ memcpy(s+80*17,buf,snprintf(buf,81,"<x> Execute <s> Save"));
1260+ break;
1261+ case 5:
1262+ for(i=0;i<2;i++) {
1263+ u=i?&uxnfile1:&uxnfile0;
1264+ memcpy(s+80*(7*i+1),buf,snprintf(buf,81,"[File%d]",i));
1265+ memcpy(s+80*(7*i+2),buf,snprintf(buf,81," name=%s",u->name));
1266+ if(u->file) memcpy(s+80*(7*i+3),buf,snprintf(buf,81," File fd=%d offset=0x%lX",fileno(u->file),ftell(u->file)));
1267+ // if(u->dir) memcpy(s+80*(7*i+4),buf,snprintf(buf,81," Dir fd=%d offset=0x%lX",dirfd(u->dir),telldir(u->dir)));
1268+ memcpy(s+80*(7*i+5),buf,snprintf(buf,81," mode=0x%02X",u->mode));
1269+ memcpy(s+80*(7*i+6),buf,snprintf(buf,81," <%c> Close <%c> Rewind","cC"[i],"rR"[i]));
1270+ }
1271+ break;
1272+ case 6:
1273+ j=break_pc;
1274+ for(i=0;i<16 && j<0x10000;i++) {
1275+ memcpy(s+80*i,buf,snprintf(buf,81,"%04x: %c%c %c%c%c%c%c%c",j,breakpoint==j+1?'*':' ',i?' ':'>',
1276+ opname[mem[j]&0x1F],opname[(mem[j]&0x1F)+0x20],opname[(mem[j]&0x1F)+0x40]
1277+ ,mem[j]&0x20?'2':'_',mem[j]&0x40?'r':'_',mem[j]&0x80?'k':'_' ));
1278+ if(mem[j]==0x80 || mem[j]==0xC0) {
1279+ memcpy(s+80*i+9,buf,snprintf(buf,81,"LIT_%c %02x",mem[j]&0x40?'r':'_',mem[j+1]));
1280+ j+=2;
1281+ } else if(mem[j]==0xA0 || mem[j]==0xE0) {
1282+ memcpy(s+80*i+9,buf,snprintf(buf,81,"LIT2%c %02x%02x",mem[j]&0x40?'r':'_',mem[j+1],mem[j+2]));
1283+ j+=3;
1284+ } else {
1285+ if(!mem[j]) memcpy(s+80*i+9,"BRK",3);
1286+ j++;
1287+ }
1288+ }
1289+ memcpy(s+80*17,buf,snprintf(buf,81,"ds:%02x rs:%02x",ds.p,rs.p));
1290+ memcpy(s+80*19,buf,snprintf(buf,81,"<SPACE> Step <RET> Continue <x> Execute"));
1291+ memcpy(s+80*20,buf,snprintf(buf,81,"<,> Set Breakpoint <.> Clear Breakpoint"));
1292+ break;
1293+ default:
1294+ if(page<0) page=6; else page=0;
1295+ goto show;
1296+ }
1297+ } else {
1298+ if(k==9 || k==']') {
1299+ ++page;
1300+ } else if(k=='[') {
1301+ --page;
1302+ } else if(k>=1 && k<=7) {
1303+ page=k;
1304+ } else if(k>=14 && k<=25) {
1305+ page=k-6;
1306+ } else if(k==26) {
1307+ page=0;
1308+ } else if(k==27) {
1309+ debugger=0;
1310+ return;
1311+ } else switch(page) {
1312+ case 0:
1313+ if(k=='c') use_console^=1;
1314+ if(k=='d') use_debug^=1;
1315+ if(audio_option) {
1316+ if((k=='-' || k==10) && audio_option['v'-'a']) --audio_option['v'-'a'];
1317+ if(k=='+' || k==11) ++audio_option['v'-'a'];
1318+ if(k==8) audio_option['v'-'a']/=10;
1319+ if(k>='0' && k<='9') audio_option['v'-'a']=10*audio_option['v'-'a']+k-'0';
1320+ }
1321+ break;
1322+ case 1: case 2:
1323+ if(page==1) z=&ds; else z=&rs;
1324+ if(k==8) z->p--;
1325+ if(k==12) z->p++;
1326+ if(k==10) z->p+=16;
1327+ if(k==11) z->p-=16;
1328+ if(k>='0' && k<='9') z->d[z->p]=(z->d[z->p]<<4)+(k-'0');
1329+ if(k>='a' && k<='f') z->d[z->p]=(z->d[z->p]<<4)+(k+10-'a');
1330+ break;
1331+ case 3:
1332+ i=port;
1333+ if(k==8) port--;
1334+ if(k==12) port++;
1335+ if(k==10) port+=16;
1336+ if(k==11) port-=16;
1337+ if(k>='0' && k<='9') device[i>>4].d[i&15]=(device[i>>4].d[i&15]<<4)+(k-'0');
1338+ if(k>='a' && k<='f') device[i>>4].d[i&15]=(device[i>>4].d[i&15]<<4)+(k+10-'a');
1339+ if(k=='i') din=device[i>>4].in(device+(i>>4),i&15);
1340+ if(k=='o') device[i>>4].out(device+(i>>4),i&15);
1341+ if(k=='x') run(GET16(device[i>>4].d));
1342+ break;
1343+ case 4:
1344+ if(k==8) addr--;
1345+ if(k==12) addr++;
1346+ if(k==10) addr+=16;
1347+ if(k==11) addr-=16;
1348+ if(k==',') scrol-=0x10,addr-=0x10;
1349+ if(k=='.') scrol+=0x10,addr+=0x10;
1350+ if(k=='<') scrol-=0x100,addr-=0x100;
1351+ if(k=='>') scrol+=0x100,addr+=0x100;
1352+ if(k=='q') scrol-=0x1000,addr-=0x1000;
1353+ if(k=='w') scrol+=0x1000,addr+=0x1000;
1354+ if(k=='Q') scrol-=0x10000,addr-=0x10000;
1355+ if(k=='W') scrol+=0x10000,addr+=0x10000;
1356+ if(k=='=') scrol=addr=0;
1357+ if(addr>=MEMSIZE+0x1000) scrol=addr=0;
1358+ if(k>='0' && k<='9') mem[addr]=(mem[addr]<<4)+(k-'0');
1359+ if(k>='a' && k<='f') mem[addr]=(mem[addr]<<4)+(k+10-'a');
1360+ if(k=='x' && addr<0x10000) run(addr);
1361+ if(k=='s') {
1362+ f=fopen("_uxn_memory","w");
1363+ if(f) {
1364+ fwrite(mem,1,MEMSIZE,f);
1365+ fprintf(stderr,"Saved 0x%X bytes to file _uxn_memory\n",(int)(MEMSIZE));
1366+ fclose(f);
1367+ } else {
1368+ warn("Cannot open file _uxn_memory");
1369+ }
1370+ }
1371+ break;
1372+ case 5:
1373+ if(k=='c') files_set(device+10,0);
1374+ if(k=='C') files_set(device+11,0);
1375+ if(k=='r') files_seek(&uxnfile0,0,0);
1376+ if(k=='R') files_seek(&uxnfile1,0,0);
1377+ break;
1378+ case 6:
1379+ if(k==8 || k==11) --break_pc;
1380+ if(k==12 || k==10) ++break_pc;
1381+ if(k>='0' && k<='9') break_pc=(break_pc<<4)+(k-'0');
1382+ if(k>='a' && k<='f') break_pc=(break_pc<<4)+(k+10-'a');
1383+ if(k==',') breakpoint=break_pc+1;
1384+ if(k=='.') breakpoint=0;
1385+ if(k=='x') run(break_pc);
1386+ if(k==' ') {
1387+ j=breakpoint;
1388+ breakpoint=break_pc+2;
1389+ i=mem[break_pc];
1390+ if(i==0x80 || i==0xC0) {
1391+ breakpoint=break_pc+3;
1392+ } else if(i==0xA0 || i==0xE0) {
1393+ breakpoint=break_pc+4;
1394+ } else if((i&0x1F)==0x0C || (i&0x1F)==0x0D || (i&0x1F)==0x0E) {
1395+ if((i&0x1F)==0x0D) {
1396+ i&=0x60;
1397+ if(i==0x00 && ds.p>1 && !ds.d[ds.p-2]) goto no_jump;
1398+ if(i==0x20 && ds.p>2 && !ds.d[ds.p-3]) goto no_jump;
1399+ if(i==0x40 && rs.p>1 && !rs.d[rs.p-2]) goto no_jump;
1400+ if(i==0x60 && rs.p>2 && !rs.d[rs.p-3]) goto no_jump;
1401+ }
1402+ i&=0x60;
1403+ if(i==0x00 && ds.p) breakpoint=break_pc+((Sint8)ds.d[ds.p-1])+2;
1404+ else if(i==0x20 && ds.p>1) breakpoint=GET16(ds.d+ds.p-2)+1;
1405+ else if(i==0x40 && rs.p) breakpoint=break_pc+((Sint8)rs.d[rs.p-1])+2;
1406+ else if(i==0x60 && rs.p>1) breakpoint=GET16(rs.d+rs.p-2)+1;
1407+ else goto no_run;
1408+ } else if(i) {
1409+ no_jump:
1410+ breakpoint=break_pc+2;
1411+ } else {
1412+ goto no_run;
1413+ }
1414+ run(break_pc);
1415+ no_run:
1416+ breakpoint=j;
1417+ break;
1418+ }
1419+ if(k==13) {
1420+ paused=debugger=0;
1421+ run(break_pc);
1422+ return;
1423+ }
1424+ break;
1425+ }
1426+ }
1427+}
1428+
1429+static void redraw(void) {
1430+ static Uint8*s=0;
1431+ int a,r,u,v,x,y;
1432+ Uint8*p;
1433+ if(debugger) {
1434+ if(!s) s=calloc(80,26);
1435+ if(!s) err(1,"Allocation failed");
1436+ debug_screen(s,0);
1437+ }
1438+ if(size_changed) set_screen_mode(scr_w,scr_h);
1439+ picture_changed=0;
1440+ SDL_LockSurface(screen);
1441+ a=0;
1442+ p=screen->pixels;
1443+ r=screen->pitch;
1444+ if(debugger) {
1445+ for(y=0;y<scr_h*zoom;y++) {
1446+ for(x=0;x<scr_w*zoom;x++) {
1447+ if(y>=25*8-7 || x>=80*8 || (v=s[(y/8)*80+x/8]-32)<=0) p[x]=0;
1448+ else p[x]=(fontdata[v*8+(y&7)]>>(7&~x))&1;
1449+ }
1450+ p+=r;
1451+ }
1452+ if(scr_h*zoom>9) {
1453+ p=screen->pixels+r*(scr_h*zoom-8);
1454+ for(y=0;y<8;y++) {
1455+ for(a=0;a<scr_w*zoom;a++) p[a]=(a>>4)&7;
1456+ p+=r;
1457+ }
1458+ }
1459+ } else if(layers) {
1460+ for(y=0;y<scr_h;y++) {
1461+ for(x=0;x<scr_w;x++) {
1462+ u=(layers==1?fglayer:bglayer)[a];
1463+ for(v=0;v<zoom;v++) memset(p+v*r+x*zoom,u,zoom);
1464+ a++;
1465+ }
1466+ p+=r*zoom;
1467+ }
1468+ } else {
1469+ for(y=0;y<scr_h;y++) {
1470+ for(x=0;x<scr_w;x++) {
1471+ u=fglayer[a]?fglayer[a]+4:bglayer[a];
1472+ for(v=0;v<zoom;v++) memset(p+v*r+x*zoom,u,zoom);
1473+ a++;
1474+ }
1475+ p+=r*zoom;
1476+ }
1477+ }
1478+ SDL_UnlockSurface(screen);
1479+ SDL_Flip(screen);
1480+}
1481+
1482+static inline int select_joystick(Uint8 n) {
1483+ if((joy_mask&1) && n==joy_player[0]) return 2;
1484+ if((joy_mask&2) && n==joy_player[1]) return 5;
1485+ if((joy_mask&4) && n==joy_player[2]) return 6;
1486+ if((joy_mask&8) && n==joy_player[3]) return 7;
1487+ return 0;
1488+}
1489+
1490+static int run_screen(void) {
1491+ SDL_Event e;
1492+ int i,j,k;
1493+ while(SDL_WaitEvent(&e)) {
1494+ switch(e.type) {
1495+ case SDL_QUIT: return 0;
1496+ case SDL_VIDEOEXPOSE: redraw(); break;
1497+ case SDL_USEREVENT: timer_expired=0; if(!paused) run(GET16(device[2].d)); break;
1498+ case SDL_KEYDOWN:
1499+ i=0;
1500+ switch(e.key.keysym.sym) {
1501+ case SDLK_LCTRL: case SDLK_END: i=0x01; break;
1502+ case SDLK_LALT: i=0x02; break;
1503+ case SDLK_LSHIFT: i=0x04; break;
1504+ case SDLK_HOME: i=0x08; break;
1505+ case SDLK_UP: i=0x10; break;
1506+ case SDLK_DOWN: i=0x20; break;
1507+ case SDLK_LEFT: i=0x40; break;
1508+ case SDLK_RIGHT: i=0x80; break;
1509+ case SDLK_PAGEUP: i=-scroll_size; goto scroll;
1510+ case SDLK_PAGEDOWN: i=scroll_size; goto scroll;
1511+ case SDLK_F1: run(GET16(device[2].d)); timer_expired=0; break;
1512+ case SDLK_F2: if(audio_option) audio_option['m'-'a']^=1; picture_changed=debugger; break;
1513+ case SDLK_F3: use_mouse^=1; set_cursor(); picture_changed=debugger; break;
1514+ case SDLK_F4: layers=(layers+1)%3; redraw(); break;
1515+ case SDLK_F5: redraw(); if(SDL_GetModState()&KMOD_RSHIFT) debug(-1); break;
1516+ case SDLK_F6: palet=(palet+1)&7; SDL_SetColors(screen,colors+palet*8,0,8); redraw(); break;
1517+ case SDLK_F7: palet=(palet-1)&7; SDL_SetColors(screen,colors+palet*8,0,8); redraw(); break;
1518+ case SDLK_F8: paused=picture_changed=debugger=1; break;
1519+ case SDLK_F9: return 1;
1520+ case SDLK_F10: return 0;
1521+ case SDLK_PAUSE: debugger=0; paused^=1; set_cursor(); picture_changed=1; break;
1522+ }
1523+ if(paused) {
1524+ if(debugger) {
1525+ if(i&0xF0) {
1526+ debug_screen(0,i==0x10?11:i==0x20?10:i==0x40?8:i==0x80?12:0);
1527+ } else if(i=e.key.keysym.unicode) {
1528+ debug_screen(0,i);
1529+ }
1530+ picture_changed=1;
1531+ }
1532+ break;
1533+ }
1534+ if(i) {
1535+ if(joypad_repeat || !(device[8].d[2]&i)) {
1536+ device[8].d[2]|=i;
1537+ run(GET16(device[8].d));
1538+ }
1539+ } else if(i=e.key.keysym.unicode) {
1540+ device[8].d[3]=i;
1541+ run(GET16(device[8].d));
1542+ if(!debugger) device[8].d[3]=0; else debug_op=8;
1543+ }
1544+ break;
1545+ scroll:
1546+ if(paused || !i) break;
1547+ PUT16(device[9].d+12,i);
1548+ run(GET16(device[9].d));
1549+ if(!debugger) PUT16(device[9].d+12,0); else debug_op=9;
1550+ break;
1551+ case SDL_KEYUP:
1552+ if(paused) break;
1553+ i=0;
1554+ switch(e.key.keysym.sym) {
1555+ case SDLK_LCTRL: case SDLK_END: i=0x01; break;
1556+ case SDLK_LALT: i=0x02; break;
1557+ case SDLK_LSHIFT: i=0x04; break;
1558+ case SDLK_HOME: i=0x08; break;
1559+ case SDLK_UP: i=0x10; break;
1560+ case SDLK_DOWN: i=0x20; break;
1561+ case SDLK_LEFT: i=0x40; break;
1562+ case SDLK_RIGHT: i=0x80; break;
1563+ }
1564+ if(device[8].d[2]&i) {
1565+ device[8].d[2]&=~i;
1566+ run(GET16(device[8].d));
1567+ }
1568+ break;
1569+ case SDL_MOUSEMOTION:
1570+ case SDL_MOUSEBUTTONDOWN:
1571+ case SDL_MOUSEBUTTONUP:
1572+ if(paused || !use_mouse) break;
1573+ k=SDL_GetMouseState(&i,&j);
1574+ i/=zoom; j/=zoom;
1575+ if(i<0 || i>=screen->w || j<0 || j>=screen->h) break;
1576+ if(touch_mode) {
1577+ if(e.type==SDL_MOUSEBUTTONDOWN && !device[9].d[6]) {
1578+ PUT16(device[9].d+2,i);
1579+ PUT16(device[9].d+4,j);
1580+ run(GET16(device[9].d));
1581+ } else if(e.type==SDL_MOUSEBUTTONUP && !k) {
1582+ device[9].d[6]=0;
1583+ run(GET16(device[9].d));
1584+ i=j=0x8000;
1585+ } else if(e.type==SDL_MOUSEMOTION && !k) {
1586+ break;
1587+ }
1588+ }
1589+ PUT16(device[9].d+2,i);
1590+ PUT16(device[9].d+4,j);
1591+ device[9].d[6]=k&7;
1592+ run(GET16(device[9].d));
1593+ break;
1594+ case SDL_USEREVENT+1:
1595+ device[1].d[2]=e.user.code;
1596+ device[1].d[7]=1;
1597+ if(e.user.data1) {
1598+ if(!(device[1].d[6]&1)) break;
1599+ device[1].d[7]=0;
1600+ }
1601+ run(GET16(device[1].d));
1602+ SDL_CondBroadcast(stdin_cond);
1603+ break;
1604+ case SDL_JOYAXISMOTION:
1605+ if(!joy_axis_mode) break;
1606+ if(j=select_joystick(e.jaxis.which)) {
1607+ k=device[8].d[j];
1608+ if(e.jaxis.axis==joy_axis_x) {
1609+ i=e.jaxis.value*(joy_axis_mode&1?-1:1);
1610+ k&=0x3F;
1611+ if(i>=joy_sensitivity) k|=0x80; else if(i<=-joy_sensitivity) k|=0x40;
1612+ } else if(e.jaxis.axis==joy_axis_y) {
1613+ i=e.jaxis.value*(joy_axis_mode&2?-1:1);
1614+ k&=0xCF;
1615+ if(i>=joy_sensitivity) k|=0x10; else if(i<=-joy_sensitivity) k|=0x20;
1616+ }
1617+ trigger:
1618+ if(k!=device[8].d[j]) {
1619+ device[8].d[j]=k;
1620+ if(!paused) run(GET16(device[8].d));
1621+ }
1622+ }
1623+ break;
1624+ case SDL_JOYBUTTONDOWN:
1625+ case SDL_JOYBUTTONUP:
1626+ if(e.jbutton.button&~127) break;
1627+ if(j=select_joystick(e.jbutton.which)) {
1628+ k=device[8].d[j];
1629+ i=joy_button_map[e.jbutton.button];
1630+ if(e.jbutton.state==SDL_PRESSED) k|=i; else k&=~i;
1631+ goto trigger;
1632+ }
1633+ break;
1634+ case SDL_JOYHATMOTION:
1635+ if(!joy_hat_mode) break;
1636+ if(j=select_joystick(e.jhat.which)) {
1637+ k=device[8].d[j]&0x0F;
1638+ // Note that the SDL_HAT_ values are bits counted clockwise from UP.
1639+ i=(e.jhat.value*0x1111)>>joy_hat_mode;
1640+ if(i&SDL_HAT_UP) k|=0x10;
1641+ if(i&SDL_HAT_DOWN) k|=0x20;
1642+ if(i&SDL_HAT_LEFT) k|=0x40;
1643+ if(i&SDL_HAT_RIGHT) k|=0x80;
1644+ goto trigger;
1645+ }
1646+ break;
1647+ }
1648+ if(picture_changed) redraw();
1649+ }
1650+ return 0;
1651+}
1652+
1653+static int stdin_thread_fn(void*unused) {
1654+ int c;
1655+ SDL_Event e;
1656+ SDL_mutex*mut=SDL_CreateMutex();
1657+ SDL_LockMutex(mut);
1658+ e.type=SDL_USEREVENT+1;
1659+ e.user.data1=0;
1660+ while((c=fgetc(inf))>=0) {
1661+ e.user.code=c;
1662+ while(SDL_PushEvent(&e)) SDL_CondWaitTimeout(stdin_cond,mut,timer_rate?:10);
1663+ }
1664+ if(use_extension) {
1665+ e.user.code=0;
1666+ e.user.data1="";
1667+ while(SDL_PushEvent(&e)) SDL_CondWaitTimeout(stdin_cond,mut,timer_rate?:10);
1668+ }
1669+ return 0;
1670+}
1671+
1672+static void set_datetime(char*s) {
1673+ int i=2;
1674+ if(*s=='@') {
1675+ struct tm r;
1676+ time_t t=strtoll(s+1,0,10);
1677+ if(use_utc) gmtime_r(&t,&r); else localtime_r(&t,&r);
1678+ PUT16(device[12].d,r.tm_year+1900);
1679+ device[12].d[2]=r.tm_mon;
1680+ device[12].d[3]=r.tm_mday;
1681+ device[12].d[4]=r.tm_hour;
1682+ device[12].d[5]=r.tm_min;
1683+ device[12].d[6]=r.tm_sec;
1684+ device[12].d[7]=r.tm_wday;
1685+ PUT16(device[12].d+8,r.tm_yday);
1686+ device[12].d[10]=r.tm_isdst;
1687+ } else {
1688+ i=strtol(s,&s,10);
1689+ PUT16(device[12].d,i);
1690+ if(*s) s++;
1691+ i=2;
1692+ while(*s && i<15) {
1693+ device[12].d[i++]=strtol(s,&s,10);
1694+ if(*s) s++;
1695+ }
1696+ }
1697+}
1698+
1699+static void set_audio(char*s) {
1700+ int i;
1701+ audio_option=calloc(sizeof(Sint32),26);
1702+ if(!audio_option) err(1,"Allocation failed");
1703+ audio_option['b'-'a']=2048;
1704+ audio_option['c'-'a']=2;
1705+ audio_option['r'-'a']=44100;
1706+ audio_option['v'-'a']=273;
1707+ while(*s && *s!='.') {
1708+ if(*s<'a' && *s>'z') err(1,"Invalid audio option");
1709+ audio_option[*s-'a']=strtol(s+1,&s,10);
1710+ }
1711+ audiospec.freq=audio_option['r'-'a'];
1712+ audiospec.channels=audio_option['c'-'a'];
1713+ audiospec.samples=audio_option['b'-'a'];
1714+ audiospec.format=AUDIO_S16SYS;
1715+ audiospec.callback=audio_callback;
1716+ for(i=3;i<7;i++) {
1717+ device[i].aux=calloc(1,sizeof(UxnAudio));
1718+ if(!device[i].aux) err(1,"Allocation failed");
1719+ device[i].out=audio_out;
1720+ }
1721+ if(!audio_option['e'-'a']) audio_option['e'-'a']=audio_option['r'-'a']/15;
1722+}
1723+
1724+static void set_joystick(char*s) {
1725+ int c,i,n;
1726+ SDL_Joystick*j;
1727+ if(*s=='?') {
1728+ if(SDL_Init(SDL_INIT_JOYSTICK|SDL_INIT_NOPARACHUTE)) err(1,"Cannot initialize SDL");
1729+ atexit(SDL_Quit);
1730+ if(s[1]) {
1731+ j=SDL_JoystickOpen(i=strtol(s+1,0,10));
1732+ if(!j) err(1,"Cannot open joystick");
1733+ printf("Opened Joystick %d\n",i);
1734+ printf("Name: %s\n",SDL_JoystickName(i));
1735+ printf("Axes: %d\n",SDL_JoystickNumAxes(j));
1736+ printf("Buttons: %d\n",SDL_JoystickNumButtons(j));
1737+ printf("Hats: %d\n",SDL_JoystickNumHats(j));
1738+ printf("Balls: %d\n",SDL_JoystickNumBalls(j));
1739+ SDL_JoystickClose(j);
1740+ } else {
1741+ n=SDL_NumJoysticks();
1742+ for(i=0;i<n;i++) printf("%d: %s\n",i,SDL_JoystickName(i));
1743+ }
1744+ exit(0);
1745+ return;
1746+ }
1747+ n=0;
1748+ while(*s) {
1749+ if(*s>='0' && *s<='9') {
1750+ if(n&~3) err(1,"Too many players");
1751+ joy_player[n]=strtol(s,&s,10);
1752+ joy_mask|=1<<n;
1753+ } else if(*s==',') {
1754+ s++;
1755+ n++;
1756+ } else {
1757+ break;
1758+ }
1759+ }
1760+ if(*s=='/') ++s; else err(1,"Improper joystick setting");
1761+ while(*s) {
1762+ c=*s++;
1763+ n=strtol(s,&s,10);
1764+ switch(c) {
1765+ case 'A': joy_button_map[n&0x7F]|=0x01; break;
1766+ case 'B': joy_button_map[n&0x7F]|=0x02; break;
1767+ case 'D': joy_button_map[n&0x7F]|=0x20; break;
1768+ case 'H': joy_hat=n; joy_hat_mode=6; break;
1769+ case 'h': joy_hat=n; joy_hat_mode=4; break;
1770+ case 'I': joy_hat=n; joy_hat_mode=5; break;
1771+ case 'i': joy_hat=n; joy_hat_mode=7; break;
1772+ case 'L': joy_button_map[n&0x7F]|=0x40; break;
1773+ case 'R': joy_button_map[n&0x7F]|=0x80; break;
1774+ case 'S': joy_button_map[n&0x7F]|=0x04; break;
1775+ case 'T': joy_button_map[n&0x7F]|=0x08; break;
1776+ case 'U': joy_button_map[n&0x7F]|=0x10; break;
1777+ case 'X': joy_axis_x=n; joy_axis_mode|=1; break;
1778+ case 'Y': joy_axis_y=n; joy_axis_mode|=2; break;
1779+ case 's': joy_sensitivity=n; break;
1780+ case 'x': joy_axis_x=n; joy_axis_mode|=4; break;
1781+ case 'y': joy_axis_y=n; joy_axis_mode|=8; break;
1782+ default: err(1,"Improper joystick setting");
1783+ }
1784+ }
1785+}
1786+
1787+static void set_other_program(const char*s) {
1788+ int pf[4];
1789+ pid_t pi;
1790+ if(pipe(pf) || pipe(pf+2)) err(1,"Pipe failed");
1791+ pi=fork();
1792+ if(pi==(pid_t)(-1)) err(1,"Fork failed");
1793+ if(pi) {
1794+ // Parent
1795+ close(pf[1]);
1796+ close(pf[2]);
1797+ inf=fdopen(pf[0],"r");
1798+ if(!inf) err(1,"Cannot open pipe for input");
1799+ outf=fdopen(pf[3],"w");
1800+ if(!outf) err(1,"Cannot open pipe for output");
1801+ } else {
1802+ // Child
1803+ close(pf[0]);
1804+ close(pf[3]);
1805+ if(dup2(pf[1],1)<0 || dup2(pf[2],0)<0) err(1,"Cannot duplicate file descriptors");
1806+ close(pf[1]);
1807+ close(pf[2]);
1808+ execl("/bin/sh","/bin/sh","-c",s,(char*)0);
1809+ fprintf(stderr,"Cannot exec\n");
1810+ _exit(1);
1811+ }
1812+}
1813+
1814+static void set_palette(char*s) {
1815+ int p=palet<<3;
1816+ FILE*f=fmemopen(s,strlen(s),"r");
1817+ if(!f) err(1,"Error with fmemopen during parsing command-line arguments");
1818+ while(p<64 && fscanf(f,"%2hhX%2hhX%2hhX",&colors[p].r,&colors[p].g,&colors[p].b)) {
1819+ p++;
1820+ fscanf(f,"%*[, ]");
1821+ }
1822+ fclose(f);
1823+}
1824+
1825+static void set_script(char*s) {
1826+ static size_t siz;
1827+ Script o={0,0,0,0,0};
1828+ if(!scriptf) {
1829+ scriptf=open_memstream((char**)&scriptv,&siz);
1830+ if(!scriptf) err(1,"Error with open_memstream during parsing command-line arguments");
1831+ }
1832+ if(*s=='@') {
1833+ char*line=0;
1834+ size_t line_size=0;
1835+ FILE*fp=fopen(s+1,"r");
1836+ if(!fp) err(1,"Cannot open file");
1837+ while(getline(&line,&line_size,fp)>0) {
1838+ s=line+strlen(line);
1839+ while(s>line && (s[-1]=='\r' || s[-1]=='\n' || s[-1]==' ' || s[-1]=='\t')) *--s=0;
1840+ if(*s=='@') err(1,"Nested file in -m not allowed");
1841+ if(*s && *s!='#') set_script(s);
1842+ }
1843+ fclose(fp);
1844+ free(line);
1845+ } else {
1846+ Uint8 b;
1847+ if(*s=='.') o.stage=1,s++;
1848+ if(*s>'f') o.kind=*s++;
1849+ o.addr=strtoll(s,&s,16);
1850+ if(*s=='=') {
1851+ s++;
1852+ if(strlen(s)>=0x1FFFF) err(1,"Argument too long");
1853+ o.data=malloc(strlen(s)/2+1);
1854+ if(!o.data) err(1,"Allocation failed");
1855+ while(*s && s[1]) {
1856+ if(!sscanf(s,"%2hhX",&b)) break;
1857+ o.data[o.len++]=b;
1858+ s+=2;
1859+ }
1860+ if(*s) err(1,"Syntax error in -m");
1861+ } else if(*s) {
1862+ err(1,"Syntax error in -m");
1863+ }
1864+ if(o.kind || o.len) {
1865+ if(!fwrite(&o,sizeof(Script),1,scriptf)) err(1,"Cannot write to memory stream");
1866+ ++scriptc;
1867+ }
1868+ }
1869+}
1870+
1871+static void do_script(Uint8 stage) {
1872+ Uint8 u=use_extension;
1873+ Uint16 n,i,j;
1874+ Script*o;
1875+ use_extension=1;
1876+ for(n=0;n<scriptc;n++) if(scriptv[n].stage==stage) {
1877+ o=scriptv+n;
1878+ switch(o->kind) {
1879+ case 0: // Memory write
1880+ memcpy(mem+o->addr,o->data,o->len);
1881+ break;
1882+ case 'p': // Device port (including trigger)
1883+ j=o->addr;
1884+ for(i=0;i<o->len;i++) {
1885+ device[(j>>4)&15].d[j&15]=o->data[i];
1886+ device[(j>>4)&15].out(device+((j>>4)&15),j&15);
1887+ j++;
1888+ }
1889+ break;
1890+ case 's': // Device port (set only)
1891+ j=o->addr;
1892+ for(i=0;i<o->len;i++) {
1893+ device[(j>>4)&15].d[j&15]=o->data[i];
1894+ j++;
1895+ }
1896+ break;
1897+ case 'u': // Extension set
1898+ mem[o->addr]=3;
1899+ memcpy(mem+o->addr+1,o->data,o->len);
1900+ do_extension_by_uuid(o->addr);
1901+ break;
1902+ case 'x': // Execute
1903+ run(o->addr);
1904+ break;
1905+ case 'z': // Others
1906+ if(o->addr==2) {
1907+ if(o->len) screencompat=o->data[0];
1908+ blend[0][0]=(screencompat&0x01?4:0);
1909+ } else {
1910+ err(1,"Unrecognized command");
1911+ }
1912+ break;
1913+ default: err(1,"Unrecognized command");
1914+ }
1915+ }
1916+ use_extension=u;
1917+}
1918+
1919+static void set_full_screen_size(void) {
1920+ SDL_Rect**m=SDL_ListModes(0,scrflags);
1921+ int i;
1922+ if(!m || m==(SDL_Rect**)(-1) || !*m) err(1,"Cannot determine size to use for full screen mode");
1923+ default_width=m[0]->w/zoom;
1924+ default_height=m[0]->h/zoom;
1925+}
1926+
1927+int main(int argc,char**argv) {
1928+ int i,j;
1929+ for(i=0;i<16;i++) {
1930+ device[i].in=default_in;
1931+ device[i].out=default_out;
1932+ device[i].exp=default_exp;
1933+ }
1934+ device[0].in=system_in;
1935+ device[0].out=system_out;
1936+ device[0].exp=system_exp;
1937+ device[10].aux=&uxnfile0;
1938+ device[11].aux=&uxnfile1;
1939+ device[12].in=datetime_in;
1940+ inf=stdin; outf=stdout;
1941+ while((i=getopt(argc,argv,"+ADFIJ:NOQST:YZa:de:h:ijm:np:qs:t:w:xyz:"))>0) switch(i) {
1942+ case 'D': scrflags|=SDL_DOUBLEBUF; break;
1943+ case 'F': scrflags|=SDL_FULLSCREEN; default_width=default_height=0; break;
1944+ case 'I': use_thread=1; break;
1945+ case 'J': set_joystick(optarg); break;
1946+ case 'N': scrflags|=SDL_NOFRAME; break;
1947+ case 'O': touch_mode=1; device[9].d[2]=device[9].d[4]=0x80; break;
1948+ case 'Q': use_mouse=0; break;
1949+ case 'S': disallow_size_change=1; break;
1950+ case 'T': device[12].in=default_in; set_datetime(optarg); break;
1951+ case 'Y': allow_write=1; device[10].out=device[11].out=files_out; device[10].in=device[11].in=files_in; device[10].exp=device[11].exp=files_exp; break;
1952+ case 'Z': use_utc=1; break;
1953+ case 'a': set_audio(optarg); break;
1954+ case 'd': use_debug=1; break;
1955+ case 'e': set_other_program(optarg); break;
1956+ case 'h': default_height=strtol(optarg,0,10); break;
1957+ case 'i': hide_cursor=1; break;
1958+ case 'j': joypad_repeat=1; break;
1959+ case 'm': set_script(optarg); break;
1960+ case 'n': use_screen=0; break;
1961+ case 'p': palet=strtol(optarg,0,10)&7; if(*optarg && optarg[1]=='=') set_palette(optarg+2); break;
1962+ case 'q': use_console=0; break;
1963+ case 's': scroll_size=strtol(optarg,0,10); break;
1964+ case 't': timer_rate=strtol(optarg,0,10); break;
1965+ case 'w': default_width=strtol(optarg,0,10); break;
1966+ case 'x': use_extension=1; break;
1967+ case 'y': allow_write=0; device[10].out=device[11].out=files_out; device[10].in=device[11].in=files_in; device[10].exp=device[11].exp=files_exp; break;
1968+ case 'z': zoom=strtol(optarg,0,10); break;
1969+ default: return 1;
1970+ }
1971+ if(optind==argc) err(1,"Required argument missing");
1972+ rom_name=argv[optind];
1973+ if(use_console) device[1].out=console_out;
1974+ if(scriptf) {
1975+ fclose(scriptf);
1976+ if(!scriptv) err(1,"Allocation failed");
1977+ do_script(0);
1978+ }
1979+ load_rom();
1980+ if(use_screen) {
1981+ if(zoom<1) err(1,"Zoom out of range");
1982+ if((default_height<1 || default_width<1) && !(scrflags&SDL_FULLSCREEN)) err(1,"Screen size out of range");
1983+ if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|(audio_option?SDL_INIT_AUDIO:0)|(joy_mask?SDL_INIT_JOYSTICK:0))) err(1,"Cannot initialize SDL");
1984+ atexit(SDL_Quit);
1985+ device[2].out=screen_out;
1986+ if(!default_width && !default_height && (scrflags&SDL_FULLSCREEN)) set_full_screen_size();
1987+ scr_w=default_width;
1988+ scr_h=default_height;
1989+ PUT16(device[2].d+2,scr_w);
1990+ PUT16(device[2].d+4,scr_h);
1991+ size_changed=1;
1992+ if(joy_mask) {
1993+ if((joy_mask&1) && !SDL_JoystickOpen(joy_player[0])) err(1,"Cannot open joystick for player I");
1994+ if((joy_mask&2) && !SDL_JoystickOpen(joy_player[1])) err(1,"Cannot open joystick for player II");
1995+ if((joy_mask&4) && !SDL_JoystickOpen(joy_player[2])) err(1,"Cannot open joystick for player III");
1996+ if((joy_mask&8) && !SDL_JoystickOpen(joy_player[3])) err(1,"Cannot open joystick for player IV");
1997+ SDL_JoystickEventState(SDL_ENABLE);
1998+ }
1999+ }
2000+ if(optind+1<argc) strncpy(uxnfile0.name,argv[optind+1],4095);
2001+ if(optind+2<argc) strncpy(uxnfile1.name,argv[optind+2],4095);
2002+ restart:
2003+ size_changed=1;
2004+ ds.p=rs.p=0;
2005+ device[1].d[7]=(optind+1==argc)?0:1;
2006+ if(scriptc) do_script(1);
2007+ run(0x0100);
2008+ if(device[1].d[0] || device[1].d[1]) for(i=optind+1;i<argc;i++) {
2009+ for(j=0;argv[i][j];j++) {
2010+ device[1].d[2]=argv[i][j];
2011+ device[1].d[7]=2;
2012+ run(GET16(device[1].d));
2013+ }
2014+ device[1].d[2]='\n';
2015+ device[1].d[7]=(i==argc-1?4:3);
2016+ run(GET16(device[1].d));
2017+ }
2018+ if(use_screen) {
2019+ if(size_changed) set_screen_mode(scr_w,scr_h);
2020+ if(use_thread) {
2021+ stdin_cond=SDL_CreateCond();
2022+ SDL_CreateThread(stdin_thread_fn,0);
2023+ }
2024+ while(run_screen()) {
2025+ for(i=0;i<15;i++) for(j=0;j<16;j++) device[i].d[j]=0;
2026+ if(scriptc) do_script(0);
2027+ load_rom();
2028+ goto restart;
2029+ }
2030+ } else if(audio_option) {
2031+ run_audio();
2032+ } else {
2033+ device[1].d[7]=1;
2034+ while((device[1].d[0] || device[1].d[1]) && ((i=fgetc(inf))>=0)) {
2035+ device[1].d[2]=i;
2036+ run(GET16(device[1].d));
2037+ }
2038+ if(use_extension && (device[1].d[6]&1)) {
2039+ device[1].d[2]=device[1].d[7]=0;
2040+ run(GET16(device[1].d));
2041+ }
2042+ }
2043+ return 0;
2044+}
+0,
-0
A
x.diff
+85,
-0
1@@ -0,0 +1,85 @@
2+--- uxn2.c
3++++ uxn2.c
4+@@ -66,7 +66,7 @@ typedef struct {
5+ /* ------------------------------------------------------------------ */
6+ /* Font data (unchanged) */
7+ /* ------------------------------------------------------------------ */
8+-static const Uint8 fontdata[]={
9++static const Uint8 __attribute__((unused)) fontdata[]={
10+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00,
11+ 0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00,
12+@@ -128,8 +128,8 @@ static Uint8 *fglayer = NULL;
13+ static UxnFile uxnfile0;
14+ static UxnFile uxnfile1;
15+-static FILE *inf = NULL;
16+-static FILE *outf = NULL;
17++static FILE * __attribute__((unused)) inf = NULL;
18++static FILE * __attribute__((unused)) outf = NULL;
19+
20+ static const char *rom_name = "uxn.rom";
21+ static Uint8 use_console = 0; /* keypad is limited */
22+@@ -190,7 +190,7 @@ static void err(int e, const char *str)
23+ exit(e);
24+ }
25+
26+-static void warn(const char *fmt, ...)
27++static void __attribute__((unused)) warn(const char *fmt, ...)
28+ {
29+ /* silent on calculator – optional: use nspireio */
30+ (void)fmt;
31+@@ -210,7 +210,7 @@ static void debug(int i)
32+ (void)i;
33+ }
34+
35+-static void uxnerr(int n, int pc)
36++static void __attribute__((unused)) uxnerr(int n, int pc)
37+ {
38+ (void)n; (void)pc;
39+ if (use_debug) debug(-1);
40+@@ -230,7 +230,6 @@ static void run(Uint16 pc)
41+ Stack *s;
42+ Uint8 k, v;
43+ Uint16 x, y, z;
44+ if (!pc) return;
45+-start:
46+ while ((v = mem[pc++])) {
47+ if (pc == breakpoint && use_screen) goto stop;
48+ s = (v & 0x40) ? &rs : &ds;
49+@@ -385,6 +384,7 @@ static void system_out(Device *dev, Uint8 id)
50+ /* ------------------------------------------------------------------ */
51+ static void console_out(Device *dev, Uint8 id)
52+ {
53++ (void)dev;
54+ switch (id) {
55+ case 8: /* stdout – ignored on calc */ break;
56+ case 9: /* stderr – ignored */ break;
57+@@ -396,9 +396,9 @@ static void console_out(Device *dev, Uint8 id)
58+ /* ------------------------------------------------------------------ */
59+ /* File device */
60+ /* ------------------------------------------------------------------ */
61+-static Uint16 files_stat(int fd, char *name, Uint16 len, Uint8 *out)
62++static Uint16 files_stat(char *name, Uint16 len, Uint8 *out)
63+ {
64+ struct stat st;
65+- if (strlen(name) + 7 > len || fstat(fd, name, &st, 0)) return 0;
66++ if (strlen(name) + 7 > len || stat(name, &st)) return 0;
67+ if (S_ISDIR(st.st_mode)) return snprintf((char*)out, len, "---- %s\n", name);
68+ else if (st.st_size < 0x10000) return snprintf((char*)out, len, "%04x %s\n", (unsigned)st.st_size, name);
69+ else return snprintf((char*)out, len, "???? %s\n", name);
70+@@ -470,7 +470,7 @@ static void files_out(Device *dev, Uint8 id)
71+ addr = GET16(dev->d + 4);
72+ dev->d[2] = dev->d[3] = 0;
73+ if (!uf->name[0]) break;
74+- y = files_stat(AT_FDCWD, uf->name, len, mem + addr);
75++ y = files_stat(uf->name, len, mem + addr);
76+ if (y <= len) PUT16(dev->d + 2, y);
77+ break;
78+ case 7:
79+@@ -705,6 +705,7 @@ static void screen_out(Device *dev, Uint8 id)
80+ /* ------------------------------------------------------------------ */
81+ static void system_exp(Device *dev, Uint16 addr)
82+ {
83++ (void)dev;
84+ Uint32 src, dst;
85+ Uint16 len, n;
86+ switch (mem[addr]) {