ASMotor is a portable and generic assembler engine and development system written in ANSI C99

ASMotor

ASMotor is a portable and generic assembler engine and development system written in ANSI C99 and licensed under the GNU Public License v3. The package consists of the assembler, the librarian and the linker. It can be used as either a cross or native development system.

The assembler syntax is based on the Motorola style macro language.

Currently supported CPUs are the 680x0 family, 6502, MIPS32, Z80, Game Boy, DCPU-16, CHIP-8/SCHIP and the RC811 CPU core.

ASMotor is the spiritual successor to RGBDS, which was a fairly popular development package for the Game Boy. ASMotor is written by the original RGBDS author.

Installing

Building from source

Windows

A script (install.sh) is included that will install the compiled binaries into the %USERPROFILE%\bin directory. This path should be added to your $PATH for easier use. This script will also accept the destination root (for instance %USERPROFILE\\bin). The installation directory should be added to your path variable.

To build from source, cmake must be installed. Installing cmake with Chocolatey using command choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' is suggested. A C compiler that cmake can find must also be installed. Visual Studio Community edition is suggested.

Then, using PowerShell, run the following commands:

	Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
	install.ps1

Linux and macOS

A script (install.sh) is included that will install the compiled binaries into the $HOME/bin directory. This path should be added to your $PATH for easier use. This script will also accept the destination root (for instance /usr/local).

For even easier installation, provided you have the necessary prerequisites, git and cmake, installed, the latest version of ASMotor can be installed using

    curl https://raw.githubusercontent.com/asmotor/asmotor/master/bootstrap.sh | sh

If you want to install it globally, you can supply the installation prefix as a parameter:

    curl https://raw.githubusercontent.com/asmotor/asmotor/master/bootstrap.sh | sh -s /usr/local

To install git and cmake, it is suggested you use your distribution's package manager. For macOS, use brew or MacPorts.

Editing code

A VSCode extension that enables syntax highlighting is also available at https://marketplace.visualstudio.com/items?itemName=ASMotor.asmotor-syntax

Further reading

Dive into the documentation to learn more about:

Index and reference

