Nestor80 is Z80, R800 and Z280 assembler written in C# and almost fully compatible with the Microsoft MACRO-80 assembler.
The project also includes Linkstor80 and Libstor80, which are the respective replacements for the LINK-80 and LIB-80 tools that were part of the MACRO-80 package and are relevant when writing relocatable code.
-
Multiplatform. Runs on any machine/OS that supports the .NET 6 runtime; of course this includes Windows, Linux and macOS.
-
Almost fully compatible with Microsoft MACRO-80 for Z80 code (Nestor80 can't assemble 8080 code). Most of the incompatibilites are for obscure or undocumented features.
-
Can produce absolute and relocatable binary files. Relocatable files can conform to the format used by Microsoft LINK-80, or to the format used by SDAS and SDLD (the assembler and linker used by SDCC).
-
Supports the Z80 undocumented instructions.
-
Allows disallowing privileged instructions and I/O instructions when assembling Z280 code.
-
Over 50 program arguments for fine-grained customization of the assembling process and the listing file generation (but all are optional and have sensible defaults). Pass arguments in the command line, in a file, and/or in an environment variable.
-
Detailed, comprehensive error reporting, unlike MACRO-80:
- Use unlimited length, arbitrary character encoding symbols in your code:
Ñoñería: ;This is a valid symbol
このラベルは誇張されていますがNestor80がいかに強力であるかを示しています equ 34 ;This too!
- Modern string handling: it's possible to choose the encoding to be used when converting text strings (supplied as arguments to
DEFB
instructions) to sequences of bytes, and most of the C# string escape sequences are allowed in strings:
.STRENC 850
HELLO_SP:
defb "¡Hola en español, esto es fantástico!"
.STRENC shift_jis
HELLO_JP:
defb "日本語でこんにちは、これは素晴らしいです!"
.STRENC default
JOKE:
defb "A tab,\ta line feed\nand a form feed\fwalk into a bar...\0"
- User-triggered warnings and errors, with support for expression interpolation:
if $ gt 7FFFh
.error ROM page boundary crossed, current location pointer is {$:H4}h
endif
-
Nested INCLUDEd files (MACRO-80 allows only one level for
INCLUDE
) and of course, support for arbitrary paths for included files. -
Additionally to being compatible with MACRO-80 it also borrows a few features from other assemblers, like Sjasm-style modules and relative labels:
call GRAPHICS.INIT
call SOUND.INIT
ret
module GRAPHICS
INIT:
;Init graphics
endmod
module SOUND
INIT:
;Init sound
endmod
INANE:
ld b,34
.loop: ;Actually assembled as INANE.loop
djnz .loop
ret
USELESS:
ld b,89
.loop: ;Actually assembled as USELESS.loop
djnz .loop
ret
- Programmatic API. The
Assembler.dll
library file can be referenced and used from any .NET language in order to assemble code from an IDE or any kind of custom tool. Here's a simple example in C#:
var sourceStream = File.OpenRead("PROGRAM.ASM");
var assemblyConfig = new AssemblyConfiguration() { BuildType = BuildType.Absolute };
var assemblyResult = AssemblySourceProcessor.Assemble(sourceStream, Encoding.UTF8, assemblyConfig);
sourceStream.Close();
if(!result.HasErrors) {
var outputStream = File.Create("PROGRAM.BIN");
OutputGenerator.GenerateAbsolute(assemblyResult, outputStream);
outputStream.Close();
var listingStreamWriter = File.CreateText("PROGRAM.LST");
var listingConfig = new ListingFileConfiguration() { TitleSignature = "My simple assembler" };
ListingFileGenerator.GenerateListingFile(assemblyResult, listingStreamWriter, listingConfig);
listingStreamWriter.Close();
}
The Linker.dll
library file is also available to write code to link relocatable code.
- Head to the releases page and download the appropriate Nestor80 variant for your system. Note that:
- The "Framework dependant" and "Portable" variants require the .NET 6 runtime to be installed.
- The "Standalone" variants don't require the .NET runtime to be installed, but they are much bigger in size (about 60MB vs about 400KB for the framework dependand variants).
- You'll need the "Portable" variant if your system supports .NET 6 but there isn't a a native variant (standalone or framework dependant) available. To run this variant the
dotnet
tool (installed as part of the .NET runtime) needs to be used as follows:dotnet N80.dll <arguments>
. Otherwise this variant works exactly like the native ones.
You may want to get a standalone variant if you just want to give Nestor80 a try, but if you plan to use it regularly the framework dependant variants are recommended.
- Paste this sample Z80 code (a "hello world" ROM for MSX computers) in a text file, name it HELLO.ASM:
CHGET: equ 009Fh
CHPUT: equ 00A2h
org 4000h
db 41h,42h
dw START
ds 4010h-$
START:
call PRINT
call CHGET
ret
PRINT:
ld hl,HELLO
loop:
ld a,(hl)
or a
ret z
call CHPUT
inc hl
jr loop
HELLO:
db "Hello, world!\r\n"
db "Press any key...\0"
;Padding to get a 16K ROM
;(required by some emulators)
ds 8000h-$
- Run the following:
N80 HELLO.ASM
.
The source will be assembled and a binary file named HELLO.BIN
will be produced (if you want the file name to be HELLO.ROM
instead, run N80 HELLO.ASM HELLO.ROM
or N80 HELLO.ASM --output-file-extension ROM
).
- Burn the resulting
HELLO.BIN/.ROM
file in a flash cartridge, insert it in your MSX, and turn it on. Or (probably easier) use an MSX emulator such as WebMSX.
Here's the full documentation you might want to take a look at before (or while!) using Nestor80 to assemble your Z80 code:
- Language reference, explains the supported assembly language syntax and lists the available pseudo-operators.
- Writing relocatable code, explains in depth how the process of writing and linking relocatable code works.
- Relocatable file format reference, details the format of the LINK-80 relocatable files generated by Nestor80.
- Z280 support, contains relevant information related to the Z280 processor support.
- SDCC relocatable file format support, contains information related to the SDCC relocatable file format and how Nestor80 builds such files.
To get the full reference of the existing command line arguments, including how to use environment variables and files to pass arguments, you can run Nestor80 with the --help
argument; to get help about a specific argument, add the short or the long argument name after --help
, for example N80 --help se
or N80 --help string-encoding
. You can also look at the help text in the Nestor80 source code.
If you want to build Nestor80 itself you have two options:
- Use Visual Studio (2022 or newer)
Open the Nestor80 solution, right click in the N80, LK80 or LB80 project, and click "Build". If you want to build for a platform other than Windows you'll need to configure the target platform of the projects, see: How to: Configure projects to target platforms.
- Use a dedicated script
If you don't have Visual Studio (or you prefer a more automated option) you'll need the .NET 7 SDK to build Nestor80. The tools target the .NET 6 runtime, but the .NET 7 SDK is required to build them because the source code uses C#11 syntax that isn't supported by the .NET 6 SDK.
Open a command prompt, go to the root directory of the project and run the build.sh
script. Running it without arguments will build all the variants, which will be located in the N80/Release
, LK80/Release
and LB80/Release
directories; you can choose which tools and which variants are built by using environment variables, for example:
RUNTIMES=linux-x64 PROGRAMS=N80 BUILD_TYPES=FrameworkDependant ./build.sh
See the build.sh
script itself for the available options.
In Linux and macOS you can run the script directly, in Windows 10 and 11 you need to have WSL installed and run it like this: wsl ./build.sh
The assembler syntax supported by MACRO-80 is quite complex and thus Nestor80 is a complex program. Expect to find bugs in the first few releases, especially when dealing with complex macros and conditional blocks in code; if you are one of the lucky ones, please submit an issue in GitHub so that I can take a look. Please add as many information as possible to help me reproduce the error, including the error message and the "offending" source code snippet.
I hope Nestor80 is useful for you. On a completely unrelated and random note, and just in case you feel generous, my PayPal is open, just sayin'.