# $NetBSD: README.technote,v 1.2 1999/03/27 05:48:53 scottr 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