6809 ASM: Infogrames 6809 Assembler 1.0/1.1 User Guide for Thomson MO5, MO6 and Olivetti Prodest PC 128 (part 1)


In this article we’ll see how to install and use Infogrames Motorola 6809 Assembler 1.0/1.1 for Thomson MO5, MO6 and Olivetti Prodest PC 128 microcomputers (MCs).

$0000 – Intro

Infrogames Assembler 1.0/1.1 was the very first Assembler I ever learned and used, it’s dated 1986 folks, yeah eons ago now! (so, don’t be surprised it does NOT have all the fancy features of modern macro assemblers).

Assembler may look a bit scary nowadays, but it was the only way to squeeze performance out of microcomputers at the time, so it was a popular choice for many programmers especially in the game industry. If you are not familiar with technical terms that may be used in this series of posts on the matter of CPU, instructions etc, please have a look at this article that will provide you all the basics that you’ll need to know in order to be able to read this series of articles without any issue.

$0001 – Setup Infogrames 6809 Assembler

If you don’t have a Thomson MO6 or a cool Olivetti Prodest PC 128, you’ll need an emulator of those old systems to be able to play with the specific programming environment we talk about on this article. The best PC 128 emulator I am aware of is the dcmoto and I wrote an entire article to cover the installation and configuration, so click here to read it and get it up and running on your Windows, Mac, Linux or BSD system.

If you are ready then go to dcmoto website and download the cassette image of the Infogrames Assembler by clicking here and then unzip it somewhere on your HD. Yeah cassette folks! Right now its loading will be ultra-fast, but at the time it was freaking slow and every time I froze my microcomputer I had to reset it, reload the assembler from the tape again and then either retype my programs or reload them from another tape, so the whole process of discovering secrets was extremely slow!

When the cassette image is unzipped somewhere on your hard disc you can pre-load it in your dcmoto by clicking “Removable Media” on the top of dcmoto window menu, then click on the button “load” next to the field “Tape (.k7)” and find your unzipped cassette image. Then click “OK”.

$0002 – Loading Infogrames 6809 Assembler

As you have noticed the cassette image comes without any instructions/manual and nor did it at the time, so yeah I had to hack my way around to understand how the Assembler worked, literally from scratch… This means that this documentation may not have all the possible info, so, if you find something missing please let me know in the comments at the end of the article and I’ll be very happy to add it!

To load the assembler: From the main screen of your Thomson/Olivetti click on the box on the left of the option “2 Microsoft BASIC 1.0”, the one usually below the option “1 Microsoft SIMIV BASIC 128” (you can select it also by pressing the key 2 on your keyboard).

When on the BASIC prompt type:

LOADM "CASS:",R

For who is new to all this: the old MO6/PC128 had an AZERTY keyboard, so some of the key may be miss-placed on your PC keyboard if you use DCMOTO Emulator, and so typing the commands may be problematic. One workaround to this is to display the video keyboard provided with the emulator (to do so click on the option “Tools” from the top main menu and then click on “Keyboard” option) OR you can also use MAME emulator, but that requires more work since you have to extract ROMs from dcmoto and put them in MAME. If there are enough people interested I’ll write an article on how to configure MAME to run 6809 emulators.

When the assembler is loaded your will see a prompt in Italian that says:

ASSEMBLER PRONTO!

it means the “Assembler is ready”.

Assembler

The Assembler editor is a screen editor (so you can move the cursor where ever you want using the cursor keys or your Joystick and edit the line you are on). The user area, or editable area, is represented in black and white text, while the blue area contains information about:

1) “RISERVA.=” (RESERVE) means reserved memory from where your code can be stored and it’s expressed in hexadecimal notation. This is usually on BANK 0 of the MO6/PC 128 memory. To reserve memory you can use the command line ZONE (explained later).

2) “RIMAN. =” (REMAINING) means amount of memory locations free for source code and it’s expressed in decimal notation. This value depends on from where you have reserved memory (read #1). This value does not take consideration of the memory required by the LABELS TABLE.

3) “OPZIONE=” (OPTION) shows in which mode the Assembler is working (it supports two modes “ASSE” and “TBUG”, first option is default and means ASSEmbler, while the second is the debugger or monitor).

4) “RICERCA=” (SEARCH) shows last user’s searched term (you can search lines of code using a specific function F described later).

