Jam Assembler version 1.141







Copyright ©

This program is the copyright property of David Brant and is protected by both British and International law. You are allowed to copy and pass on this program, as long as no finances are exchanged. While every care has been taken in writing this software. I am not held liable for any mistakes or omissions, nor responsible or held liable for any damages that may arise from the use of this software.


First of all you need an up to date Java Runtime installed this is available from www.java.com . You also need to extract the zip file to your chosen directory. If you don't have simcoupe you will also need to download and install this.

Using Jam Assembler


To start the program click the jar file directly, if all is well you should see the Options dialog, shown later. There is an icon file in the images folder called JamAss.ico that can use with a desktop shortcut.

Project View: This is where you have shortcut links to different elements in your source files. Each list is only updated when you assemble or save a file.

When you use Jam Assembler for the first time you see the dialog below. Some of the setting are setup automatically but you may need to change them. Simcoupe path will need to be changed especially when your not using a Windows™ system. This dialog is also available from the tools menu.

Simcoupe path: This holds the correct path for simcoupe.
Disk image path: This holds the path to the disk image you want to assemble to. The disk image must be only original mgt type.
System include path: This is the path to your main include files. i.e. the source files you will use for most of your projects.
Object file name: The file name that the assembler will save to the disk image and to the local hard drive. Don't change this if you use Default save to the disk option

The option buttons are for how the assembler will save the object file to the disk image. The 'Default Save to the disk' uses a system so you can save across different page and addresses using the minimum file size. This option needs a loader on the Sam coupe to load the file. 'Save to the disk as memory dump' saves the file as you would normally on a Sam coupe. The first line of code that is assembled MUST BE at the lowest page and address than the rest of the file. 'Save as Driver application' is as memory dump but as Driver application file type. If you have DEFS commands at the end of the source code these are not saved to the object file. With Driver applications this may cause a problem if application runs over pages, so end your source with DEFB 0.

The first two check boxes are used to automatically loads the files that have been included when you assemble the code. This is to make the Files, Functions, Macros, Structs and Labels view boxes show all source files in your project as the program only shows the opened files.

The next check box, is used to format recognized text and make tokens upper case when importing from a comet assembler source file and when typing. When format source option is active the undo and redo do not works as normally you would expect. The last check box moves the project view to the left.

When you press OK the options will be saved.

Apple Mac: Simcoupe path will not work if you type something like '/Applications/Games/SAM/Emulator/SimCoupe.app' you would need to add to the end ''/Contents/Mac OS/SimCoupe' this is because of the way MAC OS works. I don't own or use a Mac so I will not be able to help with OS problems.

Entering Source


Labels: All labels can be any length, they must be followed by a colon and must have white space before any more code, you can use local labels, these are local to the source file. Local labels are not displayed in the label list box but are displayed in the project tree view. To make a local label add a '.' at the start, so to make a label 'loop' local you call it '.loop'. Example:

  DJNZ .loop

You can also define function local labels by putting in front of a label a '@' or '..' in label.tab these are stored as functionname..label

When assembled the assembler saves a list of labels used with their values. In this file all label are shown including local labels. The file is always called 'label.tab' and is found in same directory as your main file. When the assembler finds a local label, it adds a string in front of it in the label table normally a '_' then a number. You can change the string by using 'DEFINE LOCAL string' in your source to make a section local, but you can't return to the automatic one afterwards. Example:


  DJNZ .loop ;this jumps to the first .loop
  DJNZ .loop ;this jumps to the second .loop


Expressions: Now you are allowed to have floating point numbers in an expression but are converted to an int at the end. Expressions must not have any spaces. You are allowed to have the following functions:- rand(),sin(),cos(),atan(),sqrt(),int(). sin(), cos() and atan() use degrees not radians. To use these commands you use multiply i.e.

sin value 10: equ 10*sin()*32768 ;This gives the sine of 10 degrees the multiplied by 32768 to give the fixed point value
rand number equ rand()*256 ;This gives a random number between 0-255 as rand returns a number between 0.0 and 1.0

Jam Assembler still uses precedence like comet i.e 5+10*2=30 but now you can use [ ] to change the precedence i.e. 5+[10*2]=25

Because expressions now use floating point you can't use the expression to get the next 256 boundary by using DEFS $/256+1*256-$ you now need to use the int() function like DEFS $/256+1*int()*256-$, but a better way is 256-[$\256]

Multiple Commands: For op codes that have no operand i.e. NOP, LDI, HALT etc. You can write 'LDI 10' this will place 10 LDI commands into the object code. The maximum number is 3000. You now can have multiple shift/rotate commands like 'SLA A 10' this will place 10 SLA A commands into the object code.

Include: If you write INCLUDE 'filename' the assembler will use the system include path (see above) if you use INCLUDE "filename" the assembler will use the local path of the file you assemble from. ??.i files are normal include files. ??.h files are normally used defining macros and structures/classes as these must be defined first before they are used.

