Computers Overview
Commodore PET
Sinclair ZX80
Sinclair ZX81
BBC Micro
Sinclair Spectrum
Memotech MTX
          Dev. Corner
                  MTX Shell
      Web Tools
    User Groups
    Video Wall
Memotech CP/M
Atari ST
Commodore Amiga
DEC 3000 AXP
Raspberry Pi



The Memotech MTX Series

MTX  / Z80 Assembly - Under RISCOS


Many years ago, Martin Allcorn wrote a Z80 assembler in BBCBASIC for RISCOS to run on his Acorn Archimedes. These days, Martin runs his assembler on a Raspberry Pi running RISCOS and uses it to do all the development work for our MTX based add-ons. Although Martin has made the assembler freely available, I don't think that anyone else is using it, and any users of our hardware just download compiled versions of EPROM code etc. as required.

Version Update - May 2021

Martin has rewritten the assembler in ARM assembly language and renamed it !A80. The new version uses file type 080 instead of 281 so that "old"  code can still be built on the earlier version of the program. It's still a RISCOS only program, tested on both  RiscOS 4 (RiscPC) and RiscOS 5 (Raspberry Pi). Martin adds, "there's no reason it shouldn't work on older versions if anyone's daft enough to try it, as I used the RiscOS 3 reference manuals when writing it".

It builds the MTX ROMs (17k lines of source) in about 8 seconds on a 200Mhz RiscPC. A RaspPi will be faster, how much faster depends on the model and the storage, Martin's model 3B finished the same build in under 4 sec. The slow bit is the writing out of the listing file, and some SD cards are particularly slow and will hold the Pi back, A really slow card might actually make a Pi slower than the RiscPC despite the 3 to 5 times faster CPU!

The BASIC version took about 10x as long. The re-written expression evaluator is MUCH better***  no +ASC"x" kludge to insert character codes. 

Martin feels that this is much more like a "releasable" program, so has included a License file and a help file in the distribution. (These are accessible outside the ARCFS archive file in the Zip file download at the bottom of this page.)

In another improvement to the previous version, the Help file provides some limited documentation of how to use the program.


Whilst Martin's assembler is fully functional, it does have some "quirks" that make it a little awkward for a novice to use, particularly as there is no documentation for the assembler and it only runs on RISCOS. (The ARM assembler version does now include some limited documentation as noted above.)

In 2019, while Bill Brendling was working to add CFX-II emulation to his MEMU-Pi system, he needed to analyse some of the CFX-II code during his debugging of MEMU-Pi. To make things easier, Bill wrote an assembler in Python 3 that worked with Martin's assembler source files.

A copy of Martin's Assembler can be downloaded from the bottom of the page and Bill's Python based assembler can be downloaded from this page.

Documentation - BASIC Version - There isn't any. ARM Assembler Version - help file included.

During the course of Bill's discussions with Martin, a few snippets of information that might be useful to anyone wanting to make use of Martin's assembler or Bill's Python implementation came out. I have included a few brief notes on this page.

Q. What is the difference between ORG and OFFSET in your assembler?
A. My assembler is written in BBC BASIC and is heavily influenced by the one in BBC BASIC. Because I'm running it on the 32 bit Arm version of BBC BASIC I can build images greater than 64k in size. (I usually have it set to use 128k as that's the size of most of my "stock"  flash chips). To do that the assembler keeps multiple pointers.
ORG is the origin of the code within the image equivalent of P% on the BBC.
OFFSET on the other hand, is the option to assemble for a different address like O% on the BBC.
Offset assembly is heavily used when building paged ROMs like the MTXPlus+ or the various CFX options   What the assembler does when it encounters OFFSET is calculate the difference between the current assembly position and the run time address and add (or subtract) them from any future address calculations.
Q. What does OFFSET with no address mean?
A. OFFSET on it's own cancels the offset assembly by setting the difference back to 0 (like aligning P% and O%).
Building the SDX and CPM ROMs is made more complicated by the references back to the MTX ROM in the SDX extensions, and the CPM ROM having to re-locate into RAM.

So the build script builds the 3 basic ROMs first, so that all the BASIC/OS labels are available to the SDX sources. The addresses could have been hard coded as in the original source, however the build code started from the MTXPlus+ code base and for that the system ROMs can (and have) change so the SDX ROM has to have access to the actual labels.

The Build also puts the ROMs in the same place within a 64k image as they would have been in the MTXPlus+. OS in the first 8k, ASSEM next, and then  BASIC in the 16-24k area, but offset to run at 8-16k. (In the MTXPlus+ build there are 7 page ROMs and 1 fixed which fills all of the 64k space)

The CPM ROM sits in the MTXPlus+ ROM image in the 40-48k range, so the Origin for assembly is #A000 (found in the CPMboot source file) When running in ROM, the code will be at #2000 so there's an offset instruction at the start of the same file. Once CPM is running, it runs in RAM so uses a different offset (see CPMzmon1).

The code you pointed to in vectors, is to fill the last section in high memory where the CPM BDOS has been patched to expect the hardware drivers, the ORG statement tells the assembler where to put it within the build space, since offset assembly is already in use at that point, there's no need for the matching OFFSET as the assembler automatically keeps that in step, but the comment is there in case there's issues.

The SDX ROM is assembled into the 48-56k range, but with offsets so hat the ROM based part is assembled for 8-16k, and the RAM based part the occupy the correct area between the CPM BDOS and BASIC's system variables.
Q. How does your assembler handle conflicting labels? Use the first definition, the last one, something depending upon the include nesting, or otherwise?
A. Any inconsistent label and the assembler will throw an error on pass 2, but only if the run time address changes. So where you're getting CPMtrust appearing to be at BFE7 (where it sits) and FFE7 (where it runs), my assembler only sees the FFE7 address so there's no conflict.
Q. What is the significance of the ",281" at the end of the file names?
A. 281 is the RiscOs file type I use for Z80 assembler source code. The assembler creates a 2nd file to hold the build number which increments each time a source file is sent to the assembler.  
For the record I use 280 for the file type for the Z80 binary, 180 for a Z180 binary and 181 for Z180 source. Both the Z80 and Z180 will assemble the other assembler's files if they're included, though the Z80 version will error if it encounters a Z180 only opcode.



Zip Version Description

Martin's Z80 Assembler for RISCOS, rewritten in ARM assembly language
As previously, the distribution is in the form of a zipped ARCFS archive. The Zip file here is a normal Zip file, with the Arc file inside it, but also contains the release notes and license file in PC readable text form.
Since the files are small, by way of example, the Zip file also contains a disassembled version of the MTX computer ROMs. (The 080 file is the source file and the txt file is the output from the assembler.)
(2015) Martin's Z80 Assembler for BBC BASIC under RISCOS

NB : The Assembler is in the form of a zipped ARCFS archive, it is NOT a PC Zip file. Read the "instructions" file for more details and restrictions on its use.


mailto: Webmaster

 Terms & Conditions