============================================================================
The instruction set is kept minimalistic. The exact set of instructions
changes occasionally, but the following list has been stable for about a
year. (The last three, dealing with the port-based I/O model, are new)


 0   NOP         Does nothing
 1   LIT         Push the value in the 
                 following cell to the 
                 stack
 2   DUP         Duplicate the top 
                 item on the stack
 3   DROP        Drop the top item 
                 on the stack
 4   SWAP        Exchange the top two 
                 items on the stack
 5   PUSH        Push the top item on 
                 the stack to the 
                 address stack, drop 
                 TOS
 6   POP         Pop the top item of 
                 the address stack off 
                 and put it on the 
                 data stack
 7   CALL        Call the address that 
                 the following literal 
                 corresponds to
 8   JUMP        Jump to the address 
                 that the following 
                 literal corresponds 
                 to
 9   ;           Return to the caller, 
                 used with CALL
10   >JUMP       Conditional jump. It
                 compares TOS and NOS.
11   <JUMP       Conditional jump. It
                 compares TOS and NOS.
12   !JUMP       Conditional jump. It
                 compares TOS and NOS.
13   =JUMP       Conditional jump. It
                 compares TOS and NOS.
14   @           Fetch the value of 
                 the cell specified on 
                 TOS
15   !           Store NOS to the 
                 cell specified by TOS
16   +           Add TOS to NOS
17   -           Subtract TOS from NOS
18   *           Multiply TOS by NOS
19   /MOD        Divide and get remainder
20   AND         Bitwise AND
21   OR          Bitwise OR
22   XOR         Bitwise XOR
23   <<          Shift bits left
24   >>          Shift bits right
25   0;          Exit (and drop) if 
                 TOS is 0
26   1+          Increment TOS by 1
27   1-          Decrement TOS by 1
28   IN          Read a port
29   OUT         Store to a port
30   WAIT        Wait for a port-based
                 request to finish


If an unsupported opcode is encountered, the interal IP register is set to 
the end of memory. Execution of the image code will halt when this happens.

A few instructions make use of a the following cell to contain addresses or
values. These are:

 1   LIT
 7   CALL
 8   JUMP
10   >jump
11   <jump
12   !jump
13   =jump

In the memory image, these would look like:

 7     | CALL
 100   | Address 100

 1     | LIT
 1812  | Value is 1812

The conditional jump forms take an address to jump to if the condition is 
met. CALL and BRANCH take an address to call or jump to. LIT pushes the 
following value to the stack. All addresses are absolute.
============================================================================
Video and I/O

The video subsystem currently provides a 800x480, 256 color framebuffer. 
Code in the image can directly write to this and the actual display will be
updated by a separate thread. 

There is also a character generator that can display strings and single
characters. This is accessible via the port i/o subsystem. 

I/O devices are port-driven. To get input, set port 0 to 0, and then WAIT
for an input to come in. Read from port 1 to get the keyboard value.

Full details follow:

  0       Set to 0 to wait for an event. Then use WAIT.
  1       Read to get a keypress (0 if none)
  2       Set to 1 to display a character
          This will pull from the stack:   x y character --
  3       Enable video update
  4       Save the current memory state back to an image
  5       Mouse X (on button click)
  6       Mouse Y (on button click)
============================================================================