$0A00 – Infogrames 6809 Assembler Editor commands

In this article we’ll focus mostly on the commands to use the Assembler (so, if you are new to all this, we’ll discuss mostly commands that are NOT Assembly mnemonics). On future articles, however, we’ll have a look at how to program the Motorola 6809, the 6809 Opcodes and relative mnemonics which is still very useful stuff to learn nowadays because the 6809 it’s still used as micro-controller.

The Infogrames Assembler supports two modes, the Assembler mode (to edit and assemble code) and the Debugger mode to test assembled code, analyse memory and disassemble stuff…

$0AA0 – Assembler mode (ASSE)

Let’s begin with the Assembler mode (which is also the default mode when you load it).

In the Assembler mode we can load/save, edit our Assembly code (aka “Assembler source” code).

$0AA1 – Loading and saving Assembly sources files

LOAD

To load an ASM (aka Assembly Source Code) file you can use the command load:

LOAD file-name.ASS

Where file-name is long maximum 8 characters not case sensitive.

Official ASM files extension in Infogrames Assembler is ASS instead of the usual ASM (the Assembler was made by a company who clearly did not pay too much attention to the English form here, so please do not mind the “particular” file extension! LOL)

SAVE

If, instead, you need to save your Assembly Source code on tape you can use the command:

SAVE file-name.ASS

Again, file-name length is max 8 characters.

PLEASE NOTE: Infogrames Assembler 1.0 and 1.1 can only use cassette tape as storage memory for programs and files, so you’ll need to use that on real hardware or a blank .k7 file for the dcmoto emulator.

$0AA2 – Editing Assembly Source

To edit your Assembly source you must add first a line-number expressed in decimal notation, then you can add your label (if any), your mnemonic code and then the operands. so, as general form/template use the following:

line-number [label] MNEMONIC [operands]
  • Square brackets [] identify optional parameters
  • “line-number” is an integer number (expressed in decimal notation) that can go from 00001 to 65535 max
  • A “label” is a string (of max 8 characters) that can be used to point at the specific code line for jumps etc.
  • A “mnemonic” is an Assembly instruction (aka a machine code) expressed via acronym. For example the LDA mnemonic means LoaD A (A is a 6809 Accumulator)
  • “Operands” are mnemonic’s parameters and we’ll see later on how they work and which type of values they accept

Here is an example:

00080         LBEQ     $5003

Infogrames Assembler for Thomson MCs is very old school and always requires a line number for each line of code (like it used to be for the old BASIC interpreters).

Please Note: There are much more “modern” Assemblers available on dcmoto website and we’ll discuss them on later articles since they come with some documentation, so those are less in need for an how-to article like this one.

Code editing cheat-sheet:
  1. A useful editing trick is to move your cursor using arrow keys to the very top of the screen or the very bottom to display respectively source code rows on top of the last edited one till the very first row or the rows below the last edited one till the very last source row.
  2. If you press the HOME button after inserting a line-number then it will automatically tabulate the cursor to the mnemonics column and, if you press it again, to the position for the operands.
  3. If you press the INS button then it will move all text after the cursor location of one character to your right, to allow you to insert a new character on your cursor position.
  4. To delete a line from your source just type the line-number and press ENTER. This will remove the line from the source code.
  5. Infogrames Assembler 1.0 is case sensitive for mnemonics (while it is not case sensitive for editor commands like load, save a file etc.), so mnemonics must by typed in capital letters. In other words  “lda” is interpreted as wrong while “LDA” is interpreted as a correct mnemonic.

Please Note: If you find it boring to have to edit assembly on a primitive 8 bit editor from 1986, then I recommend to use a modern editor like Atom on your Windows/Mac/Linux system and then copy your ASM source in the clipboard and use a really cool feature offered by dcmoto: Click on “File” from top main menu and then click on the “Simulate keyboard” option and then click on “Simulate with clipboard”, so dcmoto will type your ASM source on the Infogrames Assembler for you.

DCMOTO Also support auto-typing from a source file in text format.

$0AA3 – Assembler Editor Commands

AUTO

If you don’t want to worry about line-numbers then you can let the Assembler number each line of source code for you by using the command:

AUTO

This will start each new line with an incremental line-number so you can focus on the Assembly coding. To stop auto numbering press CTRL + C.

