BreaksCore

The native C++ core: motherboards, chip wiring and a debug hub — plus the two front-ends: the WinForms app and the SDL2 port

BreaksCore is the native part of the emulator, the gate-level NES/Famicom/Dendy emulator that both front-ends are built on. On top of the native core sit two applications: the managed WinForms application (Breaknes) and, for those who like minimalism, a Breaknes build using SDL2 (BreaknesSDL).

BreaksCore

The native part of the emulator.

Abstract Board

The abstract motherboard is used as a base class for all other NES/Famicom/Dendy variations.

The Board Factory is used to instantiate the motherboard:

So far it's a bit abstract, but later we will make the links between classes.

Boards

List of supported boards.

Famicom

The plan is to simulate the Generic Famicom board as follows:

Famicom board — Logisim diagram

NES

The plan is to simulate the Generic NES board as follows:

Generic NES board

Dendy/Subor/Phantom/Whatever

TBD.

Bogus Board

BogusBoard is a default motherboard if BreaksCore did not recognize the board type when it created the instances or other erroneous parameters.

BogusBoard

This system contains 64 KBytes of RAM, a 6502 processor core and nothing else.

In other words, it's a minimal computing system to check if anything is ticking in the emulator.

PPUPlayer Board

A special debug board for the PPUPlayer.

PPUPlayer board

The board contains the PPU, adjacent logic (Address Latch, VRAM) and partial support for the cartridge connector (only the PPU/CHR pins are used).

APUPlayer Board

Another debug board for "playing" the APU register dump.

APUPlayer board

It is roughly the same as PPUPlayer, but simpler in that the APU does not require a cartridge connector and additional bindings associated with it.

The DPCM samples are loaded into the extended up to 64 Kbytes memory (WRAM).

Debug Hub

Breaknes debug infrastructure.

Warning: The current implementation is based on string associative lists and cannot be considered superfast.

Since Breaknes is a gate-level emulator, the main focus of debugging is monitoring various signals, buses and other internal states of the emulated system.

Debug entities are divided into the following categories:

Debug Hub

DebugInfo

From the GUI side, DebugInfo is displayed as PropertyGrid. The PropertyGrid is filled in dynamically, based on debugging information entries returned by the native Breaknes core.

Debug Information Types (DebugInfoType):

Methods:

MemLayout

The different pieces of memory within the emulated system are described by the MemDesrciptor structure.

Methods:

The managed app (Breaknes)

NES/Famicom/Dendy emulator at the gate level.

Two TV Sets (issue #515)

The emulator supports up to 2 virtual TV Sets. The video signal of each PPU of the motherboard is bound to a TV Set; the binding is configured in the BoardDescription.json:

Select a debug board ("NES Debug: one PPU on two TVs (horizontal)" or "NES Debug: one PPU on two TVs (vertical)") in the settings to see the two-TV window in action.

Build

Use VS2022.

To make the generation of the native and managed parts in the same Build folder, you need to use this:

https://docs.microsoft.com/en-us/answers/questions/202445/output-path-ignored-with-net-5-c-classes-lib.html

The SDL2 port (BreaknesSDL)

For those who like minimalism — Breaknes build using SDL2.

The implementation does not differ from Managed application: the same native part of BreaksCore is used. The motherboard and chip revisions are taken from the BoardDescription.json (next to the executable, shared with the managed application): the SDL build looks up the board by name, the config is required (there is no built-in fallback).

Selecting the board

By default the NES (NES-CPU-07, 1987) entry of the BoardDescription.json is used. Any other board from the same file can be selected on the command line:

breaknes --board "NES-101 (NESN-CPU-JIO-01, 1994-1995)" game.nes

Two TV Sets (issue #515)

The SDL build renders the video signal of every connected TV Set in one window. Up to 2 TVs are supported; the physical arrangement is controlled by the tv_layout property of the board in BoardDescription.json:

The binding of the PPUs to the TVs is described by the tvs array (tvs[i] = index of the PPU shown on the i-th TV). The default binding is TV[i] shows PPU[i]; for debugging, one PPU can be bound to both TVs at once ("tvs": [0, 0]).

IO subsystem

The IO subsystem is integrated into the SDL build (issue #516). SDL2 Input is used as the source of input events:

The devices (Famicom/NES/Dendy controllers, virtual controllers), their bindings of IOState to input events and the Attach/Detach status to the motherboard ports are configured interactively:

breaknes --ioconfig [config_path]

The logic of the configurator is based on the IO settings dialog of the managed application (Breaknes/FormIOConfig.cs): the device pool (add/remove), the bindings (IOState <-> input event) and the Attach/Detach to ports.

The IO settings are stored separately from the managed application (IOConfigSDL.json by default, the managed application uses its own IOConfig.json), so the settings never overlap. At startup the emulator loads the settings from the same file and attaches the configured devices.

Note: virtual controllers have no on-screen dialogs in the SDL build; they are driven by the bound keyboard/game controller events like ordinary controllers.

Source: Breaknes/BreaksCore/Readme.md, Breaknes/Breaknes/Readme.md, Breaknes/BreaknesSDL/Readme.md · this page is part of the docs site.