Skip to content

Instantly share code, notes, and snippets.

@SuppliedOrange
Last active February 4, 2026 05:27
Show Gist options
  • Select an option

  • Save SuppliedOrange/6ac158e5089918011a11bbf7a6019b43 to your computer and use it in GitHub Desktop.

Select an option

Save SuppliedOrange/6ac158e5089918011a11bbf7a6019b43 to your computer and use it in GitHub Desktop.

VRCRISC DOCUMENTATION

Author: @kusohanadayo
Version: 0.7

1. INTRODUCTION

Hello there! You may be wondering why the hell I did this… and I actually don’t know! I did it mostly to entertain myself and as a way to improve my skills when it comes to coding in Udon Sharp. I always like to impose odd challenges on myself, and video games and VRChat weren’t going to be an exception!

Data Types

This emulation is nowhere near as complicated as you might be thinking. In fact, it’s not directly emulating or translating bytes. Its architecture and entire operation are based on a similar contraption I made in the video game BAROTRAUMA using vanilla components not long ago. So instead of making it unnecessarily complicated, it can hold easily interpretable values in its memory cells instead of raw bytes.

All memory cells can store the following data types: String - Integer - Floating Point

When it needs to perform a comparison or an arithmetic operation, it first checks the data types of its registers and tries to convert them to the most convenient type. If that’s not possible, it simply skips the operation. I know this directly impacts performance, but this wasn’t made to be optimal—it was made to be fun!

Basic Operation

When it comes to working, the emulation’s memory functions like a very long text file or a "Microsoft Excel" sheet. It normally starts interpreting operations at the first cell (which is address $0), but this can be set to any other point. The index that indicates which point is currently being interpreted is called the pointer, or program counter. This is a simple variable that holds the number of the cell currently being interpreted; after processing it, the pointer increments by one and moves on to the next memory cell.

User-implemented programs can also decide which parts of the code are interpreted when certain conditions are met, as you can see in the example below:

Code Explanation
$0 = 5 Stores the number 5 at memory address $0
$1 = LDA $0 Loads the number 5 into the A register
$2 = LDB $0 Loads the number 5 into the B register
$3 = CMP AB Compare them ( A = B? / 5 = 5? )
$4 = JMP EQ $0 If they are equal, it makes the pointer go back to address $0, repeating this loop forever.

2. MEMORY MAP

General Purpose Memory Area

Range: $0 to $1499899

The range of memory addresses between $0 and $1499899 is the programmable memory. You can place all the instructions that make up your program here.

To assign a value or instruction to any memory cell, you just need to write ${CellNumber} = {Value}.

Example:

$10 = POTATO

This stores the value "POTATO" in the 10th memory cell. If you want to store an instruction instead of a simple value, the method is the same.

Example:

$20 = $15 = POTATO

When the emulator reads and executes the 20th memory cell, it will set the value of memory cell 15 to "POTATO".

Internal I/O Memory Area

Range: $1499900 to $1499999

This region consists of memory points that directly affect the behavior of the computer itself. They work like commands but are executed immediately and/or automatically during program execution.

Sound Memory Addresses

Setting these values to any number greater than zero will cause the generator to start playing the respective sound wave. The value written is interpreted as the target frequency (in Hz). Setting it back to 0 will stop the sound immediately.

Address Description
$1499900 Square-wave sample generator control.
$1499905 Sine-wave sample generator control.
$1499910 Sawtooth-wave sample generator control.
$1499915 Noise-wave sample generator control.

Control Memory Addresses

Address Description
$1499950 Changes the clock value. Any number written here will be used as the new clock speed. Same effect as $CLOCK command.
$1499960 Changes the tick value. Any number written here will be used as the new tick speed. Same effect as $TICK command.
$1499970 If set to 1, the emulator will immediately start executing the code. If it was loading data, that operation aborts so execution can begin right away. Used by diskettes to auto-run.
$1499980 The number written to this address will be used as the program counter, causing code execution to start from that point.

Special Read-Only Memory Addresses

Address Description
$1499940 User Input Buffer: Every time the user enters something starting with $ in the terminal, the input is written here in the format I:{UserInput}.
Ex: If user types $POTATO, this address contains I:$POTATO. Loops can read this to determine user responses. Can be cleared to remove previous content.
$1499945 RNG (Random Number Generator): Every time this address is read (e.g., LDA $1499945), it returns a random number between 0 and 1 with four decimal places. Writing to this address has no effect.

Screen Memory Area

Range: $1500000 to $1504096