To specify the line-number increment step you can add the step you want as a parameter for AUTO like:

AUTO 30

This will start from line-number 100 and will increment each new line-number of 30.

DEL

To remove lines from your Assembly source you can use the DEL command, it works as follow:

DEL line-number

Will delete the Assembly source line “line-number“.

If you need to remove a bunch of lines then the syntax is:

DEL start-line-number, end-line-number

This will delete your Assembly source lines from “start-line-number” till “end-line-number” included.

Also DEL support special characters # and * to point at first and last line of source code, so to delete the entire source code from memory:

DEL #,*
F (FIND)

If you don’t know which lines you need you can search for line containing a string using the command:

F string-to-search

Where string to search is an arbitrary string in the assembly source code, like a mnemonic or a message or a comment.

F can also be used without parameters, in which case it will keep searching for the next occurrence of the string in the “RICERCA” field (if any previously specified).

LIST

To list your source code you can use the command:

LIST

It will display your entire source, if you need to display only a specific line then you can use LIST followed by the line-number you want to display:

LIST 20480

And if you need to list a set of lines then you can use the syntax:

LIST 20480,20483

In this case it will display your source from line 20480 till 20483 included.

To list the first line of your source code you can use special syntax:

LIST #

To list the last line of your source code you can use the special syntax:

LIST *
RENUM

If we want to renumber our source code we can use the instruction:

RENUM start-index

This will renumber the entire source with the first line having “start-index” and then each line to follow being incremented of 10.

If you want you can use RENUM without parameters, this will renumber your source code starting from 00100 and each next line being incremented of 10, so 00100,00110,00120 and so on.

If you want to change the step used from default 10 to let’s say 30, you can use the following syntax:

RENUM 30,20

This will start numbering from 20 and with a step of 30, so your second line will be 00050 while your first will be numbered 00020 and so on.

ZONE

This command allow the user to choose the reserved memory zone:

ZONE $5100

Values allowed for this instruction are comprised between $5075 up to $9FFF. When you change the reserved zone you’ll see values of RISERVA. and RIMAN. changing based on which zone you reserve for your source code.

For more info on how memory was mapped on the MO6 and PC 128 please have a look at this article here.

$0AA4 – Assembler Files Management Commands

LOADM

Loadm command allow you to load a BINARY module in memory (as it does from the BASIC interpreter). Syntax is identical to the BASIC LOADM.

LOADM syntax is simple, first parameter is optional and, if specified, will be used to find on the tape which binary file you want to load, second parameter tells LOADM in which memory location you want to download the binary file (you can specify the address in hexadecimal or in decimal notation) and the third parameter, if specified, can be an R, if you use it it will try to run the binary code after being loaded in memory.

Example here:

LOADM "MYMOD.BIN",$5000
MERGE

Merge command allow you to combine 2 assembly files together in memory.

Please note that both the assembly files (the one already in memory and the one you are about to merge from the tape) should have different line-numbers to avoid deleting lines from the one already in memory.

To use merge you can either type it without parameters, this will try to load the first file from the default device (which is cassette/tape) or you can specify a file name as:

MERGE TEST.ASS

Merge needs to load a .ASS file format otherwise you’ll get an error message: “Discordanza di tipo” which mean “Type mismatch”

SAVEM

SAVEM command allows you to save a BINARY module to cassette, syntax is identical to the SAVEM of the BASIC interpreter. Please note that BINARY modules should end with an RTS Mnemonic if you want them to give back control to the calling routine or to the BASIC interpreter.

$0AA5 – Assembler Directives

Assembler directives at the time looked like mnemonics in most cases, however you should not confuse them with a 6809 mnemonic, since a directive is specific for the Assembler (and even the Assembler release in some cases).

* (star symbol) means a line of comment, so each line that start with a * will not be assembled and won’t be columned as it happens for normal assembly source lines.

END this directive tells the Assembler the END of a source code.

01000         END

EQU (Equal) Defines a value for a constant symbol as follow:

00020 TESTSYM EQU     $DF4

Assign value $DF4 to symbol TESTSYM. If you come from other more high level programming languages you may think of EQU as the  assignment operation of a value to a variable. However, be careful, in assembly we use only memory locations and CPU registers (and yes generally speaking also a high level language’s variable is a memory location, but it usually also has “meta-data”), so, in assembly, symbols and labels are just an “easy way” to refer to a given value or memory address.

FCB (Fill Constant Byte) defines a field of 8 bit values as follow:

00030         FCB     Val1[,Val2,Val3...Valn]

Here is a practical example

00030         FCB     $FF,$0C

FCC (Fill Constant Character), this directive defines a chain of constant characters as follow:

00030         FCC     /string of characters/

FDB (Fill Double Byte) Defines a field of 16 bit values as follow:

00030         FDB     $FFFF,$AB0C

ORG (Origin) allows the user to specify from which memory address we want to assemble our source:

00010         ORG     $5000

The line above means “assemble from memory location 5000 (in hexadecimal)”. This is usually the very first directive in most Assembly Sources.

As a general rule, a 6809 assembly should always start with ORG directive to tell the Assembler from which memory location we want to assemble our code.

RMB (Reserve Memory Byte) Allow to reserve one or more 8 bit memory zones as follow:

RMB size-in-8bit[, filling-value]

Here a practical example:

00020         RMB     $FF,$C0

UTIL (Utility) allows the user to modify the assembler parameters during the assembling of your code:

UTIL    4bit-long-flag-set

Example:

00050         UTIL    %0011

the 4 bit long flag set are as follow:

  • %1000 1st bit on specifies you want to display labels table during assembling of your code
  • %0100 2nd bit on specifies that you want to send displayed values to the printer instead of the screen
  • %0010 3rd bit on specifies that you want to display assembly source code during its assembling
  • %0011 3rd and 4th bits on specifies that you want to display both source code and labels table during the assembling of your code.

$0AA6 – Supported memory addressing modes

Infogrames Assembler support all memory addressing modes offered by the 6809.

Note for the Assembly expert: this Assembler is not designed to support the original 6809 external MMU (the 6829, for more info on the 6829 click here), so here we discuss only memory management offered in the Thomson and Olivetti Prodest microcomputers.

Constant values

Addresses, pointers and values can be specified using constant values that can be expressed in one of the following notations:

  • hexadecimal notation using the $ sign before the address number, for ex: $8FFFF (since the 6809 is an 8bit CPU you can generally use value from $00000 to $FFFFF). Please Note: When using Hexadecimal values you MUST use CAPITAL letters for the A,B,C,D,E,F symbols
  • decimal notation (default notation, so no special signs are required), for ex: 20480 (again max allowed size is 65535 in general, please check for instructions extra limitations)
  • binary notation (using % sign before the address or value), for ex: %101011

On this Assembler only Physical memory addressing is supported, so no Virtual Memory addressing is possible, although if the Motorola 6809E supported an external MMU (the 6829).

So, here is the list of supported memory addressing modes (definitions are from the 6809 original User Guide, examples are written by me for the specific syntax of the Infogrames Assembler):

Inherent

Inherent addressing refers to those instructions which have no addressing associated with them.

00100 * Add B accumulator to X
00110         ABX
Accumulator

Accumulator addressing is done in those instructions which can specify the A or B accumulator. In some cases this may be the 16-bit D accumulator.

00100 * Decrement the A accumulator
00110         DECA
Immediate

In Immediate addressing the byte or bytes following the opcode are the information being addressed. These byte or bytes are specified as part of the instruction.

00100 * Load immediate value (aka 8) 
00110 * into A accumulator
00120         LDA     #8
Relative – Long and Short

In Relative addressing, the value of the byte(s) immediately following the opcode (1 if short, 2 if long) are added as a two’s complement number to the current value of the program counter (PC register) to produce a new PC location. In the source code, the programmer specifies the desired address to which execution should be transferred and the assembler determines the correct offset to place after the opcode.

00100 * Jump/branch to location "THERE"
00110 THERE   EQU     $5000
00120         LBRA    THERE
Extended

In Extended addressing, the two bytes (16-bits) following the opcode are used as an absolute memory address value.

00100 * Load A accumulator from memory location
00110 * 1000 in hex
00120         LDA     $1000
Direct

In Direct addressing, the single byte (8-bits) following the opcode is used as a pointer into a 256-byte window or “page” of memory. The page used for this purpose is the one currently found in the Direct Page register. Thus, the effective address is a concatenation of the Direct Page register as the most significant half and the byte following the opcode as the least significant half.

