Microdrive

Discussion and advice about emulating the QL on other machines.
Mike
ROM Dongle
Posts: 13
Joined: Sun Apr 12, 2015 2:59 pm

Microdrive

Post by Mike »

Hi folks,

I'm writing a cross plattform port of Jan Venema's QLAY, to support Mac and Linux (in addition to Windows, which QL2K supports). Most of the basics is working, but I need some documentation about the Microdrive implementation in the QL, as that code (and perhaps the reset of the IPC as well) is due for a total rewrite. Has anyone a spec on the interface between the CPU and the IPC?

Thanks,
Mike


Mike
ROM Dongle
Posts: 13
Joined: Sun Apr 12, 2015 2:59 pm

Re: Microdrive

Post by Mike »

Snapshots...
Mac
Mac
Linux
Linux


User avatar
tofro
Font of All Knowledge
Posts: 2700
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Microdrive

Post by tofro »

Mike wrote:Hi folks,

I'm writing a cross plattform port of Jan Venema's QLAY, to support Mac and Linux (in addition to Windows, which QL2K supports). Most of the basics is working, but I need some documentation about the Microdrive implementation in the QL, as that code (and perhaps the reset of the IPC as well) is due for a total rewrite. Has anyone a spec on the interface between the CPU and the IPC?

Thanks,
Mike
Mike,
there actually isn't much documentation on the microdrive inner workings, because, in pure old Sinclair fashion, there isn't much to document..... As always, the QL has been carefully engineered for extreme hardware efficency (or, expressed a bit differently: The QL microdrive hardware is plain dumb :) )

The only source of a (complete) list of IPC commands is the 8049 disassembly that can be found on Dilwyn's site. An explanation of the usable commands is in the QL trechnical manual with the MT.IPCOM trap.

Code: Select all

0: init IPC
1: get interrupt status
2: open ser1
3: open ser2
4: close ser1
5: close ser2
6: serial1 receive
7: serial2 receive
8: read keyboard
9: keyrow
a: set sound
b: kill sound
c: set P2.3
d: set serial baudrate
e: get random 
f: test
And the only thing the 8049 does with regards to Microdrives is watching the write protect switch. Everything else is in the 8302.

When emulating microdrives, all the emulators I know don't really go down to the hardware level (where the mdv is actually a pure repeating serial byte stream issuing interrupts when certain conditions occur - which is pretty complicated to emulate), but rather intercept the OS somewhere in the mdv device driver where the QL considers the mdv as a sectorized medium. They would then fill the slave blocks from (PC) files and simply have the driver return.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Mike
ROM Dongle
Posts: 13
Joined: Sun Apr 12, 2015 2:59 pm

Re: Microdrive

Post by Mike »

tofro wrote: Mike,
there actually isn't much documentation on the microdrive inner workings, because, in pure old Sinclair fashion, there isn't much to document..... As always, the QL has been carefully engineered for extreme hardware efficency (or, expressed a bit differently: The QL microdrive hardware is plain dumb :) )

The only source of a (complete) list of IPC commands is the 8049 disassembly that can be found on Dilwyn's site. An explanation of the usable commands is in the QL trechnical manual with the MT.IPCOM trap.

Code: Select all

0: init IPC
1: get interrupt status
2: open ser1
3: open ser2
4: close ser1
5: close ser2
6: serial1 receive
7: serial2 receive
8: read keyboard
9: keyrow
a: set sound
b: kill sound
c: set P2.3
d: set serial baudrate
e: get random 
f: test
And the only thing the 8049 does with regards to Microdrives is watching the write protect switch. Everything else is in the 8302.

When emulating microdrives, all the emulators I know don't really go down to the hardware level (where the mdv is actually a pure repeating serial byte stream issuing interrupts when certain conditions occur - which is pretty complicated to emulate), but rather intercept the OS somewhere in the mdv device driver where the QL considers the mdv as a sectorized medium. They would then fill the slave blocks from (PC) files and simply have the driver return.

Tobias
Thanks Tobias,

right, i was mixing up the names. The source I have is a bit of a mess, likely because the spec of the 8302 is unavailable (or was when Jan wrote it). I spent some time searching for information but came up empty. So, if anyone have more information, it would be most helpful.

