1# Internals: Nga Virtual Machine
2
3## Overview
4
5At the heart of RETRO is a simple MISC (minimal instruction
6set computer) processor for a dual stack architecture.
7
8This is a very simple and straightforward system. There are
930 instructions. The memory is a linear array of signed 32
10bit values. And there are two stacks: one for data and one
11for return addresses.
12
13## Instruction Table
14
15                                         |     Stacks      |
16    | Opcode | Muri | Full Name          | Data  | Address |
17    | ------ | ---- | ------------------ | ----- | ------- |
18    |  0     | ..   | nop                |   -   |   -     |
19    |  1     | li   | lit                |   -n  |   -     |
20    |  2     | du   | dup                |  n-nn |   -     |
21    |  3     | dr   | drop               |  n-   |   -     |
22    |  4     | sw   | swap               | xy-yx |   -     |
23    |  5     | pu   | push               |  n-   |   -n    |
24    |  6     | po   | pop                |   -n  |  n-     |
25    |  7     | ju   | jump               |  a-   |   -     |
26    |  8     | ca   | call               |  a-   |   -A    |
27    |  9     | cc   | conditional call   | af-   |   -A    |
28    | 10     | re   | return             |   -   |  A-     |
29    | 11     | eq   | equality           | xy-f  |   -     |
30    | 12     | ne   | inequality         | xy-f  |   -     |
31    | 13     | lt   | less than          | xy-f  |   -     |
32    | 14     | gt   | greater than       | xy-f  |   -     |
33    | 15     | fe   | fetch              |  a-n  |   -     |
34    | 16     | st   | store              | na-   |   -     |
35    | 17     | ad   | addition           | xy-n  |   -     |
36    | 18     | su   | subtraction        | xy-n  |   -     |
37    | 19     | mu   | multiplication     | xy-n  |   -     |
38    | 20     | di   | divide & remainder | xy-rq |   -     |
39    | 21     | an   | bitwise and        | xy-n  |   -     |
40    | 22     | or   | bitwise or         | xy-n  |   -     |
41    | 23     | xo   | bitwise xor        | xy-n  |   -     |
42    | 24     | sh   | shift              | xy-n  |   -     |
43    | 25     | zr   | zero return        |  n-?  |   -     |
44    | 26     | ha   | halt               |   -   |   -     |
45    | 27     | ie   | i/o enumerate      |   -n  |   -     |
46    | 28     | iq   | i/o query          |  n-xy |   -     |
47    | 29     | ii   | i/o invoke         | ...n- |   -     |
48
49## Encoding
50
51Up to four instructions can be packed into each memory cell.
52
53As an example,
54
55    Opcode 4 Opcode 3 Opcode 2 Opcode 1
56    00000000:00000000:00000000:00000000
57
58If we have a bundle of `duliswst`, it would look like:
59
60    st       sw       li       du
61    00010000:00000100:00000001:00000010
62
63Each `li` should have a value in the following cell(s). These
64values will be pushed to the stack. E.g., `lili....` and
651, 2:
66
67    00000000:00000000:00000001:00000001
68    00000000 00000000 00000000 00000001 (1)
69    00000000 00000000 00000000 00000010 (2)
70
71## Shifts
72
73`sh` performs a bitwise arithmetic shift operation.
74
75This takes two values:
76
77    xy
78
79And returns a single one:
80
81    z
82
83If y is positive, this shifts `x` right by `y` bits. If negative,
84it shifts left.
85
86## Queries: Memory, Stacks
87
88The `fe` instruction allows queries of some data related to
89the Nga VM state. These are returned by reading from negative
90addresses:
91
92    | Address | Returns                |
93    | ------- | ---------------------- |
94    | -1      | Data stack depth       |
95    | -2      | Address stack depth    |
96    | -3      | Maximum Image Size     |
97    | -4      | Minimum Integer Value  |
98    | -5      | Maximum Integer Value  |
99
100## I/O Devices
101
102Nga provides three instructions for interacting with I/O devices.
103These are:
104
105    ie   i/o enumerate    returns the number of attached devices
106    iq   i/o query        returns information about a device
107    ii   i/o interact     invokes an interaction with a device
108
109As an example, with an implementation providing an output source,
110a block storage system, and keyboard:
111
112    ie    will return `3` since there are three i/o devices
113    0 iq  will return 0 0, since the first device is a screen (0)
114          with a version of 0
115    1 iq  will return 1 3, since the second device is a block
116          storage (3), with a version of 1
117    2 iq  will return 0 1, since the third device is a keyboard
118          (1), with a version of 0
119
120In this case, some interactions can be defined:
121
122    : c:put
123    i liiire..
124    d 0
125
126    : c:get
127    i liiire..
128    d 2
129
130Setup the stack, push the device ID to the stack, and then use
131`ii` to invoke the interaction.
132
133A RETRO system requires one I/O device (a generic output for a
134single character). This must be the first device, and must have
135a device ID of 0.
136
137All other devices are optional and can be specified in any order.
138
139The currently supported and reserved device identifiers are:
140
141    | ID   | Device Type      | Notes                      |
142    | ---- | ---------------- | -------------------------- |
143    | 0000 | Generic Output   | Always present as device 0 |
144    | 0001 | Keyboard         |                            |
145    | 0002 | Floating Point   |                            |
146    | 0003 | Block Storage    | Raw, 1024 cell blocks      |
147    | 0004 | Filesystem       | Unix-style Files           |
148    | 0005 | Network: Gopher  | Make gopher requests       |
149    | 0006 | Network: HTTP    | Make HTTP requests         |
150    | 0007 | Network: Sockets |                            |
151    | 0008 | Syscalls: Unix   |                            |
152    | 0009 | Scripting Hooks  |                            |
153    | 0010 | Random Number    |                            |
154
155This list may be revised in the future. The only guaranteed
156stable indentifier is 0000 for generic output.
157