Virtual Boy - Sacred Tech Scroll

Overview
Memory Map
ROM Format
CPU - NVC/V810 Family Microprocessor
System Reset
About

System Components
Game Pad
Game Pak
Serial Port
Timer
Wait Controller
VIP - Virtual Image Processor
VSU - Virtual Sound Unit


Memory Map

The Virtual Boy memory bus is 27 bits wide and is organized by hardware component:

0x00000000 - 0x00FFFFFF VIP - Virtual Image Processor
0x01000000 - 0x01FFFFFF VSU - Virtual Sound Unit
0x02000000 - 0x02FFFFFF Miscellaneous Hardware
0x03000000 - 0x03FFFFFF Unmapped
0x04000000 - 0x04FFFFFF Game Pak Expansion
0x05000000 - 0x05FFFFFF WRAM
0x06000000 - 0x06FFFFFF Game Pak RAM
0x07000000 - 0x07FFFFFF Game Pak ROM
0x08000000 - 0xFFFFFFFF Mirroring of memory map

Writes to the unmapped address range 0x03000000 - 0x03FFFFFF have no effect, and reads in that range will return zero.

WRAM is 64 KiB in size, meaning the effective address range is 0x05000000 - 0x0500FFFF. Any addresses in the 0x05010000 - 0x05FFFFFF range consequently have bits 16-23 masked out, producing mirrors of the contents of WRAM across the entire address range.

WRAM is pseudostatic RAM that requires 200 microseconds to initialize. Virtual Boy software must wait at least this long before accessing WRAM, or else its behavior is undefined.

For information on the Game Pak Expansion, Game Pak RAM and Game Pak ROM address ranges, see Game Pak.

The upper 5 bits of any address in the 0x08000000 - 0xFFFFFFFF range are masked out, making the maximum effective address 0x07FFFFFF.


ROM Format

Addresses 0xFFFFFDE0 - 0xFFFFFFF must contain specific kinds of data. Due to the address mirroring behavior of the memory map, these addresses correspond with addresses 0x07FFFDE0 - 0x07FFFFFF in the game pak ROM address range. The significance of these addresses is described below.

Due to the address mirroring behavior of the game pak ROM address range in all commercial game paks, addresses starting at 0x07FFFDE0 are traditionally located at the end of the ROM data, regardless of the size of the ROM module.

Virtual Boy ROM Header

Addresses 0xFFFFFDE0 - FFFFFDFF contain the Virtual Boy ROM header:

0xFFFFFDE0 - 0xFFFFFDF3 Title
0xFFFFFDF4 - 0xFFFFFDF8 Reserved
0xFFFFFDF9 - 0xFFFFFDFA Maker code
0xFFFFFDFB - 0xFFFFFDFE Game code
0xFFFFFDFF Version

Title The game's title in Shift JIS character encoding.
Reserved Reserved bytes and should be zeroes.
Maker code A 2-character ASCII identifier for the game's developer.
Game code A 4-chararacter ASCII identifier for the game.
Version An unsigned byte representing the minor version number of the software. The major version number is always 1.

Nintendo maintains a list of maker codes that is beyond the scope of this document.

The game codes for commercial software is printed on the packaging and game pak label.

Exception Handlers

Addresses 0xFFFFFE00 - FFFFFFFF contain the CPU exception handlers:

0xFFFFFE00 - 0xFFFFFE0F Game pad interrupt
0xFFFFFE10 - 0xFFFFFE1F Timer interrupt
0xFFFFFE20 - 0xFFFFFE2F Game pak interrupt
0xFFFFFE30 - 0xFFFFFE3F Communication interrupt
0xFFFFFE40 - 0xFFFFFE4F VIP interrupt
0xFFFFFE50 - 0xFFFFFF5F Unused
0xFFFFFF60 - 0xFFFFFF6F Floating-point exception
0xFFFFFF70 - 0xFFFFFF7F Unused
0xFFFFFF80 - 0xFFFFFF8F Zero division exception
0xFFFFFF90 - 0xFFFFFF9F Illegal opcode exception
0xFFFFFFA0 - 0xFFFFFFAF TRAP instruction (vector < 16)
0xFFFFFFB0 - 0xFFFFFFBF TRAP instruction (vector ≥ 16)
0xFFFFFFC0 - 0xFFFFFFCF Address trap
0xFFFFFFD0 - 0xFFFFFFDF Duplexed exception
0xFFFFFFE0 - 0xFFFFFFEF Unused
0xFFFFFFF0 - 0xFFFFFFFF Reset

These addresses do not contain the addresses of the corresponding handlers, but rather the handler machine code itself. At 16 bytes each, there is enough room to construct an address and jump to it.


Game Pak

A game pak is a cartridge containing a ROM module and optionally a RAM module, battery and/or other circuitry. It is inserted into the Virtual Boy unit and supplies the software.

Memory

The following address ranges in the memory map are allocated to the game pak:

0x04000000 - 0x04FFFFFF Game Pak Expansion
0x06000000 - 0x06FFFFFF Game Pak RAM
0x07000000 - 0x07FFFFFF Game Pak ROM

The game pak expansion range is provided for game pak-specific use, but was not used in any commercial game pak.

Game paks may or may not contain RAM modules. Commercial game paks that contained RAM modules were battery-backed, retaining RAM contents while the power is off (SRAM).

Every game pak must supply program data, typically provided by a ROM module.

In all commercial game paks, the sizes in bytes of the ROM and RAM (if present) data are powers of 2. Addresses into game pak memory that exceeds the size of the corresponding data simply have their upper bits masked out, producing mirrors of the data across the entire respective address range.

Interrupt

The game pak is able to request an interrupt with a code of 0xFE20. No commercial game paks make use of this.

Pinout

Editor's Note: A pinout diagram and description of each pin is needed.


VIP - Virtual Image Processor

Overview
Overview
Memory Map
Drawing and Display Procedures

Memory
Characters
Objects
Background Maps
Worlds
Column Table
Frame Buffer

Registers
Display
Drawing
Brightness
Palettes
Interrupts
Miscellaneous


Overview

The displays used in the Virtual Boy were invented by Reflection Technology, Inc. and pitched to Nintendo, who accepted the proposal and initiated the Virtual Boy project. Each display consists of a column of red LEDs and creates the illusion of a two-dimensional image by precicely projecting light onto an oscillating mirror. The two mirrors oscillate opposite one another to maintain balance and optimize power consumption.

A double-buffered, stereoscopic frame buffer is read from video memory to transmit to the eyes. Typically, this frame buffer is manipulated by the VIP during its drawing procedure. Alternately, the drawing functionality can be disabled and the frame buffer can be accessed directly by the CPU, facilitating software rendering.

Images on Virtual Boy are 384×224 pixels per eye at 50.0 Hz.

Image Elements

The atomic unit of graphics on Virtual Boy is the character, also known as a "tile". Characters are 8×8 pixel graphics with 2 bits per pixel. They can be used on their own in a scene or as part of a larger mosaic. There is memory for 2,048 characters.

Individual characters can be displayed anywhere on the screen by using them in an object, often called a "sprite". There is memory for 1,024 objects.

Background maps are 64×64-character mosaics that themselves are arranged into larger mosaics called backgrounds. There is memory for 14 full background maps.

The top-level unit of graphics on Virtual Boy is the world, also known as a "window". A world specifies a rectangular region in the scene where a background can be drawn. The portion of a background that appears within a world can be determined in a number of ways, from simple scrolling to affine transformations. There is memory for 32 worlds.

Other Features

The VIP is capable of raising a CPU interrupt for a number of different conditions. This is the primary means by which a program is synchronized with the video rate.

Three levels of brightness can be configured before a frame is displayed. Used in conjunction with a black value, there can be four base shades of red in a given image.

A column table exists that is used by the physical display unit to maintain pixel proportions as the mirror oscillates, since the mirror's angle relative to the LEDs is constantly changing. The table can also be used to indirectly influence the absolute brightness of columns of pixels in the output, independently from the brightness settings.

The drawing feature can be configured to swap the front and back frame buffers after some number of display cycles rather than every cycle, thereby tuning the frame rate of the program.


Memory Map

The VIP occupies addresses 0x00000000 - 0x00FFFFFF in the system memory map.

Memory Map

0x00000000 - 0x00005FFF Left frame buffer 0
0x00006000 - 0x00007FFF Character table 0
0x00008000 - 0x0000DFFF Left frame buffer 1
0x0000E000 - 0x0000FFFF Character table 1
0x00010000 - 0x00015FFF Right frame buffer 0
0x00016000 - 0x00017FFF Character table 2
0x00018000 - 0x0001CFFF Right frame buffer 1
0x0001E000 - 0x0001FFFF Character table 3
0x00020000 - 0x0003D7FF Background maps and world parameters
0x0003D800 - 0x0003DBFF World attributes
0x0003DC00 - 0x0003DDFF Left column table
0x0003DE00 - 0x0003DFFF Right column table
0x0003E000 - 0x0003EFFF Object attributes
0x00040000 - 0x0005DFFF Unmapped
0x0005E000 - 0x0005FFFF I/O Registers (see below)
0x00060000 - 0x00077FFF Unmapped
0x00078000 - 0x00079FFF Mirror of character table 0
0x0007A000 - 0x0007BFFF Mirror of character table 1
0x0007C000 - 0x0007DFFF Mirror of character table 2
0x0007E000 - 0x0007FFFF Mirror of character table 3
0x00080000 - 0x00FFFFFF Mirroring of VIP memory map

Writing to unmapped addresses has no apparent effect, and their values are undefined when read.

I/O Registers

0x0005F800 INTPND Interrupt Pending
0x0005F802 INTENB Interrupt Enable
0x0005F804 INTCLR Interrupt Clear
0x0005F820 DPSTTS Display Control Read Register
0x0005F822 DPCTRL Display Control Write Register
0x0005F824 BRTA Brightness Control Register A
0x0005F826 BRTB Brightness Control Register B
0x0005F828 BRTC Brightness Control Register C
0x0005F82A REST Rest Control Register
0x0005F82E FRMCYC Game Frame Control Register
0x0005F830 CTA Column Table Read Start Address
0x0005F840 XPSTTS Drawing Control Read Register
0x0005F842 XPCTRL Drawing Control Write Register
0x0005F844 VER VIP Version Register
0x0005F848 SPT0 OBJ Control Register 0
0x0005F84A SPT1 OBJ Control Register 1
0x0005F84C SPT2 OBJ Control Register 2
0x0005F84E SPT3 OBJ Control Register 3
0x0005F860 GPLT0 BG Palette Control Register 0
0x0005F862 GPLT1 BG Palette Control Register 1
0x0005F864 GPLT2 BG Palette Control Register 2
0x0005F866 GPLT3 BG Palette Control Register 3
0x0005F868 JPLT0 OBJ Palette Control Register 0
0x0005F86A JPLT1 OBJ Palette Control Register 1
0x0005F86C JPLT2 OBJ Palette Control Register 2
0x0005F86E JPLT3 OBJ Palette Control Register 3
0x0005F870 BKCOL BG Color Palette Control Register

VIP I/O registers are intended to be accessed as halfwords. Byte writes use the lower 16 bits of the source. Halfword and word writes, as well as all reads, behave normally.

Any address in the 0x0005E000 - 0x0005FFFF range that does not correspond with one of the above I/O registers is unused. Writing to these addresses has no apparent effect, and their values are undefined when read.


Drawing and Display Procedures

This section describes the graphical processing performed by the VIP each frame.

Frame Types

A frame is an image produced by the hardware and presented to the user. The image may be produced by the VIP itself through its drawing procedure, the drawing feature can be disabled and the image produced through software, or a mixture of both. In all cases, the image to be displayed is stored in the frame buffer.

The primary clock signal used to produce and display images is the display frame, which drives the physical display unit. Display frames occur at a fixed interval of 20 milliseconds, or 50hz. During each display frame, the contents of the frame buffer are transmitted to the LEDs for display to the user.

Drawing, if enabled, produces a new image in the frame buffer. The interval at which this occurs is a game frame. The timing of game frames is relative to display frames: the FRMCYC register can be used to configure how many display frames to wait between game frames.

Drawing Procedure

If enabled, the VIP will draw a new image into the frame buffer every game frame using settings from VIP memory such as characters, worlds and palettes.

Because the VIP memory bus is 16 bits wide and frame buffer memory is 2 bits per pixel stored in column-major order, a halfword access into frame buffer memory corresponds with a 1×8 pixel unit of data. The VIP only writes each location in frame buffer memory once per frame, performing all graphical processing necessary for the current halfword internally.

Halfwords are processed into the frame buffer in left-to-right order, therefore processing 8 rows of pixels at a time. Groups of 8 rows of pixels are procesed in top-to-bottom order. When all 28 groups of 8 rows of pixels have been processed, the drawing procedure completes.

For each 1×8 halfword unit of frame buffer data, the following algorithm is carried out:

All pixels in the halfword are initialized to the value specified by BKCOL
A temporary object world counter is initialized to 3
For each world from 31 to 0:
If the END flag is set (control world):
Stop processing worlds
If LON and RON are both clear (dummy world):
Skip to the next world
If BGM = 3 (object world):
Draw the object group specified by the temporary counter
Decrement the object group counter (wraps back to 3 after 0)
Otherwise (background world):
Draw the world's background
Store the halfword into the frame buffer

Drawing is performed on frame buffer 0 or 1, alternating each game frame. This enables drawing to one frame buffer while the other is being displayed.

Editor's Note: Is there a way to control which frame buffer is accessed when drawing is disabled?

Display Procedure

If enabled, then each display frame, the frame buffer is transmitted to the LEDs for display to the user.

For each group of 4 columns of pixels, the following algorithm is carried out:

The column table entries pointed to by CTA are loaded
If the LOCK flag in DPSTTS is clear:
CTA is updated for the next column table entries
The pixels are emitted using the appropriate brightness and column table values

Editor's Note: Research is needed to determine the direction in which column table entries are loaded as well as whether scanning occurs when the mirrors are moving in both directions.


Characters

The fundamental graphical element on Virtual Boy is the character, or "tile", which is an 8×8 pixel image with 2 bits per pixel. There is memory for 2,048 characters broken up into four blocks of 512 characters each:

0x00006000 - 0x00007FFF Character table 0
0x0000E000 - 0x0000FFFF Character table 1
0x00016000 - 0x00017FFF Character table 2
0x0001E000 - 0x0001FFFF Character table 3

These address ranges exist in between frame buffer memory and are not contiguous. In ordrer to facilitate fully linear access, virtual addresses are provided that map to character memory in such a way that all addresses are consecutive:

0x00078000 - 0x00079FFF Mirror of character table 0
0x0007A000 - 0x0007BFFF Mirror of character table 1
0x0007C000 - 0x0007DFFF Mirror of character table 2
0x0007E000 - 0x0007FFFF Mirror of character table 3

Format

A character is an 8×8 pixel graphic represented by 16 bytes. Bytes are stored in the character data consecutively by address.

Each halfword contains 8 pixels at 2 bits per pixel in the following format:

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
p7 p6 p5 p4 p3 p2 p1 p0
2 2 2 2 2 2 2 2

Each halfword represents one row of pixels in the character. Pixels at lower-order positions are displayed to the left of pixels at higher-order positions. Rows within the character are ordered top to bottom for a total of 8 halfwords.


Objects

Individual characters can appear anywhere in the scene by using them as objects, or "sprites". There is memory (OAM) for 1,024 objects:

0x0003E000 - 0x0003FFFF Object attributes

Object elements are 8 bytes in size, organized into 4 halfwords with the following format:

0
15 10 9 0
JX
6 10
1
15 14 13 10 9 0
J
L
O
N
J
R
O
N
JP
1 1 4 10
2
15 8 7 0
JY
8 8
3
15 14 13 12 11 10 0
J
H
F
L
P
J
V
F
L
P
JPLTS JCA
2 1 1 1 11
Unused These bits are not used by the VIP, but are functional memory.
JXDisplay Pointer X The signed horizontal coordinate of the left edge of the object from the left edge of the image.
JLONLeft Display On If set, the object will be drawn to the left image.
JRONRight Display On If set, the object will be drawn to the right image.
JPParallax The signed parallax offset applied to the horizontal coordinate. (See below)
JYDisplay Pointer Y The vertical coordinate of the top edge of the object from the top edge of the image. (See below)
JPLTSPalette Selector Specifies the palette index to use for this object.
JHFLPHorizontal Flip If set, the character graphic will be reversed horizontally.
JVFLPVertical Flip If set, the character graphic will be reversed vertically.
JCACharacter Number The index of the character to draw.

The JP field is used to specify the apparent depth of the object in the image. This is achived by modifying its horizontal position differently for each eye. The final horizontal position for each of the left and right images is calculated as follows:

Left:JX - JP
Right:JX + JP

The palette index specified by JPLTS selects one of the object ("OBJ") palettes.

JY is not formally two's complement, but is effectively the lower 8 bits of a signed halfword value. It can express values in the range of -8 to +224. Values 0xE0 through 0xF8 are beyond the bounds of the image, so the exact range of the field is unknown.

JCA indexes characters consecutively across all four character tables. The virtual mirroring address of the character in question can be calculated as 0x00078000 + JCA.


Background Maps

A background map is a mosaic of 64×64 characters. Background maps are stored in a region of memory that is shared with world parameters:

0x00020000 - 0x0003D7FF Background maps and world parameters

There is enough memory in this address range for 14 full background maps, plus a few more bytes. When accessing background maps, a full 16 indexes are allowed, but indexes 14 and 15 will access memory not intended for background maps.

Background maps are each 8,192 bytes in size and appear consecutively in memory by address.

Background maps contain 64×64 = 4,096 cells. Cell elements are halfwords with the following format:

15 14 13 12 11 10 0
B
H
F
L
P
B
V
F
L
P
GPLTS Character
2 1 1 1 11
Unused These bits are not used by the VIP, but are functional memory.
GPLTSPalette Selector Specifies the palette index to use for this object.
BHFLPHorizontal Flip If set, the character graphic will be reversed horizontally.
BVFLPVertical Flip If set, the character graphic will be reversed vertically.
CharacterCharacter Number The index of the character to draw.

The palette index specified by GPLTS selects one of the background ("BG") palettes.

Character indexes characters consecutively across all four character tables. The virtual mirroring address of the character in question can be calculated as 0x00078000 + Character.

The order of cells in a background map is first left-to-right for each row, then top-to-bottom row order. For instance, the first halfword represents the left-most cell in the top row, the sixty-fourth halfword the right-most cell in the top row, the sixty-fifth cell the left-most cell in the second row and so-on.


Worlds

Overview
Overview
Backgrounds
World Attributes

Types
Normal Worlds
H-Bias Worlds
Affine Worlds
Object Worlds


Overview

All scenes drawn by the VIP are defined in worlds. Worlds can specify either backgrounds or objects to be drawn, both of which use pixel data stored in characters.

Worlds containing backgrounds define a rectangular region of pixels in the image, with position and dimension attributes. The contents of this area involve the world's background, which can be manipulated in various ways.

Worlds containing objects do not specify a windowed region. When an object world is processed, all of its child objects are drawn to the image at the locations specified in their own attributes.

There is memory for 32 worlds, and they are processed in reverse order: beginning with world 31 and working backwards to world 0. Worlds with higher indexes will appear behind, and be obscured by, worlds of lesser indexes. If at any time a control world is encountered (its END flag is set), that world and all subsequent worlds are skipped and the drawing procedure immediately completes.

Worlds come in six varieties:

Normal The world's background is drawn normally, without any special modifications.
H-Bias Contains all of the features of Normal, but also allows each row of pixels within the background to be shifted horizontally, independently from one another.
Affine Each row of pixels is processed with a source coordinate within the background and a vector, allowing for affine transformations of the background such as rotation and scaling, and can even be used to achieve perspective.
Object Draws a group of objects.
Dummy Configured to produce no output. This occurs when both the LON and RON flags are clear in the world's attributes.
Control Signals early termination of the drawing procedure. This is specified by setting the END flag in the world's attributes.

For more information regarding world configuration, see World Attributes.


Backgrounds

Every world mode except object selects pixels from a background to draw to the image. The background is composed of 1 to 8 background maps arranged in some number of rows and columns within the world.

Backgrounds specify one background map as a base, and any additional background maps are selected sequentially from memory. The background map to use as the base is specified by the BG Map Base field of the world's attributes. For example, if a background consisting of four background maps uses 8 as its base map, the background will consist of maps 8, 9, 10 and 11.

The dimensions of the world's background are specified in units of background map, which are each 512×512 pixels in size. The number of background maps wide or tall a background can be is any power of 2 from 1 to 8. However, no more than 8 maps total are intended to be used in a single background, restricting which combinations of width and height are intended to be used.

For backgrounds consisting of 8 or fewer background maps, the arrangement of maps regardless of dimension is left-to-right for each row, then top-to-bottom row order. For example, a background that is 4 maps wide and 2 maps tall with a base map of 0 will be arranged as follows:

0 1 2 3
4 5 6 7

For backgrounds consisting of more than 8 background maps, the behavior of the VIP is unintended but nonetheless well-defined. Initially, the background is treated as the largest 8-map background that can be expressed with the specified height. This vertical arrangement is then repeated horizontally as many times as is necessary to fill in the entire background. For example, a 4×4 Background with a base map of 0 will be arranged as follows:

0 1 0 1
2 3 2 3
4 5 4 5
6 7 6 7

The actual index of the background map to use as the base depends on the number of maps in the background. Generally speaking, the value written to BG Map Base in the world's attributes will automatically be rounded down to the next multiple of the total number of background maps. For example, if a background consists of 4 maps and the base map index is 11, the actual map used as the base will be rounded down to 8. For the purposes of determining which map to use as the base, backgrounds consisting of more than 8 maps are treated as though they contain only 8, making their effective base map indexes either 0 or 8.


World Attributes

There is memory for 32 worlds:

0x0003D800 - 0x0003DBFF World attributes

World elements are 32 bytes in size, organized into 16 halfwords with the following format:

0
15 14 13 12 11 10 9 8 7 6 5 4 3 0
L
O
N
R
O
N
O
V
E
R
E
N
D
BGM SCX SCY BG Map Base
1 1 2 2 2 1 1 2 4
4
15 13 12 0
MX
3 13
8
15 0
H
16
1
15 10 9 0
GX
6 10
5
15 14 0
MP
1 15
9
15 0
Param Base
16
2
15 10 9 0
GP
6 10
6
15 13 12 0
MY
3 13
10
15 0
Overplane Character
16
3
15 0
GY
16
7
15 13 12 0
W
3 13
11 - 15
15 0
16
Work memory These bits do not specify world attributes, but are used by the VIP as work memory.
LONLeft Display On If set, the world will be drawn to the left image.
RONRight Display On If set, the world will be drawn to the right image.
BGMBG Modification Indicates the world's contents. (See below)
SCXScreen X Size Raise 2 to this power for the width of the world's background in background maps.
SCYScreen Y Size Raise 2 to this power for the height of the world's background in background maps.
OVEROverplane If clear, the world's background will repeat indefinitely. If set, characters beyond the background's bounds will use the character specified by Overplane Character.
ENDEnd World Specification Flag If set, this world and all worlds of lesser index will not be drawn to the frame buffer.
BG Map Base The index of the first background map in the world's background.
GXBG X Destination The signed horizontal coordinate of the left edge of the world from the left edge of the image.
GPBG Parallax Destination The signed parallax offset applied to the world's horizontal coordinate. (See below)
GYBG Y Destination The signed vertical coordinate of the top edge of the world from the top edge of the image.
MXBG X Source The signed horizontal coordinate of the pixel within the world's background, relative to the top-left corner of the background, to be displayed in the top-left corner of the world.
MPBG Parallax Source The signed parallax offset applied to the background's horizontal source coordinate. (See below)
MYBG Y Source The signed vertical coordinate of the pixel within the world's background, relative to the top-left corner of the background, to be displayed in the top-left corner of the world.
WWindow Width Add 1 to this figure to yield the width in pixels of the world. This field's format depends on BGM. (See below)
HWindow Height Add 1 to this figure to yield the height in pixels of the world. This value is signed. (See below)
Param Base Multipy this figure by 2 to yield the offset into world parameter memory where this world's parameters can be found.
The corresponding address is 0x00020000 + Param_Base × 2
Overplane Character When OVER is set, characters beyond the background's bounds will use the cell in background map memory at the index given by this field.
The corresponding address is 0x00020000 + Overplane_Character × 2

BGM determines the type of content displayed in the world:

0Normal BG
1H-Bias BG
2Affine BG
3OBJ

The GP field is used to specify the apparent depth of the world in the image. This is achived by modifying its horizontal position differently for each eye. The final horizontal position for each of the left and right images is calculated as follows:

Left:GX - GP
Right:GX + GP

The MP field is used to specify the apparent depth of the background within the world. This is achived by modifying its horizontal background source position differently for each eye. The final horizontal background source position for each of the left and right images is calculated as follows:

Left:MX - MP
Right:MX + MP

For normal and H-bias worlds, W is a 13-bit signed value. For affine worlds, it is a 10-bit unsigned value.

The minimum height of normal and H-bias worlds is 8 pixels, even if H is in the range of 0 to 6. Affine windows can be any height.

Editor's Note: Extensive research is required in order to determine the exact behavior of the VIP when drawing worlds with unintended attributes, such as negative or large dimensions, excessive parallax, etc. Research is also needed to determine which bits of world attribute memory are used by the VIP as work memory and in what ways.

Normal Worlds

A normal world is defined entirely with an entry in world attribute memory. All attributes except Param Base apply to normal worlds, and BGM must be 0.


H-Bias Worlds

An H-bias world inherits all of the features of normal worlds and introduces the ability to manipulate the horizontal scrolling of each row of pixels independently. All fields in world attribute memory apply to H-bias worlds, and BGM must be 1.

The Param Base attribute points to the location in world parameter memory where H-bias parameters can be found. The number of H-bias elements required for a world is equal to the height of the world, as there is one element for each row of pixels.

H-bias elements are 4 bytes in size, organized into 2 halfwords with the following format:

0
15 13 12 0
HOFSTL
3 13
1
15 13 12 0
HOFSTR
3 13
Unused These bits are not used by the VIP, but are functional memory.
HOFSTLLeft The signed horizontal offset to apply to the row of pixels for the left eye.
HOFSTRRight The signed horizontal offset to apply to the row of pixels for the right eye.

H-bias offsets function by adjusting the horizontal source position within the world's background for each row of pixels. The final horizontal background source position for each of the left and right images is calculated as follows:

Left: GX - GP + HOFSTL
Right: GX + GP + HOFSTR

The VIP appears to determine the address of HOFSTR by OR'ing the address of HOFSTL with 2. If the Param Base attribute in the world is not divisibe by 2, this will result in HOFSTL being used for both the left and right images, and HOFSTR will not be accessed.



Affine Worlds

An affine world inherits some basic features of normal worlds, but replaces the specifics of how each row of pixels is drawn. All fields in world attribute memory except MX, MP and MY apply to affine worlds, and BGM must be 2.

The Param Base attribute points to the location in world parameter memory where affine parameters can be found. The number of affine elements required for a world is equal to the height of the world, as there is one element for each row of pixels.

Affine elements are 16 bytes in size, organized into 8 halfwords with the following format:

0
15 0
MX
16
4
15 0
DY
16
1
15 0
MP
16
5
15 0
16
2
15 0
MY
16
6
15 0
16
3
15 0
DX
16
7
15 0
16
Work memory These bits do not specify affine parameters, but are used by the VIP as work memory.
MXBG X Source 13.3 fixed-point signed horizontal coordinate of the pixel within the world's background, relative to the top-left corner of the background, to be displayed in the left-most column of the current row of pixels.
MPBG Parallax Source The 16-bit signed parallax offset applied to the background's source coordinates. (See below)
MYBG Y Source 13.3 fixed-point signed vertical coordinate of the pixel within the world's background, relative to the top-left corner of the background, to be displayed in the left-most column of the current row of pixels.
DXBG X Direction 7.9 fixed-point signed horizontal source offset added to the coordinate of the previous source pixel in the current row of pixels.
DYBG Y Direction 7.9 fixed-point signed vertical source offset added to the coordinate of the previous source pixel in the current row of pixels.

The affine parameters MX and MY are analogous to the world attributes of the same names, but specify source coordinates with sub-pixel precision. They will be used as the source background coordinates of the left-most column in the corresponding row of output pixels in the world. The source background coordinates for each subsequent column are produced by adding DX and DY to the source background coordinates of the pixel in the previous column.

The affine parameter MP is analogous to the world attribute of the same name. It is processed as though producing output for pixels in the world that are shifted horizontally. For instance, a value of 1 in MP will produce output pixels as though they were 1 world column to the right of their actual position.

If MP is negative, it only applies to the left-eye image and is added, not subtracted. If it is non-negative, it only applies to the right-eye image.