I'm not trying to do a full blown emulation of the hardware, i just need enough information to rewrite the code and make it as compatible as possible. There are also a couple of bugs i have found, which i hope to be able to resolve.

Thanks,
Mike


User avatar
tofro
Font of All Knowledge
Posts: 2700
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Microdrive

Post by tofro »

Mike,

most known details about the 8302 (e.g. register mappings,...) are collected in this forum in this thread:
http://qlforum.co.uk/viewtopic.php?f=2&t=894

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Mike
ROM Dongle
Posts: 13
Joined: Sun Apr 12, 2015 2:59 pm

Re: Microdrive

Post by Mike »

tofro wrote:Mike,

most known details about the 8302 (e.g. register mappings,...) are collected in this forum in this thread:
http://qlforum.co.uk/viewtopic.php?f=2&t=894

Tobias
Thanks,

Yes, I read that thread, not much information. I do wonder how Jan V. and the others who wrote the simulators figured out how those parts work.


User avatar
tofro
Font of All Knowledge
Posts: 2700
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Microdrive

Post by tofro »

Mike wrote: Yes, I read that thread, not much information. I do wonder how Jan V. and the others who wrote the simulators figured out how those parts work.
They most probably didn't :)

As said above - If you intercept the read and write calls in the OS while this is still working on sector read/write level, you don't need to worry about the microdrive low-level nitty-gritty.

I did the port of the uqlx emulator to the Raspberry Pi - uqlx works exactly like that.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Mike
ROM Dongle
Posts: 13
Joined: Sun Apr 12, 2015 2:59 pm

Re: Microdrive

Post by Mike »

tofro wrote:
Mike wrote: Yes, I read that thread, not much information. I do wonder how Jan V. and the others who wrote the simulators figured out how those parts work.
They most probably didn't :)

As said above - If you intercept the read and write calls in the OS while this is still working on sector read/write level, you don't need to worry about the microdrive low-level nitty-gritty.

I did the port of the uqlx emulator to the Raspberry Pi - uqlx works exactly like that.

Tobias
I think they actually did, or at least to a certain extent. uqlx is patching the rom to intercept system calls as you say, but qlay does not. There's probably about thousand lines of code to handle memory mapped i/o. Both IPC and 8302 are emulated. This is the very thing that i appreciate with qlay and it's derivates, and the reason I'm spending time on it :-)

Here's a piece of the code documentation:

Code: Select all

/*
MDV control
at reset; and after data transfer of any mdv
	(02 00) 8 times			stop all motors
start an mdvN:
	(03 01) (02 00) N-1 times	start motorN
format (erase):
	0a
	(0e 0e) 0a per header and per sector
format (verify):
	02
	(02 02) after finding pulses per header/sector
format (write directory):
	0a (0e 0e) 02 write sector
format (find sector 0):
	(02 02) after pulses
format (write directory):
	0a (0e 0e) 02 write sector
	(02 00) 8 times 		stop motor

read sector:
	(02 02) after pulses
	get 4 bytes
	(02 02) indication to skip PLL sequence: 6*00,2*ff
*/
regards,
Mike


User avatar
tofro
Font of All Knowledge
Posts: 2700
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Microdrive

Post by tofro »

Mike,

you asked for it, now you get it :D - I figured it might be about time to collect what I know (mean to know, can somehow remember or have collected from elsewhere over the years ;) ) on the inner workings of the QL microdrives - once you're through that, you might understand the hardware description in the related thread really are enough of information - As everywhere in Sinclair world, it's the software that's tricky ;)

BTW - If someone here happens to know more details, please feel free to correct/amend.

Before anything can happen, a microdrive needs to be formatted - The QL basically writes headers, followed by data blocks, with gaps in-between.
A microdrive sector header is 26 bytes long and mainly contains the sector number of the following data sector and the medium name.
The formatting routine writes headers and sectors (in descending order from 255 down) onto the tape multiple times, then tries to find the highest sector number that actually got onto the tape (as the sectors are written in backwards order, and a cartridge can't hold much more than around 230 sectors, the higher sector numbers become overwritten at the end of the formatting run because of the tape actually being a loop). The highest sector number found is what QDOS prints after FORMAT mdv_x as overall # of sectors. Note that the sector headers will never be written to again after the formatting run (Tat is why there is gaps between them and the data - To make sure we don't accidentally hit a header instead of data).

