Atari cross-development

List of contents:

  1. Introduction
  2. Cross compiling and setting up of cygwin and gcc 4.4.0 under win XP
  3. Cross compiling and setting up of cygwin and gcc 4.4.0 with vasm as a m68k assembly compiler under win XP
  4. Cross compiling with VBCC under win XP with TOS/MiNT targets
  5. Installing and setting up FreeMiNT environment under Aranym and/or STEEM as a testbed for our programs
  6. Debugging your programs
  7. How to include assembly(GAS) with GCC
  8. External references
  9. Credits

Last updates:

1) Introduction

This article is an attempt to gather all the needed instructions to set up fully working development environment that will enable you writing and compiling programs for TOS/MiNT based machines under modern operating systems.

The benefits of this approach are pretty clear:

I will cover here few options available:

There is possibility to debug your applications with gdb (natively or under cross development environment with X11 DDD frontend), but I can’t write anything about it at this moment, because there are some problems with cygwin X11 packages and I wasn’t able to set up working X11 server :( .

There also other options like using VBCC under Mac OSX and cross-development with gcc under Linux, but they will be not covered here. Instead, I will put some references regarding this topic in the end of this article.

I will also try to cover some basic how-to’s regarding setting up makefiles for different targets (CPU wise and release-wise), using additional tools that will help during development process (packing, generation of documentation).
I don’t think that I will cover all the issues involved (it’s not physically possible). If you think that something should be added, you’ve spotted an error or you have an idea what is missing and you can provide the missing parts then contact me and I will incude it.

Note: This page at this moment contains some missing parts, which will be added gradually.

2) Cross compiling and setting up of cygwin and gcc 4.4.0 under Windows XP

Follow the instructions contained on the Vincent Riviere page.
As an additional step you can add two lines in your .bashrc file from your $HOME folder:

user@host ~/.bashrc

...
export PATH=$PATH:~/m68k-cross-tools/usr/local/cross-mint/bin
export PATH=$PATH:~/m68k-cross-tools/usr/local/cross-mint/m68k-atari-mint/bin

In the end you will not have to retype all the export commands each time you launch Cygwin.
Note: ‘~’ means current user $HOME folder.

Setting up SDL and other libraries

First thing is to get the sources of SDL. You can grab the sources from Patrice Mandin’s webpage or get the latest snapshot from official SDL SVN repository (http://svn.libsdl.org/branches/SDL-1.2) and rebuild it from sources. Rebuilding from sources is recommended, because it guarantees the proper installation of libraries in your environment.
First thing is generation of configure script, after that we will be launching configure script, we will compile and install library afterwards. Very important is the –prefix switch.
It must point to the directory, where cross compiler is installed. If it will be wrongly specified configure script will be unable to find falcon.h, mintbind.h headers and will be unable to find the correct tools.

./autogen.sh

./configure --disable-threads --enable-static --disable-shared --disable-video-opengl /
--host=m68k-atari-mint --prefix=/path/to/usr/local/cross-mint/m68k-atari-mint

make

make install

If everything will be all right then SDL will be installed in /path/to/usr/local/cross-mint/m68k-atari-mint .

Note: When I’ve downloaded SDL from SVN I’ve got some errors related to bad file encoding. If something will go wrong when launching autogen.sh script then for sure there is something wrong with script file encoding, converting file to UN*X one will solve the problem.

Configure script invocation when running gcc cross-compiler

3) Cross compiling and setting up of cygwin and gcc 4.4.0 with vasm as a m68k assembly compiler under win XP

I assume here that you have native gcc compiler in your Cygwin installation (for example I’ve used gcc 3.4.4 and some tools like autoconf, make etc..). Just launch the Cygwin setup, download and install missing tools.

Firstly you will need daily snapshot of VASM which can be found here. Download it and extract for example in your $HOME folder in “vasm” directory. After that type in your Cygwin bash shell:

user@host ~

$ cd ~/vasm
$ make CPU=m68k SYNTAX=mot

After that gcc 3.4.4 (or another gcc version that you have) will build two files:

Rename them and move them to Cygwin /bin directory:

user@host ~/vasm

 $ mv vasmm68k_mot /bin/vasm68k_mot.exe
 $ mv vobjdump /bin/vobjdump.exe

Now you can check if the vasm is visible in your Cygwin environment by typing in bash:

$ cd ~
$ vasmm68k_mot

The following message should appear:

vasm 1.3d (c) in 2002-2009 Volker Barthelmann
vasm M68k/CPU32/ColdFire cpu backend 1.0c (c) 2002-2009 Frank Wille
vasm motorola syntax module 2.7d (c) 2002-2009 Frank Wille
vasm test output module 1.0 (c) 2002 Volker Barthelmann

fatal error 16: no input file specified
aborting...

Now to compile with VASM file “test.s” just type in:

vasmm68k_mot -Ftos test.s -o test.tos