The final background source positions for each of the left and right images, for each column of pixels i where i = 0 is the left-most column, is calculated as follows:

If MP < 0:
Left X: MX + DX × (i - MP)
Left Y: MY + DY × (i - MP)
Right X: MX + DX × i
Right Y: MY + DY × i
If MP ≥ 0:
Left X: MX + DX × i
Left Y: MY + DY × i
Right X: MX + DX × (i + MP)
Right Y: MY + DY × (i + MP)

Editor's Note: Research is needed to determine which bits of affine parameter memory are used by the VIP as work memory and in what ways.


Object Worlds

An object world is used only to display objects and therefore ignores all attributes in world attribute memory except BGM, which must be 3.

The LON and RON world attributes do not influence which eyes objects get drawn to: object visibility is determined entirely by object attributes. However, if both flags are clear, the world will be interpreted as a dummy world and will be skipped. In this situation, the world does not count as an object world.

Objects are organized into one of four object groups, which are managed through global object group settings:

0x0005F848 SPT0 OBJ Control Register 0
0x0005F84A SPT1 OBJ Control Register 1
0x0005F84C SPT2 OBJ Control Register 2
0x0005F84E SPT3 OBJ Control Register 3

The format of all object group registers is the same:

15 10 9 0
OBJ End Number
6 10
These bits have no function and are undefined when read.
OBJ End NumberR/W The ending index of objects in the group.

An object group defines a range of objects with a start index and an end index. The end index is given by the corresponding object group register. The start index is 1 greater than the register of the next lower group. The start index of group 0 is always 0.

An internal object world counter is initialized to 3 at the start of image processing. Each time an object world is processed, the object group with the same index as the counter is drawn, then the counter is decremented by 1. The counter will reset to 3 every time it is decremented from 0, allowing each object group to be processed multiple times in one frame.

Objects within an object group are drawn in reverse order, beginning with the end index of the group and counting down until the start index of the group has been processed. If the end index is less than the start index, the process is still carried out as usual, continuing with processing of object index 1,023 after object index 0.


Column Table

While the LEDs are emitting light during the display procedure, the angle between the mirror and the user's eye is constantly changing. If LED emissions were of constant duration for each column of pixels, then pixels on one side of the image would appear wider than pixels on the other side of the image. In order to correct for this behavior, the column table was implemented.

0x0003DC00 - 0x0003DDFF Left column table
0x0003DE00 - 0x0003DFFF Right column table

An entry in the column table is loaded during the display of every 4 columns of pixels. Column table entries are stored in column table memory consecutively by address. There are 512 column table entries total, 256 for each eye. Column table entries are halfwords with the following format:

15 8 7 0
Repeat Column Length
8 8
RepeatR/W Add 1 to this figure for the number of times to produce LED pulses for each column of pixels.
Column LengthR/W Add 1 to this figure for the amount of time to spend emitting light for each column of pixels, in units of 200 nanoseconds.

LED Emission

The LEDs in the display unit cannot actually emit light of varying intensity, so brightness is instead achieved by adjusting how long each pixel emits light. The less light that reaches the eye when displaying a pixel, the dimmer that pixel will appear to be. For the configuration of the base durations of LED emission for each level of brightness, see Brightness.

In addition to the LED emission interval per brightness level, there is also an idle interval:

0x0005F82A REST Rest Control Register
15 8 7 0
Duration
8 8
These bits have no function and are undefined when read.
Duration R/W Specifies the duration in units of 5 nanoseconds.

When a pixel is displayed, its value is loaded from the frame buffer. The LED will pulse for the appropriate brightness duration, then idle for the REST duration. The number of times this occurs for each column of pixels is given by the Repeat field in the column table. Since more light reaching the eye produces a brighter pixel, Repeat serves as a sort of brightness multiplier for the column.

If the total configured brightness + idle duration exceeds the time allotted for the corresponding column of pixels, the display will stop emitting and move onto the next column.

Apparent Brightness

After a certain amount of time spent emitting light, the full intensity of the LEDs can be perceived by the human eye, and longer emissions will not appear to get any brighter.

The measurable brightness of a pixel is given by the duration of its brightness level multiplied by the Repeat field in the column table. If this measurement reaches about 128, then any longer durations will not appear brighter to the user.

Recommended Column Table

Nintendo provides a recommended column table configuration that is used by all commercial software. The following data is to be loaded to addresses 0x0003DC00 and 0x0003DE00:

+000
+010
+020
+030
+040
+050
+060
+070
+080
+090
+0A0
+0B0
+0C0
+0D0
+0E0
+0F0
+100
+110
+120
+130
+140
+150
+160
+170
+180
+190
+1A0
+1B0
+1C0
+1D0
+1E0
+1F0
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 E0 00 BC 00
A6 00 96 00 8A 00 82 00  7A 00 74 00 6E 00 6A 00
66 00 62 00 60 00 5C 00  5A 00 58 00 56 00 54 00
52 00 50 00 50 00 4E 00  4C 00 4C 00 4A 00 4A 00
48 00 48 00 46 00 46 00  46 00 44 00 44 00 44 00
42 00 42 00 42 00 40 00  40 00 40 00 40 00 40 00
3E 00 3E 00 3E 00 3E 00  3E 00 3E 00 3E 00 3C 00
3C 00 3C 00 3C 00 3C 00  3C 00 3C 00 3C 00 3C 00
3C 00 3C 00 3C 00 3C 00  3C 00 3C 00 3C 00 3C 00
3C 00 3C 00 3C 00 3C 00  3C 00 3C 00 3C 00 3C 00
3C 00 3C 00 3C 00 3C 00  3C 00 3C 00 3C 00 3C 00
3C 00 3E 00 3E 00 3E 00  3E 00 3E 00 3E 00 3E 00
40 00 40 00 40 00 40 00  40 00 42 00 42 00 42 00
44 00 44 00 44 00 46 00  46 00 46 00 48 00 48 00
4A 00 4A 00 4C 00 4C 00  4E 00 50 00 50 00 52 00
54 00 56 00 58 00 5A 00  5C 00 60 00 62 00 66 00
6A 00 6E 00 74 00 7A 00  82 00 8A 00 96 00 A6 00
BC 00 E0 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00
FE 00 FE 00 FE 00 FE 00  FE 00 FE 00 FE 00 FE 00

The shaded data represents the column table entries for the visible columns of pixels, with +0A04 corresponding with the left-most column.


Frame Buffer

Virtual Boy processes images in a double-buffered, stereoscopic frame buffer. The drawing procedure automatically alternates between buffers 0 and 1 for each eye, allowing one frame to be drawn while the previous frame is being displayed.

0x00000000 - 0x00005FFF Left frame buffer 0
0x00080000 - 0x0000DFFF Left frame buffer 1
0x00010000 - 0x00005FFF Right frame buffer 0
0x00018000 - 0x0001DFFF Right frame buffer 1

A frame buffer is a 384×256 pixel image represented by 0x6000 bytes. Bytes are stored in the frame buffer data consecutively by address.

Each halfword contains 8 pixels at 2 bits per pixel in the following format:

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
p7 p6 p5 p4 p3 p2 p1 p0
2 2 2 2 2 2 2 2

Pixels at lower-order positions are displayed above pixels at higher-order positions.

Pixels are stored in column-major order in the frame buffer in order to transfer them more efficiently when displayed by the scanner. The order of pixels in the frame buffer is first top-to-bottom for each column, then left-to-right column order. For instance, the first halfword represents the top 8 pixels of the leftmost column, the sixteenth halfword the bottom 8 pixels in the leftmost column, the seventeenth halfword the top 8 pixels of the second column and so-on.

The VIP will only draw and display the top 224 rows of pixels in the frame buffer. In the interest of simplifying design and manufacture, additional memory is present for 32 rows below the bottom of the image within each frame buffer. This memory is never modified by the VIP.


Display

The display unit in the VIP produces two images: one for each eye. A vertical column of LEDs is reflected off of oscillating mirrors in order to produce the illusion of a two-dimensional image.

The display is configured through two registers:

0x0005F820 DPSTTS Display Control Read Register
0x0005F822 DPCTRL Display Control Write Register

Both display registers have the same format:

15 11 10 9 8 7 6 5 4 3 2 1 0
L
O
C
K
S
Y
N
C
E
R
E
F
C
L
K
SCAN
RDY
R
1
B
S
Y
L
1
B
S
Y
R
0
B
S
Y
L
0
B
S
Y
D
I
S
P
D
P
R
S
T
5 1 1 1 1 1 1 1 1 1 1 1
These bits have no function and are undefined when read.
LOCKR/W When set, CTA is prevented from updating.
SYNCER/W When clear, display sync signals are notsent to the display servo, preventing images from being displayed.
RER/W When clear, memory refresh signals will not be issued on VIP memory.
FCLKR The display frame clock signal is high.
SCANRDYR When set, the mirrors are stable.
R1BSY [note]R Right frame buffer 1 is being displayed.
L1BSY [note]R Left frame buffer 1 is being displayed.
R0BSY [note]R Right frame buffer 0 is being displayed.
L0BSY [note]R Left frame buffer 0 is being displayed.
DISPR/W When set, the display is enabled.
DPRSTW When set, display functions are reset. When clear, no action occurs.
[note] These fields are formally sub-fields of a 4-bit field called DPBSY.

DPSTTS is read-only and writes have no effect. DPCTRL is write-only and undefined when read. Fields marked "R" above apply to DPSTTS and fields marked "W" apply to DPCTRL.

SYNCE and DISP must both be set in order for images to be displayed. With precise timing, SYNCE might be used to enable only one image at a time, but its function is effectively the same as DISP.

While RE is clear, any VIP memory not used by the drawing procedure will degrade after several seconds.

Setting the DPRST flag will cause the following flags in DPSTTS to be undefined: LOCK, FCLK, SCANRDY and all four DPBSY flags.

Setting the DPRST flag will clear the following flags in INTENB and INTPND: TIMEERR, FRAMESTART, GAMESTART, RFBEND, LFBEND and SCANERR.

For more informaiton on the display frame clock signal, see Drawing and Display Procedures.


Drawing

The VIP has a drawing feature built in that can produce images for display using graphics data supplied by the software. This drawing feature can be disabled, allowing software rendering through direct access to the frame buffer.

Drawing is configured through two registers:

0x0005F840 XPSTTS Drawing Control Read Register
0x0005F842 XPCTRL Drawing Control Write Register

Both drawing registers have the same format:

15 14 13 12 8 7 5 4 3 2 1 0
SB
OUT
OVER
TIME
F
1
B
S
Y
F
0
B
S
Y
X
P
E
N
X
P
R
S
T
SBCOUNT /
SBCMP
1 2 5 3 1 1 1 1 1
SBOUTR Set when SBCOUNT becomes the same value as SBCMP.
SBCOUNTR The current group of 8 rows of pixels, relative to the top of the image, currently being drawn.
SBCMPW The group of 8 rows of pixels, relative to the top of the image, to compare with while drawing.
OVERTIMER The drawing procedure has taken longer than the allotted time.
F1BSY [note]R Frame buffer 1 is being drawn to.
F0BSY [note]R Frame buffer 0 is being drawn to.
XPENR/W When set, drawing is enabled.
XPRSTW When set, drawing functions are reset. When clear, no action occurs.
[note] These fields are formally sub-fields of a 2-bit field called XPBSY.

XPSTTS is read-only and writes have no effect. XPCTRL is write-only and undefined when read. Fields marked "R" above apply to XPSTTS and fields marked "W" apply to XPCTRL.

The VIP will draw to the frame buffer in units of 1×8 pixels, from left to right. This corresponds with a halfword write into frame buffer memory. For this reason, the vertical position of drawing into the frame buffer is tracked in units of 8 rows of pixels relative to the top of the image. SBCOUNT is the current group of 8 rows of pixels being processed during the drawing procedure.

SBOUT will automatically clear itself about 56 microseconds after it becomes set.

Setting the XPRST flag will clear the XPEN flag in XPSTTS.

Setting the XPRST flag will clear the following flags in INTENB and INTPND: TIMEERR, XPEND and SBHIT.

For more informaiton on drawing processing, see Drawing and Display Procedures.


Brightness

The displays in the Virtual Boy are only capable of emitting red light, but the intensity of that light can be adjusted in order to produce four shades of red per image, one of which is always black. The intensity of the other three can be controlled with global brightness settings:

0x0005F824 BRTA Brightness Control Register A
0x0005F826 BRTB Brightness Control Register B
0x0005F828 BRTC Brightness Control Register C

The format of all brightness registers is the same:

15 8 7 0
Duration
8 8
These bits have no function and are undefined when read.
Duration R/W Specifies the duration in units of 5 nanoseconds.

The LEDs in the display unit cannot actually emit light of varying intensity, so brightness is instead achieved by adjusting how long each pixel emits light. The less light that reaches the eye when displaying a pixel, the dimmer that pixel will appear to be. For additional information regarding LED emission periods and apparent brightness, see Column Table.

The brightness of each pixel in the frame buffer is determined by the pixel's value. Since pixels are 2 bits in size, there are four possible brightness levels:

0Black
1Brightness level A
2Brightness level B
3Brightness level C

Brightness levels A and B are configured directly, with zero representing no intensity and larger durations appearing brighter.

The actual duration of brightness level C is the sum of the durations in all three brightness registers: A + B + C.


Palettes

When a character is drawn by the VIP, a palette is applied to each pixel before storing the result in the frame buffer. The palette used depends on the context in which the character is used:

0x0005F860 GPLT0 BG Palette Control Register 0
0x0005F862 GPLT1 BG Palette Control Register 1
0x0005F864 GPLT2 BG Palette Control Register 2
0x0005F866 GPLT3 BG Palette Control Register 3
0x0005F868 JPLT0 OBJ Palette Control Register 0
0x0005F86A JPLT1 OBJ Palette Control Register 1
0x0005F86C JPLT2 OBJ Palette Control Register 2
0x0005F86E JPLT3 OBJ Palette Control Register 3

The format of all palette registers is the same:

15 8 7 6 5 4 3 2 1 0
c3 c2 c1
8 2 2 2 2
These bits have no function and are undefined when read.
c3 R/W The frame buffer pixel value for character pixel value 3.
c2 R/W The frame buffer pixel value for character pixel value 2.
c1 R/W The frame buffer pixel value for character pixel value 1.

A pixel value of 0 in a character is interpreted as a transparent pixel and will not modify the contents of the frame buffer when drawn. Accordingly, there is no palette entry for character pixel value 0.

