mirror of
https://github.com/Dillonb/n64.git
synced 2025-04-02 10:42:08 -04:00
308 lines
16 KiB
ReStructuredText
308 lines
16 KiB
ReStructuredText
CPU (detailed)
|
|
==============
|
|
|
|
|
|
Registers
|
|
---------
|
|
|
|
As noted in the CPU overview, r0 is **hardwired to a value of zero**, and all registers are 64 bits.
|
|
|
|
+-----------------+---------------+
|
|
| Register Number | Register Name |
|
|
+=================+===============+
|
|
| 0 | zero |
|
|
+-----------------+---------------+
|
|
| 1 | at |
|
|
+-----------------+---------------+
|
|
| 2 | v0 |
|
|
+-----------------+---------------+
|
|
| 3 | v1 |
|
|
+-----------------+---------------+
|
|
| 4 | a0 |
|
|
+-----------------+---------------+
|
|
| 5 | a1 |
|
|
+-----------------+---------------+
|
|
| 6 | a2 |
|
|
+-----------------+---------------+
|
|
| 7 | a3 |
|
|
+-----------------+---------------+
|
|
| 8 | t0 |
|
|
+-----------------+---------------+
|
|
| 9 | t1 |
|
|
+-----------------+---------------+
|
|
| 10 | t2 |
|
|
+-----------------+---------------+
|
|
| 11 | t3 |
|
|
+-----------------+---------------+
|
|
| 12 | t4 |
|
|
+-----------------+---------------+
|
|
| 13 | t5 |
|
|
+-----------------+---------------+
|
|
| 14 | t6 |
|
|
+-----------------+---------------+
|
|
| 15 | t7 |
|
|
+-----------------+---------------+
|
|
| 16 | s0 |
|
|
+-----------------+---------------+
|
|
| 17 | s1 |
|
|
+-----------------+---------------+
|
|
| 18 | s2 |
|
|
+-----------------+---------------+
|
|
| 19 | s3 |
|
|
+-----------------+---------------+
|
|
| 20 | s4 |
|
|
+-----------------+---------------+
|
|
| 21 | s5 |
|
|
+-----------------+---------------+
|
|
| 22 | s6 |
|
|
+-----------------+---------------+
|
|
| 23 | s7 |
|
|
+-----------------+---------------+
|
|
| 24 | t8 |
|
|
+-----------------+---------------+
|
|
| 25 | t9 |
|
|
+-----------------+---------------+
|
|
| 26 | k0 |
|
|
+-----------------+---------------+
|
|
| 27 | k1 |
|
|
+-----------------+---------------+
|
|
| 28 | gp |
|
|
+-----------------+---------------+
|
|
| 29 | sp |
|
|
+-----------------+---------------+
|
|
| 30 | s8 |
|
|
+-----------------+---------------+
|
|
| 31 | ra |
|
|
+-----------------+---------------+
|
|
|
|
While these all have special names, for the purposes of emulation they all operate identically (except for r0 and r31)
|
|
|
|
As I've mentioned many times by now, r0 is hardwired to 0, and r31, or $ra, is used by the "branch/jump and link" instructions to hold the return address.
|
|
|
|
The various other names are useful for assembly programmers who need to know what registers are conventionally used for what purposes.
|
|
|
|
COP0 Registers
|
|
-------------
|
|
|
|
+-----------------+---------------+----------------------------------+
|
|
| Register Number | Register Name | Size |
|
|
+=================+===============+==================================+
|
|
| 0 | Index | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 1 | Random | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 2 | EntryLo0 | 32 or 64 bits, depending on mode |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 3 | EntryLo1 | 32 or 64 bits, depending on mode |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 4 | Context | 32 or 64 bits, depending on mode |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 5 | PageMask | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 6 | Wired | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 7 | 7 | ?? |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 8 | BadVAddr | 32 or 64 bits, depending on mode |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 9 | Count | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 10 | EntryHi | 32 or 64 bits, depending on mode |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 11 | Compare | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 12 | Status | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 13 | Cause | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 14 | EPC | 32 or 64 bits, depending on mode |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 15 | PRId | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 16 | Config | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 17 | LLAddr | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 18 | WatchLo | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 19 | WatchHi | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 20 | XContext | 64 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 21 | 21 | ?? |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 22 | 22 | ?? |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 23 | 23 | ?? |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 24 | 24 | ?? |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 25 | 25 | ?? |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 26 | Parity Error | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 27 | Cache Error | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 28 | TagLo | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 29 | TagHi | 32 bits |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 30 | ErrorEPC | 32 or 64 bits, depending on mode |
|
|
+-----------------+---------------+----------------------------------+
|
|
| 31 | 31 | ?? |
|
|
+-----------------+---------------+----------------------------------+
|
|
|
|
COP0 TLB Registers
|
|
^^^^^^^^^^^^^^^^^
|
|
|
|
These registers are used to query and control the TLB. Please see the TLB section for more information.
|
|
|
|
* Index
|
|
* EntryLo0
|
|
* EntryLo1
|
|
* EntryHi
|
|
* PageMask
|
|
* Context
|
|
|
|
COP0 Random Number Registers
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
These registers are used to generate random values.
|
|
|
|
The Random register is read-only. The high 26 bits are unused, leaving the low 6 bits to represent a random value. This value can be read and used by software, but is mainly meant to be used by the TLBWR (TLB Write Random) instruction.
|
|
|
|
On a real CPU, the value is decremented every instruction. When the value of Random is <= the value of Wired, it is reset to 0x1F (31)
|
|
|
|
It should be fine for emulation purposes to generate a random value in the range of Wired <= Value <= 31 every time Random is read, as checking and decrementing Random every single instruction will be expensive.
|
|
|
|
* Random
|
|
|
|
Holds a random value between the value of Wired and 0x1F (31)
|
|
|
|
* Wired
|
|
|
|
Provides the lower bound for the random value held in Random.
|
|
|
|
COP0 Timing Registers
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
Since the N64 has no timers, these registers are the only way the system can tell how much time has passed.
|
|
|
|
* Count
|
|
|
|
This value is incremented every other cycle, and compared to the value in Compare. As noted below, fire an interrupt when Count == Compare.
|
|
|
|
The easiest way to emulate this would be to store count as a 64 bit integer, increment it once per cycle, and shift it to the right by one when read or compared.
|
|
|
|
* Compare
|
|
|
|
Fire an interrupt when Count equals this value. This interrupt sets the ip7 bit in Cause to 1.
|
|
|
|
Writes to this register clear said interrupt, and sets the ip7 bit in Cause to 0.
|
|
|
|
COP0 Cache Registers
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
These registers are used for the cache, which is not documented here yet.
|
|
|
|
* TagLo
|
|
* TagHi
|
|
|
|
COP0 Exception/Interrupt Registers
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
These registers are used for exceptions and interrupts.
|
|
|
|
* BadVAddr
|
|
When a TLB exception is thrown, this register is automatically loaded with the address of the failed translation.
|
|
|
|
* Cause
|
|
Contains details on the exception or interrupt that occurred. Only the low two bits of the Interrupt Pending field can be written to using MTC0, the rest are read-only and set by hardware when an exception is thrown. More information can be found in the interrupts section.
|
|
|
|
+-------+------------------------------------------------------------------------------------------------------+
|
|
| Bit | Description |
|
|
+-------+------------------------------------------------------------------------------------------------------+
|
|
| 0-1 | Unused (always zero) |
|
|
+-------+------------------------------------------------------------------------------------------------------+
|
|
| 2-6 | Exception code (which exception/interrupt occurred?) |
|
|
+-------+------------------------------------------------------------------------------------------------------+
|
|
| 7 | Unused (always zero) |
|
|
+-------+------------------------------------------------------------------------------------------------------+
|
|
| 8-15 | Interrupt Pending (which interrupts are waiting to be serviced? Used with Interrupt Mask on $Status) |
|
|
+-------+------------------------------------------------------------------------------------------------------+
|
|
| 16-27 | Unused (always zero) |
|
|
+-------+------------------------------------------------------------------------------------------------------+
|
|
| 28-29 | Coprocessor error (which coprocessor threw the exception, often not used) |
|
|
+-------+------------------------------------------------------------------------------------------------------+
|
|
| 30 | Unused (always zero) |
|
|
+-------+------------------------------------------------------------------------------------------------------+
|
|
| 31 | Branch delay (did the exception/interrupt occur in a branch delay slot?) |
|
|
+-------+------------------------------------------------------------------------------------------------------+
|
|
|
|
* EPC
|
|
* ErrorEPC
|
|
* WatchLo
|
|
* WatchHi
|
|
* XContext
|
|
* Parity Error
|
|
|
|
The N64 does not generate a parity error, so this register is never written to by hardware.
|
|
|
|
* Cache Error
|
|
|
|
The N64 does not generate a cache error, so this register is never written to by hardware.
|
|
|
|
COP0 Other Registers
|
|
^^^^^^^^^^^^^^^^^^^
|
|
|
|
These registers don't fit cleanly into any other category.
|
|
|
|
* PRId
|
|
* Config
|
|
* LLAddr
|
|
* Status
|
|
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| Bit | Description |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 0 | ie - global interrupt enable (should interrupts be handled?) |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 1 | exl - exception level (are we currently handling an exception?) |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 2 | erl - error level (are we currently handling an error?) |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 3-4 | ksu - execution mode (00 = kernel, 01 = supervisor, 10 = user) |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 5 | ux - 64 bit addressing enabled in user mode |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 6 | sx - 64 bit addressing enabled in supervisor mode |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 7 | kx - 64 bit addressing enabled in kernel mode |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 8-15 | im - interrupt mask (&'d against interrupt pending in $Cause) |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 16-24 | ds - diagnostic status (described below) |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 25 | re - reverse endianness (0 = big endian, 1 = little endian) |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 26 | fr - enables additional floating point registers (0 = 16 regs, 1 = 32 regs) |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 27 | rp - enable low power mode. Run the CPU at 1/4th clock speed |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 28 | cu0 - Coprocessor 0 enabled (this bit is ignored by the N64, COP0 is always enabled!) |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 29 | cu1 - Coprocessor 1 enabled - if this bit is 0, all COP1 instructions throw exceptions|
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 30 | cu2 - Coprocessor 2 enabled (this bit is ignored by the N64, there is no COP2!) |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
| 31 | cu3 - Coprocessor 3 enabled (this bit is ignored by the N64, there is no COP3!) |
|
|
+-------+---------------------------------------------------------------------------------------+
|
|
|
|
COP1 (FPU) Registers
|
|
-------------------
|
|
TODO
|
|
|
|
Instructions
|
|
------------
|
|
|
|
See either the official manual, or `this fantastic wiki page <https://n64brew.dev/wiki/MIPS_III_instructions>`_
|