Learn Multi platform 68000 Assembly
Programming...By Magic!
Hello World Series
Introduction to the Hello
World Series...
In this series of tutorials we create the classic 'Hello World'
program... a basic program to just show a text message onscreen!...
each example will be a single ASM file (with font where required)
and we'll look at the stages required to compile the ASM, and get it
onto a disk or cartridge.
Once we've got 'hello world' working,
we'll extend it, adding a 'Monitor' to show registers, and MemDump,
to display part of the RAM to the screen... these are a useful
starting point if you're building something new.
Lesson
H1
- Hello World on the X68000
The X68000 has a graphics mode, which we've looked at before
in the platform specific series, but if we're looking to just
get text to the screen, then using operating system calls will
be easiest!
Lets learn how to use it to get 'Hello World' to the screen!
x68_HelloWorld.asm
Coding Hello World
When it comes to printing a character to the screen, we're
going to use a system call...
On the X68000 these are defined by a word which starts $Fxxx -
the PutChar routine is $FF02
It takes its parameter off the stack, so we need to push
the character we want to show... we then use the command (by
defining it as an inline word with DC.W $FF02)... we need to pop
the parameter off the stack after we're done.
We'll extend our Print Char function to print chr 255
terminated strings
We can start a new line by printing Characters 13 and 10 to
the screen
We can load the address of our string to show...
We use system call $FF00 after we're done to return to DOS.
When we define the string, we put a 'EVEN' command after it...
this is because our code must be Word Aligned, but if our string
has an odd number of bytes it won't be! - 'Even' will fix this!
Our 'Hello World' message will be shown to screen.
Building our disk image
We build our file with Vasm - Vasm has
support for the special Xfile format used by the x68 for
executable files... I use this build command in my batch files.
We need to specify the source asm file
to compile
we're specifying the processor type as
68000
We're specifying that VASM should ignore case,
and check if labels look like commands (in case we forgot
our tab on a command)
I define a couple of symbols, but you
won't need them for the simple example...
We're telling VASM to output a listing.
This is a text file which shows how the asm commands convert
to bytecode... We don't need it - but it may help us if we
have problems!
We need to tell vasm to build an
Xfile - this is the executable file type of the x68k
Finally, we specify a filename for
the output file
We're using NDC
to alter disk image, I use a template disk that has a
basic dos boot, and automatically starts prog.x
We first delete the old version of the program from the disk...
then we add the new file to the disk image
We start X68K high speed - the configuration of the program is
set up to pre-insert the disk image.
The X68000
needs an operating system boot disk... this tutorial uses a
'minimal' disk with starts a Human68k Dos command line - the
autoexec.bat will start up the program.
Just because it has an Autoexec.bat, Don't think that Human68k
is the same thing as MS-DOS - it's similar but a totally
different OS!
Xfile format
If you're not using Vasm, or another
assembler that can output Xfiles you're going to have to build
your own header with the correct header... I used to attach a
template header into the file, then patch in a new length into
the filename.
The binary file is shown to the right, we can see the
following sections... The
Header is at the start of the file The
Code (text) segment - it's
size
can be seen in the header The
Data segment -it's size is also in the
header The
Symbol table - it's
size
is also in the header. The
Relocation table has the addresses of code which needs it's
addresses altering - it's
size
is also in the header
Monitor Tools
As part of my tutorials, I wrote some simple 'Monitor Tools'
which will help with debugging
By including a few extra files we can use those tools with this
example.
These tools provide two useful functions...
"Monitor" will show the register contents to the screen
"Memdump" Will output some lines of memory to the screen from
the specified memory address
The registers and requested memory area will be shown to the
screen.
Lesson
H2 - Hello World on the Atari ST
This time, lets take a look at the Atari ST!... we'll use
operating system calls to show Hello World to the screen.
Coding Hello World
When it comes to printing a character to the screen, we're
going to use a system call... We'll use Trap #1 (Gemdos) and
Function #2 (Console Out)
First we push the Character number onto the stack... then we
push the function number #2... finally we use the Trap #1
command.
The Character will be printed to the screen, we now need to
remove the two words off the stack before returning.
We'll extend our Print Char function to print chr 255
terminated strings
We can start a new line by printing Characters 13 and 10
to the screen
Our program starts with a 'Text' Section - this defines
the area as being program code.
We can load the address of our string to show... and use our
function.
If we just RETurned straight away, our output would only
appear for a moment - so we'll pause a moment for a
keypress..
We use Trap #1 - Function #1 (ConIn) to read in a key from
the console first... this will pause for a moment for us to
admire our work!
Our 'Hello World' message will be shown to screen.
Building and Starting our program
We build our file with Vasm - Vasm
has support for the special Xfile format used by the x68 for
executable files... I use this build command in my batch
files.
We need to specify the source asm
file to compile
We're specifying that VASM should ignore
case, and check if labels look like commands (in case
we forgot our tab on a command)
I define a couple of symbols, but you
won't need them for the simple example...
We're telling VASM to output a listing.
This is a text file which shows how the asm commands convert
to bytecode... We don't need it - but it may help us if we
have problems!
We need to tell vasm to build an
ELF - We'll need to link this later
Finally, we specify a filename
for the output file
We need to 'Link' the ELF file to convert it into an
executable
We specify the source ELF from the
last assembly step
We specify an output file in TOS format
(Atari executable).
We need to specify the file format as
AtariTos
We can use a folder on our windows machine as a hard drive
- we've mapped the folder \RelAST to
the C drive
Any files we put in this folder will appear as a drive on
our machine
Monitor Tools
As part of my tutorials, I wrote some simple 'Monitor
Tools' which will help with debugging
By including a few extra files we can use those tools with
this example.
These tools provide two useful functions...
"Monitor" will show the register contents to the screen
"Memdump" Will output some lines of memory to the screen
from the specified memory address
The registers and requested memory area will be shown to
the screen.
We're
just using Text console mode in this example... if you
want to see the same functions in bitmap mode, please see
the platform specific series.
That's probably what you'll want to do if you're writing a
game... unless it's a text adventure!
Lesson
H3
- Hello World on the NeoGeo
The NeoGeo uses 5 bits per channel, has 16 colors per
palette, and up to 256 palettes!
Lets learn how to set the colors on the Neo Geo!
NEO_HelloWorld.asm
Starting a NeoGeo Cartridge
First we're going to define some symbols pointing to RAM -
we're going to need a few bytes for our code.
The start of our cartridge needs to contain the 'Traps' -
these handle CPU and system events - we need to point them
to the bios
These won't need changing for a simple program
We now need the actual 'Cartridge header'
This has a few system parameters, and links to settings and
subroutines for system events
You probably won't need to change this
We need to define a bank of settings for the 'Dip
Switches'
We need some functions to handle system events.
The VBlank one here is one you may wish to change, this
occurs every frame redraw, so can be useful for controlling
game speed - but you don't need to worry about it when
you're just starting out.
Phew! that's the end of the 'header'... Lets start writing
our code!
Setting up our screen
Now we can start our program!
First we're going to do a write to $300001 - this is known as
'Kicking the Watchdog'... We're going to see this a lot!
The watchdog is a hardware function of the NeoGeo - if the
Watchdog is not routinely 'kicked' then it will reset the
machine! this is to ensure the Arcade games didn't crash and
end up locked in an unplayable state!
Next we need to set up our palette... this is handled by
addresses $400000+... we set the background color, a few of
the first palette entries, and color 15 - this will be used by
our font.
Next we need to init the screen... we use some firmware
functions to clear the 'Fix Layer' (we'll use this for our
font) and the first sprite.
Our actual program is rediculously small! We just call our
Printstring routine (we'll see it in a moment)... then we loop
indefinitely, just kicking the watchdog to stop the machine
rebooting.
Printing a Character to the screen
You'll notice we never mention a font file in this section -
it's a ROM included in the Mame XML...
When it comes to getting characters on the screen on the
NeoGeo, we'll use the 'Fix Layer'... a tilemap that starts at
VRAM address $7000
This is a 40x32 tilemap of 8x8 tiles... rather surprisingly
the axis are flipped...each consecutive byte goes DOWN the
screen first, then Across.
For this reason, the formula for our tilenumber is:
VRAM address = $7000 + (Ypos * 32) + Xpos
We achieve multiplication by bit-shifting...
We need to subtract 32 from our character number (as the first
character in our font is 32)... but we also add $1800 - 1xxx
because we want palette 1... $800 is the first tile of our
font (the other $800 are reserved for system use)
We need to select a VRAM address by writing the address to
$3C0000, Writing to VRAM is achieved by writing to $3C0002
We extend our PrintChar routine into a PrintString routine
... it prints a Character 255 terminated string
We also need a 'NewLine Function to start a new line.
The message will be shown to the screen.
The XML! (MAME ROM Layout)
To run a custom game on MAME, we need to create a hash file
- usually called 'neogeo.xml'
This defines how the various binary files that make up a game
are attached to the system... multiple files can be combined
for a single purpose - the 'Offset'
The Operating system needs 202-s1.s1,
202-c1.c1, 202-c2.c2
Our 68000 Program Code is 202-p1.p1
... we have a z80 program called 202-m1.m1
... This is a sound driver
For this example We need the FONT.FIX
RawNEO.FIX, Sprites.c1 and Sprites.c2 are not needed for this
example (they are for my other tutorials!)
Section NAME
Detail
How to make this?
maincpu
68000 binary data
compile a 68000 ASM file with VASM
fixed
FIX Layer Tiles
My AkuSprite Editor can make this format
audiocpu
Z80 binary data
compile a z80 ASM file with VASM
sprites
Sprite pattern data
My AkuSprite Editor can make this format
There are various parameters for
'rom' files that must correct for MAME to be happy, otherwise
you will get the error "One or more ROMs/CHDs for this machine
are incorrect. The machine may not run correctly"...
To fix this you must ensure the following parameters are
correct:
parameter
name
Detail
code used by my
MakeNeoGeoHash.exe
size
File size in bytes (0x denotes it's in HEX)
%size%
crc
Cyclic Redundancy Check (32 bit) of file
%crc%
sha1
sha1 of file
%sha%
If you want to calculate the hashes, you can do so with my
'MakeNeoGeoHash' program - you need to provide it a template
(shown to the right) - it will calculate the size,crc and sha1
of each rom, and write out a new xml which mame will be happy
with!
MakeNeoGeoHash is included in my 68000 development tools
package, with scripts to use it automatically with my
tutorials samples
Sprites and Tiles MUST be defined in romfiles,
and included in the XML, this is the only way ROMS can be
built on the NeoGeo...
This is because of the way the hardware is designed, each
'module' (Graphics sound etc) has it's own physically
independent rom files.
The NeoGeo CD is different, it has ram that can be filled by
our program, but it's slower as a result.
Building the ASM file
We build our file with Vasm - Vasm
has support for the special Xfile format used by the x68 for
executable files... I use this build command in my batch
files.
We need to specify the source asm
file to compile
We're specifying that VASM should ignore
case, and check if labels look like commands (in case
we forgot our tab on a command)
I'm specifying to output 68000
CPU code
I define a couple of symbols, but you
won't need them for the simple example...
We're telling VASM to output a listing.
This is a text file which shows how the asm commands convert
to bytecode... We don't need it - but it may help us if we
have problems!
We need to tell vasm to build an
BINary file
Our source sample will only compile correctly in DevPac
mode
Finally, we specify a filename
for the output file
Our File is built, but we need to
do more, we need to convert the byte data into the correct
format for the NeoGeo by swaing the byte pairs... we also
need to pad the file
We need to make sure the SIZE, CRC
and SHA are correct in the XML for each file... I've written
a little program to calculate the hashes
If your hashes are wrong, MAME will whine... if your Size is
wrong MAME may crash!
Finally, we can load MAME and start our game.
Monitor Tools
As part of my tutorials, I wrote some simple 'Monitor
Tools' which will help with debugging
By including a few extra files we can use those tools with
this example.
These tools provide two useful functions...
"Monitor" will show the register contents to the screen
"Memdump" Will output some lines of memory to the screen
from the specified memory address
The registers and requested memory area will be shown to
the screen.
Lesson
H4 - Hello World on the Sinclair QL
The Sinclair QL has a fairly impressive OS for an 8 bit
(or a slightly disappointing one for a 16 bit!)... We can
use it to get text to the screen without any bitmap
routines, lets learn how!
SQL_HelloWorld.asm
Coding Hello World
We're going to use an OS trap to draw characters to the
screen
Trap #3 - Function #5 (In D0) will send a byte to the
screen... we need to set the Timeout (D3) and Channel ID
(A0) as well... and make sure the character code is in D0
We're going to extend our PrintChar routine into a
PrintString Routine - it'll use Char 255 terminated strings.
We just send each character to PrintChar until we get to the
255
We can start a new line by printing a character 10 to the
screen.
Let's start our program!
We load the address of our string into A3, before calling
Printstring
Before we return to basic we need to load D0 with zero -
otherwise basic will complain!
And here's the result!
Building and Starting our program
We build our file with Vasm - Vasm
has support for the special Xfile format used by the x68 for
executable files... I use this build command in my batch
files.
We need to specify the source asm
file to compile
We're specifying that VASM should ignore
case, and check if labels look like commands (in case
we forgot our tab on a command)
I define a couple of symbols, but you
won't need them for the simple example...
We're telling VASM to output a listing.
This is a text file which shows how the asm commands convert
to bytecode... We don't need it - but it may help us if we
have problems!
We need to tell vasm to build an
BIN file
Finally, we specify a filename
for the output file
We need to set up QemuLator to use the destination
directory as a drive... we do this by right clicking on a
drive number, and Attaching Directiory
We need to create a startup file called BOOT on drive
WIN1... this will cause our program to launch with the
emulator.
The basic program to the right will load the program to ram
address 32768 and launch it.
This program can be saved with the command "save win1_BOOT"
We can save a settings file with correct settings for the
disk image, and load it on the commandline with QemuLator
Our program will run as soon as the emulator starts (after
we select monitor type with F2)
Monitor Tools
s part of my tutorials, I wrote some simple 'Monitor
Tools' which will help with debugging
By including a few extra files we can use those tools with
this example.
These tools provide two useful functions...
"Monitor" will show the register contents to the screen
"Memdump" Will output some lines of memory to the screen
from the specified memory address
The registers and requested memory area will be shown to
the screen.
We've
only used the basic text mode, which isn't too useful for
gaming... Take a look at the 'Platform Specific' series,
where we covered the bitmap modes for more 'useful' code!
Lesson
H5 - Hello World on the Genesis / Megadrive
The Genesis is another Tile/Sprite system... we're going to
have to define a bitmap font as Tiles in VRAM, then use those
tiles to draw characters to the screen,
Lets get started!
GEN_HelloWorld.asm
Starting our program
The start of the Genesis cartridge needs to define the
'Traps' - these are needed by the processor.
We then need the cartridge header... a sample one is shown.
We're going to define two symbols for ram addresses (Cursor
X and Y) we need these for our text writing.
We're also going to define two symbols for VRAM data and VRAM
address/control - we'll need these for writing to VRAM
Our Header needs a dummy interrupt handler (Just a
return)...
We now need to start our program... first we'll disable the
TMSS if it exists (TradeMark Security System)
Initialize the Graphics
We're going to need to set up the screen... we do this by
writing words to the control port... the top byte is the Reg
Num (the top BIT must be 1)... the bottom byte is the value
for that register.
We read in the values from a table 'VDP Settings'
We' define one byte for each register... we've got a set of
settings to set up a basic screen for our purposes here.
We need to define some colors - We need to at least define
the background color 0... and the font color (15)...
We do this by writing an 'address' to the VDP control port,
then a pair of bytes for the color to the data port.
The address format for the palette is $C0nn0000 - where nn is
the color address (Color *2 as we have 2 bytes per color)
We're using a bitmap font for our characters... it uses 96
characters (First is character 32 - space)
each character is 8x8 1bpp - so each character is 8 bytes
We need to convert it from 1bpp (2 color) to 4bpp (16 color)
We need to start our VDP writes to VRAM address $0000 (the
tile definitions)
We do this by writing $40000000 to the control port
We now need to convert the font lines...
We shift one bit from the font in ROM, shift it to the left 3
times, and repeat this 7 times, this puts the bits in the 4
bytes of the font Long as color 1...
We then do 3 shifts and ORs - effectively copying the bits to
all 3 other positions in the nibble, converting it to color 15
OK, Our screen is finally set up!
We reset our cursor position to zero... and turn on the
screen!
Printing a character to the screen
We're going to define a PrintChar routine - this will print
a character in D0 to the screen.
We need to calculate the VRAM address for the next tile we're
going to set... the tilemap is 64x64, starts at $C000, and
each tile is two bytes so the formula is:
VRAM address= $C000 + (Ypos *128) + (Xpos * 2)
Because of the strange format of the ram commands, to specify
the base of $C000 we add to the long $40000003
Once we've calculated the address... we write the address to
VDP Ctrl, and the Tile number word to VDP Data.
After we've set the tile, we need to check if we're at the end
of a line - if we are we start a newline
We're going to extend our PrintChar routine into a
PrintString Routine - it'll use Char 255 terminated strings.
We just send each character to PrintChar until we get to the
255
We also need a newline function to zero the Xpos, and INC the
Ypos
The hello world message will be shown to screen.
We've
learned how to use the tilemap for 8x8 characters here...
next time we'll take things further, and actually draw some
nice graphics!
Tune in next time in the 'Simple Series' to see more!
Building and Starting our program
We build our file with Vasm - Vasm
has support for the special Xfile format used by the x68 for
executable files... I use this build command in my batch
files.
We need to specify the source asm
file to compile
We're specifying that VASM should ignore
case, and check if labels look like commands (in case
we forgot our tab on a command)
I define a couple of symbols, but you
won't need them for the simple example...
We're telling VASM to output a listing.
This is a text file which shows how the asm commands convert
to bytecode... We don't need it - but it may help us if we
have problems!
We need to tell vasm to build an
BIN file
Finally, we specify a filename
for the output file
We can start Fusion with the cartridge specified on the
command line
Monitor Tools
s part of my tutorials, I wrote some simple 'Monitor
Tools' which will help with debugging
By including a few extra files we can use those tools with
this example.
These tools provide two useful functions...
"Monitor" will show the register contents to the screen
"Memdump" Will output some lines of memory to the screen
from the specified memory address
The registers and requested memory area will be shown to
the screen.
Lesson
H6 - Hello World on the Amiga
Lets take a look at the Amiga, and look at a simple way to get
'Hello World' onto the screen...
We'll use OS calls this time, and get a 'Hello World' message
onto the command line... Lets get to work!
AMI_HelloWorld.asm
Coding Hello World
OK, lets get started!... we're going to Jump to some OS Functions
to get access to the console screen...
First we need to use the 'Exec' function to gain access to the
'dos.library' Library, we call this with a JSR, and get the dos
handle back in D0... which we save for later!
When we make the call, we load A1 with a string containing the
library name... we'll also define one for the 'Console:' which we'll
need in the next stage.
We also need to define some ram bytes to store the handles returned
by the OS... we also use a single byte as a character buffer - as we
need to pass an address to the printing routine to get our
characters onscreen.
Next we need to use the Dos function "Dos: Open" to get access to
the Console handle, we'll need to pass the address of the string
'CONSOLE:' in D1
This function returns a handle for the console in D0... we'll store
this for later.
We're now ready to print a character... we use the "Dos: Write"
function to send a character to the console... this function can
actually handle strings, but we just do 1 character at a time....
We need to pass an address of a buffer to the function, the
DosHandle, and the ConsoleHandle we got before...
We load the single character into the buffer before we call the
function
We're going to extend our PrintChar routine into a PrintString
Routine - it'll use Char 255 terminated strings.
We just send each character to PrintChar until we get to the 255
Note: It would be more efficient to use the Dos:Write with a longer
string, I'm using this method for consistency with other platforms
in my tutorials.
We also need a newline function to zero the Xpos, and INC the Ypos
We use the PrintString routine to get our message onto the screen,
We start a new line and return to the OS with a RTS
Our hello world will be shown to the screen!
Building and Starting our program
We build our file with Vasm - Vasm has
support for the special Xfile format used by the x68 for
executable files... I use this build command in my batch files.
We need to specify the source asm file to
compile
We're specifying that VASM should ignore case,
and check if labels look like commands (in case we forgot
our tab on a command)
I define a couple of symbols, but you won't
need them for the simple example...
We're telling VASM to output a listing. This
is a text file which shows how the asm commands convert to
bytecode... We don't need it - but it may help us if we have
problems!
We need to specify to output a valid amiga
executable file
Finally, we specify a filename for the
output file
We need to specify the path we save our
file to as a virtual hard drive in FSUAE... we can then save a
template config file, which will start our emulator ready to run.
We can start UAE with the config file.
We can speed up UAE with WARP MODE, via Alt-W... starting the
emulator in WarpMode will save us some testing time as it reduced
boot time
I even save the program with the name 'w' so we can start the
program with a single key.
Monitor Tools
s part of my tutorials, I wrote some simple 'Monitor Tools'
which will help with debugging
By including a few extra files we can use those tools with this
example.
These tools provide two useful functions...
"Monitor" will show the register contents to the screen
"Memdump" Will output some lines of memory to the screen from the
specified memory address
The registers and requested memory area will be shown to the
screen.
We've learned
how to get text to the screen... slowly!... but it's just an
example...
We'll look at bitmap graphics to do more proper stuff later...
We've already covered it in the Platform specific series... but
we'll look at it in the 'Simple Series' too.
Lesson
H7 - Hello World on the X68000 with native tools.
We looked at writing a 'hello world' example before using cross
compilation from windows.
This time we'll compile using an assembler from within the X6800
itself!... Lets learn how!
x68_HelloWorld.asm
Assembling with the X68000 assembler AS
Lets have a go with the 'THE福袋 V2.0 システムディスク' also known as 'The
Luckybag V2.0 system disk' for you non japanese speakers!
This disk contains a few tools, and includes and assembler, linker
and text editor.
We need to go into the BIN folder, so we should type CD
BIN
We have a few useful programs ED is our text editor - we'll use it to make our
asm file AS is our assembler - we'll use it to assembler the
asm. LK is our liner - we'll use it to make an
executable.
First we need to create our ASM file with ED.... type ED
hello.asm to create a new file for our program
The ED program is in japanese, but you'll only need a few essential
keypresess (Shown below)... for a full list of commands see here
Keypress
Command
ESC-E
Save All files and Exit
ESC-T
Rename file
ESC-X
Save and exit
ESC-Q
Don't save and Quit
ESC-O
Reset to last save
We need to type in our program,
Then press ESC-X to save and close
Once we've written our ASM file we need to assemble it!
First we use AS to compile the
file into object code - we type as
-phello.lst -d hello.asm
If that went OK, Next we use LK to
link it into an executable (X file) - we type lk hello.o
If that went OK, we can run our compiled program! - we type
hello.x
If there were any problems, we can look at the listing file we
created during assembly by typing ed
hello.lst
Here we made a mistake on line 5 - we wrote CD.B, not DC.B!
Making a batch file
Like DOS, we can create Batch files on the X68000 with basically
the same syntax.
Here's a batch file to assemble, link and run our program - if at
any stage an error occurs, the process will jump to the abort label.
Create this in ED with the
command ED assemble.bat
If we save the file as assemble.bat
We can compile our program with the command assemble
hello
Here something went wrong with the AS command's assemble...
This set the errorlevel>0, and the batch file stopped!
With a little work it's not so bad compiling
on the native assembler, especially since we can automate things
with batch files!
All you need to do now is find some sprite editors and the like
for your native gamedev!
the X68000 DOS doesn't seem to support @echo off, or
the @ symbol at all!
This means we can't exclude certain lines from being shown, which
is a shame! but at least we have reasonable batch functionlity!