One of four palettes can be selected for each character, which is applied to every pixel within the character. The "BG" palettes are selected when the character is used in a background map, and the "OBJ" palettes are selected when the character is used in an object.

Background Color

If any given pixel in the frame buffer is never drawn to by a character, its color will be determined by a global background color:

0x0005F870 BKCOL R/W BG Color Palette Control Register
15 2 1 0
value
14 2
These bits have no function and are undefined when read.
value R/W The initial frame buffer pixel value.

After BKCOL is written, the new background color will not be applied until after the first 8 rows of pixels are drawn to the frame buffer the next time a frame is drawn.


Interrupts

The VIP is capable of signalling the CPU with an interrupt request for a number of different conditions. Regardless of the cause, all VIP interrupts have a code of 0xFE40.

VIP interrupts are configured through three registers:

0x0005F800 INTPND Interrupt Pending
0x0005F802 INTENB Interrupt Enable
0x0005F804 INTCLR Interrupt Clear

All interrupt registers have the same format:

15 14 13 12 5 4 3 2 1 0
TIME
ERR
XP
END
SB
HIT
FRAME
START
GAME
START
RFB
END
LFB
END
SCAN
ERR
1 1 1 8 1 1 1 1 1
These bits have no function and are undefined when read.
TIMEERR The drawing procedure has taken longer than the allotted time.
XPEND The drawing procedure has finished.
SBHIT Drawing has begun on the group of 8 rows of pixels specified in the SBCMP field of DPCTRL.
FRAMESTART The display procedure has begun.
GAMEESTART The drawing procedure has begun.
RFBEND The display procedure has completed for the right eye.
LFBEND The display procedure has completed for the left eye.
SCANERR The mirrors are not stable.

INTPND is read-only and writes have no effect. INTCLR is write-only and undefined when read.

Interrupt conditions are enabled or disabled by writing to INTENB. If the corresponding flag is set, the interrupt condition will be enabled, and if it is clear, the interrupt condition will be disabled.

When an interrupt condition is satisfied, regardless of whether or not the condition is enabled, the corresponding flag in INTPND will be set. If any flag is set in both INTENB and INTPND, the VIP will issue an interrupt request signal to the CPU.

Interrupt conditions are acknowledged by writing to INTCLR, which will clear the corresponding flags in INTPND.

Setting the DPRST flag in DPCTRL will clear the following flags in INTENB and INTPND: TIMEERR, FRAMESTART, GAMESTART, RFBEND, LFBEND and SCANERR.

Setting the XPRST flag in XPCTRL will clear the following flags in INTENB and INTPND: TIMEERR, XPEND and SBHIT.

For more information on the SBHIT interrupt condition, see Display.


Miscellaneous Registers

CTA - Column Table Read Start Address

As the image is being displayed, the a column table entry is loaded every 4 columns of pixels. The current addresses being accessed can be queried with the following register:

0x0005F830 CTA Column Table Read Start Address
15 8 7 0
CTA_R CTA_L
8 8
CTA_RR Index into the right column table.
The corresponding address is 0x0003DE00 + CTA_R × 2
CTA_LR Index into the left column table.
The corresponding address is 0x0003DC00 + CTA_L × 2

CTA is automatically updated by the display unit while the frame buffer is being displayed. The current value can be frozen by setting the LOCK flag in DPCTRL. The value in CTA will not be updated until LOCK is cleared.

FRMCYC - Game Frame Control Register

A game frame is the interval between invocations of the VIP drawing procedure. One game frame can be synchronized with a particular number of display frames:

0x0005F82E FRMCYC Game Frame Control Register
15 4 3 0
FRMCYC
12 4
These bits have no function and are undefined when read.
FRMCYCR/W Add 1 to this figure for the number of display frames for each game frame.

For more information regarding the synchronization of game frame and display frame, see Drawing and Display Procedures.

VER - VIP Version Register

The version of the current VIP hardware can be queried with the following register:

0x0005F844 VER VIP Version Register
15 5 4 0
VER
11 5
These bits have no function and are undefined when read.
VERR The version number of the current VIP hardware.

Only one model of Virtual Boy was ever produced. Its VIP version is 2.


CPU - NVC/V810 Family Microprocessor

Overview
Specifications
Data Types
Register Set
Instruction Formats

Exceptions
Exceptions
Exception Processing
List of Exceptions

Instruction Set
Memory and Register
Arithmetic and Bitwise
Jump and Control
Floating-Point
Bit Strings
Miscellaneous
Nintendo

Appendix
Assembly Notation
Condition Numbers
List of Instructions by Mnemonic
List of Instructions by Opcode
System Register Numbers


Specifications

Virtual Boy uses a modified NEC V810 CPU called NVC:

Name:NVC
Bus width:16 bits
Clock speed:20.0 MHz
General registers:32
Instruction cache:1 KiB
Instruction set:RISC
Manufacturer:Nintendo
Word size:32 bits
Year:1995

A handful of instructions were added by Nintendo, but otherwise the processor is the same as the stock V810.

The I/O bus is mapped to the memory bus, meaning all read and write instructions access the same data.

Editor's Note: Three system registers are functional on VNC that are not mentioned in the V810 manual. It's possible Nintendo may have introduced them, but so far no record of where they came from can be found.


Data Types

Operations on NVC registers can take place on five different types of data:

Byte An 8-bit, two's complemement integer.
Halfword A 16-bit, two's complemement integer.
Word A 32-bit, two's complemement integer.
Floating Short  A 32-bit floating-point value in the IEEE 754-1985 format. Only normal real numbers and zero are accepted by the CPU: indefinites, NaNs and non-zero denormal values are regarded as invalid operands and cannot be processed.
Bit String A sequence of contiguous bits, starting at a given offset (0 to 31) within a given word in memory and extending for a given number of bits in length. For more information, see Bit Strings.

All multi-byte data types are accessed in memory with the lowest-order byte at the lowest address within the data type (little-endian).

Memory accesses are aligned. That is to say, the address being accessed is divisible by the number of bytes in the corresponding data type. If an unaligned access is attempted, the lowest-order bit(s) of the address are ignored and the effective address is rounded down to the next lower multiple of the size in bytes of the data type.

Dedicated instructions exist for converting between word and floating short data types.


Register Set

All CPU registers are 32 bits wide.


Program Counter

The program counter (PC) stores the address of the current instruction being executed. After an instruction completes, the address in PC is updated in preparation of the next instruction. This is done automatically, although a branch or jump instruction specifies the new address directly.

If an instruction raises an exception, PC will generally not be changed. Accordingly, it is the responsibility of the exception handler to modify the corresponding "PC" status-saving register before returning in order to prevent the exception from immediately being raised again.

The lowest-order bit of PC is always clear: instructions always begin on a 16-bit boundary.


Program Registers

There are 32 general-purpose registers that can be used by programs for whatever reason, called program registers. Program registers are named r0 through r31 and they all behave the same way, with the exception of r0, which has a fixed value of zero.

While program registers can be used for whatever purpose by the program, specific registers are used by certain instructions as input or output targets. The following program registers have significance regarding the execution of CPU instructions:

r0 Contains a fixed value of zero.
r26 Bit string destination bit offset.
r27 Bit string source bit offset.
r28 Bit string length.
r29 Multiple uses:
Bit string destination word address.
Bit string number of bits skipped in a search.
r30 Multiple uses:
Stores upper 32 bits of integer multiplication results.
Stores remainder of integer division results.
Represents the exchange value for the CAXI instruction.
Bit string source word address.
r31 Stores the return address of the JAL instruction.

Certain program registers have names according to their intended use by compilers and assemblers:

r0 Zero Register Contains a fixed value of zero.
r1 Assembler Reserved To be used for the construction 32-bit immediate data.
r2hp Handler Stack Pointer Stack pointer within exception handlers. [note]
r3sp Stack Pointer Program stack pointer. Points to the value most recently added to the stack ("full stack" convention).
r4gp Global Pointer References global memory.
r5tp Text Pointer References the beginning of text data. [note]
r31lp Link Pointer Return address of a function call.

[note] These registers have no designated purpose on Virtual Boy.

Upon entering a function, the calling convention defines the following roles for program registers:

r6 First argument, if applicable.
r7 Second argument, if applicable.
r8 Third argument, if applicable.
r9 Fourth argument, if applicable.
r31 Return address.

When a function completes, any return value will be stored in r10.

If more than four arguments are passed to a function, additional arguments will be located on the stack such that the fifth argument is pointed to by r3 and subsequent arguments follow at consecutively higher addresses. The callee is not responsible for cleaning up these arguments from the stack before returning: the value of r3 will remain the same when returning as it was upon entering the function.

Registers r1 and r6 through r31 are not guaranteed to be preserved during a function call.


System Registers

System registers are additional registers that can't be used by the program directly, but represent and configure CPU operating behavior. There are 13 system registers:

25 ADTRE Address Trap Register for Execution Configures the execution address for the hardware breakpoint.
24 CHCW Cache Control Word Configures the instruction cache.
4 ECR Exception Cause Register Stores values indicating the source of exceptions or interrupts.
0 EIPC Exception/Interrupt PC Stores the value to restore to PC when an exception finishes processing.
1 EIPSW Exception/Interrupt PSW Stores the value to restore to PSW when an exception finishes processing.
2 FEPC Fatal Error PC Stores the value to restore to PC when a duplexed exception finishes processing.
3 FEPSW Fatal Error PSW Stores the value to restore to PSW when a duplexed exception finishes processing.
6 PIR Processor ID Register Indicates to the program what kind of processor it's being run on.
5PSW Program Status Word Contains status flags and the interrupt masking level.
7 TKCW Task Control Word Specifies the behavior of floating-point instructions.
29 29 [note] This system register has unknown significance.
30 30 [note] This system register has unknown significance.
31 31 [note] Calculates the absolute value of the number written into it.

[note] The official names of these system registers are unknown.

System registers can be accessed by the program through the LDSR and STSR instructions, which transfer values between system registers and program registers.

The format and functionality of each system register is described below.


ADTRE - Address Trap Register for Execution

Configures the execution address of the address trap, which is the hardware breakpoint function.

31 0
TA
32
TATrap Address R/W The memory address to monitor for address traps. The lowest-order bit is always clear.

CHCW - Cache Control Word

Configures the instruction cache. The significance of the bits varies depending on the context in which the register is used.

31 20 19 8 7 6 5 4 3 2 1 0
I
C
R
I
C
D
I
C
E
I
C
C
CEN CEC RFU RFU
12 12 2 1 1 2 1 1
31 8 7 6 5 4 3 2 1 0
I
C
R
I
C
D
I
C
E
I
C
C
SA RFU RFU
24 2 1 1 2 1 1
RFUReserved for Future Use R These bits have no function and are read as zeroes.
CENClear Entry Number W The index of the first cache entry to clear. Read as zeroes.
CECClear Entry Count W The number of cache entries to clear. Read as zeroes.
SASpill-Out Base Address W The higher 24 bits of of the address to use for dump and restore operations. The lower 8 bits will be zero. Read as zeroes.
ICRInstruction Cache Restore W When set, a cache restore operation is performed. Read as zero.
ICDInstruction Cache Dump W When set, a cache dump operation is performed. Read as zero.
ICEInstruction Cache Enable R/W When set, the instruction cache is enabled.
ICCInstruction Cache Clear W When set, a cache clear operation is performed. Read as zero.

If CEN >= 128, no dump or restore operation will be performed.

If CEC > 128, the actual number of entries to clear becomes 128.

A clear operation will stop after it clears entry 127.

If more than one of ICR, ICD or ICC are specified simultaneously, the operation is undefined.


ECR - Exception Cause Register

Indicates the source of an exception.

31 16 15 0
FECC EICC
16 16
FECCFatal Error Cause Code R The exception code of the source of a duplexed exception.
EICCException/Interrupt Cause Code R The exception code of the source of a regular exception or interrupt.

This register cannot be modified by the LDSR instruction.


EIPC, EIPSW, FEPC, FEPSW - Status-saving registers

Whenever an exception occurs, the values of PC and PSW are copied into the corresponding status-saving registers prior to handling the exception:

EIPC, EIPSW in case of a regular exception or interrupt.
FEPC, FEPSW in case of a duplexed exception.

EIPC and FEPC share the same format as PC. The lowest-order bit is always zero.

EIPSW and FEPSW share the same format as PSW. Reserved bits in PSW likewise cannot be written in EIPSW or FEPSW.


PIR - Processor ID Register

Contains the identification code of the processor.

31 16 15 0
RFU PT
16 16
RFUReserved for Future Use R These bits have no function and are read as zeroes.
PTProcessor Type R The numeric value 0x5346.

This register is read-only and contains a fixed value of 0x00005346.

Editor's Note: The NVC format of PIR differs slightly from the V810 format.


PSW - Program Status Word

Contains status flags and an interrupt masking level.

31 20 19 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
N
P
E
P
A
E
I
D
F
R
O
F
I
V
F
Z
D
F
O
V
F
U
D
F
P
R
C
Y
O
V
RFU I RFU S Z
12 4 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1
RFUReserved for Future Use R These bits have no function and are read as zeroes.
IInterrupt Level R/W If an interrupt is requested and the interrupt's level is less than I, the interrupt will be masked.
NPNMI Pending R/W Set during processing of a duplexed exception or reset.
EPException Pending R/W Set during processing of an exception or interrupt.
AEAddress Trap Enable R/W If set, the address trap feature will be enabled.
IDInterrupt Disable R/W If set, all interrupts will be masked.
FROFloating Reserved Operand R/W Set when a floating-point operation is attempted with a reserved operand.
FIVFloating Invalid R/W Set when an invalid floating-point operation attempted.
FZDFloating Zero Divide R/W Set when the DIVF.S instruction is executed with a denominator of zero.
FOVFloating Overflow R/W Set when the result of a floating-point operation is too large to be represented by the floating short data type.
FUDFloating Underflow R/W Set when the result of a floating-point operation is too small to be represented as a normal floating short value.
FPRFloating Precision R/W Set when the result of a floating-point operation is subjected to rounding and suffers precision degradation.
CYCarry R/W Set when an operation produces a carry.
OVOverflow R/W Set when an operation results in integer overflow.
SSign R/W Set when the result of an operation is negative.
ZZero R/W Set when the result of an operation is zero.

During the operation of the Bcond and SETF instructions, certain flag state combinations are checked in PSW.


TKCW - Task Control Word

Specifies how floating-point operations are to be processed.