What we have now, is a loop of tape filled with 26-byte headers and 512-byte (empty, but formatted) sectors in-between. Sectors and data blocks are interspersed with empty lengths of tape - The so-called gap. The gap is important, because the microdrive circuitry contains mechanisms to distinguish random noise from the read head (the gaps) from actual data blocks (headers or sectors) on the tape - This allows the ZX8302 to fire an interrupt to the 68008 when a gap runs by on the tape.

Registers
$18002 - Transmit register. Bit 4 controls whether we talk to network or microdrive. 1 means microdrive. Note this register is shared between the 8302 and the IPC. Also note those bits cannot be read back from the register and also other bits are used to talk to the IPC. That is why the QL always has a valid copy of what this register should be in the system variable $a0. Write $10 to that register to talk to the microdrive (after having made sure no IPC comms takes place at the moment by waiting some milliseconds in supervisor mode)

$18020 - microdrive control register (write)
bit 0 - select bit - a kind of token that can be shifted through the chain of drives selected together with
bit 1 - the select clock bit
(You set the select bit to the desired state and toggle the clock bit <drive number> times. This works like a shift register across the drives) The drive that has the token after that is the drive for future communications)
Once a drive is selected, the motor will also run.
bit 2 - read or write mdv (write is 1)
bit 3 - erase tape (erase is 1)

$18020 - microdrive status register (same as above, but read)
bit 1 - microdrive transmit buffer full (you are only allowed to write the next byte to the drive if this is 0)
bit 2 - microdrive receive buffer ready (there's a byte to pick up)
bit 3 - tape gap present

$18022 - transmit data (write a byte here to put it on the tape)
$18022 - microdrive read track 1
$18023 - microdrive read track 2

$18021 - interrupt control/status (bits 0 and 5 enable/disable the gap interrupt)

Now a short description of how this is all working together:

Assume you want to read a sector, say "21" from the microdrive 2.

1. Start up the drive by clocking 1 "1" into drive 2 (set select bit, then toggle clock bit 2 times)
2. wait some time for the drive to spin up, enable read
3. wait for a gap interrupt
4. start reading from $18022/$18033 - if it's a header, check for sector #21
5. goto (4) if it's not the correct sector header (basically wait for sector header #21 to come by)
6. wait one more gap (data sector comes by)
7. read 513 bytes (512 bytes data + 1 byte checksum) making sure you only read next byte after "mdv rec buffer ready" has made a 1-0-1 transition)
8. spin down the drive by clocking in a "0" into drive 2.

Writing works the other way round (make sure you never try to write to a sector header - This will corrupt the tape), with some involvement of the erase head, I think, to protect the gaps. Also make sure you enable write only after you have seen a gap, a header, and another gap.

Obviously, there's also a bit of timing involved here - The QL ROMs do this with fine-tuned tight loops. Note this will not work in RAM with unexpanded QLs in contended memory because of the 8301 getting in the way for video output. Only from ROM or upper memory.

Also, I have disregarded the fact that the drive actually works with two tracks. But that doesn't change much in principle. The proper interrupts also need to be en/disabled at the proper time in order to mae this working, obviously.

Maybe this helps a bit forward.
Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Mike
ROM Dongle
Posts: 13
Joined: Sun Apr 12, 2015 2:59 pm

Re: Microdrive

Post by Mike »

*KUDOS*

Thanks Tobias,

this was exactly what i was looking for! What you wrote corresponds quite well with the code in qlay. Now i finally have enough understanding to fix the bugs :-)

All this knowledge that you (and others out there) have about the QL should really be stored in a Wiki for future archeology!

I'll post any progress here, though my work will keep me away for a while.

And yes, if any one else have more information, it's awesome if yo can share it. I spent lots of time searching for this information, and there's virtually nothing out there. For other historic machines there are so many sources, but for the QL it's for some reason very little written (or perhaps i can't find it).

Many thanks,
Mike


Post Reply