Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

The Sinclair ZX Microdrive Resurrection Project (long)

1,538 views
Skip to first unread message

Volker Bartheld

unread,
Mar 3, 2012, 1:16:35 PM3/3/12
to
Dear Spectrum fans!

[Management summary: Download http://www.bartheld.net/temp/mdv2img.zip and
tell me what you think. All help very much appreciated.]

As mentioned in Message-ID: <4j9pqs271vnp$.d...@news.bartheld.net> (Subject:
Microdrives and stuff with Interface 1), I wondered whether my almost
thirty year old Sinclair Microdrive Cartridges were still usable. Not
because I wanted to retrieve some games I had multifaced there but because
of some private coding stuff I wanted to rescue from decay.

My Speccy, which I had put into some PC-like case, together with a better
power supply, separate voltage regulator, two Microdrives, IF-1 and a
first-generation Multiface One first had to be equipped with a composite
output since I had no TV with an analog tuner anymore. Thanks to Womble's
Retro Repair Shack this was an easy soldering job to do, I connected the
cinch socket to a cheap rear view camera from Amazon and fascinatingly
enough, the little Z80 computer was "booting" right up. "(C) 1983 Sinclair
Research Ltd.". Yeah! Not bad.

Next thing was getting the basic communication right. Davide Guida's spxfr
plus his instructions on building a Speccy-to-PC RS232 cable were very
instructive and so I got my first bit of BASIC transferred from the PC to
the Speccy and back with a whooping 19200 baud.

Of course spxfr is cool for isolated (and few) transfers, but not exactly
what I wanted because some of my data has been saved to MDV (namely some
PAW adventures, Tasword documents etc.) using Romantic Robot's Multiface
One and other software already came on MDV.

Of course, I could use the "tape out" socket, the "Save To Tape" option of
the MF-1 and my PC's soundcard, but this would take ages and still wasn't
what I was imagining. Also the fear came up that there could be data
integrity issues with those cartridges, so I needed something more
elegant. As it turned out, the first problem wasn't software related at
all but affected the hardware, the cartridges themselves to be precise.

As soon as I touched one of those little foam pieces that should ensure
good contact with the drive head with my tweezers, the foam literally
disintegrated and the slick fleece liner fell off. However I figured that
patience and double-sided adhesive foam tape would do the trick. And
indeed, I successfully could fix the foam pads of a few cartridges while
recycling the top fleece from the cartridge without having to extract the
brass spring thingie which would probably never go back in place
correctly.

After that I ran a few tests with an empty cartridge, reformatted, SAVE
*"m";1;"test" CODE 0, 65535 etc. and read back. Excellent. So the tape
itself and the Microdrive mechanics (rubber roller etc.) were still
intact. As it turned out, "old data" from last century wasn't in a shape
this good. Probably due to head alignment/contamination issues, variations
in tape speed (probably the rubber roller had shrunken a bit) and probably
magnetization has "broadened" or copied through the layers of tape on the
spindle, lowering signal-to-noise-ratio.

These problems are better fixed on the PC side since I didn't intend to
address the Microdrives on a hardware/low level without having the IF-1
attached. This might be possible with some Arduino-platform but was beyond
my time schedule and skills.

The idea came up to write some kind of Z80 machine code tool that would be
uploaded onto the Spectrum which spun the tape, read as much sectors as it
could (those with checksum errors probably multiple times) and transfer a
RAW image of those sectors/the cartridge to PC via RS232.

That's where mdv2img entered the stage. Thanks to Andy Pennel's "Master
Your ZXMicrodrive 1st Edition", a few Your Sinclair issues, Gianluca
Carri's "Spectrum Shadow ROM Disassembly" and a few other tools (namely
Gerton's WinZ80 emulator) I successfully coded a tool that even created a
graphic map of the cartridge's sector in the lower part of the Spectrum's
attribute area, allowed configuring how many retries should be attempted
for sectors with HDCHK, DESCHK and DCHK errors and a few other
specialties.

The attribute color map is like this:

HDCHK DESCHK DCHK
- - -
- - X
- X -
- X X
X - -
X - X
X X -
X X X
BLUE GREEN RED

- but it eventually all boils down to: "If it's not black or bright white,
you're in big trouble." ;-)

On WinZ80 everything ran fine and consistent, so I decided to give it a go
on the real machine. Some minor changes had to be done. The most
mentionable ones were to
delay sector extraction a bit after starting the drive motor to allow for
some settling and to increase the sector counter (that's used as an
indicator for the maximum number of sectors to skip before giving up) to 16
bits. So I could initialize it with 512 because the emulator seems to be
a bit more forgiving. Afterwards, the crude BASIC loader below worked like
a charm

10 FORMAT "b";19200
20 CLEAR 32767
30 LOAD *"b" CODE 32768
40 PAUSE 0
50 RANDOMIZE USR 32768
60 GOTO 40

on the Speccy side, spxfr and the binary Z80 machine code file on the
other.

I had to add 9 bytes of header to make it a .snp file spxfr understands
(it's basically how the Spectrum would SAVE *"b" CODE 32768,xxxx via
RS232) and it was uploaded to the Spectrum fine from within the PC at 19200
baud. The next iteration brought up .snp/.tap files that had the machine
code embedded as a few BASIC DATA lines together with some configuration
GUI to simplify matters.

After uploading the code, I ran Termite on the PC side, activated (RAW)
RS232 logging (a bit tweaking of the logfile filter was necessary here) at
19200,8,N,1, inserted one cartridge after the other (changing log file
name after each change as appropriate) and hit SPACE on the Sinclair each
time.

It took a few spins to complete, but I eventually managed. In the following
discussion, I use these definitions:

'-': no error
'H': header checksum error (HDCHK)
'R': record descriptor checksum error (DESCHK)
'D': data block checksum error (DCHK)

Findings (with mdv2img configured to a max. of seven error retries):

1) Some sectors are perfectly good. Just one read and that's it.
2) Some sectors produce exactly the same error type, i. e. "--D" three or
even seven times.
3) Other sectors seem to be unstable and show "H-D" two times and "--D"
another five times.

It can happen, that a sector has a defect header ("H" error class) so I'm
probably not reading the sector number I intended to, since the error
could have affected the HDNUMB byte. That can add complications since
probably collisions can arise (a "broken" sector 0xA0 with wrong header
checksum with a "good" sector 0xA0 with correct header checksum read
elsewhere).

For that reason, it might be a wise idea to throw away sectors with "H"
errors without mercy unless that exact sector number is unoccupied.

Data block ("D") errors _could_ be thrown away, if there's another good
copy of them. Unfortunately this is rarely the case, just once during my
tests:

--D
--D
H-D
H-D
H--
H-D
H-D

but this comes in conjunction with a defect header, so probably it wasn't
even the sector I intended to read but some surrogate.

As a matter of fact, the only remedy to "D" errors would be bit averaging
(if there's enough statistics) to make

00000000
01000000
01000000
01001000
01000000
00000000
00000000
========
01000000

(i. e. more "1"s that "0"s result in "1" and vice versa) and hope for the
best. At least this sector will be loadable again but at the risk of a
crash later if machine code (or compressed data) is affected.

Fortunately, a nice side aspect is, that there are VERY few record
descriptor checksum errors ("R" class). Which means that the filesystem
itself (=the logical structure between sectors) is pretty much intact.
Just one single "R" error in one sector will kill the whole file which
might span over sectors containing the bad one.

Moral is: I'm not quite sure how to interpret the data that I got.

So I wrote some forensic C++ code for the PC to allow better analyzing
and even repairing microdrive cartridge images, making use of the
redundancy that is in there. The last step was to write a .mdr
file that WinZ80 can understand so the data can be emulated.

Here comes mdv2img.exe - but it's at a rather early stage and still needs
much tweaking. I. e. the bit averaging fixes and file system
reconstruction details are not implemented yet. But it *CAN* rewrite
checksums based on various policies to make data blocks readable again and
it *WILL* occupy unused sectors with those that have bad checksums if it
needs (and is told) to.

The results are .mdr files having 137923 bytes (254 sectors à 543 bytes
plus one "write protection" byte) that you can virtually mount in WinZ80.

I've uploaded a .zip archive containing the aforementioned tools (binary
and source) along with some demonstrational cartridge images (a perfect
right out of the emulator, then a freshly formatted cartridge and finally
a tough one with Lunar Jetman, Galaxians and Pheenix) for you to play
with. The games cartridge refused to load anything else but the BASIC
loader saying "File not found.". If we can restore that one, I believe
nearly everything is possible.

Check out my homepage at: http://www.bartheld.net/temp/mdv2img.zip (about
400k).

For your own experiments, you should get the Termite terminal along with
the Logfile and Hexview plugin from
http://www.compuphase.com/software_termite.htm,
spxfr from http://www.angelfire.com/games6/atari2600/spxfr/index.html and
probably tniASM from http://www.tni.nl/products/tniasm.html if you want to
tweak the machine code.

Then connect everything as discussed above, type

