Giter Site home page Giter Site logo

asmotor / asmotor Goto Github PK

View Code? Open in Web Editor NEW
59.0 7.0 34.0 2.69 MB

Powerful macro (cross) assembler package for several CPUs

License: GNU General Public License v3.0

Shell 0.68% Assembly 10.27% C 85.35% NSIS 0.19% CMake 3.29% PowerShell 0.08% R 0.13%
assembler gameboy rgbds retro 68k 680x0 amiga commodore sega genesis

asmotor's Introduction

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.

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.

The assembler syntax is based on the friendly, well-known Motorola style macro language. ASMotor aims to be a friendly assembler and toolchain, well-suited to projects that incorporate a large body of hand crafted assembly code.

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

In addition to raw binary dumps, the linker can output target specific binaries for a number of devices using these processors - various Commodore machines, Nintendo Game Boy, Sega Master System and Genesis and more.

Interoperability is important and continues to improve. The linker will read ASMotor's own object format and ELF linkable objects, so it is easy to use a bit of C if necessary. The assembler can output ASMotor's own object format, Amiga hunk format (link and executable) and ELF. The assembler should slot right in to another toolchain without any trouble, if that is preferred.

Why choose ASMotor?

Mix different architectures easily. No special tricks or other tools required, assemble a 6502 file and a Z80 file and have the linker output a ready to run Commodore 128 .PRG. ASMotor is also a great fit for Sega Genesis (Mega Drive) with its 68000 main CPU and Z80 subsystem.

Cross-assemble or not. The package is 100% portable ANSI C99 and will work as a native or cross assembler.

Quality of life built in:

Flexible constant expressions. All expressions, whose value the assembler's macro language does not need to know, are deferred to the linker. That means this contrived example is valid, because why shouldn't it be?

           moveq  #(MyConstant + SomebodyElsesExportedConstant) & $8F,d0

MyConstant EQU 4
           IMPORT SomebodyElsesExportedConstant

String interpolation is available with embedded expressions in string literals, for instance "The result of 4*5 is {4*5}" will produce the string "The result of 4*5 is 20". Many formatting options and functions are available to use on both integers and strings.

Speaking of strings, code and data literals can be used to reduce clutter and improve readability. To load the register a0 with the address of a string, you might do

lea { DC.B "This is a string",0 },a0

or to produce the address of a chunk of code

jsr {
	moveq #0,d0
	rts
}

Complete macro language. The macro language is based on Motorola's syntax and includes common extensions such as macros, repeating blocks of code and conditional assembly. While basic, the features have been tuned to allow for Turing completeness. Features for fixed point math are also present, it is for instance straightforward to generate a sine table at translation time using the macro language, or even the Mandelbrot set.

Installing

Prebuilt binary

Binaries can be found in the releases section.

There is no schedule for releases, and binaries are most likely somewhat older than the most recent commit. Releases happen after a period of dog fooding without any issues.

Installing from source

The latest in-development version can easily be installed from source by following the directions below. Generally the master branch should be stable and safe to use.

Windows

A script (install.ps1) 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 the 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; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/asmotor/asmotor/master/install.ps1'))

Linux and macOS

The project uses the just command runner for project operations. An install recipe is available that will compile and install the compiled binaries into the $HOME/.local/bin directory. This path should be added to your $PATH for easier use. This recipe will also accept the destination root as an argument (for instance /usr/local).

For even easier installation on a supported platform, the latest version of ASMotor can be installed using the install.sh script. Currently supported platforms are ones with either port (MacPorts macOS), brew (Homebrew macOS/Linux), apt-get (Debian, Ubuntu and derivates), dnf (Fedora and friends) or pacman (Arch and derivates) installed. If the platform is not currently supported by install.sh it will complain and prompt you to install the necessary prerequisites just, git and cmake yourself.

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

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

curl https://raw.githubusercontent.com/asmotor/asmotor/master/install.sh | bash -s /usr/local "sudo"

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

asmotor's People

Contributors

csoren avatar moonheart08 avatar ryandesign avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

asmotor's Issues

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?

Error installing: Build failure in tokens.c

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

marcel@marcel-linux:/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.

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+)

[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)

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 ());
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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.

"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;
}

m68k branch offset wrong when ORG is used

If the following is assembled with motor68k -fb:

	SECTION "main",CODE
	ORG $100
	bra target	; 100
	nop		; 104
	nop		; 106
	nop		; 108
	nop		; 10a
	nop		; 10c
	nop		; 10e
target:	rts		; 110

... then the bra instruction is assembled as 6000 0010, which would jump to $112. If you remove the ORG then it's assembled correctly.

(Thanks for asmotor - I've been having a lot of fun writing 68k code with it lately!)

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.

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.

Z80: Error "SECTION_FULL" if section size exceeds 16kB

First of all many thanks for the asmotor project. Great work for many retro friends!

I tried the cpm-loader program for my C128. That worked well.
Then when I tested it with the current asmotor code (1.3.0.rc), the motorz80 program encountered the SECTION_FULL error when inserting binary data beyond the 16kB size.
The cause of the problem was that z80_ParseOption() works with a local copy of the structure z80_XasmConfiguration and therefore only the default value 16kB of the section size was used in the assembler.

The changes concern 2 source files.
z80_main.c: line 31 (delete static)

SConfiguration
z80_XasmConfiguration = {

z80_options.c: line 31 (add external)

external SConfiguration z80_XasmConfiguration;

These changes have eliminated the error for me and the program works.

☺️

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.