31 9 8 7 6 5 4 3 2 1 0
O
T
M
F
I
T
F
Z
T
F
V
T
F
U
T
F
P
T
R
D
I
RFU RD
23 1 1 1 1 1 1 1 2
RFUReserved for Future Use R These bits have no function and are read as zeroes.
OTMOperand Trap Mask R If set, floating-point invalid operand exceptions will be masked.
FITFloating Invalid Operation Trap Enable R If set, floating-point invalid operation exceptions will be enabled.
FZTFloating-Zero Divide Trap Enable R If set, floating-point zero division exceptions will be enabled.
FVTFloating-Overflow Trap Enable R If set, floating-point overflow exceptions will be enabled.
FUTFloating-Underflow Trap Enable R If set, floating-point underflow exceptions will be enabled.
FPTFloating-Precision Trap Enable R If set, floating-point precision degradation exceptions will be enabled.
RDI Floating Rounding Control Bit
for Integer Conversion
R Specifies the direction of floating-point rounding operations when converting to integer:
0 = Same as RD
1 = Undocumented
RD Floating Rounding Control R Specifies the direction of floating-point rounding operations:
0 = Toward nearest
1 = Undocumented
2 = Undocumented
3 = Undocumented

This register is read-only and contains a fixed value of 0x000000E0. This corresponds with the following configuration:

OTM= 0 Invalid operand exceptions will be raised.
FIT= 1 Invalid operation exceptions will be raised.
FZT= 1 Zero-division exceptions will be raised.
FVT= 1 Overflow exceptions will be raised.
FUT= 0 Underflow exceptions will not be raised.
FPT= 0 Precision degradation exceptions will not be raised.
RDI= 0 Rounding to integer uses nearest value.
RD= 0 Rounding to floating short uses nearest value.

Editor's Note: Since this register was never intended to be modified, the effects of other values for RDI and RD were not provided in the documentation for the V810 or V830 processors.


29 - System register 29

This register has unknown significance.

31 0
???
32
??? R/W Unknown. All 32 bits of this field can be read and written.

30 - System register 30

This register has unknown significance.

31 0
???
32
??? R Unknown.

This register is read-only and contains a fixed value of 0x00000004.


31 - System register 31

Calculates the absolute value of a signed word.

31 0
X
32
X Value R/W Any signed word value.

Reading from this register will give the absolute value of the most recent value written to it.


Instruction Formats

Instructions are fetched as halfword units from the bus and may be 16 or 32 bits in size. A common opcode field is present in the highest-order bits of the first halfword of every instruction, which is used to determine the instruction's binary format and whether an additional 16 bits need to be fetched.

If an instruction is 32 bits in size, a second halfword is fetched from the bus at the immediate next higher halfword address. The resulting word value is formed by taking the first halfword (bits 0-15) as the upper 16 bits and the second halfword (bits 16-31) as the lower 16 bits.

Every instruction is encoded into one of seven binary formats, referred to as Format I through Format VII. The structure of each of these instruction formats is described below.


Format I - Register-Register

16 bits. Used for register-to-register operations.

15 10 9 5 4 0
opcode reg2 reg1
6 5 5
opcode The instruction's opcode.
reg2 Destination register and left-hand operand.
reg1 Source register and right-hand operand.

Format II - Immediate-Register

16 bits. Used for immediate-to-register operations.

15 10 9 5 4 0
opcode reg2 imm
6 5 5
15 10 9 5 4 0
opcode reg2 cond
6 5 5
15 10 9 5 4 0
opcode reg2 regID
6 5 5
15 10 9 5 4 0
opcode reg2 vector
6 5 5
15 10 9 5 4 0
opcode reg2 sub-opcode
6 5 5
opcode The instruction's opcode.
reg2 Destination register and left-hand operand.
imm Source value and right-hand operand.
cond Condition for SETF instruction. The highest-order bit of this field is ignored.
regID The zero-extended system register index for the LDSR and STSR instructions.
vector The zero-extended vector for the TRAP instruction.
sub-opcode Additional opcode bits for bit string instructions.

Depending on the instruction, imm may or may not be sign-extended.


Format III - Conditional Branch

16 bits. Used by the Bcond instruction for short-distance branches.

15 13 12 9 8 0
opcode cond disp
3 4 9
opcode The instruction's opcode.
cond Condition for branch to occur.
disp Sign-extended displacement offset.

For the numeric codes of each condition, see Bcond.

The displacement offset is measured in bytes relative to the address of the first byte of the instruction.

This is the only format that does not have a 6-bit opcode field. The 3 bits that represent the Bcond instruction's opcode (100) are not shared as the upper 3 bits of any other instruction's opcode.


Format IV - Middle-Distance Jump

32 bits. Used for middle-distance jumps using a displacement offset.

15 10 9 0 31 16
opcode disp
6 26
opcode The instruction's opcode.
disp Sign-extended displacement offset.

The displacement offset is measured in bytes relative to the address of the first byte of the instruction.


Format V - 3-Operand

32 bits. Used for operations that require three operands.

15 10 9 5 4 0 31 16
opcode reg2 reg1 imm
6 5 5 16
opcode The instruction's opcode.
reg2 Destination register.
reg1 Source register and left-hand operand.
imm Source value and right-hand operand.

Depending on the instruction, imm may or may not be sign-extended.


Format VI - Load/Store

32 bits. Used for memory access operations.

15 10 9 5 4 0 31 16
opcode reg2 reg1 disp
6 5 5 16
opcode The instruction's opcode.
reg2 Data register.
reg1 Base address register.
disp Sign-extended address displacement offset.

The effective address of the memory access operation is determined by adding disp to the value in register reg1.

For load and input operations, register reg2 receives the value read. For store and output operations, the register supplies the value to write.


Format VII - Extended

32 bits. Functions similarly to Format I, but with additional opcodes.

15 10 9 5 4 0 31 26 25 16
opcode reg2 reg1 sub-opcode RFU
6 5 5 6 10
opcode The instruction's opcode.
reg2 Destination register and left-hand operand.
reg1 Source register and right-hand operand.
sub-opcode Additional opcode bits.
RFU Reserved for Future Use. These bits are ignored.


Exceptions

Certain events can cause the CPU to break its current execution, saving its status and beginning execution somewhere else according to what happened. The general term for such an occurrence is an exception, and exceptions come in three froms:

Exception The processing of an instruction resulted in a error condition.
Interrupt Another hardware component requested a program break.
Address Trap A hardware execute breakpoint was triggered.

Every exception has an associated 16-bit code and a 32-bit handler address. When an exception is raised, the code is stored into ECR and the handler address into PC. For a list of codes and handler addresses, see List of Exceptions.


Exception

Processing of CPU instructions can raise exceptions on their own. This can happen in any of the following situations:

The opcode or sub-opcode of the instruction being decoded does not correspond with any valid instruction.
The operation cannot be performed with the given operands.
The TRAP instruction was executed.

Interrupt

Hardware components other than the CPU are allowed to request interrupts. This provides a mechanism to synchronize all system operations as well as a way for a hardware component to signal the program when certain conditions are met.

Interrupts can be disabled by setting the ID flag in PSW. The CLI and SEI instructions manipulate this flag directly, and the LDSR instruction can also be used to configure it.

Each hardware component that can request an interrupt is assigned a numeric level. Interrupts with greater levels are given priority over and are accepted before interrupts with lesser levels. If the interrupt's level is less than the value of the I field in PSW, the interrupt request will be ignored.

When an interrupt is requested, it will not be accepted until after the current CPU instruction has finished executing.

Interrupts are ignored during exception processing: whenever of the EP or NP flags is set in PSW.

The HALT instruction will stop all CPU activity until an interrupt request is accepted, at which point it resume with exception processing.


Address Trap

A hardware breakpoint can be configured to raise an exception when the CPU is to execute an instruction at the configured address.

The ADTRE register can be configured with the breakpoint address, and the address trap function can be enabled by setting the AE flag in PSW. Under these conditions, if the value of PC matches ADTRE prior to fetching the instruction at that address, an address trap exception will be raised.


Duplexed Exception

If an exception is raised during the processing of another exception, a duplexed exception occurs. The return status of both exceptions is held in ECR and the status-saving registers, and a special handler specifically for duplexed exceptions is run.

If an exception is raised during the processing of a duplexed exception, a fatal exception occurs. Debugging information is stored to the bus and the CPU enters a permanent halt state until reset. For more information, see Exception Processing.


Exception Processing

Restore PC

When exception handling begins, the contents of PC and PSW are transferred into the appropriate status-saving registers. The value used for PC in this case is known as the restore PC, and is determined relative to the address of the current instruction being executed.

The following exceptions will use the address of the current instruction, known as current PC, as the restore PC:

Any regular exception not raised by the TRAP instruction.
Any interrupt that is accepted during the processing of a bit string instruction.
An address trap.

The following exceptions will use the address of the following instruction, known as next PC, as the restore PC:

The TRAP instruction.
Any interrupt that does not occur during the processing of a bit string instruction.

Interrupt Handling

An interrupt that is requested will only be accepted if all of the following conditions are met:

ID = 0 in PSW.
EP = 0 in PSW.
NP = 0 in PSW.
I in PSW is less than or equal to the interrupt's level.

Exception Handling

When an exception is raised, the following algorithm is carried out:

If the NP flag in PSW is set, a fatal exception occurs:
The exception's code is OR'd with 0xFFFF0000 and the result is written to memory address 0x00000000.
The value in PSW is written to memory address 0x00000004.
The value in PC is written to memory address 0x00000008.
× The CPU halts until system reset.
If the EP flag in PSW is set, a duplexed exception occurs:
The exception's code is stored into the FECC field of ECR.
The value in PSW is stored into FEPSW.
The restore PC is stored into FEPC.
The NP flag in PSW is set.
0xFFFFFFD0 is stored into PC.
Else, a regular exception occurs:
The exception's code is stored into the EICC field of ECR.
The value in PSW is stored into EIPSW.
The restore PC is stored into EIPC.
The EP flag in PSW is set.
The exception's handler address is stored into PC.
If the exception was an interrupt:
1 is added to the interrupt's level and the result is stored into the I field of PSW.
Any pending HALT instruction completes.
The ID flag in PSW is set.
The AE flag in PSW is cleared.

Editor's Note: Research is needed to determine the number of cycles taken by this process.


Returning from Exceptions

When handling of an exception is completed, control is returned to the program with the RETI instruction.

According to the NP flag of PSW, RETI will restore PC and PSW from the appropriate status-saving registers.


List of Exceptions

Name Type Code Level Handler
Address
Restore PC Note
Reset Interrupt 0xFFF0 - 0xFFFFFFF0 - Occurs at system power-on
Duplexed exception Exception - - 0xFFFFFFD0 Current PC Exception during exception processing
VIP Interrupt 0xFE40 4 0xFFFFFE40 [note] Various video conditions
Communication Interrupt 0xFE30 3 0xFFFFFE30 [note] Completion of serial port transfer
Game Pak Interrupt 0xFE20 2 0xFFFFFE20 [note] Initiated by the game pak
Timer Interrupt 0xFE10 1 0xFFFFFE10 [note] The timer counter reached zero
Game Pad Interrupt 0xFE00 0 0xFFFFFE00 [note] Button press
Address trap Address trap 0xFFC0 - 0xFFFFFFC0 Current PC Hardware breakpoint
TRAP instruction (vector < 16) Exception 0xFFA0 + vector - 0xFFFFFFA0 Next PC Instruction operation
TRAP instruction (vector ≥ 16) Exception 0xFFA0 + vector - 0xFFFFFFB0 Next PC Instruction operation
Illegal opcode Exception 0xFF90 - 0xFFFFFF90 Current PC Invalid opcode or sub-opcode
Zero division Exception 0xFF80 - 0xFFFFFF80 Current PC Integer division by zero
Floating-point reserved operand Exception 0xFF60 - 0xFFFFFF60 Current PC Indefinites, NaNs or non-zero denormals
Floating-point invalid operation Exception 0xFF70 - 0xFFFFFF60 Current PC Impossible operation
Floating-point zero division Exception 0xFF68 - 0xFFFFFF60 Current PC Division by zero
Floating-point overflow Exception 0xFF64 - 0xFFFFFF60 Current PC Result is too large for data type

[note] If an interrupt occurs during the processing of a bit string instruction, current PC is used. Otherwise, next PC is used.

This list is ordered such that items that appear earlier in the list have higher priority than items that appear later in the list. If any two exceptions should coincide, the one with the highest priority is the one that will be processed.

Although interrupts are given high priority, they cannot occur simultaneously with instruction exceptions because the CPU checks for interrupt requests in between executing instructions.

The reset interrupt is automatically acknowledged when the CPU is initialized. PSW is initialized in such a way that the I field is zero, meaning reset has no meaningful interrupt level.

If a floating-point instruction satisfies multiple error conditions (such as dividing NaN by zero), only the one with the highest priority will be processed and have its status flag set in PSW.


Memory and Register

Register Transfer

Mnemonic Opcode Format Z S OV CY Cycles Name Operation
MOV 010000 II - - - - 1 Move Immediate reg2 = (sign extend) imm
MOV 000000 I - - - - 1 Move Register reg2 = reg1
MOVEA 101000 V - - - - 1 Add reg2 = reg1 + (sign extend) imm
MOVHI 101111 V - - - - 1 Add reg2 = reg1 + (imm << 16)

The purpose of the MOVEA and MOVHI instructions is to provide a means for populating a register with 32 bits of immediate data without modifying the status flags in PSW.

Since MOVEA sign-extends the immediate value, care needs to be taken to ensure that the appropriate value is stored in the upper halfword of the register by MOVHI.


Load and Input

Mnemonic Opcode Format Z S OV CY Cycles Name Operation
IN.B 111000 VI - - - - * Input Byte from Port reg2 = (zero extend) (byte ptr) [reg1 + disp]
IN.H 111001 VI - - - - * Input Halfword from Port reg2 = (zero extend) (halfword ptr) [reg1 + disp]
IN.W 111011 VI - - - - * Input Word from Port reg2 = (word ptr) [reg1 + disp]
LD.B 110000 VI - - - - * Load Byte reg2 = (sign extend) (byte ptr) [reg1 + disp]
LD.H 110001 VI - - - - * Load Halfword reg2 = (sign extend) (halfword ptr) [reg1 + disp]
LD.W 110011 VI - - - - * Load Word reg2 = (word ptr) [reg1 + disp]

Halfword operations will mask the lowest bit of the effective address to 0, and word operations will mask the two lowest bits to 0. This ensures that data in memory is accessed on a boundary the same size as the data type.

