We're looking for your comments on how to best organize the wiki's content.
Under normal circumstances, lines of code are executed sequentially.
SET A, 5 ; First instruction SET [0x1000], A ; Second instruction ADD I, A ; Third instruction
However, sometimes it it required that code is executed in a non-sequential manner. Changing the order of execution of instructions is referred to as control flow.
 The Program Counter
The special register that controls the flow of executed statements is called the program counter (PC). The PC always holds the value of the location in memory where the next command is located. The first instruction will always be at position 0. Each instruction's length can be between 1 and 3 words (see instruction set for more information).
Many assembly languages feature a command called
JMP, which sets the PC to a certain value and thus alters the program flow. The same result can be obtained in DCPU-16 by using the SET command to change the PC's value.
SET A, 5 ; Store 5 in A SET PC, 3 ; The fourth location is at position 3 (0,1,2,3) SET A, 1 ; SKIPPED SET B, A ; We skipped the third instruction, so A = 5, not 1.
In addition to setting the PC, we can also save the PC in another location to preserve the current memory location. This behavior is very important when handling subroutines.
SET X, PC ; If we ever run SET PC, X, we will return to the spot AFTER this line. SET A, 5 ; And execute this.
Note that when you set the PC, it is important that it is never set to locations that occur in the middle of instructions. This would cause the CPU to try and interpret an invalid instruction and possibly cause it to crash.
The usual place to temporarily store the PC is stack. The code sending the PC to stack and then jumping somewhere would be like:
SET PUSH, PC ; The PC is stored on the stack SET PC, somewhere ; and then is set to "somewhere" where a subroutine is located
SET PUSH, PC will store the PC of the next instruction,
SET PC, somewhere, it is more complicated:
SET A, PC ; address of ADD A, 4 ADD A, 4 ; this instruction is 1 word long SET PUSH, A ; this instruction is 1 word long SET PC, somewhere ; this instruction is 2 words long ; stack value points here, the instruction *after* SET PC, somewhere
Although valid, the above is highly inconvenient. Hence, a single (so called "atomic") instruction exists:
JSR somewhere ; "SET PUSH, PC" plus "SET PC, somewhere"
One can return from the subroutine by retrieving the PC from the stack in a single operation:
SET PC, POP ; It is atomic
Trying to calculate and keep track of the numerical value of the PC becomes tedious when the line positions shift, due to new lines being added. As such, labels are a very effective way to make your code both easier to read and modify.
A label is a name that refers to a certain location in the code. When the program is assembled, every time the label appears, it will have its actual value calculated automatically.
Here is the previous program, implemented with a label.
SET A, 5 SET PC, end ; Now it's easy to see that we are skipping the third instruction. SET A, 1 :end SET B, A ; We 'jump' directly to the last line of code.
The label "end" in this code is still equal to 3, but if we added a line between the first and second command, it would automatically update the label to the appropriate value without any user intervention.
 Conditional Instructions
These instructions can be used to execute program statements only when certain requirements are met. Observe the following psuedo-code:
if register A == register B: do action 1 otherwise: do action 2
Action 1 will only be executed if the two registers in question are equal, otherwise, action 2 will be executed. The following code is an assembly program that performs this function:
IFE A, B ; Check to see if A == B SET PC, action1 ; If they are equal, this step will run SET PC, action2 ; Otherwise, this one will run
The conditional instruction will only execute the next instruction if its condition is true. In other words, if the conditional check fails, the next instruction will be skipped.
The conditional instructions are
IFEA, B (IFEQUAL) - Perform the next operation if A and B are equal.
IFNA, B (IFNOTEQUAL) - Perform the next operation if A and B are not equal.
IFGA, B (IFGREATER) - Perform the next operation if A is strictly greater than B.
IFBA, B (IFBITWISE) - Perform the next operation if all of the bits set in A are also set in B (in other words, if A&B != 0).
 Jump Tables
The following code presents a situation where there is multiple cases to choose from.
Menu: 1. Do dishes 2. Clean laundry 3. Play Minecraft Otherwise: Error
Trying to do a series of IF conditionals would be confusing and time consuming. However, it is possible to implement this efficiently by using a jump table.
A jump table is a location in code that has a list of addresses that can be used as the target of a SET PC instruction. By setting the value of the PC equal to this memory location added with the value in the menu, it's possible to handle complicated cases with very little actual code.
:menu IFG A, 3 ; If A is greater than 3.... SET A, 0 ; ...set A to 0. This handles the 'error' case. This instruction will be ignored if A is not greater than 3. SET PC, [jumptable + A] :jumptable DAT error, dishes, laundry, minecraft
 See Also