commit 192cc07

chld  ·  2026-10-27 12:40:04 +0000 UTC
parent 50819bf
init uxn38
25 files changed,  +8381, -0
A uxn.c
A x.diff
+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
+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+[![builds.sr.ht status](https://builds.sr.ht/~rabbits/uxn2.svg)](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 ) ;&lt1-return #0002 STA2 ( <hi>,<lo> )
 105+	#2c #0004 STA ( JMP2 )
 106+	#ffff JMP2 &lt1-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 ) ;&lt2-return #0002 STA2 ( <hi>,<lo> )
 111+	#2c #0004 STA ( JMP2 )
 112+	#fffe JMP2 &lt2-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+	&lt1-wrap "Lt1-wrap: 20 $1
 159+	&lt2-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+	&times ( -- )
 57+		[ LIT2 &color $1 -Screen/sprite ] DEO
 58+		INC DUP ?&times
 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 ,&center 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 &center $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
+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]) {