This memory region is directly linked to the 64×64 screen texture. All values set here will directly affect the displayed pixels.

  • Top Left: $1500000
  • Bottom Right: $1504096

The pixels correspond linearly to the memory addresses. Adding +64 to any value will give you the pixel directly below the current one. When you reach the right edge and add one more, it wraps around to the next line on the left side.

If the value stored in these cells isn't recognized as a valid pixel value, it will be ignored and won't produce an update on the screen. As a last resort, you can also store programmable data in this region.

  • Hint: To clean the screen you can use the commands $FORMAT or $RESET.

3. INSTRUCTION SET (CHEAT SHEET)

Memory Instructions

Instruction Description
${TargetAddress} = {Value} Sets the desired value into the target memory address.
$A = B Applies the value in register B to the address specified by A.

Register Instructions

Instruction Description
LDA ${TargetAddress} Loads into register A the value stored at the target address.
LDB ${TargetAddress} Loads into register B the value stored at the target address.
STA ${TargetAddress} Stores the value contained in register A into the target address.
STB ${TargetAddress} Stores the value contained in register B into the target address.
STR ${TargetAddress} Stores the value contained in register R into the target address.
STC ${TargetAddress} Stores the value contained in register C into the target address.

Arithmetic Instructions

Instruction Description
ADD AB Adds the values of A and B and stores the result in register R.
SUB AB Subtracts the values of A and B and stores the result in register R.
MUL AB Multiplies the values of A and B and stores the result in register R.
DIV AB Divides the values of A and B and stores the result in register R.

Branching Instructions

Instruction Description
JMP ${TargetAddress} Jumps to the specified target address.
CMP AB Compares A and B and sets the internal flags [EQ, GT, LT].
JMP EQ ${TargetAddress|A} Jumps to the specified target address (or value in A) if EQ is true (Equals).
JMP GT ${TargetAddress|A} Jumps to the specified target address (or value in A) if GT is true (Greater Than).
JMP LT ${TargetAddress|A} Jumps to the specified target address (or value in A) if LT is true (Less Than).

Misc Instructions

Instruction Description
PRI ${TargetAddress} Prints the value of the specified address to the output terminal.
CON AB Concatenates A and B (As strings) and stores the result in register C.
NOP (No Operation) Performs no action and does not affect registers or memory.
INC {A/B} Increments by one the value of A or B.
DEC {A/B} Decrements by one the value of A or B.
LDA $B Loads the A register with the value corresponding to the memory address stored in the B register.
LDB $A Loads the B register with the value corresponding to the memory address stored in the A register.

4. TERMINAL COMMANDS

The following commands are entered using the VR keyboard to operate the emulation.

Command Description
$RESET Resets the entire system, wiping all memory and internal function values back to defaults. Note: May cause a 1-second lag.
$STOP Stops execution by halting the program counter increment. Also resets sound values to 0.
$RUN Starts executing and interpreting code from the current program counter position (usually $0).
$FORMAT Similar to reset, but only clears the memory and restores it to its default state.
$LIST Lists all internal files stored in the emulator from Unity.
$LOAD [NUMBER] Loads the file corresponding to that number in the list of internal files.
$DEBUG Enables the debug overlay showing the real-time state of registers and internal data.
$VERBOSE Displays the instructions currently being executed in real time. Note: Can cause significant lag at high speeds!
$OSC Toggles the on-screen sound oscillator feature on or off.
$GLOBAL Toggles global command broadcasting (makes the computer operate in global mode). Note: Disabled by default due to poor results; enable only for testing.
$>{ADDRESS} Checks the value of a specific memory address (e.g., $50 displays the value at address 50).
${ADDRESS} = {VALUE} Assigns a value to a specified memory address.
$POINTER {NUMBER} Changes the current program counter position.
$CLOCK {NUMBER} Changes internal clock value (frames per second the emulation executes instructions). Valid: 1 to 60.
$TICK {NUMBER} Changes internal tick value (instruction batches executed per clock tick). Valid: 1 to 650.
$HELP Displays the list of valid terminal commands.

5. GRAPHICAL SET

Color Palette

Valid values for each memory cell in the Screen Memory Region range from 0 to 255. In an effort to optimize these values, they represent a color range that may feel counter-intuitive.

  • Value 0: Black.
  • Value 1: White.
  • Values 2 to 255: Create a gradient between Blue and Magenta.

Image Mapping

For demonstration purposes, simple scripts were created to automatically convert any image or sequence of images to the format used by this emulation.

  • Hint: The best approach is to force black-and-white for a monochrome effect, or map the luma value of the original image to the blue-magenta palette.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment