# $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 µ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