Since Virtual Boy maps the I/O bus to the memory bus, the input instructions access the same data as the load instructions. They're nearly identical in function, except the input instructions zero-extend the data being read whereas the load instructions sign-extend it.

The number of cycles taken by load instructions depends on prior bus activity:

1 cycle When used immediately after an instruction that takes many cycles[note] and which does not conflict with the operation of the load instruction.
4 cycles When immediately following another load instruction.
5 cycles When used in an isolated context.

[note] Editor's Note: The V810 documentation uses the phrase "many cycles" with regards to a one-cycle load operation, but it doesn't explicitly define exactly how many is "many". Logic suggests that the instruction needs only take long enough for the pipeline to ready the load operation with its effective address, then can immediately execute it when the long instruction finishes. Either way, this needs some research.

Editor's Note: The cycle counts for input instructions needs to be researched, as they may be identical to the load instructions' counts.

Editor's Note: While the number of CPU cycles taken for an input or load instruction may be small, the actual amount of time taken depends on the speed of whatever is being accessed on the bus (video memory, WRAM, etc.). The exact latencies for reads needs to be researched.


Store and Output

Mnemonic Opcode Format Z S OV CY Cycles Name Operation
OUT.B 111100 VI - - - - * Output Byte to Port (byte ptr) [reg1 + disp] = reg2 AND 0xFF
OUT.H 111101 VI - - - - * Output Halfword to Port (halfword ptr) [reg1 + disp] = reg2 AND 0xFFFF
OUT.W 111111 VI - - - - * Output Word to Port (word ptr) [reg1 + disp] = reg2
ST.B 110100 VI - - - - * Store Byte (byte ptr) [reg1 + disp] = reg2 AND 0xFF
ST.H 110101 VI - - - - * Store Halfword (halfword ptr) [reg1 + disp] = reg2 AND 0xFFFF
ST.W 110111 VI - - - - * Store Word (word ptr) [reg1 + disp] = reg2

Halfword operations will mask the lowest bit of the effective address to 0, and word operations will mask the two lowest bits to 0. This ensures that data in memory is accessed on a boundary the same size as the data type.

Since Virtual Boy maps the I/O bus to the memory bus, the output instructions access the same data as the store instructions. They're identical in function.

The number of cycles taken by store instructions depends on prior bus activity:

1 cycle The first two consecutive executions of store instructions.
4 cycles Subsequent consecutive executions.

Editor's Note: The cycle counts for output instructions needs to be researched, as they may be identical to the store instructions' counts.

Editor's Note: While the number of CPU cycles taken for an output or store instruction may be small, the actual amount of time taken depends on the speed of whatever is being accessed on the bus (video memory, WRAM, etc.). The exact latencies for writes needs to be researched.


Arithmetic and Bitwise

Arithmetic

Mnemonic Opcode Format Z S OV CY Cycles Name Operation
ADD 010001 II 1 Add Immediate reg2 = reg2 + (sign extend) imm
ADD 000001 I 1 Add Register reg2 = reg2 + reg1
ADDI 101001 V 1 Add Immediate reg2 = reg1 + (sign extend) imm
CMP 010011 II 1 Compare Immediate (discard) = reg2 - (sign extend) imm
CMP 000011 I 1 Compare Register (discard) = reg2 - reg1
DIV 001001 I - 38 Divide r30 = reg2 MOD reg1, reg2 = reg2 / reg1
DIVU 001011 I 0 - 36 Divide Unsigned r30 = reg2 MOD reg1, reg2 = reg2 / reg1
MUL 001000 I - 13 Multiply (result) = reg2 * reg1, r30 = (result) >> 32, reg2 = (result)
MULU 001010 I - 13 Multiply Unsigned (result) = reg2 * reg1, r30 = (result) >> 32, reg2 = (result)
SUB 000010 I 1 Subtract reg2 = reg2 - reg1

Compare operations perform subtraction and update the status flags accordingly, but discard the result.

Division operations produce the arithmetic quotient without any fractional part (round towards zero), and the remainder, which shares the same sign as the dividend. The remainder is first stored into r30, then the result is stored into reg2. If a division is attempted with a divisor of zero, a Zero Division exception will be raised with a code of 0xFF80 and a restore PC of current PC.

The result of multiplication operations is 64 bits in size. The upper 32 bits are first stored into r30, then the lower 32 bits are stored into reg2.

The zero flag (Z) is set when the result of any operation is zero, or is cleared otherwise. For multiply operations, only the lower 32 bits of the result are considered.

The sign flag (S) is a copy of the highest-order bit of the result of any operation. For multiply operations, only the lower 32 bits of the result are considered.

The overflow flag (OV) is set in the following situations, or is cleared otherwise:

Addition or subtraction results in signed wrap-around. For instance, if adding two positive numbers produces a negative result.
The DIV instruction is performed dividing 0x80000000 by -1. In this situation, the result is 0x80000000 and the remainder is zero.
The full 64-bit result of a multiplication is not equivalent to the 64-bit value produced by sign-extending the lower 32 bits.

The carry flag (CY) is set when addition or subtraction results in unsigned wrap-around, or is cleared otherwise. For example, carry will be set when subtracting an unsigned value from a lesser value.


Bitwise

Mnemonic Opcode Format Z S OV CY Cycles Name Operation
AND 001101 I 0 - 1 And reg2 = reg2 AND reg1
ANDI 101101 V 0 0 - 1 And Immediate reg2 = reg1 AND (zero extend) imm
NOT 001111 I 0 - 1 Not reg2 = NOT reg1
OR 001100 I 0 - 1 Or reg2 = reg2 OR reg1
ORI 101100 V 0 - 1 Or Immediate reg2 = reg1 OR (zero extend) imm
SAR 010111 II 0 1 Shift Arithmetic Right by Immediate reg2 = reg2 >> (zero extend) imm (sign-propagating)
SAR 000111 I 0 1 Shift Arithmetic Right by Register reg2 = reg2 >> (reg1 AND 0x1F) (sign-propagating)
SHL 010100 II 0 1 Shift Logical Left by Immediate reg2 = reg2 << (zero extend) imm
SHL 000100 I 0 1 Shift Logical Left by Register reg2 = reg2 << (reg1 AND 0x1F)
SHR 010101 II 0 1 Shift Logical Right by Immediate reg2 = reg2 >> (zero extend) imm (zero-filling)
SHR 000101 I 0 1 Shift Logical Right by Register reg2 = reg2 >> (reg1 AND 0x1F) (zero-filling)
XOR 001110 I 0 - 1 Exclusive Or reg2 = reg2 XOR reg1
XORI 101110 V 0 - 1 Exclusive Or Immediate reg2 = reg1 XOR (zero extend) imm

Arithmetic right shift will produce copies of the highest-order bit when filling from the left. Logical right shift will fill with zeroes.

The zero flag (Z) is set when the result of any operation is zero, or is cleared otherwise.

The sign flag (S) is a copy of the highest-order bit of the result of any operation.

The carry flag (CY) is a copy of the last bit shifted out of the register during a shift operation, or cleared if the shift amount was zero.


Jump and Control

Conditional Branch

Mnemonic Opcode Format Z S OV CY Cycles Name Operation
Bcond 100[note] III - - - - * Branch on Condition if cond = true then PC = PC + disp

[note] Format III has a 3-bit opcode field. No other instruction contains an opcode whose highest 3 bits match the opcode of Bcond.

If the condition specified by cond in PSW is true, then PC is updated directly. Otherwise, PC advances to the next instruction as usual.

All conditional branch instructions are permutations of the Bcond instruction, just with different values for cond. Each one is given its own mnemonic.

The following conditions can be checked:

Value Mnemonic Condition Test Note
0 BV Overflow if OV = 1
1 BC, BL Carry, Lower if CY = 1 < unsigned
2 BE, BZ Equal, Zero if Z = 1
3 BNH Not higher if (CY OR Z) = 1 ≤ unsigned
4 BN Negative if S = 1
5 BR Always if true Unconditional branch
6 BLT Less than if (OV XOR S) = 1 < signed
7 BLE Less than or equal if ((OV XOR S) OR Z) = 1 ≤ signed
8 BNV Not overflow if OV = 0
9 BNC, BNL Not carry, Not lower if CY = 0 ≥ unsigned
10 BNE, BNZ Not equal, Not zero if Z = 0
11 BH Higher if (CY OR Z) = 0 > unsigned
12 BP Positive if S = 0
13 NOP [note] Not always if false Does not branch
14 BGE Greater than or equal if (OV XOR S) = 0 > signed
15 BGT Greater than if ((OV XOR S) OR Z) = 0 ≥ signed
[note] The NOP instruction is technically the configuration of Bcond that never branches.

Certain conditions have more than one mnemonic. In these situations, either mnemonic can be used and the two are interchangeable.

The number of cycles taken by Bcond varies depending on whether the branch is taken:

1 cycleThe branch is not taken.
3 cyclesThe branch is taken.

The cond field uses the same numeric values for each condition as the SETF instruction.


Jump

Mnemonic Opcode Format Z S OV CY Cycles Name Operation
JAL 101011 IV - - - - 3 Jump and Link r31 = PC + 4, PC = PC + disp
JMP 000110 I - - - - 3 Jump Register PC = reg1
JR 101010 IV - - - - 3 Jump Relative PC = PC + disp

Because the lowest-order bit of PC is fixed clear, the effective address of jump instructions will have its lowest bit masked to a 16-bit boundary.


CPU Control

Mnemonic Opcode Format Z S OV CY Cycles Name Operation
HALT 011010 II - - - - - Halt Wait for interrupt
LDSR 011100 II * * * * 8 Load to System Register SystemRegister[regID] = reg2
RETI 011001 II * * * * 10 Return from Trap or Interrupt if NP then PC = FEPC, PSW = FEPSW else PC = EIPC, PSW = EIPSW
STSR 011101 II - - - - 8 Store Contents of System Register reg2 = SystemRegister[regID]
TRAP 011000 II - - - - 15 Trap Raise exception (0xFFA0 + vector)

The HALT instruction will cause the CPU to stop all processing until an interrupt is accepted. If all interrupts are masked or disabled, HALT cannot finish and the CPU will be stopped until reset.

The following numeric codes for system registers are used by the LDSR and STSR instructions:

0 EIPC
1 EIPSW
2 FEPC
3 FEPSW
4 ECR [note]
5PSW
6 PIR [note]
7 TKCW [note]
...Reserved
24 CHCW
25 ADTRE
...Reserved
29System register 29
30 System register 30 [note]
31System register 31

[note] Attempting to write to these system registers with the LDSR instruction will have no effect.

Attempting to write to a reserved system register will have no effect, and they are all read as zero.

The resulting exception raised by the TRAP instruction will have a code of (0xFFA0 + vector) and a restore PC of next PC, the address of the following instruction.


Floating-Point

All of the floating-point instructions are stored in Format VII and share a common opcode of 111110. They are identified by their sub-opcode field.

Mnemonic Sub-opcode Z S OV CY FRO FIV FZD FOV FUD FPR Cycles Name Operation
ADDF.S 000100 0 - - 9-28 Add Floating Short reg2 = reg2 + reg1
CMPF.S 000000 0 - - - - - 7-10 Compare Floating Short (discard) = reg2 - reg1
CVT.SW 000011 0 - - - - 9-14 Convert Short Floating to Word Integer reg2 = (word) round(reg1)
CVT.WS 000010 0 - - - - - 5-16 Convert Word Integer to Short Floating reg2 = (float) reg1
DIVF.S 000111 0 44 Divide Floating Short reg2 = reg2 / reg1
MULF.S 000110 0 - - 8-30 Multiply Floating Short reg2 = reg2 * reg1
SUBF.S 000101 0 - - 12-28 Subtract Floating Short reg2 = reg2 - reg1
TRNC.SW 001011 0 - - - - 9-14 Truncate Short Floating to Word Integer reg2 = (word) truncate(reg1)

The CVT.SW and TRNC.SW instructions produce an approximate word value from a floating short value. CVT.SW will round to the nearest integer value, wheras TRNC.SW will simply remove the fractional part.

The zero flag (Z) is set when the result of any operation is zero, or is cleared otherwise.

The carry flag (CY) and sign flag (S) are both copies of the highest-order bit of the result of any operation.

PSW contains status flags that pertain only to floating-point operations. When a floating-point status condition is met, the corresponding flag is set in PSW, but otherwise will not be modified. The floating-point status conditions are as follows:

Flag Code Name Condition
FRO 0xFF60 Reserved operand Either operand is a NaN, an indefinite, or a non-zero denormal value.
FIV 0xFF70 Invalid operation Multiple conditions:
A conversion or truncation was attempted on a value beyond the range of the word data type.
DIVF.S attempted to divide zero by zero.
FZD 0xFF68 Zero division DIVF.S attempted to divide non-zero by zero.
FOV 0xFF64 Overflow The result was beyond the maximum normal range of the floating short data type.
FUD - Underflow The result was beyond the minimum normal range of the floating short data type. Zero is used as the result.
FPR - Precision degradation The result was subjected to rounding and suffered a loss of precision.

Status conditions in the list with an associated code will raise an exception with that code if they are met. They are ordered in the list such that items that appear earlier in the list have higher priority than items that appear later in the list. In the event an instruction satisfies more than one such condition, only the one with the highest priority will be processed and have its corresponding flag set in PSW.

Editor's Note: The overflow condition appears to process the result as usual, updating FPR and reg2 as appropriate, then raise the overflow exception when writing the exponent field. Research is needed to determine exactly which values are produced in this situation.

Editor's Note: While the V810 documentation gives ranges for the number of cycles taken for each floating-point instruction, it does not give specifics about which situations result in which cycle counts. Research is needed to determine how long any given operation will take.


Bit Strings

Overview

Bit strings are contiguous sequences of bits in memory. Operations can be performed on one or two bit strings.

Bit strings are defined with three parameters:

Word address  The address in memory of the word containing the first bit of the bit string.
Bit offset The binary position within the word where the first bit of the bit string is located (0 = least significant, 31 = most significant).
Length The number of bits in the bit string. Bit strings of length zero are valid.

Data storage for bit strings follows the order of least-significant to most-significant for bits within words, and by memory address for words.

Registers r26 through r30 are used to define bit strings:

r26  Destination string bit offset. The upper 26 bits are cleared prior to operation.
r27 Source string bit offset. The upper 26 bits are cleared prior to operation.
r28 String length. All 32 bits are regarded as an unsigned integer.
r29 Multiple meanings:
Destination string word address. The lower 2 bits are cleared prior to operation.
Incremented for each bit skipped in a search. All 32 bits are regarded as an unsigned integer.
r30 Source string word address. The lower 2 bits are cleared prior to operation.