00100 * Load A from memory location $XX22 where
00110 * XX represents the content of the DP register
00120         LDA     $22
Extended Indirect

In Extended Indirect addressing, the 16-bit value following the opcode is used to point to two bytes in memory which are used as the effective address.

00100 * Loads D from the address stored at 
00110 * location $A012 AND $A013
00120         LDD     ($A012)

Please note: the traditional parentheses () here above!! A lot of 6809 Assembly books report the Extended Indirect syntax using square brackets however at the time most of 8bit Assemblers used traditional parentheses for such memory addressing (this is a common thing also on other computers like on the Commodore 128 and C64).

Indexed

The Indexed addressing mode of the 6809 is an extremely powerful method of specifying addresses which is, in general, some sort of offset from the value stored in one of the registers X, Y, U, S, or PC. There are several forms of indexed addressing which could each be considered an addressing mode in itself. We will, however, discuss each as a subset of Indexed addressing in general. Note that except for the Auto-increment and Auto-decrement modes, determining the effective address has no effect on the register being used as the index.

  1. Constant-Offset Indexed
    This mode uses a two’s complement offset value found in the byte or bytes following the opcode. The offset is added to the contents of the specified register to produce a 16-bit effective address. The offset may be represented as a number, a symbol, or any valid expression. It can be either positive or negative and can be a full 16-bits.

    00100 * Loads A from location pointed 
    00110 * to by X
    00120         LDA     0,X
  2. 00100 * Loads A from (Y) plus 5216
    00110         LDA     5216,Y
  3. 00100 * Loads A from (U) minus 36
    00110         LDA     -36,U
  4. 00100 * Loads A from (S) plus VAL
    00110 VAL     EQU     20
    00120         LDA     VAL,S
  5. Accumulator Indexed
    In Accumulator indexing, the contents of the specified accumulator (A, B, or D) are added to the specified indexing register as a two’s complement value. The result is the effective address.

    00100 * Loads A from (B) + (Y)
    00110         LDA     B,Y
  6. 00100 * Loads X from (D) + (S)
    00110         LDX     D,S
  7. Auto-Increment
    The contents of the selected register are used as the effective address with no offset permitted. After that effective address has been determined, the selected register is incremented by one (for single plus sign) or two (double plus sign).

    00100 * Loads A from X and then 
    00110 * increment X by 1
    00120         LDA     ,X+
  8. 00100 * Loads D from Y and then 
    00110 * increment Y by 2
    00120         LDD     ,Y++
  9. Auto-Decrement
    In auto-decrementing, the selected register is first decremented by one (single minus sign) or two (double minus sign). The resulting value, with no offset, is used as the effective address.

    00100 * Decrements U by 1 and then 
    00110 * loads A from the address in U
    00120         LDA     ,-U
  10. 00100 * Decrements S by 2 and then loads U
    00110 * from address in S
    00120         LDU     ,--S

A simple trick here to simulate the Extended Indirect using Indexed Addressing :

00100 * Loads D from the address stored at 
00110 * location $A012 AND $A013
00120         LDX $A012 
00130         LDD 0,X

We load the content of address $A012 in Index register X and then we use Indexed Addressing to load in register D what is pointed by X content.

$0AA7 – Assembling Assembly code

To assemble your assembly source into an executable (or object file) you can use the command:

ASS

If you committed syntax errors or some logic errors (like for example too far jumps or not enough memory etc…) it will be displayed via error messages during the assembling phase here.

As far as I know Infogrames Assembler was released only in Italian (although it derived from another French Assembler specific for the M05 called ASSDEASS), so error messages will be displayed in Italian language, if you have problems let me know with a comment or a message and I’ll try to provide some help on here.

The ass command supports parameters as well to control more the assembling operation, let’s have a look at them:

  • ECR, this parameter instruct the assembler to display the source code while assembling it
  • CO, this parameter instruct the assembler to display the assembly source code as well as the opcodes while assembling it
  • TL, this parameter instruct the assembler to display the table of labels while assembling your code
  • RM, this parameter instruct the assembler to assemble your code directly into the reserved zone (“RISERVA.=”). Please note that if you are using addresses in BANK 0 then there is no need to reserve memory for your code.
  • :FileName ,  the : parameter allows you to specify a FileName for the executable and this instruct the assembler to assemble and store the executable on the tape using the filename you have specified.

