Last update: 1/1/11 (Modified SVM to reflect actual wiring)
= DUO ASSEMBLY GUIDE =This description gives the details of DUO assembly syntax and commands.
Each command begins with an opcode or a function name. Opcodes have 3 letters. Examples of opcodes include SVM and GVL. There are either 2 or 3 arguments after each opcode. Spaces separate opcodes and arguments in a command. Newlines separate commands. An example command is shown below:
BON 10101010 4 253
Arguments can be given in a variety of forms:
The SVM (set VRAM) command accepts a 2 byte VRAM address and 1 byte to write in that address. This effectively displays a group of 8 pixels on the display. To try this command for yourself, copy the code below, paste it in the "assembly code" box, press "compile", then press "execute". You should see 4 white dots on the display.
SVM 32 48 01010101
There are 256 bytes of RAM. The NOT command accepts a byte, inverts the byte, then stores the result in a given address. Examine this code:
The first command stores the byte 11000011 in RAM address 7. The second command calls the data at that address by using brackets ([7]), then displays that byte on the screen. This command is effectively the same as SVM 0 0 11000011.
There are many commands which perform a calculation on arguments and store the result in RAM. The behavior of these commands is demonstrated below.
On this page you will find a list of all the commands in DUO assembly.
After pixels have been drawn with SVM, they may be read with the command GVM (get VRAM):
All commands and long-term data are stored in 64 kilobytes of main memory. Unlike RAM, this memory is preserved after power to the machine is cut off. Using SMM (set main memory) and GMM (get main memory), a program can modify any byte in main memory.
The computer has a counter which determines the address of the current command to be executed in main memory. The value of this counter may be conditionally set by CGO (goto). This command effectively skips program execution to a specified location, but only if the boolean value given is false.
Using main memory addresses directly is a somewhat cumbersome way to program, since they may change if the program is modified. To remedy this problem, the assembler supports the usage of labels. The program below is functionally identical to the one above:
Label names may not contain any spaces, must contain letters, and may not be a keyword recognized by the assembler. A label's address in main memory is declared by placing it on its own line. Main memory addresses are 2 bytes long; to access the more significant byte of a label's address, a caret (^) is placed before the label name. When there is no caret, the less significant byte is accessed.
The programmer may want to make code which modifies its own arguments. To do so, use the notation LABEL_NAME+OFFSET in combination with SMM:
The computer contains another 2 byte counter, called the timer, which provides a steady pace for programs when necessary. It increments at a constant rate of 64 times per second. The STM (set timer) and GTM (get timer) commands are used to get and set the value of the timer:
This program will make a line, wait 2 seconds, then make the line longer. The program works by entering a loop in which it constantly checks to see if the timer has exceeded 128 beats. Once this is true, the loop terminates and a command is executed to extend the line.
The timer is particularly useful when creating music to play through the computer's speakers. Unfortunately, the SNT (set note) command does not work in this JavaScript emulator.
The GIN (get input) command lets the program read keyboard strokes. Whenever the user presses or releases a key, the 2 byte input register is modified. The GIN command accesses the last value stored in this register:
When the program is running, it will display the contents of the input register each time the user presses or releases a key.
If you still have questions about DUO assembly, please email me at esperantanaso at gmail.