NetBSD/sys/lkm/arch/mac68k/iwm
..
Makefile
README.iwm
README.technote
TODO
iwm_mod.c

README.technote

#	$NetBSD: README.technote,v 1.4 2005/12/11 12:24:46 christos Exp $


The IWM chip (the Mac floppy controller) is a descendant of the Apple
][ disk controller and quite different from the everyday FDC. Instead
of configuring your FDC, sending a command and sleep()ing until it
completes, you have to do everything by hand.

That means: Sit on the floppy's head, look for a header ID and read &
decode the header. If it indicates the sector you want, read the
sector data and decode it while you're reading (a fairly complex
scheme, and one of apple's best kept secrets, too). Continue at will;
similarly for writing.

Now, did you miss the word "interrupt"? -- There is none. The IWM runs
entirely in polled mode, all interrupts disabled. The MacOS .Sony
driver polls one serial port during disk I/O to maintain LocalTalk
connectivity; other than that, the machine is locked.




IWM Registers:
==============


1. IWM register selection

Q6    Q7    Register
-----------------------------------------------------------------------------
off   off   Read from data register
off   on    Read from handshake register
on    off   Read from status register
on    on    Write to mode register -- drive is off
            Write to data register -- drive is on


2. IWM mode register

Bit   Function
-----------------------------------------------------------------------------
7     reserved
6     reserved
5     reserved
4     clock speed:         0 = 7 MHz (Apple II)
                           1 = 8 MHz (Mac)
3     bit cell time:       0 = 2 usec/bit (3.5")      (*)
                           1 = 4 usec/bit (5.25")
2     motor-off timer:     0 = motor off delayed by 1 sec (5.25")
                           1 = no delay (3.5")
1     handshake protocol:  0 = synchronous/software timing (5.25")
                           1 = asynchronous/IWM timing (3.5")
0     latch mode:          0 = read data valid for 7 usec (5.25")
                           1 = read data valid for full byte time (3.5")


3. IWM status register

Bit   Function
-----------------------------------------------------------------------------
7     sense input:         5.25" write protect line
                           3.5"  general status line
6     reserved             HD media format?
5     drive enabled        1 = drive is on
4     clock speed:         0 = 7 MHz (Apple II)
                           1 = 8 MHz (Mac)
3     bit cell time:       0 = 2 usec/bit (3.5")      (*)
                           1 = 4 usec/bit (5.25")
2     motor-off timer:     0 = motor off delayed by 1 sec (5.25")
                           1 = no delay (3.5")
1     handshake protocol:  0 = synchronous/software timing (5.25")
                           1 = asynchronous/IWM timing (3.5")
0     latch mode:          0 = read data valid for 7 usec (5.25")
                           1 = read data valid for full byte time (3.5")


4. IWM handshake register

Bit   Function
-----------------------------------------------------------------------------
7     IWM state:           0 = busy
                           1 = ready for data
6     underrun:            0 = write underrun (data not delivered in time)
                           1 = no error
5     reserved
4     reserved
3     reserved
2     reserved
1     reserved
0     reserved


---
(*)   inverse to "iwmstuff"!! Is this really the bit cell time?
      Valid reads from a Macintosh Sony drive have a '1' here.






SWIM registers:
===============

(coming soon...)




Floppy drive registers:
=======================


1. Status bits:

The result of the query for 'Param' is returned in Bit 7 of q7L, which is
usually checked by a bmi/bpl branch.


CA1   CA0   SEL   CA2   Param    Register    Function (q7L, Bit 7)
-----------------------------------------------------------------------------
off   off   off   off   0x00     DIRTN       direction of head step:
                                             0 = inward (greater track no)
                                             1 = outward (smaller track no)
off   off   off   on    0x01     RDDATA0     Reading sets up drive to read
                                             data from lower head
off   off   on    off   0x02     CSTIN       Disk inserted:
                                             0 = disk in drive
                                             1 = drive empty
off   off   on    on    0x03     RDDATA1     Reading sets up drive to read
                                             data from upper head
off   on    off   off   0x04     STEP        Disk head is stepping (1)
                                             0 = yes, still stepping
                                             1 = no, drive ready
off   on    off   on    0x05     -----       Not used
off   on    on    off   0x06     WRTPRT      Disk is locked:
                                             0 = write-protected
                                             1 = write-enabled
off   on    on    on    0x07     -----       Not used
on    off   off   off   0x08     MOTORON     Drive motor state:
                                             0 = on
                                             1 = off
on    off   off   on    0x09     SIDES       Number of sides:
                                             0 = single-sided drive
                                             1 = double-sided drive
on    off   on    off   0x0A     TK0         Track 00 switch:
                                             0 = head is at track 00
                                             1 = head is elsewhere
on    off   on    on    0x0B     ?????       Head loaded/drive ready:
                                             0 = ready
                                             1 = not ready
on    on    off   off   0x0C     ?????       (Disk switched?)
on    on    off   on    0x0D     ------      Not used
on    on    on    off   0x0E     TACH        Tachometer (60 pulses/rev)
on    on    on    on    0x0F     DRVIN       Drive installed: (2)
                                             0 = drive is connected
                                             1 = no drive

(1)   After step is done, wait ca. 30 <20>s before issuing next step command;
otherwise steps tend to get lost.

(2)   The SWIM & SuperDrive apparently use DRVIN (0x0F) to distinguish between
DD and HD disk media and check for an installed drive with 0x0D.


2. Control bits:


CA1   CA0   SEL   CA2   Param    Register    Function
-----------------------------------------------------------------------------
off   off   off   off   0x00     DIRTN       Set direction of head step
                                             to inward (greater track no)
off   off   off   on    0x01                 Set direction of head step
                                             to outward (smaller track no)
off   off   on    off   0x02     -----       Not used
off   off   on    on    0x03                 (Reset disk switched flag?)
off   on    off   off   0x04     STEP        Step disk head
off   on    off   on    0x05     -----       Not used
off   on    on    off   0x06     -----       Not used
off   on    on    on    0x07     -----       Not used
on    off   off   off   0x08     MOTORON     Turn drive motor on
on    off   off   on    0x09                 Turn drive motor off
on    off   on    off   0x0A     -----       Not used
on    off   on    on    0x0B     -----       Not used
on    on    off   off   0x0C     EJECT       Eject disk
on    on    off   on    0x0D                     "
on    on    on    off   0x0E     ------      Not used
on    on    on    on    0x0F     ------      Not used

Disk commands are formed by the CA1, CA0, SEL lines. For a given command
code CA2 acts as a parameter bit.



Reading a GCR sector header
===========================

A sector header on a Macintosh 400/800K GCR disk consists of

o  a three byte lead-in: '0xD5 0xAA 0x96'
o  current track byte, sector byte and side bit, encoded in four bytes plus
   a one byte checksum
o  a two byte lead-out:  '0xDE 0xAA'

The lead-in and lead-out tokens are evaluated 'as is'; the content area
is subject to further processing.


1. Remapping

The byte values that the IWM can write to / read from disk reliably are
subject to several constraints:

o  They may not equal any reserved values (header markers)
o  Bit 7 == 1 for hardware synchronization
o  No more than one pair of consecutive zero bits
o  At least one pair of consecutive one bits

These constraints leave 64 valid bytes in the range of 0x95..0xFF.
For convenience, this range is mapped to a continuous range of
0x00..0x3F -- this rule applies to all user data on the disk.


2. Contents

For byte 1, the current sector number, the offered range is large enough; no
further processing is needed. The same applies to byte 3 (function?).
Byte 0 & 2 hold the side bit and the current track number; some further
massage is needed to extract their values.

o  Byte 1: Bits 6&7 are dropped, Bits 0..5 leave a range of 0..63.
o  Byte 2: Bits 0&1 become bits 6&7 of Byte 1. Bits 2..5 (range 0..0x0F)
   hold further information:
      2 - ?
      3 - ?
      4 - ?
      5 - 0 = side 0, 1 = side 1


3. Checksum

The checksum of the header content area is evaluated by XORing bytes 0..3;
the result must equal byte 4. (Alternatively the result of XORing all five
bytes can be checked against zero.)



Reading GCR sector contents
===========================

(to be done)



Disk Zone Mapping
=================

The first 12 sectors for an 800K disk map to side 0, track 0, sectors 0-11,
similar to the corresponding sectors on the 400K disk. The next 12 sectors for
the 800K disk map to side 1 in a similar manner--side 1, track 0, sectors 0-11.
Logical sectors 24-36 map to side 0, track 1, sectors 0-11, and so on. The
following table demonstrates this:

Side    Track    Sectors      Physical     Logical
                Per Track      Sectors     Sectors

  0        0       12           0-11         0-11
  1        0       12           0-11        12-23
  0        1       12           0-11        24-35
  1        1       12           0-11        36-47
 ...
  1       15       12           0-11       372-383
  0       16       11           0-10       384-394
  1       16       11           0-10       395-405
  0       17       11           0-10       405-415
 ...
  1       31       11           0-10       725-735
  0       32       10           0-9        736-745
  1       32       10           0-9        746-755
  0       33       10           0-9        756-765
 ...
  1       47       10           0-9       1046-1055
  0       48        9           0-8       1056-1064
  1       48        9           0-8       1065-1073
  0       49        9           0-8       1074-1082
 ...
  1       63        9           0-8       1335-1343
  0       64        8           0-7       1344-1351
  1       64        8           0-7       1352-1359
  0       65        8           0-7       1360-1367
 ...
  1       79        8           0-7       1592-1599