Example os use:

ASS CO,TL:MYPROG

This command will assemble your assembly source and save the executable as MYPROG.BIN on the tape as well as display the source while assembling it and the labels table.

A Note about assembling code: As far as I was able to check/understand the Infrogames Assembler assemble code in two passes:

  1. On the first pass it generates the symbols table and line addresses table
  2. On the second pass it generates the object code. However syntax checks happen between both the two passes and most of the syntax errors are usually detected during the second pass.

$0AA8 – Executing Binary code

When you have completed assembling your code you can run it using the command:

exec memory-location

Here is were usually things can go bad lol, but, oh well, try and fail is the way to go here!

$0AB0 – Monitor Mode (TBUG the Debugger)

The monitor mode (or debugger in modern days) allow you to analyse memory and your executable, it also allow you to add directly opcode on given memory areas.

To enter Monitor Mode, from the assembler prompt type:

TBUG

This will enter the monitor mode and so the prompt will change in:

TBUG PRONTO!

Which means tbug is ready.

You can exit the debugger at any moment by typing:

QUIT

Or the typical debugger one letter form:

Q

This will bring you back to the ASSEMBLER mode.

Debugger commands

D

D START-ADDR[, END-ADDR] This command ask the debugger to print out the hexadecimal values and the corresponding ascii values contained in memory addresses between START-ADDR and END-ADDR. If you do not specify an END-ADDR then the debugger will display 64 bytes of memory locations (aka 8 lines of 8 bytes each).

Example of use:

D $5000, $5100
G

G [ADDR1][, ADDR2] This command will start the execution of assembled code from address ADDR1. If no memory address it’s specified then G will start the execution from the last location used by any other debugger command. If ADDR2 is specified then G will PAUSE the execution when reaching the ADDR2, display the content of registers and give back control to the editor (this is very useful when testing code from the tbug editor).

Example of use:

G $5000, $5012
I

I [ADDR] This command allow the user to modify memory content directly. If you specify the ADDR address then you’ll be able to modify the content from that address on, if ADDR is not specified then the address used will be either the reserved one or the last one used with other instructions.

P

P [ADDR] This command allow you to start the step-by-step execution of a program from address ADDR. During the execution it will display 6809E Registers value. ADDR is optional, and if you don’t specify an address then P will start the execution from the address contained in the PC register.

Example of use:

P $5000

To control the step-by-step execution you can use the following keys:

  • [SPACE BAR] Will execute the instruction pointed in PC (if you specified an address after the P command then PC will contain that address as a starting point)
  • [P] this will skip the instruction pointed by the address in PC and will move to the next one
  • [CTRL] + [C] Will stop the execution and return control to the debugger CLI
R

R REG, VALUE This command allow you to modify the content of the register REG with the numerical value VALUE.

Example of use:

R X, 65
S

S [START-ADDR][, END-ADDR] This instruction is very important because it allows you to disassemble code from START-ADDR address till END-ADDR address. Both START-ADDR and END-ADDR are optional. If you use S without any parameters then TBUG will disassemble the next address after the last one used by previous commands. If you specify S only with START-ADDR then TBUG will start disassemble from START-ADDR until you press CTRL+C or it reaches the end of the memory addressing space.

Example of use:

S $5000, $5020
V

V This command displays the content of the 6809 registers. The registers being displayed are obviously X, Y , S, U, D, CC, DP (don’t worry if you don’t know much about the 6809, I am writing an article with all the info you’ll need!)

Example of use:

V

Ok that’s it for now, thanks for reading and I hope you’ve found some useful information here. If you enjoyed this post, please don’t forget to support my blog by:

  • Visiting my on-line hacking and engineering merchandise shop on redbubble.com by clicking here
  • Or you can also make a donation with the PayPal link in the column on your right
  • Or share this article

If you like my articles and want to keep getting informed on new ones you can follow me on one of those 21st Century thingies called FacebookTwitterInstagram or Pinterest

And as always if you have any questions please feel free to use the comments section below.

Thank you! 🙂

$0AC0 – Books and Resources about programming the Motorola 6809

What next?

Read part 2 and 3, links here below: