A project that encompasses both an assembler and a TUI emulator for the fictional NandGame computer.
Written in C99 and complies with POSIX.1-2001 through to POSIX.1-2024.
The assembler ngc-asm reads NandGame assembly instructions from a given file path and assembles NandGame machine code.
$ cat memset.asm
D = -1
LABEL loop
A, D = D + 1
*A = -1
A = loop
JMP
$ ngc-asm memset.asm -o memset.bin
NandGame machine code is output using the system's endianness.
$ ngc-asm [-vh] [-o <path>] <path>
| Option | Description |
|---|---|
<path> |
Path to assembly file. If - is used, then file will be read from stdin. |
-o <path> |
Path to output assembled machine code. If not specified, assembled machine code will be output to stdout. |
| -v, -V | Print version and exit. |
| -h | Print help and exit. |
| Value | Description |
|---|---|
| 0 | Success. |
| 1 | General failure. |
| 2 | Failure due to invalid CLI arguments. |
| 4 | Failure due to invalid assembly file. |
| 8 | Failure due to assembly language syntax error. |
The assembler supports a superset of the original NandGame assembly language. The main new language feature supported is macro definitions.
The assembler intends to be backwards-compatible the original NandGame assembly language. Any unintended differences to the original NandGame should be considered a bug.
The assembler supports syntax for declaring macros.
A macro definition begins with the opening statement %MACRO <name> [<parameters> ...], followed by the instructions within the macro, and then completed with the closing statement %END.
%MACRO push.static address
A = address
D = *A
push.D
%END
Some language features are either forbidden or behave differently if they are used within a macro definition. The table below lists differences in language features between usage within a regular assembly and usage within a macro definition.
| Feature | Within regular assembly | Within macro definition |
|---|---|---|
DEFINE statements |
Allowed, scoped to the file | Allowed, scoped to the macro |
LABEL statements |
Allowed, scoped to the file | Allowed, scoped to the macro |
%MACRO definitions |
Allowed | Forbidden |
Like DEFINE and LABEL statements, a macro can be called both before and after its definition.
Listed below are assembler features that are being considered, but not guarenteed to be implemented.
- CLI option(s) to set the endianness of the output machine code.
- Support for combining multiple assembly files (for now you can
catassembly files together, e.g.$ cat shared.asm my_program.asm | ngc-asm -). This could be in the form of either:- A new language feature to import other assembly files, e.g.
%INCLUDE shared.asm. - A new CLI option to prefix the given assembly file with another, e.g.
ngc-asm -i shared.asm my_program.asm.
- A new language feature to import other assembly files, e.g.
- Allow multiple syntax errors to be returned when assembling files, rather than returning only the first encountered error.
- Windows support.
The emulator ngc-emu loads NandGame machine code from a given file into the emulated ROM, where it will begin executing.
$ ngc-emu memset.bin
If the file path given is -, machine code instructions will be read from stdin.
$ ngc-asm memset.asm | ngc-emu -
NandGame machine code is expected to use the system's endianness.
Once the emulated program counter reaches the end of ROM, the emulator will exit.
| Key | Action |
|---|---|
P |
Pause/resume clock. |
S |
Step clock one cycle (when paused). |
[ |
Decrease clock speed 10x. |
] |
Increase clock speed 10x. |
R |
Reset volatile memory (RAM and registers). |
Q, Esc |
Exit. |
Listed below are emulator features that are being considered, but not guarenteed to be implemented.
- Additional CLI options.
- Set the expected endianness of the read machine code.
- Start the emulator paused or at a given clock speed.
- Halt the emulator when end of ROM is reached, rather than exit.
- Additional TUI functionality.
- Edit memory.
- Change displayed numerical units (binary, hex, decimal) per window.
- Display ROM as de-assembled instructions.
- Map emulated memory to files, facilitated by mmap. This would allow the emulator to interface with memory-mapped hardware, both emulated and physical.
- Unit tests.
- Windows support. Possibly would not include support for mapping emulated memory to files.
Ensure the following is available on your system:
- GCC or clang. To use clang,
CC=clangmust be passed to make commands. - An X/Open Curses implementation such as ncurses or PDCurses. This is required for the emulator only.
Clone and build:
(Replace github.com with gitlab.com if using GitLab)
$ git clone https://github.com/n-ivkovic/ngc
$ cd ngc
$ make
Run without installing:
$ ./ngc-asm code.asm | ./ngc-emu -
Install and run:
# make install
$ ngc-asm code.asm | ngc-emu -
Update after installing:
$ git pull master
$ make
# make install
Additional options:
$ make help
Please adhere to the following when creating a pull request:
- Ensure changes are branched from
developand the pull request merges back intodevelop. - Ensure changes do not cause the compiler to return any new warnings or errors.
- Ensure changes match the general coding style of the project. However, no specific style is prescribed.
- Ensures changes conform to standards followed by the project.
- Unless specified otherwise, only features available in C99 are allowed.
- POSIX features may be included only in the user interface files: ./src/asm/cli.c and ./src/emu/tui.c. Limiting POSIX features to the interfaces only ensures the core logic remains as portable as possible.
- Specifically conform to POSIX.1-2001, but do not utilise features removed from or marked as obsolete in newer standards up to POSIX.1-2024.
- Features available in standards newer than POSIX.1-2001 may be utilised as long as fallbacks are implemented.
- Ensure all ASM tests pass when making changes to
ngc-asm. Tests can be executed usingmake test-asm.
Copyright © 2025 Nicholas Ivkovic.
Licensed under the GNU General Public License version 3 or later. See ./LICENSE, or https://gnu.org/licenses/gpl.html if more recent, for details.
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.