Operations that are performed on only one bit string use the registers designated for the "source" bit string.

Bit string operations are carried out in either an "upward" or "downward" direction. In an upwards operation, the offset of bits within a word increases and the words in memory increase in address. Conversely, a downward operation observes decreased bit offsets and word addresses.

All of the bit string instructions are stored in Format II and share a common opcode of 011111. They are identified by their sub-opcode field.


Arithmetic

Mnemonic Sub-opcode Z S OV CY Name Operation
ANDBSU 01001 - - - - And Bit String Upward dest = dest AND src
ANDNBSU 01101 - - - - And Not Bit String Upward dest = dest AND (NOT src)
MOVBSU 01011 - - - - Move Bit String Upward dest = src
NOTBSU 01111 - - - - NOT Bit String Upward dest = NOT src
ORBSU 01000 - - - - Or Bit String Upward dest = dest OR src
ORNBSU 01100 - - - - Or Not Bit String Upward dest = dest OR (NOT src)
XORBSU 01010 - - - - Exclusive Or Bit String Upward dest = dest XOR src
XORNBSU 01110 - - - - Exclusive Or Not Bit String Upward dest = dest XOR (NOT src)

All of these instructions will clear the 2 lowest-order bits in r26 and r27, and clear the 26 highest-order bits in r29 and r30.

Editor's Note: The V810 manual provides a table of cycle timings for various configurations of these operations that needs to be transcribed into this document.

Editor's Note: Research is needed to determine the behavior of these operations under various overlapping conditions.

Editor's Note: Research is needed to determine the behavior of these operations when aborted by interrupts.

Editor's Note: Research is needed to determine the load/store behavior of these operations and its impact on execution time.


Search

Mnemonic Sub-opcode Z S OV CY Name Operation
SCH0BSD 00001 - - - Search Bit 0 Downward Search downward for 0
SCH0BSU 00000 - - - Search Bit 0 Upward Search upward for 0
SCH1BSD 00011 - - - Search Bit 1 Downward Search downward for 1
SCH1BSU 00010 - - - Search Bit 1 Upward Search upward for 1

These operations scan through the source bit string in the specified direction for a bit with the specified state.

r29 is incremented for each bit skipped during a search.

The zero flag (Z) is set if the specified bit was could not be found in the source bit string, or cleared otherwise.

Editor's Note: The V810 manual provides a table of cycle timings for various configurations of these operations that needs to be transcribed into this document.

Editor's Note: Research is needed regarding what happens to r29 when these instructions are executed.

Editor's Note: Research is needed to determine the behavior of these operations when aborted by interrupts.

Editor's Note: Research is needed to determine the load behavior of these operations and its impact on execution time.


Miscellaneous

CAXI - Compare and Exchange Interlocked

Mnemonic Opcode Format Z S OV CY Cycles Name Operation
CAXI 111010 VI 26 Compare and Exchange Interlocked See below.

This instruction facilitates synchronization between multiple processors. It has four operands:

reg1 Base address of lock word.
disp Lock word address displacement offset.
reg2 Compare value.
r30 Exchange value.

When executing this instruction, the following algorithm is carried out:

The bus is locked, causing other CPUs to block.
A value is loaded, as though with LD.W, from reg1 + disp.
A comparison is performed, as though with CMP, using reg2 - value.
If the result is equal (Z = 1):
A store is performed, as though with ST.W, storing r30 into address.
Otherwise:
A store is performed, as though with ST.W, storing value back into address.
value is stored into reg2.
The lock on the bus is released.

The program can check the zero flag (Z) to determine what action was taken.

Virtual Boy only has one processor.


SETF - Set Flag Condition

Mnemonic Opcode Format Z S OV CY Cycles Name Operation
SETF 010010 II - - - - 1 Set Flag Condition if cond then reg2 = 1 else reg2 = 0

Tests a condition in PSW. If the condition is true, stores 0x00000001 into reg2; otherwise, stores 0x00000000 into reg2.

The purpose of SETF is to provide a means for evaluating simple conditional operations without performing a branch via Bcond. Branching disrupts the pipeline flow and takes more cycles than the corresponding SETF implementaitons for such operations. Examples of operations that benefit from SETF include absolute value and sign.

The following conditions can be checked:

Value Mnemonic Condition Test Note
0 V Overflow if OV = 1
1 C, L Carry, Lower if CY = 1 < unsigned
2 E, Z Equal, Zero if Z = 1
3 NH Not higher if (CY OR Z) = 1 ≤ unsigned
4 N Negative if S = 1
5 T Always if true Always true
6 LT Less than if (OV XOR S) = 1 < signed
7 LE Less than or equal if ((OV XOR S) OR Z) = 1 ≤ signed
8 NV Not overflow if OV = 0
9 NC, NL Not carry, Not lower if CY = 0 ≥ unsigned
10 NE, NZ Not equal, Not zero if Z = 0
11 H Higher if (CY OR Z) = 0 > unsigned
12 P Positive if S = 0
13 F Not always if false Always false
14 GE Greater than or equal if (OV XOR S) = 0 > signed
15 GT Greater than if ((OV XOR S) OR Z) = 0 ≥ signed

Certain conditions have more than one mnemonic. In these situations, either mnemonic can be used and the two are interchangeable.

The cond field uses the same numeric values for each condition as the Bcond instruction.


Nintendo

Standalone

These instructions have unique opcodes.

Mnemonic Opcode Format Z S OV CY Cycles Name Operation
CLI 010110 II - - - - 12 Clear Interrupt Disable Flag ID = 0
SEI 011110 II - - - - 12 Set Interrupt Disable Flag ID = 1

Editor's Note: These instructions were borrowed from the 6502/65C816 instruction set used by the NES and SNES. When NEC developed the V830 in 1997, they introduced the EI and DI instructions (Enable Maskable Interrupt and Disable Maskable Interrupt, respectively), which use the same opcodes and execute the same operations as NVC's CLI and SEI instructions. However, EI and DI only take 2 cycles to complete.

Extended

These instructions are stored in Format VII and share a common opcode of 111110. They are identified by their sub-opcode field.

Mnemonic Sub-Opcode Z S OV CY Cycles Name Operation
MPHYW 001100 - - - - 9 Multiply Halfword reg2 = reg2 * (reg1 << 15 >> 15 (sign-propagating))
REV 001010 - - - - 22 Reverse Bits in Word reg2 = ReverseBits(reg1)
XB 001000 - - - - 6 Exchange Byte reg2 = (reg2 AND 0xFFFF0000) OR ((reg2 << 8) AND 0xFF00) OR ((reg2 >> 8) AND 0x00FF)
XH 001001 - - - - 1 Exchange Halfword reg2 = (reg2 >> 16 (zero-filling)) OR (reg2 << 16)

The MPYHW instruction performs a 32-bit signed multiplication. The right-hand operand is produced by sign-extending the lower 17 bits of reg1.

The REV instruction reverses the order of the bits in reg2: the highest-order bit of the input becomes the lowest-order bit of the output and so-on.


Assembly Notation

The following conventions, except as described below, apply to all instructions in the official V810 assembly notation:

When multiple operands are present, the destination is on the right.
When three operands are present, the immediate value is on the left.
The target address of read and writes is the displacement offset followed by the base address register in [square brackets]. If the displacement offset is zero, it may be omitted.
The target address of jumps and branches is the absolute address, not the relative displacement.

The above conventions do not apply to the following instructions:

Bcond Multiple notations:
For any condition other than NOP, written as a one-operand instruction using the condition's mnemonic.
NOP is written as a zero-operand instruction.
JMP Although the operation does not perform an indirection, the operand is enclosed in [square brackets].
LDSRSTSR May use the symbolic name of the system register instead of its numeric index.
SETF Multiple notations: [note]
V810 Written as a two-operand instruction, the first being either the condition's mnemonic or numeric code.
IAR Written as a one-operand instruction, where the mnemonic is the concatenation of "SETF" followed by the conditon's mnemonic.

[note] The "V810" notation is used by official NEC V810 documents, the GNU assembler, Nintendo's own Virtual Boy development tools, and NEC/Renesas-produced development tools. In the final draft of the V810 specification, this was the notation that was intended to be used.
The "IAR" notation has been known to be used by NEC in V810 presentations during development, the IAR Systems V850 assembler, and Hudson Soft's development tools for PC-FX.

The notation for each instruction is as follows:

Mnemonic Name Notation
ADD Add Immediate ADD imm, reg2
ADD Add Register ADD reg1, reg2
ADDF.S Add Floating Short ADDF.S reg1, reg2
ADDI Add Immediate ADDI imm, reg1, reg2
AND And AND reg1, reg2
ANDBSU And Bit String Upward ANDBSU
ANDI And Immediate ANDI imm, reg1, reg2
ANDNBSU And Not Bit String Upward ANDNBSU
Bcond Branch on Condition BNZ address
NOP
CAXI Compare and Exchange Interlocked CAXI disp[reg1], reg2
CLI Clear Interrupt Disable Flag CLI
CMP Compare Immediate CMP imm, reg2
CMP Compare Register CMP reg1, reg2
CMPF.S Compare Floating Short CMPF.S reg1, reg2
CVT.SW Convert Short Floating to Word Integer CVT.SW reg1, reg2
CVT.WS Convert Word Integer to Short Floating CVT.WS reg1, reg2
DIV Divide DIV reg1, reg2
DIVF.S Divide Floating Short DIVF.S reg1, reg2
DIVU Divide Unsigned DIVU reg1, reg2
HALT Halt HALT
IN.B Input Byte from Port IN.B disp[reg1], reg2
IN.H Input Halfword from Port IN.H disp[reg1], reg2
IN.W Input Word from Port IN.W disp[reg1], reg2
JAL Jump and Link JAL address
JMP Jump Register JMP [reg1]
JR Jump Relative JR address
LD.B Load Byte LD.B disp[reg1], reg2
LD.H Load Halfword LD.H disp[reg1], reg2
LD.W Load Word LD.W disp[reg1], reg2
LDSR Load to System Register LDSR reg2, regID
MOV Move Immediate MOV imm, reg2
MOV Move Register MOV reg1, reg2
MOVBSU Move Bit String Upward MOVBSU
MOVEA Add MOVEA imm, reg1, reg2
MOVHI Add MOVHI imm, reg1, reg2
MPYHW Multiply Halfword MPYHW reg1, reg2
MUL Multiply MUL reg1, reg2
MULF.S Multiply Floating Short MULF.S reg1, reg2
MULU Multiply Unsigned MULU reg1, reg2
NOT Not NOT reg1, reg2
NOTBSU Not Bit String Upward NOTBSU
OR Or OR reg1, reg2
ORBSU Or Bit String Upward ORBSU
ORI Or Immediate ORI imm, reg1, reg2
ORNBSU Or Not Bit String Upward ORNBSU
OUT.B Output Byte to Port OUT.B reg2, disp[reg1]
OUT.H Output Halfword to Port OUT.H reg2, disp[reg1]
OUT.W Output Word to Port OUT.W reg2, disp[reg1]
RETI Return from Trap or Interrupt RETI
REV Reverse Bits in Word REV reg1, reg2
SAR Shift Arithmetic Right by Immediate SAR imm, reg2
SAR Shift Arithmetic Right by Register SAR reg1, reg2
SCH0BSD Search Bit 0 Downward SCH0BSD
SCH0BSU Search Bit 0 Upward SCH0BSU
SCH1BSD Search Bit 1 Downward SCH1BSD
SCH1BSU Search Bit 1 Upward SCH1BSU
SEI Set Interrupt Disable Flag SEI
SETF Set Flag Condition SETF cond, reg2
SETFNZ reg2
SHL Shift Logical Left by Immediate SHL imm, reg2
SHL Shift Logical Left by Register SHL reg1, reg2
SHR Shift Logical Right by Immediate SHR imm, reg2
SHR Shift Logical Right by Register SHR reg1, reg2
ST.B Store Byte ST.B reg2, disp[reg1]
ST.H Store Halfword ST.H reg2, disp[reg1]
ST.W Store Word ST.W reg2, disp[reg1]
STSR Store Contents of System Register STSR regID, reg2
SUB Subtract SUB reg1, reg2
SUBF.S Subtract Floating Short SUBF.S reg1, reg2
TRAP Trap TRAP vector
TRNC.SW Truncate Short Floating to Word Integer TRNC.SW reg1, reg2
XB Exchange Byte XB reg2
XH Exchange Halfword XH reg2
XOR Exclusive Or XOR reg1, reg2
XORBSU Exclusive Or Bit String Upward XORBSU
XORI Exclusive Or Immediate XORI imm, reg1, reg2
XORNBSU Exclusive Or Not Bit String Upward XORNBSU


List of Instructions by Mnemonic

