You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AI/ARCHITECTURE.md
+7-1Lines changed: 7 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -222,10 +222,15 @@ to immediately materialize as a separate directory.
222
222
223
223
### `dma/`
224
224
225
+
- shared DMA controller and active-transfer state
225
226
- DMG OAM DMA
227
+
- transfer lifecycle such as `Idle`, `Starting`, `Active`, `Completed`, and future `Cancelled`
226
228
- transfer timing over the shared scheduler timeline
229
+
- per-transfer timing policy, block granularity, and advance-condition modeling
230
+
- publication of CPU-impact and memory-region-impact state for bus and PPU consumption
231
+
- DMA-owned validation and normalization of source and destination contracts
227
232
- integration with bus arbitration
228
-
- architectural preparation for future transfer mechanisms outside current DMG scope
233
+
- architectural preparation for future GDMA and HDMA without scheduler redesign
229
234
230
235
### `timer/`
231
236
@@ -326,6 +331,7 @@ to immediately materialize as a separate directory.
326
331
- The boot subsystem owns firmware assets, model-aware boot configuration, and boot-ROM enable/disable state.
327
332
- The boot subsystem also owns the source-of-truth startup snapshot for direct-boot entry, while the target subsystems still own the live semantics of their registers once execution begins.
328
333
- The DMA subsystem owns transfer state and transfer requests over time.
334
+
- The DMA subsystem also owns transfer-kind-specific validation, lifecycle, progress, CPU-impact policy, and region-impact publication; the bus and PPU should consume that common state instead of reverse-engineering DMA behavior from MMIO register details.
329
335
- The PPU owns LCD mode state and the rules that determine when VRAM/OAM are accessible.
330
336
- The PPU also owns the live Mode `2` OAM-row state and the DMG-family OAM corruption formulas, while the bus routes relevant access attempts and the CPU exposes the micro-events needed to classify IDU-driven triggers.
331
337
- The interrupt controller owns `IF`/`IE` register state and pending-request bookkeeping, while the CPU owns `IME`, `halted`, `stopped`, and the final decision to accept and service an interrupt.
Copy file name to clipboardExpand all lines: AI/ROADMAP.md
+29-6Lines changed: 29 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -162,7 +162,7 @@ coherent without refactoring.
162
162
Acceptance criteria: CPU and DMA use the same arbitration route, decode/ownership and access-policy layers stay distinct, and DMG OAM DMA correctly leaves CPU with HRAM only.
163
163
3.**IRQ aggregation layer** (`Phase 2`)
164
164
Goal: separate source request, `IF` visibility, and CPU acceptance.
165
-
Acceptance criteria: PPU, timer, serial, and joypad only request; the CPU accepts by `IME/IE/IF` and fixed priority; timer keeps its delayed one-M-cycle request timing.
165
+
Acceptance criteria: PPU, timer, serial, and joypad only request; the CPU accepts by `IME/IE/IF` and fixed priority; timer keeps its delayed `4`-T-cycle (`1`M-cycle) request timing.
166
166
4.**Cycle logging** (`Phase 0`, expanded later)
167
167
Goal: make the actual ordering visible per T-cycle.
168
168
Acceptance criteria: traces can expose phase, bus owner, CPU micro-op, PPU mode, DMA activity, timer or serial events, and `IF/IE/IME`.
@@ -488,7 +488,7 @@ Build a truly temporal CPU core, where observable behavior emerges from internal
488
488
489
489
#### Goal
490
490
491
-
Integrate OAM DMA as a real transfer mechanism inside the system architecture, coordinated with the scheduler and bus.
491
+
Integrate DMG OAM DMA as a real transfer mechanism inside the system architecture through a reusable DMA-controller foundation, coordinated with the scheduler and bus and already prepared for future CGB transfer families without implementing them yet.
492
492
493
493
#### Modules involved
494
494
@@ -500,19 +500,41 @@ Integrate OAM DMA as a real transfer mechanism inside the system architecture, c
500
500
501
501
#### Deliverables
502
502
503
+
- common `DmaController`-style infrastructure with explicit active-transfer state
503
504
- writing to the DMA register triggers the transfer
504
-
- real temporal copy progression
505
+
- OAM DMA as the first concrete transfer kind inside that common infrastructure
506
+
- real temporal copy progression on the shared T-cycle timeline
505
507
- integration with bus arbitration
508
+
- separation between transfer progression and DMA-published arbitration state
509
+
- explicit lifecycle and status visibility for active transfers
506
510
- observability of DMA start, progress, and completion
507
511
- scheduler-visible DMA state that bus arbitration can use on the same T-cycle
512
+
- transfer fields that already leave room for block or windowed progression without wiring CGB MMIO yet
508
513
509
514
#### Done criteria
510
515
511
516
- the transfer is not implemented as an instantaneous memory copy
517
+
- OAM DMA is implemented as an instance of the common DMA transfer infrastructure rather than a one-off path outside it
512
518
- arbitration correctly reflects DMA effects on concurrent accesses
513
519
- CPU-versus-DMA precedence is decided centrally through bus arbitration instead of CPU-local blocking logic
520
+
- DMG OAM DMA still leaves the CPU with HRAM access only while active
521
+
- DMA lifecycle and active-state visibility are explicit and traceable
522
+
- the infrastructure can already represent future block or windowed transfers without requiring a later scheduler redesign, even though GDMA and HDMA remain out of scope here
514
523
- the system can trace DMA over time
515
524
525
+
#### Recommended sequencing inside Phase 3
526
+
527
+
1. Extract OAM DMA into the common controller.
528
+
Acceptance criteria: OAM DMA no longer lives on an ad hoc path, visible DMG behavior does not regress, CPU still remains HRAM-only during active OAM DMA, and the PPU still sees the same OAM-conflict state.
529
+
2. Separate transfer mechanics from arbitration policy.
530
+
Acceptance criteria: the bus consults one common DMA constraint API, the DMA subsystem does not reimplement bus decode, and the PPU can react to common OAM or VRAM impact state rather than to transfer-specific register knowledge.
531
+
3. Add common lifecycle and status visibility.
532
+
Acceptance criteria: OAM DMA uses `Idle -> Starting -> Active -> Completed`, the common API can already represent future cancellation, and code can query active-versus-finished state without depending on one specific origin register.
533
+
4. Prepare block or windowed progression hooks.
534
+
Acceptance criteria: fields such as `block_size` and `advance_condition` exist in the controller contract, including room for future `0x10`-byte HDMA-style blocks, they are not yet wired to real HDMA registers, and Phase 3 does not need another scheduler redesign when CGB transfer work starts.
535
+
5. Lock the infrastructure with focused tests.
536
+
Acceptance criteria: tests cover OAM DMA on the new controller, published bus constraints, lifecycle visibility, completion, and at least one simulated `0x10`-byte block-style transfer shape that is not yet mapped to real CGB MMIO.
537
+
516
538
#### Risks if delayed too much
517
539
518
540
- the need to rewrite the bus
@@ -793,13 +815,14 @@ Complete basic system peripherals on top of an already consolidated bus, schedul
793
815
794
816
---
795
817
796
-
### Phase 6 — Banked cartridges and persistence
818
+
### Phase 6 — Banked cartridges, special cartridges, and persistence
Copy file name to clipboardExpand all lines: AI/TIMING-AND-ACCURACY.md
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -79,6 +79,9 @@ When implementing timing:
79
79
- For the CPU specifically, opcode fetch, immediate fetch, stack transfer, indirect memory access, conditional timing splits, and internal no-bus steps should all remain expressible as ordered events on that timeline.
80
80
- Long-running hardware activity started by a register write, such as OAM DMA, should become explicit in-flight state on the shared timeline rather than a one-shot side effect.
81
81
- When a subsystem progresses in repeated temporal slices, such as one DMA byte every four dots on DMG OAM DMA, that phase relationship should remain visible in code and tests.
82
+
- The timing model must support both fixed-duration burst transfers and windowed or block transfers that only advance in eligible windows such as HBlank, while keeping both on the same shared T-cycle timeline.
83
+
- A transfer's CPU or bus impact and its data-copy action should be expressible separately per T-cycle, because arbitration may be visible on cycles where no byte commits and future block DMA may stall only for selected windows.
84
+
- Future transfer advance may depend on other live machine state such as PPU HBlank visibility or CPU `HALT` state; keep that dependency explicit in the transfer model rather than hiding it in bus code.
82
85
- Edge-driven subsystems such as the timer should derive visible events from clocked internal state transitions, not from coarse accumulated-period shortcuts.
83
86
- CPU interrupt acceptance, delayed `EI`, `HALT` wake-up, and `HALT` bug behavior should be expressed as ordered events on that same shared timeline rather than as opaque instruction-level shortcuts.
84
87
- For the PPU specifically, dot-by-dot progression is the intended interpretation of the shared T-cycle timeline.
Copy file name to clipboardExpand all lines: AI/hardware/BUS.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,6 +21,7 @@ Address alone is not enough: the bus must also consider the current temporal har
21
21
- distinguish requester-specific access semantics when CPU, DMA, or other actors do not obey the same rules
22
22
- coordinate dynamic mapping between boot ROM, cartridge ROM, and later model-specific extensions
23
23
- consume subsystem-owned state such as PPU mode, DMA progress, and boot-ROM enable state when deciding the observable result of an access
24
+
- consume DMA-published constraint state from the common transfer controller rather than re-deriving live DMA policy from MMIO register values or ad hoc per-kind branches
24
25
- delegate all cartridge-owned accesses through one stable cartridge-device contract instead of embedding per-MBC logic in the bus
25
26
26
27
## Registers / MMIO
@@ -173,6 +174,8 @@ Address alone is not enough: the bus must also consider the current temporal har
173
174
- After nominal ownership is known, the owning region or device may still block or modify the access according to live policy, such as VRAM in Mode `3`, OAM in Mode `2/3`, `FEA0-FEFF`, disabled cartridge RAM, or cartridge-selected RTC behavior.
174
175
- CPU, DMA, and any future transfer engine must all use this one central arbitration path; no caller-specific fast path may bypass decode or access policy.
175
176
- On the shared scheduler timeline, the arbitration decision for a T-cycle should see the already-updated current-cycle DMA and PPU state before the CPU micro-operation issues its access for that same T-cycle.
177
+
- The bus should consult DMA-owned published constraints such as CPU impact, region impact, and current-cycle transfer activity instead of peeking at `FF46` or future `HDMA1-5` register state directly.
178
+
- DMA policy questions such as "HRAM-only", "fully stalled until done", or "stalled only during a block" belong to the DMA subsystem; the bus should only apply the resulting requester-visible constraints.
176
179
177
180
## Model-aware MMIO baseline
178
181
@@ -202,6 +205,7 @@ Address alone is not enough: the bus must also consider the current temporal har
202
205
- OAM access blocking during PPU Mode 2 must be represented as observable bus behavior, not as a render-only detail.
203
206
- During PPU Mode 3, both OAM and VRAM access restrictions must be represented as observable bus behavior.
204
207
- During DMG OAM DMA, CPU accesses should retain normal HRAM behavior while non-HRAM CPU accesses observe DMA-blocked semantics instead of normal memory-region behavior.
208
+
- DMA-visible blocking and DMA data movement should remain separable on the T-cycle timeline; a transfer may affect CPU-visible access policy on a cycle even if no byte commit occurs on that same cycle.
205
209
- With LCD disabled, access rules should return to the hardware state expected for LCD-off behavior.
206
210
- LCD-off accessibility should remove ordinary PPU mode locks, but it must not erase independent blocking rules coming from DMA or any later bus actor.
207
211
- The same PPU-disabled state that makes `STAT.mode` read as `0` should also be the state the bus uses to release ordinary VRAM/OAM mode restrictions.
@@ -279,6 +283,7 @@ Priority order:
279
283
- A bus context or equivalent state bundle is a good fit for carrying model, PPU mode, LCD enable, DMA activity, boot ROM mapping, and later CGB-specific selectors.
280
284
- A caller-aware access split or equivalent internal distinction between CPU-initiated and DMA-initiated accesses is recommended when the observable rules differ.
281
285
- Let subsystems define the state that causes restrictions or remapping, but keep the final blocked-access or routing decision in bus-facing handlers.
286
+
- A DMA-facing query such as `bus_constraints()` plus a separate transfer-commit path is a good fit for keeping arbitration policy separate from byte-copy mechanics.
282
287
- Prefer a centralized MMIO descriptor table or equivalent routed register map over scattered `match` blocks that each know only part of a register's semantics.
283
288
- Let subsystem-owned handlers compose readback from live state, latched state, and forced bits; do not teach the bus to fake those register internals.
284
289
- Do not special-case CPU opcode fetch, operand fetch, or stack accesses outside the common bus contract; they should use the same routed access path as any other CPU-visible memory transaction.
Copy file name to clipboardExpand all lines: AI/hardware/CGB.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -99,6 +99,7 @@ Priority order:
99
99
- CPU `STOP` should already be represented separately from `HALT`, because future CGB speed-switch behavior should attach to an existing explicit control state rather than force a later CPU-state redesign.
100
100
- The boot subsystem and bus should already treat boot-ROM mapping as model-aware routing state so future CGB split boot-ROM windows can extend the same abstraction while preserving cartridge-header visibility around `0x0100-0x014F`.
101
101
- The DMG OAM DMA implementation should already live inside a reusable DMA subsystem contract so future CGB OAM DMA timing differences, GDMA, and HDMA can extend the same infrastructure.
102
+
- When CGB DMA work starts, model GDMA as a full-burst transfer and HDMA as a windowed block transfer inside that shared DMA controller, with CPU-impact and advance-condition policy published to the scheduler and bus rather than re-encoded in CGB-only bus branches.
102
103
- The DMG timer implementation should already be expressed in terms of an internal counter plus derived edge logic so future CGB clocking changes can extend the same model rather than replace it.
103
104
- The DMG APU implementation should already derive `DIV-APU` / frame-sequencer timing from the shared divider timeline so future CGB double-speed audio timing can extend the same ownership split rather than introducing a second audio clock model.
104
105
- The DMG-family OAM corruption bug should stay behind an explicit model gate so future CGB, AGB, AGS, and GBP support can keep the documented non-bugged behavior.
Copy file name to clipboardExpand all lines: AI/hardware/CPU.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,7 +36,7 @@ The source of truth should not be "execute opcode, mutate registers, then report
36
36
- The CPU should only accept maskable interrupts at defined points in the instruction-flow pipeline, effectively at instruction boundaries or an equivalent explicitly modeled acceptance point.
37
37
- When an interrupt is accepted, the CPU should clear `IME`, clear the selected bit in `IF`, push `PC`, and jump to the matching vector as part of one explicit service sequence.
38
38
- The CPU should make that accept-or-not decision only after current-cycle MMIO side effects and interrupt aggregation are already visible; interrupt producers do not bypass that CPU-owned decision point.
39
-
- Once accepted, interrupt servicing must consume the documented DMG `5` M-cycles through the same ordered CPU execution model used for normal stack and control-flow work.
39
+
- Once accepted, interrupt servicing must consume the documented DMG `20` T-cycles (`5` M-cycles) through the same ordered CPU execution model used for normal stack and control-flow work.
40
40
41
41
## IME, HALT, and STOP baseline
42
42
@@ -135,7 +135,7 @@ Priority order:
135
135
- tests for correct push of `PC`, clearing of `IF`, and `IME -> 0` on interrupt service
136
136
- tests for `EI ; NOP`, `EI ; DI`, `DI ; EI ; NOP`, and pending-IRQ visibility around delayed `EI`
137
137
- tests for `HALT` wake-up with `IME = 1`, `IME = 0`, and `IME = 0` plus already-pending interrupt
138
-
- tests that interrupt acceptance starts a real `5` M-cycle service sequence instead of an immediate vector jump
138
+
- tests that interrupt acceptance starts a real `20` T-cycle (`5` M-cycle) service sequence instead of an immediate vector jump
139
139
- tests for `STOP` wake-up driven through the relevant hardware source path rather than by directly poking CPU state
140
140
- tests for `RETI` re-enabling interrupts and allowing later pending requests to be serviced
141
141
- tests that `inc rr` / `dec rr` with `BC`, `DE`, or `HL` in `FE00-FEFF` expose the IDU event needed by the OAM-corruption path
0 commit comments