Comments
  • compilation errors due to unresolved warnings and -Werr

    compilation errors due to unresolved warnings and -Werr

    [ 32%] Building C object xasm/common/CMakeFiles/xasm.dir/tokens.c.o
    xasm/common/tokens.c: In function 'parseSymbol':
    common/tokens.c:308:9: error: 'strncpy' specified bound 257 equals destination size [-Werror=stringop-truncation]
      308 |         strncpy(lex_Current.value.string, str_String(symbolName), sizeof(lex_Current.value.string));
          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    cc1: all warnings being treated as errors
    

    pretty sure we're dealing with a simple off-by-one here, since strncpy shouldn't copy a maximum of sizeof dest chars if it's supposed to append a \0 (which it is, since it's strncpy, not memcpy).

    the same happens a bunch of other times too in xlib/library.c.

  • Referencing two undefined labels produces a core dump

    Referencing two undefined labels produces a core dump

    I'm taking my first stumbling steps on starting to program for the Sega Genesis, and right on the first little test I've managed to break something. I'm using asmotor on Linux.

    This is my code. Note that I have not yet defined ProgramStart or IntReturn.

    SECTION "INIT",CODE[0]
    
    
    	DC.L	$FFFFFE00		;SP register value
    	DC.L	ProgramStart	;Start of Program Code
    REPT 7
    	DC.L	IntReturn		; bus err,addr err,illegal inst,divzero,CHK,TRAPV,priv viol
    ENDR
    	DC.L	IntReturn		; TRACE
    	DC.L	IntReturn		; Line A (1010) emulator
    	DC.L	IntReturn		; Line F (1111) emulator
    REPT 4
    	DC.L	IntReturn		; Reserverd /Coprocessor/Format err/ Uninit Interrupt
    ENDR
    REPT 8
    	DC.L	IntReturn		; Reserved
    ENDR
    	DC.L	IntReturn		; spurious interrupt
    	DC.L	IntReturn		; IRQ level 1
    	DC.L	IntReturn		; IRQ level 2 EXT
    	DC.L	IntReturn		; IRQ level 3
    	DC.L	IntReturn		; IRQ level 4 Hsync
    	DC.L	IntReturn		; IRQ level 5
    	DC.L	IntReturn		; IRQ level 6 Vsync
    	DC.L	IntReturn		; IRQ level 7 
    REPT 16
    	DC.L	IntReturn	; TRAPs
    ENDR
    REPT 16
    	DC.L	IntReturn	; Misc (FP/MMU)
    ENDR
    

    I'm compiling it with:

    motor68k -otest.bin -fb test.asm
    

    This outputs:

    realloc(): invalid next size
    [1]    4240 abort (core dumped)  motor68k -otest.bin -fb test.asm
    

    Expected behavior: The assembler complains about undefined labels. With just some small changes, that's exactly what it does. For example if I define either ProgramStart or IntReturn, it correctly complains that the other label is undefined.

  • Issue in calculating fixed section placement/sizes

    Issue in calculating fixed section placement/sizes

    This issue was discovered while trying to put each part of the Sega Genesis ROM header in a separate, fixed location section. However, this code fails. (Just these 4 lines alone should be sufficient to repro.)

    SECTION "HDR_SERIALNUMBER",DATA[$180]
    	DC.B	"012345678"			;ROM serial number
    
    SECTION "HDR_CHECKSUM",DATA[$18E]
    	DC.W	$1234				;16-bit Checksum (Address $000200+)
    

    Compile with:

    motor68k -otest.bin -fb test.asm
    

    Output:

    E0131 test.asm(7): Section "" cannot be placed at $18E
    

    However, the string in the HDR_SERIALNUMBER section is only 9 bytes long, which should not overlap the next section by a good margin. Suspecting it might be an issue with alignment of sections I also tried:

    SECTION "HDR_SERIALNUMBER",DATA[$182]
    	DC.B	"012345678"			;ROM serial number
    
    SECTION "HDR_CHECKSUM",DATA[$190]
    	DC.W	$1234				;16-bit Checksum (Address $000200+)
    

    Which gave the same error. In both cases, reducing the length of the string to 8 bytes got rid of the error. However, the following worked just fine, filling every single byte up until the next section.

    SECTION "HDR_SERIALNUMBER",DATA[$180]
    	DC.B	"0123456789ABCDEF"			;ROM serial number
    
    SECTION "HDR_CHECKSUM",DATA[$190]
    	DC.W	$1234				;16-bit Checksum (Address $000200+)
    
  • Error installing: Build failure in tokens.c

    Error installing: Build failure in tokens.c

    • Fresh Linux Mint 20 install
    • just installed build-essentials
    • this:

    [email protected]:/asmotor_bootstrap$ sudo sh install.sh -- The C compiler identification is GNU 9.3.0 -- The CXX compiler identification is GNU 9.3.0 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done -- Generating done -- Build files have been written to: /home/marcel/asmotor_bootstrap/build/cmake/release Scanning dependencies of target util [ 1%] Building C object util/CMakeFiles/util.dir/crc32.c.o [ 1%] Building C object util/CMakeFiles/util.dir/file.c.o [ 2%] Building C object util/CMakeFiles/util.dir/fmath.c.o [ 3%] Building C object util/CMakeFiles/util.dir/map.c.o [ 4%] Building C object util/CMakeFiles/util.dir/mem.c.o [ 5%] Building C object util/CMakeFiles/util.dir/set.c.o [ 6%] Building C object util/CMakeFiles/util.dir/str.c.o [ 7%] Building C object util/CMakeFiles/util.dir/strcoll.c.o [ 8%] Building C object util/CMakeFiles/util.dir/strbuf.c.o [ 9%] Building C object util/CMakeFiles/util.dir/strings.c.o [ 10%] Linking C static library libutil.a [ 10%] Built target util Scanning dependencies of target xasm [ 11%] Building C object xasm/common/CMakeFiles/xasm.dir/amigaobject.c.o [ 12%] Building C object xasm/common/CMakeFiles/xasm.dir/binaryobject.c.o [ 13%] Building C object xasm/common/CMakeFiles/xasm.dir/dependency.c.o [ 14%] Building C object xasm/common/CMakeFiles/xasm.dir/errors.c.o [ 15%] Building C object xasm/common/CMakeFiles/xasm.dir/expression.c.o [ 16%] Building C object xasm/common/CMakeFiles/xasm.dir/filestack.c.o [ 17%] Building C object xasm/common/CMakeFiles/xasm.dir/lexer.c.o [ 18%] Building C object xasm/common/CMakeFiles/xasm.dir/lexer_constants.c.o [ 19%] Building C object xasm/common/CMakeFiles/xasm.dir/lexer_variadics.c.o [ 20%] Building C object xasm/common/CMakeFiles/xasm.dir/linemap.c.o [ 21%] Building C object xasm/common/CMakeFiles/xasm.dir/object.c.o [ 22%] Building C object xasm/common/CMakeFiles/xasm.dir/options.c.o [ 23%] Building C object xasm/common/CMakeFiles/xasm.dir/parse.c.o [ 24%] Building C object xasm/common/CMakeFiles/xasm.dir/parse_block.c.o [ 25%] Building C object xasm/common/CMakeFiles/xasm.dir/parse_directive.c.o [ 26%] Building C object xasm/common/CMakeFiles/xasm.dir/parse_expression.c.o [ 27%] Building C object xasm/common/CMakeFiles/xasm.dir/parse_string.c.o [ 28%] Building C object xasm/common/CMakeFiles/xasm.dir/parse_symbol.c.o [ 29%] Building C object xasm/common/CMakeFiles/xasm.dir/patch.c.o [ 30%] Building C object xasm/common/CMakeFiles/xasm.dir/section.c.o [ 31%] Building C object xasm/common/CMakeFiles/xasm.dir/symbol.c.o [ 32%] Building C object xasm/common/CMakeFiles/xasm.dir/tokens.c.o In file included from /usr/include/string.h:495, from /home/marcel/asmotor_bootstrap/xasm/common/tokens.c:19: In function ‘strncpy’, inlined from ‘parseSymbol’ at /home/marcel/asmotor_bootstrap/xasm/common/tokens.c:308:9: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:10: error: ‘__builtin_strncpy’ specified bound 257 equals destination size [-Werror=stringop-truncation] 106 | return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors make[2]: *** [xasm/common/CMakeFiles/xasm.dir/build.make:336: xasm/common/CMakeFiles/xasm.dir/tokens.c.o] Fehler 1 make[1]: *** [CMakeFiles/Makefile2:328: xasm/common/CMakeFiles/xasm.dir/all] Fehler 2 make: *** [Makefile:130: all] Fehler 2

    "Fehler" (german) -> Error Had to remove ~ because of markdown.

  • [680x0] bcc with address in absolute-short range yields source operand error

    [680x0] bcc with address in absolute-short range yields source operand error

    The following code

    	section "ROM", CODE[$0]
    forever:
    	bra forever
    

    Produces the error foo.s68:3: E0103 Invalid source operand I believe what is happening here is that m68k_GetAddressingMode does some optimization on the addressing mode and so a bare label like forever in this example gets transformed into AM_WORD if the value of the symbol is already known and within the valid range for absolute short. The instruction table entries for the bcc family only have AM_LONG in the valid addressing mode bitfield which results in an error when this optimization is done

    Simplest fix is probably just to add AM_WORD as a valid addressing mode to the bcc family, but I'm not sure if that was omitted intentionally (perhaps to forbid an explicit .w for these instructions since it doesn't make sense)

  • Ambiguous C language requirements

    Ambiguous C language requirements

    README.md says:

    ASMotor is a portable and generic assembler engine and development system written in ANSI C11

    but CMakeLists.txt says:

    set (CMAKE_C_STANDARD 99)
    

    Which C language standard is required—C99 or C11?

  • sprintf format overflow

    sprintf format overflow

    /home/moony/asmotor_bootstrap/xasm/common/parse_string.c: In function ‘stringExpressionPri1’:
    /home/moony/asmotor_bootstrap/xasm/common/parse_string.c:95:25: error: ‘%0*d’ directive writing between 1 and 2147483647 bytes into a region of size 16 [-Werror=format-overflow=]
                 sprintf(t, "%0*d", precision < 0 ? 0 : precision, value);
                             ^~~~
    /home/moony/asmotor_bootstrap/xasm/common/parse_string.c:95:24: note: directive argument in the range [0, 2147483647]
                 sprintf(t, "%0*d", precision < 0 ? 0 : precision, value);
                            ^~~~~~
    In file included from /usr/include/stdio.h:873,
                     from /home/moony/asmotor_bootstrap/util/types.h:24,
                     from /home/moony/asmotor_bootstrap/util/lists.h:22,
                     from /home/moony/asmotor_bootstrap/xasm/common/patch.h:22,
                     from /home/moony/asmotor_bootstrap/xasm/common/errors.h:22,
                     from /home/moony/asmotor_bootstrap/xasm/common/parse_string.c:23:
    /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 2 and 2147483648 bytes into a destination of size 16
       return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           __bos (__s), __fmt, __va_arg_pack ());
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    cc1: all warnings being treated as errors
    
    
    
    [ 27%] Building C object xasm/common/CMakeFiles/xasm.dir/symbol.c.o
    /home/moony/projects/cpp-projects/asmotor/xasm/common/symbol.c: In function ‘callback__AMIGADATE’:
    /home/moony/projects/cpp-projects/asmotor/xasm/common/symbol.c:87:27: warning: ‘%d’ directive writing between 1 and 11 bytes into a region of size between 0 and 12 [-Wformat-overflow=]
         size_t stringLength = sprintf(dateString, "%d.%d.%d", localTime->tm_mday, localTime->tm_mon + 1, localTime->tm_year + 1900);
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /home/moony/projects/cpp-projects/asmotor/xasm/common/symbol.c:87:27: note: directive argument in the range [-2147481748, 2147483647]
    In file included from /usr/include/stdio.h:873,
                     from /home/moony/projects/cpp-projects/asmotor/xasm/common/symbol.c:20:
    /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 6 and 36 bytes into a destination of size 16
       return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           __bos (__s), __fmt, __va_arg_pack ());
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    
  • Remove MacPorts Portfile

    Remove MacPorts Portfile

    Portfiles belong in https://github.com/macports/macports-ports only.

    The PR to get the asmotor Portfile there updated is https://github.com/macports/macports-ports/pull/9663.

  • "invalid expression" for `n` in `SECTION....,BANK[n]`

    having noticed you didn't disallow banks on the "generic z80" target (and no way to set the bank size, so i hoped for something smart along the lines of "one binary file per bank"), i decided to check what it does with some simple code:

      SECTION "a",CODE
      DB $01
      SECTION "b",CODE[5]
      DB $02
      SECTION "c",CODE[10],BANK    ; E0100 [ expected ; (this is expected behaviour)
      DB $03
      SECTION "d",CODE[15],BANK[3] ; E0102 Invalid expression
      DB $04
      SECTION "e",CODE,BANK[3]     ; E0102 Invalid expression
      DB $05
    

    and with motorz80 -mcz -ms0 -mu0 i'm getting the errors i commented above.

    the parser seems to be totally fine with the BANK itself (and doesn't complain about banking being unsupported), but my integer is an invalid expression somehow in BANK (but totally fine in CODE).

    so it seems to be failing to recognize an integer in parse_ConstantExpression (called by expectBankFixed) if i'm not mistaken.

    following the control flow in those functions in my head, specifically this seems to fail:

    int32_t
    parse_ConstantExpression() {
        SExpression* expr = parse_Expression(4); // <-- this returns NULL??
    
        if (expr != NULL) {
          // ...
        } else
            err_Error(ERROR_INVALID_EXPRESSION); // <-- pretty sure I'm getting this error
        return 0;
    }
    
  • SuperFX(2) assembler/disassembler

    SuperFX(2) assembler/disassembler

    Support for the SuperFX co-processor would be a welcome addition to complement the 6502 support, as it would allow the development of SuperFX accelerated SNES games using asmotor.

A mini assembler for x86_64, written for fun and learning.

minias A mini assembler for x86_64, written for fun and learning. Goals: A simple, tiny, fast implementation (in that order). Assemble the output of c

Oct 18, 2022
Nov 16, 2022
Semantic version library written in ANSI C

semver.c Semantic version v2.0 parser and render written in ANSI C with zero dependencies. Features Standard compliant (otherwise, open an issue) Vers

Nov 28, 2022
Stack-based texture generation tool written in C99!
Stack-based texture generation tool written in C99!

Stack-based texture generation tool written in C99! Brought to you by @zaklaus and contributors Introduction zpl.texed is a cross-platform stack-based

Sep 10, 2022
Commodore 6502ASM, the original 6502/65C02/65CE02 Assembler used by Commodore for C65 project

Commodore 6502ASM This is the source code of the 6502/65C02/65CE02 assembler developed and used by Commodore for the C65 project. It aims to be compat

Nov 29, 2022
A mini x86-64 assembler for fun

A mini x86-64 assembler for fun

Oct 18, 2022
A simple assembler, made primarily for assembling output from my compiler.

Assembler This assembler is not currently meant for general use. It supports only the instructions and features emitted (and used) in my C compiler. I

Nov 14, 2021
Toy 8 bit CPU with a real assembler

neko8 neko8 is a 8 bit CPU emulator designed to be easy to learn written in C. It uses its own simple architecture and can be programmed in its own fo

Jan 4, 2022
x86 Assembler used for generating shellcode

Intel x86 assembler [email protected] syntax: Decimal “integers begin with a non-zero digit followed by zero or more decimal digits (0–9)” B

Nov 27, 2022
A basic assembler

Assembler ASSEMBLER DERLEYİCİSİ Programlama Dilleri (derleyiciler) giriş olarak yazılan bir programın kaynak kodunu alır (kodun doğru yazıldığı varsay

Nov 22, 2021
A fully customisable assembler for your own instruction sets

CASM A fully customisable assembler for your own instruction sets! What Is CASM? ?? Documentation ?? Command-Line Usage ?? How To Install CASM ?? Buil

May 7, 2022
x86-64 Assembler based on Zydis

Zasm : x86-64 Assembler based on Zydis Why? Some of my projects were using Zydis and AsmJit where instructions where were first decoded with Zydis and

Nov 27, 2022
CQC (Charmed Quark Controller) a commercial grade, full featured, software based automation system. CQC is built on our CIDLib C++ development system, which is also available here on GitHub.

The CQC Automation System What It Is CQC is a commercial quality, software based automation system, suitable for residential or commercial application

Oct 2, 2022
Tiny and portable Game Boy emulator written in C.

TinyGB TinyGB is a tiny and portable Game Boy emulator written entirely in C as a hobbyist one-man project. I only wrote this to deepen my understandi

Nov 25, 2022
A portable full system emulator of Z280 based boards

z280emu A portable full system emulator of Z280 based boards Motivation There is no working Z280 emulator that I'm aware of so I decided to write one.

Oct 8, 2022
Espressif ESP32 implementation of ANSI-ESTA E1.11 DMX-512A

This library allows for transmitting and receiving ANSI-ESTA E1.11 DMX-512A using an Espressif ESP32. It provides control and analysis of the packet configuration and allows the user to read synchronously or asynchronously from the DMX bus. This library also includes tools for data error-checking to safely process DMX commands.

Nov 28, 2022
My ANSI C solutions for Advent of Code.

ansi-adventure My optimized ANSI C solutions for Advent of Code. I tried favoring speed and performance the most here than most advent of code repos.

Dec 12, 2021
an implementation of the ansi c standard library that makes sense when ur stoned, tired, or otherwise inebriated

eli5 c stdlib an implementation of the ansi* c standard library that makes sense when ur stoned, tired, or otherwise inebriated * apparently this (htt

Oct 13, 2021
SDK for building cross-platform desktop apps in ANSI-C
SDK for building cross-platform desktop apps in ANSI-C

NAppGUI Cross-Platform C SDK. Build portable desktop applications for Windows, macOS and Linux, using just C. Quick start in Windows Prerequisites Vis

Dec 1, 2022