294 lines
11 KiB
Plaintext
294 lines
11 KiB
Plaintext
# $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
|
||
|