|
| 1 | +# HuC-3 |
| 2 | + |
| 3 | +HuC-3 is an MBC developed by Hudson Soft. Besides ROM and RAM banking, |
| 4 | +it also provides a real-time clock, speaker, and infrared communication. |
| 5 | +The CR2025 coin cell is user-replaceable. It is a successor to the |
| 6 | +[HuC1](./HuC1.md). |
| 7 | + |
| 8 | +The HuC-3 is poorly understood. Observed behavior suggests the |
| 9 | +real-time clock and tone generator are implemented using a 4-bit |
| 10 | +microcontroller core with internal program ROM. |
| 11 | + |
| 12 | +## Memory |
| 13 | + |
| 14 | +### 0000–3FFF — ROM Bank 00 [read-only] |
| 15 | + |
| 16 | +Contains the first 16 KiB of the ROM. |
| 17 | + |
| 18 | +### 4000–7FFF — ROM Bank 00–7F [read-only] |
| 19 | + |
| 20 | +This area may contain any of the further 16 KiB banks of the ROM. It is |
| 21 | +unknown whether bank $00 can be selected here. |
| 22 | + |
| 23 | +### A000–BFFF — RAM Bank 00–03, or RTC/IR register [read/write] |
| 24 | + |
| 25 | +Depending on the current register selection and RAM Bank Number (see |
| 26 | +below), this memory space is used to access an 8 KiB external RAM Bank, |
| 27 | +or a single I/O Register. |
| 28 | + |
| 29 | +## Memory Control Registers |
| 30 | + |
| 31 | +### 0000–1FFF — RAM/RTC/IR Select [read/write] |
| 32 | + |
| 33 | +Writing to this register maps cart RAM, RTC registers or IR registers |
| 34 | +into memory at $A000–BFFF. Only the lower 4 bits are significant. |
| 35 | + |
| 36 | +Value | Feature |
| 37 | +------|----------------------------- |
| 38 | + $0 | Cart RAM (read-only) |
| 39 | + $A | Cart RAM (read/write) |
| 40 | + $B | RTC command/argument (write) |
| 41 | + $C | RTC command/response (read) |
| 42 | + $D | RTC semaphore (read/write) |
| 43 | + $E | IR (read/write) |
| 44 | + |
| 45 | +If any other value is written, reads from $A000–BFFF return open bus |
| 46 | +values (often $FF, but not guaranteed), and writes are ignored. |
| 47 | + |
| 48 | +### 2000–3FFF — ROM Bank Number [write-only] |
| 49 | + |
| 50 | +HuC-3 can accept a 7-bit bank number here. |
| 51 | + |
| 52 | +### 4000–5FFF — RAM Bank Select [write-only] |
| 53 | + |
| 54 | +HuC-3 can accept a bank number of at least 2 bits here. |
| 55 | + |
| 56 | +### 6000–7FFF — Nothing? [write-only] |
| 57 | + |
| 58 | +Games write $01 here on startup, but it doesn’t seem to have any |
| 59 | +observable effect. |
| 60 | + |
| 61 | +## I/O Registers |
| 62 | + |
| 63 | +These registers are accessed by reading or writing in the $A000–BFFF |
| 64 | +range after setting the RAM/RTC/IR Select register. Address lines |
| 65 | +A12–A0 are not connected to the HuC-3 chip, so the offset within the |
| 66 | +range is ignored. Data line D7 is not connected to the HuC-3 chip, so |
| 67 | +the most significant bit of reads always returns an open bus value |
| 68 | +(usually high), and the most significant bit of writes is always |
| 69 | +ignored. |
| 70 | + |
| 71 | +The RTC MCU communication protocol is described below. |
| 72 | + |
| 73 | +### $B — RTC Command/Argument [write] |
| 74 | + |
| 75 | +The value written consists of a command in bits 6-4, and an argument |
| 76 | +value in bits 4–0. For example the value $62 is command $6 with argument |
| 77 | +value $2. Writing to this register just sets the values in the mailbox |
| 78 | +registers – it does not cause the command to be executed. |
| 79 | + |
| 80 | +### $C — RTC Command/Response [read] |
| 81 | + |
| 82 | +When read, bits 6–4 return the last command written to register $B, and |
| 83 | +bits 3–0 contain the result from the last command executed. |
| 84 | + |
| 85 | +### $D — RTC Semaphore [read/write] |
| 86 | + |
| 87 | +When reading, the least significant bit is high when the RTC MCU is |
| 88 | +ready to receive a command, or low when the RTC MCU is busy. |
| 89 | + |
| 90 | +Writing with the least significant bit clear requests that the RTC MCU |
| 91 | +execute the last command written to register $B. |
| 92 | + |
| 93 | +### $E — IR [read/write] |
| 94 | + |
| 95 | +Similar to the equivalent register of the HuC1. The least significant |
| 96 | +bit is used for infrared communication. |
| 97 | + |
| 98 | +## RTC Communication Protocol |
| 99 | + |
| 100 | +The HuC-3 chip provides read and write access to a 256-nybble window |
| 101 | +into the RTC MCU’s internal memory. Multi-nybble values are stored with |
| 102 | +the least significant nybble at the lowest address (little Endian). |
| 103 | +There are commands for setting the access address, reading and writing |
| 104 | +values, and a few higher-level operations. |
| 105 | + |
| 106 | +Games use the following sequence to execute a command: |
| 107 | + |
| 108 | +* Write $0D to $0000 (select RTC Semaphore register) |
| 109 | +* Poll $A000 until least significant bit is set (wait until ready) |
| 110 | +* Write $0B to $0000 (select RTC Command/Argument register) |
| 111 | +* Write command and argument to $A000 |
| 112 | +* Write $0D to $0000 (select RTC semaphore register) |
| 113 | +* Write $FE to $A000 (clear semaphore, requesting MCU execute command) |
| 114 | +* Poll $A000 until least significant bit is set (wait for completion) |
| 115 | +* Write $0C to $0000 (select RTC Command/Response register) |
| 116 | +* Read $A000 and use value from 4 least significant bits |
| 117 | + |
| 118 | +(The last two steps are not applicable for commands that don’t produce a |
| 119 | +response.) |
| 120 | + |
| 121 | +Known commands: |
| 122 | + |
| 123 | +Command | Description |
| 124 | +--------|----------------------------------------------- |
| 125 | + $1 | Read value and increment access address |
| 126 | + $3 | Write value and increment access address |
| 127 | + $4 | Set access address least significant nybble |
| 128 | + $5 | Set access address most significant nybble |
| 129 | + $6 | Execute extended command specified by argument |
| 130 | + |
| 131 | +Pocket Family GB2 uses command $2 with argument $0, its purpose is |
| 132 | +unknown. Commands $0 and $7 have not been observed. |
| 133 | + |
| 134 | +The following extended commands have been observed: |
| 135 | + |
| 136 | +Command | Description |
| 137 | +--------|------------------------------------------------------------- |
| 138 | + $0 | Copy current time to locations $00–06 |
| 139 | + $1 | Copy locations $00–06 to current time, and update event time |
| 140 | + $2 | Seems to be some kind of status request |
| 141 | + $E | Executing twice triggers tone generator |
| 142 | + |
| 143 | +Commands $0 and $1 are used to read and write the current time |
| 144 | +atomically. Writing the current time in this way also updates the event |
| 145 | +time to maintain the remaining duration until the event occurs. |
| 146 | + |
| 147 | +Command $2 is used on start and seems to be some kind of status |
| 148 | +request. The games will not start if the result is not $1. |
| 149 | + |
| 150 | +### RTC Location Map |
| 151 | + |
| 152 | +The purpose of some locations has been inferred by observing behavior: |
| 153 | + |
| 154 | +Location | Purpose |
| 155 | +---------|------------------------------------------------------------ |
| 156 | + $00–06 | Output or input space for reading or writing current time |
| 157 | + $10–12 | Minute of day counter (rolls over at 1440) |
| 158 | + $13–15 | Day counter |
| 159 | + $26 | Tone selection in two least significant bits |
| 160 | + $27 | Tone generator enabled if value is 1 (all bits checked) |
| 161 | + $58–5A | Event time minutes |
| 162 | + $5B–5D | Event time days |
| 163 | + |
| 164 | +## External links |
| 165 | + |
| 166 | +- Source: [GBDev Forums thread](https://gbdev.gg8.se/forums/viewtopic.php?id=744) |
0 commit comments