Bennett/Requirements
< Bennett
Base Requirements
- Multiplatform (Linux/Windows. Mac if possible, but has serious challenges) - use C++/Qt
- Needs to support different different architectures: ARM, RISC-V, [others]
- Needs to be configurable to 8, 12, 16, 24, 32, or 64 bit architecture
- Needs to support different memory models, different register configurations, etc
- Needs be able to work with simulators, or to communicate with a lab board
- Display of CPU registers (which registers are available will depend on architecture)
- Display of Status Flags (which flags are available will depend on architecture)
- Memory view, with optional disassembly.
- View should be configurable to show memory in different ways: single word, multiple words, ascii characters, disassembly (word size and disassembly will depend on architecture) and if an address matches the value in a register, the register name should be highlighted next to that address.
- Multiple memory views need to be available, and individually configurable.
- Breakpoints (stop on PC reaching memory address)
- Watchpoint (stop on value at address being changed/set to value)
- CPU controls: step [single, multiple], run, halt, reset - is continue just another form of 'run', is 'run' just unconstrained 'step'?
- Needs to be extensible to support different simulated memory-mapped peripherals. Peripherals separate from architecture?
- avoid using linux-specific mechanisms for IPC: sockets instead of pipes, for example. Dynamic loading of extensions will need thought (QLibrary system in Qt provides portable option here).
Extras
- Compilers/assemblers for target architectures
- GNU as (GAS) (part of the gcc suite) will target almost any architecture, but may not produce useful file types (MU0 support is curiously absent, for example)
- Writing assemblers for all possible targets is possible but nontrivial. Are there real reasons not to use GAS (mingw under Windows) when a suitable target exists? Would they function as stopgaps in the short-term?
Design thoughts

These are general thoughts about the design, expect these to change/be refined as things progress.
- First, and most important concept: the design of the system is split so that there is a 'monitor core' and a number of 'system modules'
- The core handles module discovery, module selection and loading, and the behaviour of the monitor UI.
- System modules contain AND FULLY ENCAPSULATE individual simulators or hardware interfaces.
- System modules should expose a set of 'capabilities' that describe the configuration of UI elements in the core.
- The core should have absolutely no system-specific logic inside it: it should be an architecture and implementation agnostic user interface that is capable of enabling/disabling/configuring the interface elements presented to the user based on the selected system module capabilities [NOTE: Means we need to decide on an appropriate superset of possible elements
- The core needs to provide a mechanism whereby system modules can register UI extensions. These allow specific UI elements or windows implemented in the system module to be shown to the user. For example, a simulator system module may provide a separate console output window, or a simulated 'screen' and keyboard. Note again: everything about such extensions - from UI definition to callbacks - should happen inside the module, all the core should care about is providing a way to register/add the UI elements!