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
//! A TurboGrafx-16 / PC Engine emulator core.
//!
//! The console is built around the Hudson Soft / NEC **HuC6280** CPU (a 65C02
//! derivative with an integrated MMU, PSG, timer and I/O port) talking to two
//! video chips:
//!
//! - **HuC6270 VDC** — the Video Display Controller. This is the "graphics
//! processor": it owns 64 KiB of VRAM and produces the tile/sprite picture.
//! It lives in [`vdc`] and is the part you'll be fleshing out next.
//! - **HuC6260 VCE** — the Video Color Encoder. It holds the 512-entry color
//! palette and the dot-clock selection. It lives in [`vce`].
//!
//! ## How the pieces fit together
//!
//! ```text
//! +-----------------------------------------------+
//! | Console |
//! | |
//! CPU <-->| mos6502::CPU<SystemBus, Huc6280> |
//! | | |
//! | v (Bus trait: get_byte/set_byte) |
//! | SystemBus -- MMU (MPR0-7) + memory map |
//! | | | | | | | |
//! | ROM RAM VDC VCE Timer IRQ ctl |
//! +-----------------------------------------------+
//! ```
//!
//! The CPU only ever emits 16-bit *logical* addresses. The [`SystemBus`]
//! performs the HuC6280 MMU translation (logical → 21-bit physical) using a
//! shadow copy of the mapping registers, then dispatches to ROM, work RAM or
//! the hardware page (bank `$FF`).
//!
//! See [`crate::bus`] for the important note on interrupt-vector handling.
pub use SystemBus;
pub use Cartridge;
pub use Console;
/// CPU clock in its high-speed mode: 21.477 MHz master / 3 ≈ 7.16 MHz.
///
/// `CSL`/`CSH` switch between this and the 1.79 MHz low-speed mode. The
/// `mos6502` core counts cycles per instruction rather than wall-clock time, so
/// the speed switch is currently a no-op (see the TODO in [`crate::bus`]).
pub const CPU_CLOCK_HZ: u32 = 7_159_090;
/// NTSC scanlines per frame (262 active + retrace ≈ 262/263).
pub const SCANLINES_PER_FRAME: u16 = 263;
/// Approximate CPU cycles per scanline at 7.16 MHz.
///
/// Master horizontal total is ~1365 master clocks per line; at master/3 that's
/// ~455 CPU cycles. This is a coarse number used to interleave CPU execution
/// with the VDC's per-scanline stepping until proper dot-clock timing lands.
pub const CPU_CYCLES_PER_SCANLINE: u64 = 455;
/// Approximate CPU cycles of the active-display portion of a scanline (before
/// HBlank). The remainder, `CPU_CYCLES_PER_SCANLINE - ACTIVE_CYCLES_PER_SCANLINE`,
/// is HBlank, during which raster/vblank interrupt handlers run and program the
/// registers for the next line.
pub const ACTIVE_CYCLES_PER_SCANLINE: u64 = 342;