#518
Compile-time-controlled logging
Ad-hoc printf tracing was replaced by a single macro-driven logging facility
(Common/BaseLogicLib). The key decision is two levels of control: compile time
(Release builds contain no logging code at all, with per-subsystem overrides) and run time
(a source mask, a per-source category mask, file and stdout sinks). Categories are owned by the
components themselves: every subsystem declares its own category enum and a public
SetLogMask().
What changed
- Traces added across all subsystems: 6502 (reset, NMI/IRQ, external bus writes), APU (OAM DMA, registers), PPU (CPU-interface registers, VBlank NMI), MMC1, CartPcb (memory accesses, latch captures), Board (board lifecycle — replacing the old
printf tracing) and IO (controllers, device attach/detach).
- BreaksCore registers the sources with their categories and exposes a logging API to the managed app.
- The Settings dialog gained
FormLogging: checkboxes per source and category, file/stdout output.
Links: PR #518 · issue #517
#519
IO subsystem ported to the SDL2 port
The SDL2 port gained the controller input it was missing: SDL2 input events (keyboard keys, gamepad
buttons/sticks/triggers) are turned into device events and dispatched through bindings to the devices
attached to the motherboard — the same scheme as in the managed app. The configuration is stored
separately (IOConfigSDL.json) so it never overlaps with the managed app’s config.
What changed
- Interactive configurator (
breaknes --ioconfig): device pool, actuator bindings (wait for an input event), attach/detach devices to the motherboard ports.
- Device identifiers come from the shared
IO::DeviceID enum instead of hardcoded values.
- Builds fixed:
CartPcbPort.cpp (missing from CMake since the #509 refactor) was added back; JsonLib was fixed for Linux (compilation, Int serialization via %llu).
Links: PR #519 · issue #516
#520
Up to two TVs: PPU⇄TV binding
Infrastructure for boards with several PPUs. The board now owns a list of PPUs, each bound to a
virtual TV Set, and the emulator window can display up to two TVs in a horizontal or vertical layout;
for debugging, one PPU can be shown on both TVs at once. Multi-PPU board wiring (several PPUs
simulated in one board) is the next step (NES-based arcade machines); the PPU list, binding, JSON
schema and API are already in place.
What changed
BoardDescription.json: new ppus, tvs, tv_layout fields; debug boards “one PPU on two TVs” (horizontal / vertical).
- Managed app: the screens are composited into a single window bitmap by
TvWall (512×240 / 256×480); a single TV now scales to fill the window like the multi-TV canvas.
- SDL2 port: reads
BoardDescription.json instead of the hardcoded board, new --board option, the window renders once per frame.
Links: PR #520 · issue #515
#522
Board database aligned with real revisions
The board list was picked sporadically and contradicted the research on real NES/Famicom motherboard
revisions (e.g. “NES-101 (NESN-101 PCB)” does not exist; all Famicom boards were marked
RP2A03G/RP2C02G regardless of era). The database was aligned with the
revision document from the breaks repository — 31 real boards with the correct chip
markings per era.
What changed
- Famicom HVC-CPU-01…08 and GPM, AV Famicom HVCN-CPU, NES-001 NES-CPU-01…11, NES-101 NESN-CPU/JIO/AV, regional boards (PAL, Comboy, Playtronic) — with the right chips for each era.
- Unsupported chip revisions are now resolved table-driven to the closest supported model instead of degrading the board to
Bogus — logged at board creation.
- PPUSim:
RP2C02H support — previously an uninitialized H/V decoder produced a black picture.
- The SDL2 port defaults to a real board, NES (NES-CPU-07, 1987);
NESBoard became the debug board “one PPU on two TVs”.
- Minor fixes: JSON configs are copied to the output directories; if a saved board name is gone from the database, the first board is used.
Links: PR #522 · issue #521
#524
Project icon
The project gained a branded icon based on DALL-E artwork. The generator
(Artwork/gen_breaknes_icon.py) square-crops the source and produces a 256×256 PNG master,
a multi-size Windows .ico (16–256 px) and a C++ header with 64×64 pixels embedded for the
SDL2 port: the window icon needs no image loader and works the same on Windows and Linux.
What changed
- The icon is set on the managed app window and the SDL2 port window.
- The generator script regenerates all artifacts (PNG, ICO, C++ header) from a single source image.
Links: PR #524 · issue #523
#526
CartPcb: scroll jumper, glue logic as chips, iNES fallback
Three connected reworks of the cartridge PCB model. (1) There is no “mirroring” attribute on a
PCB — only a solder jumper that selects the scrolling arrangement, and the concrete H/V value is a
cartridge-instance parameter derived from the iNES header. (2) The UNROM/AOROM glue logic is
modeled with real chips instead of a generic latch. (3) Dumps absent from the nescartdb database
(homebrew, rare dumps) now run: the board type is inferred from the iNES header.
What changed
- “Mirroring” → Scroll: the board declares the jumper as
"mirroring": {"mode": "scroll"}; H/V comes from Flags6 bit 0 (inverted); the legacy "hardwired" mode remains as a compatibility alias.
- UNROM: the bank register is a
74LS161 (counter loading on the /ROMSEL rising edge), the PRG address multiplexer is a 74LS32; net+chip simulation runs in two passes so chip outputs propagate through nets within one tick.
InesTranslator for “wild” dumps: 0→NROM, 1→SGROM/SHROM, 2→UNROM, 3→CNROM, 7→AOROM (new cnrom.json, shrom.json); they run through the same CartPcb path with a warning logged.
Links: PR #526 · issue #525 · issue #514