Introduction
The NEC V810 is a 32-bit RISC microprocessor (the first of NEC’s V800 family, from 1992 to 1993). Nintendo used a modified version, called the NVC,
in the Virtual Boy at 20 MHz. It has 32 general registers (r0 is always zero), a handful of system registers, little-endian memory
and a 32-bit address space of which the Virtual Boy uses the low 27 bits. Instructions are 16 or 32 bits long and always start at an even address; they come in seven formats
(register, immediate, branch, long jump, 16-bit immediate, load/store, extended). There is a bit-string group and a single-precision floating-point group.
The explorer’s disassembler is explorer/cpu/v810/ (our own code). It is used by the Virtual Boy ROM viewer and decodes an instruction at
every even offset of a region, laying the results in columns the way it does for the other fixed-width CPUs. Options: the case of the mnemonics, register names
(r1 or hp), the carry/zero branch names (BL BE or BC BZ) and pseudo-instructions (RET, NOP, MOV imm,reg).
The pages
- Registers: r0 to r31 and their conventional names, the system registers, the PSW and its flags, the condition codes.
- Instruction formats: formats I to VII with their bit layouts, and how the length and the targets are worked out.
- Instructions: the integer, load/store, branch and system instructions in groups.
- Bit-string instructions: the twelve instructions of opcode
0x1F. - Floating-point and extended instructions: opcode
0x3Eand its twelve sub-opcodes. - Opcode map: the 64-entry map and the sub-opcode tables.
- Status: documented, reserved and undefined encodings, what the checks found, and what is not described.
How an instruction is built
The first halfword (two bytes, low byte first) holds a 6-bit opcode in bits 15 to 10. If bits 15 to 13 are 101 or 11x (opcodes 0x28 to 0x3F)
a second halfword follows; otherwise the instruction is 16 bits. The remaining ten bits are reg2 (bits 9 to 5) and reg1 (bits 4 to 0), or a 5-bit immediate,
or, for a branch, a 4-bit condition and a 9-bit displacement.
Example, from the demo ROM of the emulators.org Virtual Boy page: FF AB 10 FC at 0xFFFFFFF0 is the halfword 0xABFF (opcode 0x2A, JR) and the halfword
0xFC10; the 26-bit displacement is 0x3FFFC10, which is -0x3F0, so the jump goes to 0xFFFFFC00.
Statuses in the viewer
- documented: an encoding the sources we read define.
- reserved: the bytes decode but a field has no defined meaning: a system register number that no source names, a SETF condition above 15.
- illegal: an undefined encoding (opcodes
0x1B,0x32,0x36, and the undefined bit-string and extended sub-opcodes). The CPU takes the invalid-opcode exception (vector0xFFFFFF90); the viewer shows one.HALFand decodes the next halfword on its own.
See Status for the counts.
How this was checked
- Two written tables. The instruction list in the NEC manual’s form (mnemonic, 6-bit opcode, format, operands, flags) and a second table in the shape of binutils’ opcode table (first-halfword value and mask) were written separately from the decoder and compared with it for all 65,536 first halfwords and every second-halfword context: 247,808 pairs, 1,465,856 checks, 0 failures. Same author as the decoder: it catches slips, not misreadings.
- The site’s own V810 disassembler (
emulators.org/debugger/src/cpus/v810.js) agrees on all 271,360 pairs except where it prints.wordfor an undefined opcode, names two SETF conditions differently, prints two operands forXB/XH, and does not clear bit 0 of an odd displacement (all counted on the status page). - An executing core. The site’s Virtual Boy core (
vb-core.js, integer instructions only) was run for 313,206 instructions from random states: the program counter advance and branch targets, the registers and flags it changes, the memory it writes, and that a register or flag we say is not read does not matter: 3,476,945 checks, 0 failures. - The demo ROM. The 1 KiB program that page runs decodes, instruction by instruction, to what its assembler source says: 89 checks.
- No V810 assembler, binutils, Mednafen or second core was found on this machine, and the NEC manual and the Sacred Tech Scroll could not be read here: the encodings rest on the summaries of the Mednafen core’s source that were read, on memory of the manual, and on those two checks. Clock counts are not given.
Links
- Planet Virtual Boy – the community site that hosts the V810 documents (the NEC V810 Family User’s Manual and the Virtual Boy Sacred Tech Scroll by Guy Perfect); named, not read in full here
- Beetle PC-FX (
mednafen/hw_cpu/v810) – the Mednafen V810 core, read through summaries for the opcode numbers and semantics - Binutils opcode table mistakes – a forum thread on the V810 opcode table of binutils, used for the floating-point encodings
Not described
See the list on the status page: no clock counts, the manual itself could not be read, the exact registers of the bit-string instructions and the floating-point flag details rest on memory.