4) Cross compiling with VBCC under win XP with TOS/MiNT targets

….

5) Installing and setting up freemint environment under Aranym and/or STEEM as a testbed for our programs

….

6) Debugging your programs

….

7) How to include assembly(GAS) with GCC

There are two options of using assembler with GCC :

In either case, your assembly code will be interpreted by GAS (GNU assembler). It has the reputation of not being a nice assembler (designed primarily to assemble GCC output), however it has been improved and supports Motorola syntax. You cannot write advanced macros, however anything else will work.

Inline assembly is nice, but the syntax for specifying inputs, outputs and clobbered registers is difficult.

An example of separate asm function (not tested)

sourcefile: plus.s

    .globl _plus    | This symbol will be externally visible
_plus:
    move.l    4(sp),d0
    add.l    8(sp),d0
    rts

Comments begin with a pipe “|”.

Registers may be prefixed by % like %d0 but in our binutils configuration this is not mandatory.
Beware at the symbols exported with .globl: they must begin with an underscore to be accessible from C code (without _).

Put the following prototype in your C header:

sourcefile: plus.h

#ifndef __PLUS_H__
#define __PLUS_H__  ;we want to include header once

#ifdef __cplusplus
    extern "C" {
#endif

long plus(long a, long b);

#ifdef __cplusplus
}
#endif

#endif

The #ifdefs are necessary only if you plan to call the function from C++ code.

Below is a standalone Hello, World ! program. It has similar syntax to HiSOFT Devpac one.

sourcefile: hello.s

* A simple TOS program

	pea	msg
	move.w	#9,-(sp)
	trap	#1		| Cconws()
	addq.w	#6,sp

	move.w	#8,-(sp)
	trap	#1		| Cnecin()
	addq.w	#2,sp

	clr.w	-(sp)
	trap	#1		| Pterm0()

msg:	.ascii "Hello !\r\n\0"

The following directives will be quite useful too (they have their counterparts in Devpac) :

    .text
    .data
    .bss

    .rept
    .endr

    .dc.b
    .dc.w
    .dc.l
    .ds.b
    .ds.w
    .ds.l

GAS supports a special jump instructions named “jbsr” and “jbra”. They are replaced by the smallest possible jump instruction. For example, GCC always call the functions using jbsr.

By default, jsr XX will be replaced bu jsr XX(pc), which is very annoying when you want to determine exatly what code is generated. You can avoid this behavior by using the -S assembler option.

One word about assembler options. The assembler is m68k-atari-mint-as, but it is probably easier to always use the frontend m68k-atari-mint-gcc. If you want to pass the -S option to the assemblet by using gcc, you must use the -Wa option to forward the option to the assembler. For example :

m68k-atari-mint-gcc -c hw.s -Wa,-S

Same applies with -Wl for linker options. For example, if you link your program with :

m68k-atari-mint-gcc *.o -o prog.prg -Wl,--traditional-format

the generated program will contain DRI debugging information instead of GNU. Thus, gdb will be unusable, but you will see the function labels in traditional ST debuggers like MonST. Note that in that case, m68k-atari-mint-strip will be unusable, too.

GCC inline m68k assembly explained (a little )

A simple example is a wrapper around Cconws() :

static __inline__ void Cconws(const char* s)
{
    __asm__ __volatile__
    (
        "move.l %0,-(%%sp)\n\t"
        "move.w #9,-(%%sp)\n\t"
        "trap #1\n\t"
        "addq.w #6,sp\n\t"
    : /* outputs */
    : "g"(s) /* inputs */
    : "d0", "d1", "d2", "a0", "a1", "a2" /* clobbered regs */
    );
}

First, the double underscores. “__inline__” is the same as “inline”, but GCC will never complain because it is a nonstandard extension. It is very useful in .h which may be compiled with -pedantic flag for example.

The function is declared with “static inline”, so it will always be inlined (except when optimization is turned off). “asm” begins an assembly block, “volatile” tells GCC to never remove the contents of the block, even it thinks it is useless.

The first parameter of “asm” is the assembly string. Every line must be ended with “\n\t”. The % character must be escaped as %%, so if you choose to prefix register names (not yet mandatory), you must use things like %%d0. Motorola syntax is welcome, as the string is directly transmitted to gas.

The second parameter is ths list of output variables (not used in this example).

The third parameter is the list of the input variables. The letter “g” means general, it can be replaced by a register or a memory variable. (s) is the C variable associated with this input, here it refers to the function parameter “s”. This parameter is referred in the assembly string with %0.

The fourth parameters is the list of clobbered (trashed) registers. GCC will never try to store data in that registers before calling the assembly block (but it may do it if you forget a register in the clobber list).

Here is another example. If is similar to what is found in <mint/osbind.h>:

#define SuperFromUser()                        \
(void*)__extension__                        \
({                                \
    register long retvalue __asm__("%d0");            \
                                \
    __asm__ __volatile__                    \
    (                            \
        "clr.l -(%%sp)\n\t"                \
        "move.w #0x20,-(%%sp)\n\t"            \
        "trap #1\n\t"                    \
        "addq.w #6,%%sp\n\t"                \
    : "=r"(retvalue)            /* outputs */    \
    :                    /* inputs */    \
    : "%d1", "%d2", "%a0", "%a1", "%a2"    /* clobbered regs */ \
    );           \
                 \
    retvalue; \
})

This example uses a preprocessor macro and an “extension” block instead of an inline function (the former example one is ‘more preferable’ approach).

An extension block behaves like an expression (it can be used inside formulas or other expressions), but contains a body with several instructions. The value of the resulting expression is the last expression evaluated in the block.

The variable “retvalue” is declared with “register” and asm(”%d0″), so the compiler will always store this variable in the register d0 rather in the memory. You can see the line “retvalue;” at the end of the block. That means : the value of the extension block is what is left in the d0 register after calling the inline assembly block.

Here, the output list is used. It is “=r”(retvalue), “=” indicates it is an output (mandatory here), “r” indicates that this output is a register, and “retvalue” is the associated variable.

Notes:

8) External references

GCC

  1. m68k-atari-mint page Vincent Riviere m68k Cygwin package. Here you will find recent version of GCC packages for Atari cross-development.
  2. Cygwin Home of Cygwin, Unix-like environment for Windows operating systems.
  3. GCC 3.3.6 usage with Atari projectsAn article that explains setting up gcc cross-compiler under Linux.
  4. Incompatibilities Between
    ISO C and ISO C++
    Discusses the incompatibilities of C/C++ on examples and indicates possible source of problems. There is also small introduction about C/C++ ISO standards.
  5. GNU Autoconf, automake, libtool book

GCC assembler (gcc 4.3.3) documentation reference

  1. ARM GCC Inline Assembler Cookbook
  2. Official GCC documentation about inline assembler
  3. GAS directives

VBCC

  1. VBCC/VASM for m68k Atari TOS/MiNTVBCC packages, compiler for MiNT and files for TOS and MiNT targets. Page contains also VASM(m68k assembler which also outputs gcc compatible code) and VLINK(m68k linker)
  2. VBCC under Mac OSX VBCC package for Atari cross development on Mac OSX.

GCC Atari TOS/MiNT specific libraries

  1. EasyMiNT MiNT installation package for Atari computers and Aranym.
  2. LDG Dynamically loaded libraries for Atari TOS/MiNT machines, it’s similar thing to SLB on MiNT and DLL on win32
  3. Windom library C library for programming GEM applications. It looks pretty good and some nice apllicatons were written with use of this library.
  4. SDL Home of Atari SDL port. There are also other SDL utility packages available as well(SDL_mixer, SDL_image …)
  5. Freemint Portal Contains MiNT ports of various software packages found on Unix machines

Testbeds

  1. Aranym Atari Running on Any Machine, still updated and developed.
  2. STEEM Very good Atari ST emulator, not updated from the long time though.
  3. HATARI The newest 16/32 bit Atari emulator. It has premilinary Atari Falcon030 support.
  4. Aranym 3D pack A premade Aranym installation. Just to unpack it and launch. The drawback is, that it wasn’t updated pretty long time.
  5. SainT It seems to be most accurate Atari ST emulator, still maintained and updated.

Free resources about Linux/Unix development in general:

  • Art of Unix programming
  • Codeblocks (free open-source cross platform IDE) After all you have to write the code somehow. This environment is pretty good, has syntax highlighting.
  • UPX Executable packing utility, it’s cross-platform, automatically recognizes binary type and packs it. It’s very good tool when you are about to release something.
  • Doxygen Documentation generation utility. Generates documentation from the source code.
  • GraphViz Very good addition to Doxygen, the package allows you to automatically generate graphs in your Doxygen generated documentation. Class depednencies, file dependencies all of this will be visualised in your documentation automatically.
  • Git – free & open source, distributed version control system, there is TortoiseGit too, but it needs msysGit under Windows. TortoiseGit cannot handle Cygwin Git version yet. But mastering Git from commandline isn’t as hard. Here are the tutorials/screencasts showing Git in action(feature after feature).
    There is also video in which Linus Torvalds speaks about Git and why he hates CVS so much ;) . It’s really funny to watch. It doesn’t deal about working with Git, but rather explains ideas behind it.
  • TortoiseSVN free win32 SVN client
  • TortoiseCVS free win32 CVS client
  • Assembla If you’re seeking free/cheap svn/Trac space then it’s right place. If your project is quite small this is good alternative to Sourceforge.net.
  • 9) Credits

    This is the place to say thanks to several people that provided input to this page:


    Gallery

    normal_sapphon-rear copy
    night goblin fanatic 2
    Gayle 9
    Plague Marine 1
    Necromunda Goliath 8
    Kat 8
    Kat 6
    Kat 3
    Razyda