MDAT and MDATA: MDAT works the same as in comet and merges data from your disk image. MDATA merges data from your local hard drive, as with include it uses path of the file you assemble from as its root. For most programs it is best to copy your data files to the local disk, using the SamDisk part of this program or any other disk image utility, then use MDATA. This will save you changing the disk image in the options dialog for each project. MDATA uses your main source file path as the root.


Extra Commands

Undocumented Instructions: Most undocumented commands are implemented except the LD register,bit test/shift,(IX+d) i.e. LD E,RR (IX+10) but if you wish you can make a macro to do the commands.

Extended Commands: There are some commands used that combine z-80 commands. The list is:

LD (HL),(BC) ;uses A register
LD (HL),(DE) ;uses A register

Extended Commands (v1.141 only)Where you see + can be -

ADC A,(HL)+ ;Add with carry A with the contents of HL and Increment HL
ADC R,A ;Add with carry A with a register then load into register
ADC RR,A ;Only uses registers in the instruction, may give strange result with the carry

ADD RR,A ;Only uses registers in the instruction


CP (HL)+


DJNZ @loop
DJNZ A,@loop
DJNZ B,@loop
DJNZ C,@loop
DJNZ D,@loop
DJNZ E,@loop
DJNZ H,@loop
DJNZ L,@loop

DJNZ BC,@loop
DJNZ DE,@loop
DJNZ HL,@loop


LD (DE),(BC)
LD (BC),(DE)
LD (DE)+,(BC)+
LD (BC)+,(DE)+

LD (RR)+,A
LD (HL)+,R
LD A,(RR)+
LD r,(HL)+

OR (HL)+



New Commands for v1.141

RUN: Used to set address to run from, same format as DUMP default is 32768 and only works with default saving of object file.

Can be either RUN address upto 65535
or RUN page,address where address is 0-16384

FLOAT: Used to define a 5 byte number for floating point same as Basic

i.e. FLOAT 1.243 (stores a 5 byte FPC version)

DEFX: Used to define a 3 byte whole number

DEFX 0-16777215 0x00-0xFFFFFF

DEFL: Used to define a 4 byte whole number

DEFL 0-4294967295 0x00-0xFFFFFFFF

DEFO: Used to define an object used with Classes see Structs and Classes


Function:Used for your main routines. Just type 'function routine_label' example:

function plot

srl h
rr l

To call the function just use the normal CALL routine_label for the above routine it would be CALL plot. Local Function are displayed in the Function list box.


Macro: Used so you can have inline code in your source, you can have up to 5 entry values and object code must be 1K (1024bytes) or less in the macro. All labels defined within the macro are local to the macro. The macros Label table is checked first for labels then the main Label table. Do not use RET command within a macro and all code must finish at the end of the macro. Because now you can have multiple macro commands you can enclosed your entry values with brackets. Example of defining a macro (x,y,color) are entry values:

defmacro plot (x,y,color)

LD H,y
LD L,x
LD A,color
JR NZ,over



So to use the macro

macro plot 10,20,&ff or macro plot (10,20,&ff)

This would do the same as in BASIC PLOT PEN 15;10,20. The macro command is now optional so you could write it as:

plot 10,20,&ff

To use the macro multiple times (with this example would be a bit pointless because your passing the same thing).

macro plot (10,20,&ff) 10

This would do the macro 10 times. Multiple macros must not exceed 16K in total. You can use the $ to pass different values to each macro in the block

You can't use in macro names and label names with + - , ( ) & % $ / \ " '[ ] @ but you can use = which you may find useful. Please note that code within DEFMACRO and ENDMACRO does not produce code until the use of the MACRO command, this command inserts the code inline into the code.


Constants:This is a new command for V1.3 the assembler treats it just the same as EQU only the project shows them separately with defines. Example:


Struct: This is so you can have C/C++ like structures you can also use the command class instead, within the struct you use commands BYTE and WORD, they can also have a number after so BYTE 10 would allow space for 10 bytes. Example:

struct sprite

.x: BYTE
.y: BYTE
.data: BYTE 10
.code: WORD


To make space in the code for a structure you use 'DEFS struct_name' so in this case of 'man: DEFS sprite'. To access the elements you would write LD A,(man+sprite.y) or if IX points to you man struct, then you would type 'LD A,(IX+sprite.y)'. But don't forget that IX offsets have a maximum of +127

Now from v1.141 you can use DEFO which inserts labels with your DEFO name i.e. if you had "oMan: DEFO sprite" this would insert into the label table oMan.x oMan.y oMan.data oMan.code so then you could access your Object directly using LD a,(oMan.x)

To do inheritance you put a struct/class command inside the struct/class. If you put struct/class command after other entries this will give different offsets for the elements. The example below if you put the struct command after the speed element then spaceship.x would be offset 1 not offset 0.

