Load .MTX files from SDX disk

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 the LOAD command so that it loads from an .MTX file on SDX disk, rather than cassette tape.

A .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 .BAS, .RUN or CP/M .COM file format.

So LOADMTX.RUN is a tool to try to make more of the Memotech software library loadable from real MTX hardware with SDX disk.

How to use

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"

Note 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.

How does it work

Normally, when you load a game from tape, you use the BASIC LOAD command. This repeatedly uses a routine called INOUT (at location 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.

Memotech emulators (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.

When 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.

Finally, INOUT is patched to load from SDX disk, by calling the CP/M entrypoint at 0xf5b0. 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 LOADMTX.RUN, double-check the filename, and try again.

LOADMTX resides between from 0xd000 to 0xd37f. The SDX support normally lowers STKLIM to d6ff or 0xd3ff, so LOADMTX must stay comfortably below that.

Which programs can be loaded

Loadable programs must :-

Using MEMU to check where a program loads to

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 .BAS format.

A couple of programs appear to load into safe areas, then copy themselves above 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 doesn't load.

Testing under MEMU

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.

The -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. MEMU supports -loadmtx as of 2012 onwards.

Included programs

In the 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.

Among the .MTX files now loadable (for which I don't have a SDX .BAS or .RUN file), are :-

These are also included as .mfloppy files. You can use MFLOPPY on Linux to turn these into 3.5" type 07 floppy discs.

Download

LOADMTX can be downloaded from http://www.nyangau.org/loadmtx/loadmtx.zip.

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 (email andy.z.key@googlemail.com).

{{{ Andy