Skip to content

Commit b215ba5

Browse files
cuavasISSOtmavivace
authored
Added preliminary HuC-3 documentation. (#433)
* Added preliminary HuC-3 documentation. * Reformatted various things: * Use typographical quotes and apostrophes. * Use radix prefix on addresses in prose. * Use em dash to separate address range and description in headings. * Use brackets to delimit read/write usage in headings. * Backed out change to MBC5. * Fixed typo * Remove double blank lines between sections * Added a few more radix prefixes on hex numbers Also removed a stay hyphen. The HuC1 chip is silkscreened "HuC1A" while the HuC-3 is silkscreened "HuC-3". the difference in punctuation is intentional. * Tighten up wording. * Update src/HuC1.md Co-authored-by: Eldred Habert <[email protected]> Co-authored-by: Antonio Vivace <[email protected]>
1 parent ada8175 commit b215ba5

File tree

3 files changed

+194
-26
lines changed

3 files changed

+194
-26
lines changed

src/HuC1.md

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,52 @@
11
# HuC1
22

3-
HuC1 is an MBC used by some Game Boy games which besides doing the usual
4-
MBC stuff, also provides IR comms. A lot of sources on the internet said
5-
that HuC1 was \"similar to MBC1\", but they didn\'t provide any detail.
6-
I took a look, and it turns out that HuC1 differs from MBC1 quite a lot.
3+
HuC1 is an MBC developed by Hudson Soft. It implements ROM and RAM
4+
banking, and also provides infrared communication.
5+
Despite many sources on the internet claiming that HuC1 is “similar to MBC1”, it actually differs from MBC1 significantly.
76

87
## Memory Map
98

109
Address range | Feature
1110
--------------|------------------------------------
12-
$0000-1FFF | RAM/IR select (when writing only)
13-
$2000-3FFF | ROM bank select (when writing only)
14-
$4000-5FFF | RAM bank select (when writing only)
15-
$6000-7FFF | Nothing?
16-
$A000-BFFF | Cart RAM or IR register
11+
$00001FFF | RAM/IR select (when writing only)
12+
$20003FFF | ROM bank select (when writing only)
13+
$40005FFF | RAM bank select (when writing only)
14+
$60007FFF | Nothing?
15+
$A000BFFF | Cart RAM or IR register
1716

18-
### 0000-1FFF IR Select (Write Only)
17+
### 00001FFF IR Select [write-only]
1918

20-
Most MBCs let you disable the cartridge RAM to prevent accidental
21-
writes. HuC1 doesn\'t do this, instead you use this register to switch
22-
the A000-BFFF region between \"RAM mode\" and \"IR mode\" (described
23-
below). Write 0x0E to switch to IR mode, and anything else to switch to
24-
RAM mode. Nevertheless some HuC1 games attempt to write 0x0A and 0x00 to
25-
this region as if it would enable/disable cart RAM.
19+
Most MBCs can disable the cartridge RAM to prevent accidental writes.
20+
HuC1 doesn’t do this. Instead, this register swtiches the $A000–BFFF
21+
region between “RAM mode” and “IR mode” (described below). Write $0E to
22+
switch to IR mode, or anything else to switch to RAM mode.
2623

27-
### 2000-3FFF ROM Bank Number (Write Only)
24+
Some HuC1 games still write $0A and $00 to this region as if it would
25+
enable/disable cart RAM.
26+
27+
### 2000–3FFF — ROM Bank Number [write-only]
2828

2929
HuC1 can accept a bank number of at least 6 bits here.
3030

31-
### 4000-5FFF RAM Bank Select (Write Only)
31+
### 40005FFF RAM Bank Select [write-only]
3232

3333
HuC1 can accept a bank number of at least 2 bits here.
3434

35-
### 6000-7FFF Nothing? (Write Only)
35+
### 60007FFF Nothing? [write-only]
3636

3737
Writes to this region seem to have no effect. Even so, some games do
3838
write to this region, as if it had the same effect as on MBC1. You may
3939
safely ignore these writes.
4040

41-
### A000-BFFF Cart RAM or IR register (Read/Write)
41+
### A000–BFFF — Cart RAM or IR register [read/write]
42+
43+
When in “IR mode” (wrote $0E to $0000), the IR register is visible
44+
here. Write to this region to control the IR transmitter. $01 turns it
45+
on, $00 turns it off. Read from this region to see either $C1 (saw
46+
light) or $C0 (did not see light).
4247

43-
When in \"IR mode\" (wrote 0x0E to 0x0000), the IR register is visible
44-
here. Write to this region to control the IR transmitter. 0x01 turns it
45-
on, 0x00 turns it off. Read from this region to see either 0xC1 (saw
46-
light) or 0xC0 (did not see light). When in \"RAM mode\" (wrote
47-
something other than 0x0E to 0x000) this region behaves like normal cart
48-
RAM.
48+
When in “RAM mode” (wrote something other than $0E to $0000) this region
49+
behaves like normal cart RAM.
4950

5051
## External links
5152

src/HuC3.md

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
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)

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
- [MMM01](./MMM01.md)
6969
- [M161](./M161.md)
7070
- [HuC1](./HuC1.md)
71+
- [HuC-3](./HuC3.md)
7172
- [Other MBCs](./othermbc.md)
7273

7374
# Accessories

0 commit comments

Comments
 (0)