class spaceship

struct sprite
speed: BYTE


Or to make easier I've added from V1.132 the extends command the above command would now be

class spaceship extends sprite

speed: BYTE


To make you code OOP like, you could write functions after the class/struct calling them something like sprite.init then if you have the above classes/structures you may want to call sprite.init function using the name spaceship.init To do this, within or outside the spaceship class enter 'DEFFUNCTION spaceship.init sprite.init' this will make spaceship.init label point to sprite.init function. Please note : Jam Assembler OOP programming was never in the orginal design and using IX/IY register uses a lot of processor time. I may improve on member function programming in the future.

Both Macros and structs/classes must be defined or included before they are used.

Conditional Assembly


The assembler has commands for conditional assembly these are DEFINE,UNDEFINE, IFDEF, IFNDEF,ELSE and ENDIF. To set a define you write:

DEFINE a_define

IFDEF means if defined. IFNDEF means if not defined. UNDEFINE is used to remove the define. If you set a define that is already set this will give an error so you can use the following (no endif):


Normally you write a if defined code as follows:

  IFDEF a_define
  ;some code
  ;some other code

You can also use this with in macros. One useful macro is:


So if SHORT_INC is defined when this macro is used it will insert INC L into the code otherwise it will insert INC HL.



If you have more than one source file loaded, you select the source file to start from. The File to Assemble box, will only show source files with .s extension. To assemble click the Assemble button, if there is an error then it will show the error in the text area. When you click close it will jump to the error. The program takes about 2-5 seconds to assemble. But more if it is loading sources files to display.

Find (in list view): This used if you want to search for a string, this can be any string i.e. a label, command, a comment or a whole line. The search is not case sensitive.

Assemble in CLI/CMD

From version 1.141 you can use JAM Assembler in CLI. In Windows You should be able just use JamAssembler.jar ... but you may have to set the Environment Variable.

In Windows 8.1 goto Control Panel/System click Advanced system settings and then click Environment Variables button. In the System variables list box scroll down to Path and click edit button. In the value add to the end a ";" Then add the path to Java which should be "C:\Program Files (x86)\Java\Jre7\bin" make sure you don't add a "\" at the end.

Before you use the program you need to setup the options. Run by typing JamAssembler.jar to run window version

After you have done the above in CMD type: "JamAssembler.jar /?" shows details how use the program. Example would be "JamAssembler.jar b=C:\JamAssembler\source.s i=C:\JamAssembler\image.mgt o=object" path and file names must not have any spaces. The "i" and "o" options are, well optional and if not included the default is used.

In MacOS and maybe Linux you have type "Java -jar JamAssembler.jar"

Running in simcoupe


After you have assembled your source the program will automatically save the object file to the disk image. So you can just click on simcoupe icon in the tool bar. Now simcoupe will select the right disk image and boot it. The disk image included (Jam_Loader1_141.mgt) has the loader for the default object code file, this will run on boot. This will load your program and run. Make sure you have set RUN address in your source if your not using 32768(0x8000). If you change the default object file name you need to change line 30 in the basic auto file to the new name and RUN. You will need to close simcoupe after each time you test your program. If your using save object as memory dump you load the file manually not by using the loader.

There is example of some source code called 'stars.s' which shows the use of macros and starsObject which shows the basic use of a class. Also there is an adjusted copy of the how to write Driver applications text document which original appeared in FRED.

How the loader works

When using the default saving, Jam Assembler only saves what it needs to i.e. does not save big DEFS space or space the DUMP command has made. This is so you can have code and MDATA's in many different pages stored on one file. If you are using Atom Boot ROM this does not clear all the memory on reset.

The format is:


Page to run from.(1 byte)
Address to run from (2 bytes)


Address of the code (2 bytes)
Length in bytes (2 bytes)
Page of code (1 byte (0-31))


the code data of the above length

After the code there will be another header then code etc. etc. until the end of the file.

Sam's loader

On the SAM Coupe's side when the disk image is booted the loader program is loaded at 32527 and uses the rest of that page so you can't use 32527-32767 for you code or extra basic code. It only loads the file as it needs it so loads the header first then the data and loads it in the right pages. So the object file on the disk says it starts at 32768 but it's never loaded there.

Sam Disk Program


Please note always have a backup of a disk image before using this program. This program only works with the original mgt disk image type. Now this program displays the image filename in the title bar and also updates after a save.

Load File button: This will load a file from the image displayed, to save to the local hard drive.
Save File button: This will load a file from the local hard drive to save to the image.
Load Comet File button: This will load a comet file from the disk image then convert and insert into a new window in the assembler.
New Disk button: This allows you to load another image to use. This will not change the disk image that assembler will use.
Close button: Closes the dialog
The directory list shows the file number, file type number, file name, type name, and length of file.

. If you find any errors or problems please e-mail me