Opcode Format Mnemonic Name Operation
010001 II ADD Add Immediate reg2 = reg2 + (sign extend) imm
000001 I ADD Add Register reg2 = reg2 + reg1
101001 V ADDI Add Immediate reg2 = reg1 + (sign extend) imm
001101 I AND And reg2 = reg2 AND reg1
101101 V ANDI And Immediate reg2 = reg1 AND (zero extend) imm
100    III Bcond Branch on Condition if cond = true then PC = PC + disp
111010 VI CAXI Compare and Exchange Interlocked See instruction section.
010110 II CLI Clear Interrupt Disable Flag ID = 0
010011 II CMP Compare Immediate (discard) = reg2 - (sign extend) imm
000011 I CMP Compare Register (discard) = reg2 - reg1
001001 I DIV Divide r30 = reg2 MOD reg1, reg2 = reg2 / reg1
001011 I DIVU Divide Unsigned r30 = reg2 MOD reg1, reg2 = reg2 / reg1
011010 II HALT Halt Wait for interrupt
111000 VI IN.B Input Byte from Port reg2 = (zero extend) (byte ptr) [reg1 + disp]
111001 VI IN.H Input Halfword from Port reg2 = (zero extend) (halfword ptr) [reg1 + disp]
111011 VI IN.W Input Word from Port reg2 = (word ptr) [reg1 + disp]
101011 IV JAL Jump and Link r31 = PC + 4, PC = PC + disp
000110 I JMP Jump Register PC = reg1
101010 IV JR Jump Relative PC = PC + disp
110000 VI LD.B Load Byte reg2 = (sign extend) (byte ptr) [reg1 + disp]
110001 VI LD.H Load Halfword reg2 = (sign extend) (halfword ptr) [reg1 + disp]
110011 VI LD.W Load Word reg2 = (word ptr) [reg1 + disp]
011100 II LDSR Load to System Register SystemRegister[regID] = reg2
010000 II MOV Move Immediate reg2 = (sign extend) imm
000000 I MOV Move Register reg2 = reg1
101000 V MOVEA Add reg2 = reg1 + (sign extend) imm
101111 V MOVHI Add reg2 = reg1 + (imm << 16)
001000 I MUL Multiply (result) = reg2 * reg1, r30 = (result) >> 32, reg2 = (result)
001010 I MULU Multiply Unsigned (result) = reg2 * reg1, r30 = (result) >> 32, reg2 = (result)
001111 I NOT Not reg2 = NOT reg1
001100 I OR Or reg2 = reg2 OR reg1
101100 V ORI Or Immediate reg2 = reg1 OR (zero extend) imm
111100 VI OUT.B Output Byte to Port (byte ptr) [reg1 + disp] = reg2 AND 0xFF
111101 VI OUT.H Output Halfword to Port (halfword ptr) [reg1 + disp] = reg2 AND 0xFFFF
111111 VI OUT.W Output Word to Port (word ptr) [reg1 + disp] = reg2
011001 II RETI Return from Trap or Interrupt if NP then PC = FEPC, PSW = FEPSW else PC = EIPC, PSW = EIPSW
010111 II SAR Shift Arithmetic Right by Immediate reg2 = reg2 >> (zero extend) imm (sign-propagating)
000111 I SAR Shift Arithmetic Right by Register reg2 = reg2 >> (reg1 AND 0x1F) (sign-propagating)
011110 II SEI Set Interrupt Disable Flag ID = 1
010010 II SETF Set Flag Condition if cond then reg2 = 1 else reg2 = 0
010100 II SHL Shift Logical Left by Immediate reg2 = reg2 << (zero extend) imm
000100 I SHL Shift Logical Left by Register reg2 = reg2 << (reg1 AND 0x1F)
010101 II SHR Shift Logical Right by Immediate reg2 = reg2 >> (zero extend) imm (zero-filling)
000101 I SHR Shift Logical Right by Register reg2 = reg2 >> (reg1 AND 0x1F) (zero-filling)
110100 VI ST.B Store Byte (byte ptr) [reg1 + disp] = reg2 AND 0xFF
110101 VI ST.H Store Halfword (halfword ptr) [reg1 + disp] = reg2 AND 0xFFFF
110111 VI ST.W Store Word (word ptr) [reg1 + disp] = reg2
011101 II STSR Store Contents of System Register reg2 = SystemRegister[regID]
000010 I SUB Subtract reg2 = reg2 - reg1
011000 II TRAP Trap Raise exception (0xFFA0 + vector)
001110 I XOR Exclusive Or reg2 = reg2 XOR reg1
101110 V XORI Exclusive Or Immediate reg2 = reg1 XOR (zero extend) imm

Bit string instructions are stored in Format II and share a common opcode of 011111. They are identified by their sub-opcode field.

Sub-Opcode Mnemonic Name Operation
01001 ANDBSU And Bit String Upward dest = dest AND src
01101 ANDNBSU And Not Bit String Upward dest = dest AND (NOT src)
01011 MOVBSU Move Bit String Upward dest = src
01111 NOTBSU NOT Bit String Upward dest = NOT src
01000 ORBSU Or Bit String Upward dest = dest OR src
01100 ORNBSU Or Not Bit String Upward dest = dest OR (NOT src)
00001 SCH0BSD Search Bit 0 Downward Search downward for 0
00000 SCH0BSU Search Bit 0 Upward Search upward for 0
00011 SCH1BSD Search Bit 1 Downward Search downward for 1
00010 SCH1BSU Search Bit 1 Upward Search upward for 1
01010 XORBSU Exclusive Or Bit String Upward dest = dest XOR src
01110 XORNBSU Exclusive Or Not Bit String Upward dest = dest XOR (NOT src)

Floating-point and Nintendo instructions are stored in Format VII and share a common opcode of 111110. They are identified by their sub-opcode field.

Sub-Opcode Mnemonic Name Operation
000100 ADDF.S Add Floating Short reg2 = reg2 + reg1
000000 CMPF.S Compare Floating Short (discard) = reg2 - reg1
000011 CVT.SW Convert Short Floating to Word Integer reg2 = (word) round(reg1)
000010 CVT.WS Convert Word Integer to Short Floating reg2 = (float) reg1
000111 DIVF.S Divide Floating Short reg2 = reg2 / reg1
001100 MPHYW Multiply Halfword reg2 = reg2 * (reg1 << 15 >> 15 (sign-propagating))
000110 MULF.S Multiply Floating Short reg2 = reg2 * reg1
001010 REV Reverse Bits in Word reg2 = ReverseBits(reg1)
000101 SUBF.S Subtract Floating Short reg2 = reg2 - reg1
001011 TRNC.SW Truncate Short Floating to Word Integer reg2 = (word) truncate(reg1)
001000 XB Exchange Byte reg2 = (reg2 AND 0xFFFF0000) OR ((reg2 << 8) AND 0xFF00) OR ((reg2 >> 8) AND 0x00FF)
001001 XH Exchange Halfword reg2 = (reg2 >> 16 (zero-filling)) OR (reg2 << 16)


List of Instructions by Opcode

Attempting to execute any invalid opcode or sub-opcode will raise an exception with code 0xFF90 and a restore PC of current PC, the address of the offending instruction.

Opcode Format Mnemonic Name Operation
000000 I MOV Move Register reg2 = reg1
000001 I ADD Add Register reg2 = reg2 + reg1
000010 I SUB Subtract reg2 = reg2 - reg1
000011 I CMP Compare Register (discard) = reg2 - reg1
000100 I SHL Shift Logical Left by Register reg2 = reg2 << (reg1 AND 0x1F)
000101 I SHR Shift Logical Right by Register reg2 = reg2 >> (reg1 AND 0x1F) (zero-filling)
000110 I JMP Jump Register PC = reg1
000111 I SAR Shift Arithmetic Right by Register reg2 = reg2 >> (reg1 AND 0x1F) (sign-propagating)
001000 I MUL Multiply (result) = reg2 * reg1, r30 = (result) >> 32, reg2 = (result)
001001 I DIV Divide r30 = reg2 MOD reg1, reg2 = reg2 / reg1
001010 I MULU Multiply Unsigned (result) = reg2 * reg1, r30 = (result) >> 32, reg2 = (result)
001011 I DIVU Divide Unsigned r30 = reg2 MOD reg1, reg2 = reg2 / reg1
001100 I OR Or reg2 = reg2 OR reg1
001101 I AND And reg2 = reg2 AND reg1
001110 I XOR Exclusive Or reg2 = reg2 XOR reg1
001111 I NOT Not reg2 = NOT reg1
010000 II MOV Move Immediate reg2 = (sign extend) imm
010001 II ADD Add Immediate reg2 = reg2 + (sign extend) imm
010010 II SETF Set Flag Condition if cond then reg2 = 1 else reg2 = 0
010011 II CMP Compare Immediate (discard) = reg2 - (sign extend) imm
010100 II SHL Shift Logical Left by Immediate reg2 = reg2 << (zero extend) imm
010101 II SHR Shift Logical Right by Immediate reg2 = reg2 >> (zero extend) imm (zero-filling)
010110 II CLI Clear Interrupt Disable Flag ID = 0
010111 II SAR Shift Arithmetic Right by Immediate reg2 = reg2 >> (zero extend) imm (sign-propagating)
011000 II TRAP Trap Raise exception (0xFFA0 + vector)
011001 II RETI Return from Trap or Interrupt if NP then PC = FEPC, PSW = FEPSW else PC = EIPC, PSW = EIPSW
011010 II HALT Halt Wait for interrupt
011011 - Invalid
011100 II LDSR Load to System Register SystemRegister[regID] = reg2
011101 II STSR Store Contents of System Register reg2 = SystemRegister[regID]
011110 II SEI Set Interrupt Disable Flag ID = 1
011111 II * Bit string: see below
100    III Bcond Branch on Condition if cond = true then PC = PC + disp
101000 V MOVEA Add reg2 = reg1 + (sign extend) imm
101001 V ADDI Add Immediate reg2 = reg1 + (sign extend) imm
101010 IV JR Jump Relative PC = PC + disp
101011 IV JAL Jump and Link r31 = PC + 4, PC = PC + disp
101100 V ORI Or Immediate reg2 = reg1 OR (zero extend) imm
101101 V ANDI And Immediate reg2 = reg1 AND (zero extend) imm
101110 V XORI Exclusive Or Immediate reg2 = reg1 XOR (zero extend) imm
101111 V MOVHI Add reg2 = reg1 + (imm << 16)
110000 VI LD.B Load Byte reg2 = (sign extend) (byte ptr) [reg1 + disp]
110001 VI LD.H Load Halfword reg2 = (sign extend) (halfword ptr) [reg1 + disp]
110010 - Invalid
110011 VI LD.W Load Word reg2 = (word ptr) [reg1 + disp]
110100 VI ST.B Store Byte (byte ptr) [reg1 + disp] = reg2 AND 0xFF
110101 VI ST.H Store Halfword (halfword ptr) [reg1 + disp] = reg2 AND 0xFFFF
110110 - Invalid
110111 VI ST.W Store Word (word ptr) [reg1 + disp] = reg2
111000 VI IN.B Input Byte from Port reg2 = (zero extend) (byte ptr) [reg1 + disp]
111001 VI IN.H Input Halfword from Port reg2 = (zero extend) (halfword ptr) [reg1 + disp]
111010 VI CAXI Compare and Exchange Interlocked See instruction section.
111011 VI IN.W Input Word from Port reg2 = (word ptr) [reg1 + disp]
111100 VI OUT.B Output Byte to Port (byte ptr) [reg1 + disp] = reg2 AND 0xFF
111101 VI OUT.H Output Halfword to Port (halfword ptr) [reg1 + disp] = reg2 AND 0xFFFF
111110 VII * Floating-point and Nintendo: see below
111111 VI OUT.W Output Word to Port (word ptr) [reg1 + disp] = reg2

Bit string instructions are stored in Format II and share a common opcode of 011111. They are identified by their sub-opcode field.

Sub-Opcode Mnemonic Name Operation
00000 SCH0BSU Search Bit 0 Upward Search upward for 0
00001 SCH0BSD Search Bit 0 Downward Search downward for 0
00010 SCH1BSU Search Bit 1 Upward Search upward for 1
00011 SCH1BSD Search Bit 1 Downward Search downward for 1
... Invalid
01000 ORBSU Or Bit String Upward dest = dest OR src
01001 ANDBSU And Bit String Upward dest = dest AND src
01010 XORBSU Exclusive Or Bit String Upward dest = dest XOR src
01011 MOVBSU Move Bit String Upward dest = src
01100 ORNBSU Or Not Bit String Upward dest = dest OR (NOT src)
01101 ANDNBSU And Not Bit String Upward dest = dest AND (NOT src)
01110 XORNBSU Exclusive Or Not Bit String Upward dest = dest XOR (NOT src)
01111 NOTBSU NOT Bit String Upward dest = NOT src
... Invalid

Floating-point and Nintendo instructions are stored in Format VII and share a common opcode of 111110. They are identified by their sub-opcode field.

Sub-Opcode Mnemonic Name Operation
000000 CMPF.S Compare Floating Short (discard) = reg2 - reg1
000001 Invalid
000010 CVT.WS Convert Word Integer to Short Floating reg2 = (float) reg1
000011 CVT.SW Convert Short Floating to Word Integer reg2 = (word) round(reg1)
000100 ADDF.S Add Floating Short reg2 = reg2 + reg1
000101 SUBF.S Subtract Floating Short reg2 = reg2 - reg1
000110 MULF.S Multiply Floating Short reg2 = reg2 * reg1
000111 DIVF.S Divide Floating Short reg2 = reg2 / reg1
001000 XB Exchange Byte reg2 = (reg2 AND 0xFFFF0000) OR ((reg2 << 8) AND 0xFF00) OR ((reg2 >> 8) AND 0x00FF)
001001 XH Exchange Halfword reg2 = (reg2 >> 16 (zero-filling)) OR (reg2 << 16)
001010 REV Reverse Bits in Word reg2 = ReverseBits(reg1)
001011 TRNC.SW Truncate Short Floating to Word Integer reg2 = (word) truncate(reg1)
001100 MPHYW Multiply Halfword reg2 = reg2 * (reg1 << 15 >> 15 (sign-propagating))
... Invalid


System Reset

This section describes the initial state of system components on reset.

CPU

The following system registers are initialized on reset:

ECR 0x0000FFF0
PC 0xFFFFFFF0
PSW 0x00008000 [note]

[note] The only bit set in PSW on reset is the NP flag.

All other system registers and all program registers except r0 are undefined on reset.

VIP

The contents of VIP memory is undefined on reset.

The following fields in I/O registers are initialized on reset:

DPSTTS
SYNCE= 0
RE= 0
DISP= 0
INTENB All fields zero
XPSTTS XPEN = 0

All other registers (including INTPND) and other fields within the above registers are undefined on reset.

WRAM

The contents of WRAM is undefined on reset.


About

Virtual Boy - Sacred Tech Scroll
    Version 1.0 (WIP draft) - June 9, 2018
    Written by Guy Perfect

Produced for Planet Virtual Boy.
    http://planetvb.com

Presentation and formatting inspired by the Nocash technical documents by Martin Korth.
    http://problemkaputt.de/

Special thanks to the following individuals: Benjamin Stevens, bigmak, dasi, DogP, Gookanheimer, HorvatM, jwestfall, KR155E, MineStorm, optiroc, Yeti_dude.

A huge shout-out to all financial backers.


References

V810 Family™ 32-bit Microprocessor User's Manual
    October 1995
    Document No. U10082EJ1V0UM00 (1st edition)
    Written by NEC Electronics Corporation, now credited to Renesas Technology Corporation.
    Download

IAR Assembler Reference Guide for V850
    October 2010
    Document No. AV850-4 (fourth edition)
    Written by IAR Systems.
    Download

V830 Family™ 32-bit Microprocessor User's Manual
    December 1997
    Document No. U12496EJ2V0UM00 (2nd edition)
    Written by NEC Electronics Corporation, now credited to Renesas Technology Corporation.
    Download

Unraveling The Enigma Of Nintendo's Virtual Boy, 20 Years Later
    August 21, 2015
    Article detailing the history of the Virtual Boy's development.
    Written by Benj Edwards.
    Link

And countless hours of original research.


June 9, 2018