FORMAT "b";19200
LOAD *"b"

and transfer Mdv2img.snp using spxfr. The program will autostart, POKE the
machine code (takes some time), ask for a few configuration values
(generally, 0 will produce reasonable defaults) and wait for you to press
the space key. Then stop spxfr, insert the cartridge you want to rip, load
Termite onto your PC, activate RAW file logging (i. e. to image.bin) and
chose the right COM port plus baud rate (19200).

Hit SPACE now.

The Speccy will spin up the Microdrive, wait about 1/2s, start loading
sectors and transfer the sectors to PC (can take a few minutes). After the
process has completed, you can select a new log file, insert a new
cartridge and repeat.

Afterwards, you'll end up with a bunch of image01.bin, image02.bin, ...
files. Use mdv2img.exe -i image##.bin -s to analyse them (mdv2img.exe -i
image##.bin -s > image##.bin.log pipes into a logfile) and mdv2img.exe -i
image##.bin -r image##.mdr to repair and use with WinZ80.

The following policies currently apply

enum tPolicies // policies of the reconstruction system
{
eNONE=0x0000,
eFIX_HEADER=0x0001, // recreate broken headers (HDCHK mismatches)
eFIX_RECORD=0x0002, // recreate broken records (DESCHK mismatches)
eFIX_DATA=0x0004, // recreate broken data blocks (DCHK)
eACCEPT_ERRORS=0x0008, // tolerate the above errors when writing back sectors
eOVERWRITE_SECTORS=0x0010, // overwrite already existing sectors
eOVERWRITE_OUTPUT=0x0020, // overwrite output file
eALLOW_NONSTANDARD_MDR=0x0040, // allow nonstandard .mdr output files (i. e. sector numbers outside [1...254]
}; // enum tPolicies
const unsigned int cPOLICIES=eFIX_DATA|eACCEPT_ERRORS|eOVERWRITE_OUTPUT; // only fix data blocks, tolerate errors, overwrite output files

which IMHO make sense. Feel free to fire up Microsoft Developer
Studio/Visual C++ and tweak the code as you like.

What I would really appreciate is input on the Z80 assembler code (there
might be bugs) and some support on more sophisticated methods to tackle
those checksum errors. I already added the CBitwiseAverage class to the
source (see helper.h) but it's currently not used anywhere. Also somebody
who has a clue about the Microdrive file system (i. e. how Sinclair BASIC
would load a file spanning more sectors) and can contribute some C++ code
regarding that aspect would be a great help.

When the mdv2img-Project is a bit more mature, I'll put up a homepage with
more tools, links, photos and screenshots of the process. Probably I also
crosspost to the World of Spectrum forum to get a larger audiency.

Good luck, happy coding and have fun!


Volker

--
@: I N F O at B A R T H E L D dot N E T
3W: www.bartheld.net

Brian Gaff

unread,
Mar 4, 2012, 12:43:42 AM3/4/12
to
Though most of this goes well over my head, it is worth pointing out that
microdrive drives wwere not all as good as one another. it can be very handy
to try several drives to read a given cart. also there is a speed control on
the bottom of the motor and sometimes changing the speed did help.
Another thing to look at is the head and motor mounting screws of course.
some adjustment is possible and might pay dividends.
Brian

--
Brian Gaff....Note, this account does not accept Bcc: email.
graphics are great, but the blind can't hear them
Email: bri...@blueyonder.co.uk
______________________________________________________________________________________________________________


"Volker Bartheld" <dr_ve...@freenet.de> wrote in message
news:vxeiw9fgl8la$.dlg@news.bartheld.net...

Brian Gaff

unread,
Mar 4, 2012, 12:45:20 AM3/4/12
to
PS as most carts used BASF Super Chrome tape this was very well known to
have a high print through tendency.
Some very late carts used some tape derived from Maxell I understand and
these were very much better in this respect.
Brian

--
Brian Gaff....Note, this account does not accept Bcc: email.
graphics are great, but the blind can't hear them
Email: bri...@blueyonder.co.uk
______________________________________________________________________________________________________________


"Volker Bartheld" <dr_ve...@freenet.de> wrote in message
news:vxeiw9fgl8la$.dlg@news.bartheld.net...

Volker Bartheld

unread,
Mar 4, 2012, 3:00:28 AM3/4/12
to
Hi Brian!

On Sun, 4 Mar 2012 05:43:42 -0000, Brian Gaff wrote:
> Though most of this goes well over my head, it is worth pointing out that
> microdrive drives wwere not all as good as one another. it can be very handy
> to try several drives to read a given cart.

Luckily, I have two of those drives built in my PC-alike case so I had the
chance to try both of them. Bummer is, that there wasn't much of a
difference. While I haven't analyzed/compared the exact output of two
readings of the same cartridge on different drives (which might reveal
more information on the nature of the read errors), my first guess is that
about the same number of errors did arise.

> also there is a speed control on the bottom of the motor and sometimes
> changing the speed did help. Another thing to look at is the head and
> motor mounting screws of course. some adjustment is possible and might
> pay dividends.

In my box full of Spectrum hardware, I have another (third) spare drive
that was originally intended as a parts donor. If some information exists
on how to externally ("in vitro") operate the Microdrive, I could attach
it to a power source, spin up the motor and have a look at the analog
signal that's present at the stereo head with an oscilloscope.

If the Microdrive allows tweaking its parameters at runtime, something like
we were doing with our cassette players might come into reach: Optimizing
head position and speed by listening to (in case of the MDV: watching) the
waveform.

I have a scanned copy of the ZX Inferface 1/2 and Microdrive Service
Manual, but this wasn't of very much help so far regarding running the
device w/o IF-1, head adjustment, motor speed and the waveforms to be
expected.

sam coupe

unread,
May 31, 2012, 12:57:09 PM5/31/12
to dr_ve...@freenet.de
cant they become sd ememory and compact flash card reader/writers please?

Volker Bartheld

unread,
Oct 8, 2012, 7:36:35 AM10/8/12
to
Hi folks!

On Sat, 3 Mar 2012 19:16:35 +0100, Volker Bartheld wrote:
> [Management summary: Download http://www.bartheld.net/temp/mdv2img.zip and
> tell me what you think. All help very much appreciated.]
> As mentioned in Message-ID: <4j9pqs271vnp$.d...@news.bartheld.net> (Subject:
> Microdrives and stuff with Interface 1), I wondered whether my almost
> thirty year old Sinclair Microdrive Cartridges were still usable. Not
> because I wanted to retrieve some games I had multifaced there but because
> of some private coding stuff I wanted to rescue from decay.

Mdv2Img is a tool to transfer and recover raw microdrive cartridge image
from a 48K ZX Spectrum to PC consisting of two separate binaries. The
first one (mdv2img.snp) is transferred via spxfr/IF1 from the PC and
installed on the Speccy (autorun BASIC/Machine Code combo). This one
generates cartridge images which are transferred via IF1 to a terminal
program (Termite etc.) on the PC. The second one (mdv2img.exe) runs on the
PC (any x86 platform will do) analyzes raw cartridge images and tries to
recover various errors before outputting a standard microdrive image (.mdr
format) that Gerton Lunter's WinZ80 Spectrum emulator understands.

Recent update:

v0.4beta is now available for download from
http://www.bartheld.net/temp/mdv2img.zip (460k) and very soon from WoS. A
complete HowTo-documentation with technical background, screenshots, demo
files as well as complete sourcecode is contained in the .zip archive.

I really appreciate input on the Z80 assembler code (there might be bugs)
and some support on more sophisticated methods to tackle potential
checksum errors. Also somebody who has a clue about the logic behind
Sinclair's Microdrive file system (i. e. how Sinclair BASIC would load a
file spanning more sectors) and can contribute some C++ code regarding
that aspect would be a great help.

Many thanks and happy hacking!

Urs

