pub struct Channel {
pub dmap: u8,
pub target: u8,
pub source_addr: u16,
pub source_bank: u8,
pub count_or_indirect: u16,
pub indirect_bank: u8,
pub hdma_addr: u16,
pub line_counter: u8,
pub scratch: u8,
pub hdma_completed: bool,
pub hdma_do_transfer: bool,
}Expand description
One of the 8 DMA channels ($43n0-$43nA).
Fields§
§dmap: u8$43n0 DMAP — transfer params: bit7 direction (0 = A→B, 1 = B→A), bit6 indirect (HDMA),
bit4 reverse (GP-DMA addr decrement), bit3 fixed (GP-DMA addr no-change), bits2-0 mode.
target: u8$43n1 BBAD — B-bus target low byte (the $21xx register).
source_addr: u16$43n2-3 A1T — A-bus source address (GP) / table address (HDMA).
source_bank: u8$43n4 A1B — A-bus source bank.
count_or_indirect: u16$43n5-6 DAS — GP byte count / HDMA indirect address.
indirect_bank: u8$43n7 DASB — HDMA indirect bank.
hdma_addr: u16$43n8-9 A2A — HDMA table running address.
line_counter: u8$43nA NTRL — HDMA line counter (bit7 = repeat, bits0-6 = lines).
scratch: u8The undocumented readable scratch latch at $43xB, mirrored at $43xF.
Nothing in the DMA controller reads it — it is a byte of storage the hardware exposes and
then forgets about. It matters because it is CPU-visible: AccuracySNES D1.10 writes it
and reads it back, snes9x passes that test, and RustySNES returned 0 from both addresses
until the test was written.
Deliberately not in the save state, and reset to 0 on load. ares and bsnes do
serialise theirs, but adding a byte to the DMA0 section changes its length, and this
format’s compatibility rules make that a version-bump decision rather than a free one
(docs/adr/0006). The latch has no effect on emulation, so the only cost is that a
$43xB read after a load returns 0 instead of the saved byte. Resetting matters more than
the omission does: inheriting the pre-load value would make that read depend on what ran
before the load, which the determinism contract rules out. Recorded in
docs/accuracysnes-plan.md so it stays a decision rather than an oversight.
hdma_completed: boolHDMA: this channel has finished its table for the frame.
hdma_do_transfer: boolHDMA: perform a transfer on this line (vs. just decrement the counter).