
Redstone Dust Mining
Adds high freqency blades from Metal Gear Rising: Revengeance
- 594
- November 22, 2022

Redstone Dust Mining
Adds high freqency blades from Metal Gear Rising: Revengeance
- 594
- November 22, 2022

This is an addon to Power Grid that adds low-level compute power based on microcontrollers and the Assembly programming language.
Systems that this addon adds encourage the player to understand their controllers and computers at the deepest layer while keeping it accessible AND challenging. By the end of your playthrough you will be the proud owner of a datacenter you've built yourself, and hopefully it doesn't STACK_OVERFLOW, but that's up to you!
This mod doesn't handle the dirty laundry for you like some of the other mods that add compute power to Minecraft! You are responsible all the way from handling CPU registers to writing to memory to controlling peripherals!
So many features are bound to change and maybe even break some existing saves. When updating to a new version - make sure to read the changelog, likely there will be a mention of a Controller suddenly combusting after updating!
I would greatly appreciate your feedback in Power Grid's Discord server in the Computationally Expensive channels!
| Notation | Accepted values |
|---|---|
Rd |
Writable register: R0–R7 |
value |
Register, decimal literal, hexadecimal literal such as 0x2A, binary literal such as 0b101010, constant, label, variable address, or symbol + offset / symbol - offset |
address |
RAM or NVM byte address supplied directly, by symbol/expression, or through a register |
target |
Zero-based instruction index, normally written as a label |
pin |
P1–P8 |
mode |
INPUT or OUTPUT |
edge |
RISING, FALLING, or BOTH |
source |
P1–P8 or TIMER |
start, end |
End-exclusive byte range containing raw eight-byte instructions |
Square brackets around an address are accepted but optional. For example, LDW R0, counter, LDW R0, [counter], and LDW R0, R1 are valid address forms.
| Operator | Opcode | Arguments | Description |
|---|---|---|---|
MOV |
0 / 0x00 |
Rd, value |
Copies a 16-bit value into a register. Does not change flags. |
LDB |
1 / 0x01 |
Rd, address |
Loads one unsigned byte from RAM and zero-extends it into Rd. |
LDW |
2 / 0x02 |
Rd, address |
Loads a little-endian 16-bit word from RAM. |
STB |
3 / 0x03 |
address, value |
Stores the low eight bits of value in RAM. |
STW |
4 / 0x04 |
address, value |
Stores a little-endian 16-bit word in RAM. |
LEA |
5 / 0x05 |
Rd, address |
Copies an address into Rd. Variables evaluate to their byte addresses. |
PUSH |
6 / 0x06 |
value |
Pushes a 16-bit value onto the downward-growing RAM stack. |
POP |
7 / 0x07 |
Rd |
Pops a 16-bit value from the stack into Rd. |
ADD |
8 / 0x08 |
Rd, value |
Calculates Rd = Rd + value. Updates Z, N, C, and V. |
ADC |
9 / 0x09 |
Rd, value |
Calculates Rd = Rd + value + C. Updates arithmetic flags. |
SUB |
10 / 0x0A |
Rd, value |
Calculates Rd = Rd - value. C is set when a borrow occurs. |
SBC |
11 / 0x0B |
Rd, value |
Calculates Rd = Rd - value - C, using C as the previous borrow. |
MUL |
12 / 0x0C |
Rd, value |
Multiplies the operands and stores the low 16 bits in Rd. |
DIV |
13 / 0x0D |
Rd, value |
Signed 16-bit division. Division by zero faults the VM. |
MOD |
14 / 0x0E |
Rd, value |
Signed 16-bit remainder. Division by zero faults the VM. |
INC |
15 / 0x0F |
Rd |
Increments Rd by one. |
DEC |
16 / 0x10 |
Rd |
Decrements Rd by one. |
NEG |
17 / 0x11 |
Rd |
Replaces Rd with its two's-complement negation. |
AND |
18 / 0x12 |
Rd, value |
Calculates a bitwise AND. Updates Z and N; clears C and V. |
OR |
19 / 0x13 |
Rd, value |
Calculates a bitwise OR. Updates Z and N; clears C and V. |
XOR |
20 / 0x14 |
Rd, value |
Calculates a bitwise XOR. Updates Z and N; clears C and V. |
NOT |
21 / 0x15 |
Rd |
Inverts all 16 bits of Rd. |
SHL |
22 / 0x16 |
Rd, count |
Logical left shift. Only the low four bits of count are used. |
SHR |
23 / 0x17 |
Rd, count |
Logical right shift with zero fill. |
SAR |
24 / 0x18 |
Rd, count |
Arithmetic right shift preserving the sign bit. |
ROL |
25 / 0x19 |
Rd, count |
Rotates the 16-bit value left. |
ROR |
26 / 0x1A |
Rd, count |
Rotates the 16-bit value right. |
CMP |
27 / 0x1B |
left, right |
Updates flags as if left - right were calculated, without storing the result. |
TEST |
28 / 0x1C |
left, right |
Updates flags from left AND right, without storing the result. |
JMP |
29 / 0x1D |
target |
Unconditionally jumps to an instruction index. |
JE |
30 / 0x1E |
target |
Jumps when equal or zero: Z = 1. |
JNE |
31 / 0x1F |
target |
Jumps when not equal: Z = 0. |
JL |
32 / 0x20 |
target |
Signed less-than jump: N ≠ V. |
JLE |
33 / 0x21 |
target |
Signed less-than-or-equal jump: Z = 1 or N ≠ V. |
JG |
34 / 0x22 |
target |
Signed greater-than jump: Z = 0 and N = V. |
JGE |
35 / 0x23 |
target |
Signed greater-than-or-equal jump: N = V. |
JB |
36 / 0x24 |
target |
Unsigned below jump: C = 1 after comparison. |
JBE |
37 / 0x25 |
target |
Unsigned below-or-equal jump: C = 1 or Z = 1. |
JA |
38 / 0x26 |
target |
Unsigned above jump: C = 0 and Z = 0. |
JAE |
39 / 0x27 |
target |
Unsigned above-or-equal jump: C = 0. |
JC |
40 / 0x28 |
target |
Jumps when carry/borrow is set. Equivalent to JB. |
JNC |
41 / 0x29 |
target |
Jumps when carry/borrow is clear. Equivalent to JAE. |
JO |
42 / 0x2A |
target |
Jumps when signed overflow is set. |
JNO |
43 / 0x2B |
target |
Jumps when signed overflow is clear. |
CALL |
44 / 0x2C |
target |
Pushes the return instruction index and jumps to target. |
RET |
45 / 0x2D |
None | Pops an instruction index and returns to it. |
HALT |
46 / 0x2E |
None | Stops top-level firmware while retaining current outputs. Inside EXEC or NVEXEC, returns to the caller. |
SLEEP |
47 / 0x2F |
cycles |
Suspends instruction execution for the specified number of VM cycles. Interrupts can wake it. |
MODE |
48 / 0x30 |
pin, mode |
Configures a GPIO pin as INPUT or OUTPUT. |
IN |
49 / 0x31 |
Rd, pin |
Reads a pin voltage in millivolts into Rd, clamped to 0–12000. |
OUT |
50 / 0x32 |
pin, value |
Drives an output pin at value millivolts, clamped to 0–12000. |
PIX |
51 / 0x33 |
x, y, value |
Sets or clears one display pixel. Valid coordinates are x = 0..9 and y = 0..7; zero clears and nonzero lights it. |
CLS |
52 / 0x34 |
None | Clears the entire 10×8 display. |
PINT |
53 / 0x35 |
pin, threshold, edge |
Enables a pin interrupt at a 0–12000 mV threshold for RISING, FALLING, or BOTH crossings. |
TIMER |
54 / 0x36 |
cycles |
Configures a repeating timer interrupt measured in VM cycles. A value of zero disables it. |
EI |
55 / 0x37 |
None | Enables interrupt dispatch. Pending interrupts remain latched until handled. |
DI |
56 / 0x38 |
None | Disables interrupt dispatch without clearing pending interrupts. |
IRET |
57 / 0x39 |
None | Restores saved flags and the return PC after an interrupt. Using it outside an interrupt faults. |
NOP |
58 / 0x3A |
None | Performs no operation but still consumes one VM cycle. |
SPEED |
59 / 0x3B |
value |
Selects the number of VM cycles scheduled for the next server tick, clamped from 1 to the configured maximum. |
NVLDB |
60 / 0x3C |
Rd, address |
Loads one unsigned byte from raw nonvolatile memory. |
NVLDW |
61 / 0x3D |
Rd, address |
Loads a little-endian 16-bit word from raw nonvolatile memory. |
NVSTB |
62 / 0x3E |
address, value |
Stores the low eight bits of value in raw nonvolatile memory. |
NVSTW |
63 / 0x3F |
address, value |
Stores a little-endian 16-bit word in raw nonvolatile memory. |
EXEC |
64 / 0x40 |
start, end |
Executes an end-exclusive byte range of eight-byte native instructions stored in RAM. |
NVEXEC |
65 / 0x41 |
start, end |
Executes an end-exclusive byte range of eight-byte native instructions stored in NVM. |
IVEC |
66 / 0x42 |
source, target |
Sets an interrupt vector for the current EXEC or NVEXEC context. Use before EI. |
| Flag | Meaning |
|---|---|
Z |
Zero result |
N |
Negative result; bit 15 is set |
C |
Carry after addition or borrow after subtraction/comparison |
V |
Signed arithmetic overflow |
I |
Interrupts enabled |
CMP should normally precede a conditional jump. Signed jumps use N and V; unsigned jumps use C and Z.
| Directive | Arguments | Description |
|---|---|---|
label: |
Identifier followed by : |
Declares a label at the current zero-based instruction index. |
.ENTRY |
label or index |
Selects the first instruction executed after boot. Defaults to instruction zero. |
.EQU |
name value |
Declares a compile-time constant. |
.DATA |
address, byte, ... |
Writes raw initial bytes into RAM. Each byte must be in 0..255. |
.VAR |
BYTE name [= value] |
Allocates one byte in static RAM. |
.VAR |
WORD name [= value] |
Allocates one aligned, little-endian 16-bit word. |
.ARRAY |
BYTE name, count |
Allocates a fixed-length byte array. Optional initializers may follow the count. |
.ARRAY |
WORD name, count |
Allocates an aligned word array. Offsets are still measured in bytes. |
.ARRAY |
BYTE/WORD name = values |
Allocates an array whose length is inferred from its initializer list. |
.VECTOR |
source, label |
Assigns a firmware interrupt handler for P1–P8 or TIMER. |
Identifiers may contain letters, digits, and underscores, but must not begin with a digit. Symbols, labels, mnemonics, and register names are case-insensitive.
BYTE initializers accept -128..255. WORD initializers accept -32768..65535. Uninitialized data is zero-filled. Static data grows upward from low RAM addresses; the stack grows downward from address 1024, so programs must avoid overlap.
There are nine interrupt sources, handled in priority order:
P1P2P3P4P5P6P7P8TIMERFirmware handlers are declared with .VECTOR. Dynamically executed RAM/NVM programs begin with interrupts disabled and an empty vector table; they must configure handlers using IVEC and then execute EI.
An enabled interrupt without a corresponding handler causes a MISSING_INTERRUPT_HANDLER fault.
EXEC and NVEXEC interpret memory as consecutive eight-byte instructions:
| Byte | Contents |
|---|---|
0 |
Stable opcode byte from the instruction table |
1 |
Packed operand modes |
2–3 |
Operand A, little-endian |
4–5 |
Operand B, little-endian |
6–7 |
Operand C, little-endian |
The execution range must:
Jumps and interrupt vectors inside the range use instruction indices relative to that range. Executed ranges may nest up to eight levels. Registers, flags, RAM, NVM, GPIO state, timers, pending interrupts, and the normal RAM stack are shared between execution contexts.
| Fault | Cause |
|---|---|
INVALID_FIRMWARE |
The flashed firmware image is malformed, unsupported, or fails validation. |
INVALID_OPCODE |
A raw RAM/NVM instruction contains an unknown opcode. |
INVALID_OPERAND |
An instruction receives an unsupported operand type or invalid value. |
MEMORY_BOUNDS |
A RAM/NVM address or executable range is outside available memory. |
STACK_OVERFLOW |
The stack exceeds RAM or executable nesting exceeds eight levels. |
STACK_UNDERFLOW |
A pop, return, or interrupt return has no matching saved value/context. |
DIVISION_BY_ZERO |
DIV or MOD uses zero as its divisor. |
MISSING_INTERRUPT_HANDLER |
An enabled pending interrupt has no assigned vector. |
PROGRAM_COUNTER_BOUNDS |
Execution jumps to or falls through to an invalid instruction index. |
INTERNAL_ERROR |
An unexpected internal VM failure occurs. |
Programs that intentionally stop must execute HALT or remain in a valid loop. Falling beyond the final instruction causes PROGRAM_COUNTER_BOUNDS.
Adds high freqency blades from Metal Gear Rising: Revengeance
Adds high freqency blades from Metal Gear Rising: Revengeance