Jam Assembler version 1.132







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 on JamAssembler.bat or you should be able to click the jar file directly, if all is well you should see the Options dialog, shown later. If your using linux, you click on JamAssRun instead of JamAssembler.bat. There is an icon file in the images folder called JamAss.ico that can use with a desktop shortcut.

Some Apple Mac computers (at the time of writing Macs that don't have Intel 64bit processor) can't run Java SE 6, so there is special version for SE 5 called JamAssemblerAM.jar. Printing has been disabled because SE 5 can't use the function I'm using. Some windows may look different from ones shown here. This version will no longer be updated (current version V1.13) because I don't think anyone needs it now. If you need it please e-mail me.

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

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

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


Using METHOD command instead of FUNCTION command for your member functions will make the function be shown in the class in the project view. Member functions must be in the same file as the class and start with the same name as the class. You will still need to manually write so registers pointing to the class.

Example: Using the sprite class

METHOD sprite.display  
  LD A,(IX+sprite.y)

;load A with y from class using IX as pointer to object

In the main code:    
alien: DEFS sprite ;define space for class instance
  LD IX,alien ;Make IX point to alien object
  CALL sprite.display ;Call member function

Have a look at starsObject.s for a working example.

Please note : Jam Assembler OOP programming was never in the orginal design and using IX/IY register uses a lot of processor time.

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.

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 (object.mgt) has the loader for the default object code file, this will run on boot.. Then will ask for you call address this can be any address in the standard SAM BASIC format. Normal rules apply with paging. If you change the default object file name you need to change line 50 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.

The format is:


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