[PARPORT] Re: Iomega Ditto 3200

Claus-Justus Heine (claus@momo.math.rwth-aachen.de)
18 Jun 1998 14:20:44 +0200

This is state of my attempts to write a driver for the parallel port
version of the Iomega Ditto 3200. While I have a working version that
uses the binary version of an interface library provided by Micro
Solutions, Inc., it is not yet clear whether MSI will allow us to
distribute this library.

I have started to reverse engineer the parport protocol, extending the
work of Grant R. Guenther who already had found out a lot.

We have proceeded so far that we know how to write data and access the
control registers of the parport drive.

This mail deals with the CRC checksum computed after each data
transfer between the host and the tape drive.

> > For the CRC that the backpack tape drive generates after each data
> > transfer: I'm a newbee w.r.t. CRC sums. On your web site you mention
> > that it is probably a "standard" CRC sum. From a brief glimpse at some
> Actually, you've hit the roadblock that stopped my work. My original
> undergrad education was in pure Mathematics - so I figured I ought to
> have been able to figure it out.
> My observation was that it was a 16 bit checksum - so presumably you
> meant a word value (not a byte). When I was first contacted by Clive,
> he was evasive about this, but eventually told me that it was a
> standard CRC-16 checksum _but_ the shift register is not re-initialised
> between blocks, so all data goes through the 16 bit shift register and
> you have to pre-load your internal model with the current value so that
> the hardware and software start in sync,

I'VE GOT IT!!!!!!!

So, this is what I have found out:

a) It really is a standard CRC checksum.

b) The host retrieves the CRC sum from the tape drive by reading the
   2-byte register 0x22 of the tape drive. Reading this register also
   resets the tape drives

        CRC shift register to 0xffff

   (it is a 16 bit CRC sum).

c) The tape drive uses 0x1021 as generating polynomial where it is to
   be understood that the MSB corresponds to the highest power,
   i.e. the generating polynomial is

                x^0 + x^5 + x^12 + x^16

d) My first attempts to adapt gzip's CRC algorithm to compute bpck's
   checksums were unsuccessful because gzip interpretes the data the
   other way round: the MSB corresponds to the lowest power.

   bpck's view of an incoming 2-byte data stream b, a (where b is the
   first byte received by the tape drive) is the following:

   (a_0 x^0 + ... + a_7 x^7) + x^8 (b_0 x^0 + ... + b_7 x^7)

   gzip's point of view would be

   (a_0 x^7 + ... + a_7 x^0) + x^8 (b_0 x^7 + ... + b_7 x^0)

   or written in a more suggestive manner (thinking of the LSB of the
   first byte to be the first bit in the byte stream)

   (a_7 x^0 + ... + a_0 x^7) + x^8 (b_7 x^0 + ... + b_0 x^7)

   This means that multiplying a polynomial by x^k is implemented by a
   LEFT shift for the bpck tape drive, while for gzip is implemented
   as a RIGHT shift.

e) Accordingly, given all 256 values for the CRC sums of a single byte
   stream are stored in a field called crc_16_tab, computing the crc
   for a byte stream s has to be implemented as

   crc = crc_16_tab[((crc >> 8) ^ (*s++)) & 0xff] ^ (crc << 8);

   while for gzip the slightly simpler C expression can be used

   crc = crc_16_tab[(crc ^ (*s++)) & 0xff] ^ (crc >> 8);

   Of course, this is all only a matter of convention. Personally I
   regard gzip's way to compute the CRC sum more "natural", but this
   is only a matter of taste (MSB-LSB). It is also not a matter of
   performance as shifting by 8 bits in reality simply means to
   reference another memory address, or virtual byte register.

I don't know when I'll be able to provide a first example
driver. Probably not before mid end of July, I'm running out of time
for other things that are virtually more important than ftape.

The algorithm described above works. Maybe one can rewrite it so that
multiplying by x^k again is a right shift. Reverting the order of
powers of a polynomial factor ring (i.e. GF(2)[X] mod p(x) where p(x)
is the generating polynomial) is a ring isomorphism. So maybe it

Mmmh. Well. Actually: it should work to use gzip's way of computing
things, and then multiply the resulting CRC by x^15 and take the
remainder mod x^16.

Will check out later.

Have fun



The attached program is a sample implementation of the CRC algorithm
described above. I have shameless stolen the code from the gzip
distribution. I have merged util.c and sample/makecrc.c.

  Claus-Justus Heine

  PGP Public Key:

  Ftape - the Linux Floppy Tape Project
  WWW : http://www-math.math.rwth-aachen.de/~LBFM/claus/ftape
  Mailing-list: linux-tape@vger.rutgers.edu

('binary' encoding is not supported, stored as-is)

-- To unsubscribe, send mail to: linux-parport-request@torque.net --
-- with the single word "unsubscribe" in the body of the message. --

This archive was generated by hypermail 2.0b3 on Wed 30 Dec 1998 - 10:17:52 EST