Unfinished work in progress. Some things work, some things that should work don't, and I'm not sure why.
I am not expecting this to work if you have a MTX512 S2. I suspect that the delta memory page is problematic. ie: 0000-3FFF in RELCPMH=1 mode isn't backed by the same physical memory as the 8000-BFFF page in RELCPM=0 mode.
Cassette tapes and tape recorders are hard to find nowadays.
LOADing file from tape, or Compact Disc, is a slow
and sometimes error-prone process.
LOADMTX.RUN is a program which changes the behavour of
LOAD command so that it loads from an
.MTX file on SDX disk, rather than cassette tape.
.MTX file is all the same bytes as would be found
on a Memotech cassette tape, only in a file.
Most of the Memotech software library is available in this format.
Only a subset is available in SDX
.COM file format.
LOADMTX.RUN is a tool to try to make more of the
Memotech software library loadable from real MTX hardware with SDX disk.
If you have
SNAPPO.MTX on disk :-
USER RUN "LOADMTX.RUN" LOAD "SNAPPO"
The name you load must match the filename on disk.
As CP/M filenames follow an 8.3 character naming convention, and as the .3
part is fixed as
.MTX, only the first 8 characters of the
filename you type is significiant in finding the file.
It doesn't matter what the name in the tape actually header is, as LOADMTX pretends this matches what you asked for.
Sometimes it is necessary to tell LOADMTX to unload itself after a certain number of chunks are loaded from the disk, perhaps because the loaded program will overwrite the memory in which LOADMTX sits. This can be specified in the 14th character of the filename. eg: for Obliteration Zone, it is necessary to :-
USER RUN "LOADMTX.RUN" LOAD "OBLITERA 5"
OBLITERA is 8 characters long, and there are 5
spaces before the digit 5 (which is the number of blocks).
Many programs are comprised of 5 blocks.
If you don't specify the number of blocks, it defaults to 255,
which is far more than any known
.MTX file uses.
Normally, when you load a game from tape, you use the BASIC
This repeatedly uses a routine called
0x0AAE in ROM)
to load the tape header, system variables, basic code, variables and other
chunks of data.
When the first part of the game has loaded, it may then load another program,
or it may load chunks of machine code and data from the tape.
The sequence and locations of the chunks loaded varies depending upon the
game being loaded.
(such as MEMU)
work by patching INOUT so that when it is called, the emulator reads the
next part of the
.MTX file from disk.
However, in a real MTX, INOUT is in a real ROM chip, and this is
therefore not patchable.
It would seem that we cannot change what the
LOAD command does.
LOADMTX.RUN is loaded it remains resident in high memory.
It puts the MTX into the mode in which all the memory space is RAM
(RELCPMH=1 in the IOBYTE).
It copies code from ROM into RAM, and patches it as necessary.
It makes sure that it patches everywhere in the ROM (now in RAM) and in RAM where an attempt is made to change the IOBYTE. Whenever an attempt is made to change which ROM page is visible, the desired ROM page is copied into RAM and (re)patched. If this isn't done, we would end up back in the memory mode with the ROMs visible (RELCPMH=0 in the IOBYTE), thus undoing the patching.
Ordinarily, switching between ROM pages is instant, but with the patching above in place, an 8KB memory copy must be performed, and this is slow. If additional measures are not taken, the MTX will run very very slowly.
There is an interrupt routine that is called 64 times a second, and unfortunately this will normally switch to ROM page 1, run a peice of code in ROM page 1, and then switch back again. Most of the time this peice of code is very small, sometimes it is large. This code is patched so that an assessment is done as to whether the small or large peice of code will be needed. If small, then its processing is done in the patch itself, without switching pages. If large, we can't avoid switching, and this is allowed to happen. This small patch dramatically speeds things up, but still the MTX will run very slow.
Next, there are "print to screen" and "keyboard reader" routines which happened to be called a lot. These save the IOBYTE, select a specific ROM page, run the actual print to screen or keyboard code in that ROM page, return and restore the IOBYTE. These are patched so that instead they save the IOBYTE, select a specific ROM page (in this case we actually allow this to happen), run the actual print to screen or keyboard code in that ROM page, return and restore the IOBYTE back into the RELCPMH=1 mode. We can do this because we know that although we've allowed the system to go into ROM mode (RELCPMH=0), control is passed back to us and we can get the system back into RAM mode (RELCPMH=1). This makes a huge difference in the responsiveness of the MTX, to the point it is usually pretty indistinguishable from normal operation.
INOUT is patched to load from SDX disk,
by calling the CP/M entrypoint at
If the desired file can't be found or there is an error reading it,
the system is restarted.
If this happens, you'd need to re-load
double-check the filename, and try again.
LOADMTX resides between from
The SDX support normally lowers STKLIM to
0xd3ff, so LOADMTX must stay comfortably below that.
Loadable programs must :-
0xd000in memory (LOADMTX and SDX disk code sits above this)
0x0000-0x3fffand contains the patched copy of the ROM code)
You can use MEMU to assess whether an
.MTX file stands
a chance of being loaded by LOADMTX :-
$ memu -vid-win-big -snd-portaudio -diag-console -diag-tape "Vortex by Paul Daniels (19xx) (PD).mtx" LOAD ""
MEMU will then spit out these diagnostics :-
LOAD fn=Vortex by Paul Daniels (19xx) (PD).mtx LOAD base=0xc011 length=0x0012 iobyte=0x00 LOAD base=0xf8f2 length=0x0259 iobyte=0x00 LOAD base=0x4000 length=0x24bc iobyte=0x00 LOAD base=0xc000 length=0x0001 iobyte=0x00
An example of something that won't work is :-
$ memu -vid-win-big -snd-portaudio -diag-console -diag-tape "SON OF PETE.mtx" LOAD ""
MEMU spits out these diagnostics :-
LOAD fn=SON OF PETE.mtx LOAD base=0xc011 length=0x0012 iobyte=0x00 LOAD base=0xf8f2 length=0x0259 iobyte=0x00 LOAD base=0x4000 length=0x1ef9 iobyte=0x00 LOAD base=0xc000 length=0x0001 iobyte=0x00 LOAD base=0x8000 length=0x55f0 iobyte=0x00
0x8000+0x55f0=0xd5f0, which means this block, when loaded,
will obliterate LOADMTX!
Luckily we already have this game in SDX
A couple of programs appear to load into safe areas, then copy themselves
0xd000, obliterating LOADMTX or the SDX disk support.
Sometimes specifying the number of blocks in the 14th character of the
filename can be used to remove LOADMTX after the program is loaded
before this copying occurs, but sometimes the copying happens before the
last block is loaded.
So there is the chance the output above looks good, but the program still
You can use MEMU to test whether LOADMTX will be able to load the file :-
$ ls LOADMTX.RUN LESFLICS.MTX SNAPPO.MTX OBLITERA.MTX $ memu -vid-win-big -snd-portaudio -sdx -loadmtx USER RUN "LOADMTX.RUN" LOAD "SNAPPO"
Note that the files have CP/M compatible 8.3 filenames so that the SDX
support in MEMU can see them.
Note particularly the
.MTX file extension in capital letters.
-loadmtx tells MEMU to emulate the SDX disk I/O,
even though the system is patently not in the right memory mode.
This is necessary due to the way LOADMTX works.
-loadmtx as of 2012 onwards.
tapes directory is a script which copies a selection
of around 50 tapes from the MEMU distribution and renames them.
These are the ones I've been able to get to work.
.MTX files now loadable
(for which I don't have a SDX
These are also included as
You can use
MFLOPPY on Linux to
turn these into 3.5" type 07 floppy discs.
LOADMTX can be downloaded from
Copying of this program is encouraged, as it is fully public domain. The source code is included in the package. It was created on the authors time and equipment. Caveat Emptor.
The author of LOADMTX and this documentation is Andy Key