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
136
137
//! # Low-Level Blitter Control Registers
//!
//! Direct access to the Blitter Control Registers (BCR) at `$4000-$4007`.
//!
//! **Note:** For most use cases, use [`video_dma::blitter::BlitterGuard`](crate::video_dma::blitter::BlitterGuard)
//! instead, which provides a safer and more ergonomic interface.
//!
//! ## Register Layout
//!
//! | Address | Name | Description |
//! |---------|---------|------------------------------------------------|
//! | `$4000` | VX | Framebuffer X coordinate (destination) |
//! | `$4001` | VY | Framebuffer Y coordinate (destination) |
//! | `$4002` | GX | Sprite RAM X coordinate (source) |
//! | `$4003` | GY | Sprite RAM Y coordinate (source) |
//! | `$4004` | WIDTH | Width of rectangle (bit 7 = horizontal flip) |
//! | `$4005` | HEIGHT | Height of rectangle (bit 7 = vertical flip) |
//! | `$4006` | START | Write 1 to start blit, 0 to acknowledge IRQ |
//! | `$4007` | COLOR | Fill color (inverted, for color fill mode) |
//!
//! ## Blitter Performance
//!
//! The blitter copies **1 pixel per CPU cycle** (~3.58 MHz). At 60 Hz:
//! - **~59,659 pixels/frame** theoretical maximum
//! - That's **~3.6× the framebuffer size** (128×128 = 16,384 pixels)
//!
//! Transparent pixels are still processed (skipped but counted), so large
//! transparent regions don't save time.
//!
//! ## Sprite Quadrants
//!
//! Sprite RAM is **512KB**: 8 pages of 256×256 pixels (64KB each). The page is selected
//! by bits 0-2 of the Banking Register. The blitter can access the full 256×256 page,
//! but the CPU can only access one **128×128 quadrant** at a time.
//!
//! The CPU-accessible quadrant is determined by the MSB of the blitter's GX/GY counters.
//! Use [`SpriteQuadrant`] to set which quadrant is accessible before loading sprites.
use WO;
use crate::;
/// Blitter Control Register hardware layout at `$4000-$4007`.
///
/// Write-only registers that control blitter DMA operations.
/// The blitter copies rectangular regions from sprite RAM to the framebuffer,
/// or fills rectangles with a solid color.
/// Blitter fill mode.
/// Sprite RAM quadrant selector.
///
/// Each sprite page is 256×256 pixels, but the CPU can only access one 128×128
/// quadrant at a time through `$4000-$7FFF`. The quadrant is determined by the
/// MSB of the blitter's GX/GY counters.
///
/// Use [`BlitterGuard::set_vram_quad`](crate::video_dma::blitter::BlitterGuard::set_vram_quad)
/// to select a quadrant before loading sprite data.
///
/// ```text
/// Sprite page quadrants (256×256 page):
/// ┌───────────┬───────────┐
/// │ Quadrant 1│ Quadrant 2│ Y = 0-127
/// │ (0,0) │ (128,0) │
/// ├───────────┼───────────┤
/// │ Quadrant 3│ Quadrant 4│ Y = 128-255
/// │ (0,128) │ (128,128) │
/// └───────────┴───────────┘
/// X=0-127 X=128-255
/// ```