1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! The Game Boy's chips (`dev-gb`).
//!
//! Phase 4's *genericity proof* (`ROADMAP.md` §13): a machine that is not
//! 6502-shaped, built out of the same core the NES was, with no change to
//! `core::` to accommodate it. What that looks like in practice is worth stating,
//! because "no core API had to change" is a claim and these are the receipts:
//!
//! | The Game Boy needs | The core already had |
//! | --- | --- |
//! | `IF`/`IE` inside the CPU, mapped at `$FF0F` and `$FFFF` | a device may publish several named regions ([`Device::region`]) |
//! | STAT blocking — a level ORed from four conditions, one interrupt | wire *levels* plus an edge detector in the sink ([`core::wire`]) |
//! | `DIV` writes being audible | one device driving another's clock over an ordinary wire |
//! | A cartridge RTC on its own 32.768 kHz crystal | a second oscillator in the forest, cross-tree by construction ([`core::clock`]) |
//! | An OAM DMA that reads the CPU's own bus | [`Initiator`], and a per-master address space |
//! | `LY` and `STAT` read at an arbitrary cycle | sync-on-access, and a quantum bounded by the device's next event |
//! | VRAM that reads `$FF` during mode 3 | nothing at all: it is the device's own `MemOps` |
//!
//! [`Device::region`]: crate::core::Device::region
//! [`Initiator`]: crate::core::device::Initiator
//! [`core::wire`]: crate::core::wire
//! [`core::clock`]: crate::core::clock
//!
//! # The modules
//!
//! | Module | Covers |
//! | --- | --- |
//! | [`cart`] | the header, ROM-only, MBC1, MBC2, MBC3 (with its RTC) and MBC5 |
//! | [`ppu`] | the LCD controller, video RAM, object memory and the OAM DMA |
//! | [`timer`] | the divider and timer, and the 512 Hz clock the sound unit runs on |
//! | [`apu`] | four sound channels and the frame sequencer |
//! | [`joypad`] | the eight-button matrix at `$FF00` |
//! | [`serial`] | the link port, which is also how a test ROM reports its result |
//!
//! The CPU is [`crate::cpu::sm83`], under its own feature: a machine is a
//! *feature set*, and a build that wants only the chips can have only the chips.
//!
//! # The oscillators
//!
//! One crystal for the console, at **4.194304 MHz** — and unlike the NES's
//! 236250000/11 Hz or the Apple 1's 315/22 MHz, that is an exact power of two:
//! 2²². It is the case that makes the rational frequency literal look like
//! ceremony, and `machines/gameboy.machine` says so explicitly, because a design
//! decision only defends itself if the case *against* it is written down beside
//! the case for it.
//!
//! A cartridge with an MBC3 real-time clock carries a **second** crystal, a
//! 32.768 kHz watch can, with no fixed relationship to the first. `ROADMAP.md`
//! §4.2 is about exactly this: within one crystal's tree the ratios are exact
//! and guest-visible, and across trees exactness is not merely expensive but
//! meaningless. So the machine file declares both.
//!
//! # Sources
//!
//! [Pan Docs](https://gbdev.io/pandocs/) throughout, which is **CC0** — the rare
//! emulation reference that can be quoted verbatim into a source comment with no
//! attribution burden at all — plus Gekkio's *Game Boy: Complete Technical
//! Reference* for sub-instruction timing. No emulator source of any licence was
//! consulted (`ROADMAP.md` §1).
// The conformance runners read downloaded ROMs off the filesystem, so they exist
// only where there is one (`ROADMAP.md` §12).
pub use GbApu;
pub use ;
pub use ;
pub use ;
pub use GbSerial;
pub use GbTimer;
use crateResult;
/// The console's crystal, in hertz.
///
/// 4 194 304 = 2²². Note what that means for `ROADMAP.md` §4.2: every domain in
/// this machine descends from one oscillator with an integer divisor, so every
/// ratio in the machine is exact *and* the absolute frequency happens to be an
/// integer too. That is the exception, not the rule — see the module
/// documentation.
pub const MASTER_HZ: u64 = 4_194_304;
/// Register every Game Boy device class this build has.
///
/// # Errors
///
/// [`crate::Error::Config`] if a name is already taken, which means two features
/// collided.
/// Bind every Game Boy device class into the machine graph.
///
/// # Errors
///
/// As [`register`].
/// What the validator should know about every Game Boy class.