unread,
Oct 8, 2012, 4:54:59 PM10/8/12
to dr_ve...@freenet.de
Hi Volker,
earlier this year I was trying to rescue my personal files from my Microdrive Cartridges and made similar experiences with both cartridges and drives. After having survived form a "Microdrive Nightmare" (see 13 episodes of it - including a tutorial of how to replace the felt pad on the cartridges - on YouTube http://www.youtube.com/playlist?list=PL2D3A41EE9415691D). I finally managed to save almost all my personal files from the 80s to my PC using a RS232 link.

Today I’ve read your message here and am interested in what you do. But what I "need" is the other way round. Why that? I’ve "lost" (destroyed by the melting felt pad) several cartridges with software on it. Some of this software is available on WoS as *.MDR images (e.g. DemoCartridge.mdr.zip) for use with emulators. My goal is to "record" such *.MDR images onto freshly formatted cartridges. Anyone on this?

Urs

Volker Bartheld

unread,
Oct 9, 2012, 8:57:59 AM10/9/12
to
Hi Urs!

On Mon, 8 Oct 2012 13:54:59 -0700 (PDT), Urs wrote:
> earlier this year I was trying to rescue my personal files from my
> Microdrive Cartridges and made similar experiences with both cartridges
> and drives. After having survived form a "Microdrive Nightmare" (see 13
> episodes of it - including a tutorial of how to replace the felt pad on
> the cartridges - on YouTube http://www.youtube.com/playlist?list=PL2D3A41EE9415691D).
> I finally managed to save almost all my personal files from the 80s to
> my PC using a RS232 link.

Neat!

But how's that? Did you fix checksum errors and rearrange the unlinked
sectors by hand? Or was the no problem at all reading them? Some tapes are
supposed to have a heavy magnetic print through tendency - perhaps your
batch survived. I'm not too confident that one of the example cartridge
images that I attached to my software has a chance to be rescued. I'm in
contact with a guy from Hungary who volunteered to add some GUI and other
stuff to my code, hopefully this will allow me to transfer my old Spectrum
data to current hardware.

> Today IοΏ½ve read your message here and am interested in what you do. But
> what I "need" is the other way round. Why that? IοΏ½ve "lost" (destroyed
> by the melting felt pad) several cartridges with software on it. Some of
> this software is available on WoS as *.MDR images (e.g.
> DemoCartridge.mdr.zip) for use with emulators. My goal is to "record"
> such *.MDR images onto freshly formatted cartridges. Anyone on this?

Shouldn't be that hard - using machine code. You'll have to transfer chunks
(parts of a sector - to be precise: the RECFLG...DCHK portion) of the .MDR
image to the Spectrum (using RS232 and terminal software on the PC side
and IF1 on the Speccy's side) and fill blank sectors of the cartridge with
it.

The PC will wait when the Speccy/IF1 pulls its CTS-line LOW (pin 5 on the
9-pin connector of the IF1) and resume transfer when data has been written
to Microdrive. So there's flow control for free.

However: A .mdr image simulates an "ideal" cartridge, i. e. the data
contained in the file will be too large to fit on a physical cartridge.
This is no problem if there are unused sectors in the .mdr file (as it
would be when it resulted from imaging a physical cartridge), so either
the Speccy or - preferrably - the PC should throw away all unused sectors.
If there's enough free space on the physical cartridge, it should be no
problem to rewrite the data here.

Normally, the order of sectors doesn't matter, so you should leave alone
HDFLAG, HDNUMB, HDNAME, HDCHK (=header information) and just write the bare
record.

This is how a microdrive sector looks like (not considering that there are
in fact two magnetic stripes written by a stereo head and gaps/indicators
on the tape that are evaluated by the Microdrive's ULA):

; Offset Length Name Contents
; ------------------------------
; 0 1 HDFLAG Value 1, to indicate header block
; 1 1 HDNUMB sector number (values 254 down to 1)
; 2 2 not used (and of undetermined value)
; 4 10 HDNAME microdrive cartridge name (blank padded)
; 14 1 HDCHK header checksum (of first 14 bytes)
;
; 15 1 RECFLG - bit 0: always 0 to indicate record block
; - bit 1: set for the EOF block
; - bit 2: reset for a PRINT file
; - bits 3-7: not used (value 0)
;
; 16 1 RECNUM data block sequence number (value starts at 0)
; 17 2 RECLEN data block length (<=512, LSB first)
; 19 10 RECNAM filename (blank padded)
; 29 1 DESCHK record descriptor checksum (of previous 14 bytes)
; 30 512 data block
; 542 1 DCHK data block checksum (of all 512 bytes of data
; block, even when not all bytes are used)
;
; 543 bytes altogether. Beware: .mdr files have an additional byte at the end.
; If it's !=0 this indicates "write protection".


So starting from hook code 26h (check out the IF1 shadow ROM disassembly
and addresses 11FFh (WR-RECD) - it writes a new record onto the next free
sector of a microdrive cartridge) I would do something according to 1275h
(SEND-BLK) which fetches the first 'free' header (bit 1 of RECFLG reset
and DESCHK valid) and then writes the buffer into the sector.

I remember to have written some code with GENS that generated XOR255ed
checksums and accessed sectors that way as part of a Microdrive cartridge
copy protection system, but unfortunately, the code is on a cartridge
itself which is pretty much unreadable.

Reading the RS232 would be done similar to address 0B81 (BCHAN-IN), you'll
have to configure a baud rate (see my mdv2img-code on info how to do that)
via the BAUD timing constant initially.

Currently, I can't help you with that any further since I neither have time
nor interest to create physical cartridges out of images. Emulating the
machine on moderately modern hardware suffices for me.

Good luck,
0 new messages