I've been playing with Spectrum emulators, their file formats and some reverse engineering tools recently.

Thanks to this forum, I was able to parse the TR-DOS disk image format and find the bytes of the code files with the address fields of where they should be loaded.

But when I try to load the code into the given address ranges into Ghidra (a reverse-engineering tool), addresses don't seem to match up.

The Spectrum and its clones used the Z80, which is 8-bit with 16-bit addresses and can access 64 KB of memory. But later Spectrums and clones added paged memory circuitry and could access 128 KB or 256 KB.

Perhaps I'm missing something about which bank(s) the code files are loaded into. TR-DOS only gives one address field, so I'm assuming it's both the load address and the execution address. But perhaps one of those assumptions is wrong and instead one of those addresses is a standard that's not in the file metadata.

I've Googled but only found high-level TR-DOS manuals. I've found the TR-DOS ROM disassembly but not the relevant code in it. I'm looking for a technical description of how this works.

Maybe such documentation is around but in Russian or Czech. Perhaps we have people who hacked on those systems back in the day, or worked on emulators for them more recently.

  • 2
    I'm about 30% sure that TR-DOS occupies the lower 16k, and applications are "somewhere" above that. There's some kind of mechanism that allows TR-DOS to call the BASIC ROM.
    – OmarL
    Apr 23 '20 at 8:25

The usual way of such HW peripherials was switching the original ZX ROM (0-16384) chip for its own memory space where was usually another ROM or even RAM on the runtime. It was done by the /ROMCS pin on the extention bus/connector.

I am not famillair with TR-DOS as I was heavily using MDOS instead. The MDOS was an ZX OS extention for Didaktik D40/D80 Floppy disc drives. It has a nice interaction with original ZX BASIC making able to use BASIC programs to use the flopies. For example:

LOAD * "some_file.P"

loads a file from floppy. It worked in a way that when you run this program original BASIC throw an exception like Syntax error or Non sense ion BASIC and D40/D80 hardware detects that by scanning Z80 pins. Then it switch to its own ROM and instead of throwing exception it executes the extended BASIC commands. After that original ROM switches back and BASIC program execution is restored.

If you want more details just study the D40/D80 or any other similar HW circuitry and its commented disassembly.

The usual detection was done by simple logic circuit detecting hardcoded address bus state along with M1,MREQ,RD signals... IIRC D40/D80 was sensitive to RST 0 and RST 8 instructions.

Now the bank switching for stuff above original 48K was done by the programs itself. Each bank switching able computer (like ZX128) had a special I/O mapped register that controls the actual configuration of memory map. That is why in file systems is usually only 16 bit target address.

Now I expect that TR-DOS was working in similar manner

  • 1
    This answer seems to be about MDOS, not TR-DOS
    – OmarL
    Apr 23 '20 at 12:58
  • @Wilson yes and its also stated ... but the mechanisms are most likely the same or at least similar
    – Spektre
    Apr 23 '20 at 13:00
  • 1
    Some of it will be similar. Probably the hardware will be similar; I don't know. One big difference is that TR-DOS does not trap BASIC errors but instead has its own prompt; (but still uses the BASIC keywords like RUN and LOAD for some reason).
    – OmarL
    Apr 23 '20 at 13:06

This is only a partial answer so far.

TR-DOS was first part of the Beta 128 disk interface, which was cloned along with the Spectrum itself in Russia and Eastern Europe.

According to this Beta 128 manual I found online, by default code does both load and start at the same address. Loading such code files manually is known as "auto-run". But you can also load code as part of a BASIC program and you can use this method to either load code at its default address, or a specified address, followed by another instruction to begin execution at another specific address:

For the machine code programs, they can be loaded to the same address from which they were saved, eg:


or loaded to a different address by specifying in the loading instructions, eg:

 LOAD "margin"CODE 51000

When running a machine code program the auto-run address should be the same as the starting address of the program, eg:

 RUN "Discound"CODE 47800

provided the code is meant to auto-run from 47800 on loading all will be well.

The alternative is to use a two line loader, eg, SAVE the following program on disk as say "DCTLOAD"LINE 10

 10 RANDOMIZE USR 15619:REM:LOAD "Dsicount"CODE 47800

To run the program you now enter RUN "DCTLOAD" which will load the machine code and the "run it" fom 47838.

A small number of the disk image files I downloaded seem to have code files with offsets and lengths that would not fit in a single RAM page, or would overlap the end of a RAM page. I have no idea what happens in such cases. Some of the files do seem to include various tricks, copy protection, and/or obfuscation though, which makes it harder to learn by exploring.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.