It was in 1977, then Woz evaluated several floppy and harddisk
controllers and found a brilliant solution with minimal hardware.
Soft sectoring (with self sync bytes) should overcome the hard
sectoring and a clever software encoding of the data should make
a clock unnecessary. The head's stepper motor was simply connected
to four flip-flops, which were toggled in a cyclic manner by
software (with timing loops) to move the arm.
All in all, he made it working with 10 IC's and some resistor/
capacitor/transistor sugar.

1. Disk layout

A Sugart SA390 floppy disk drive can access 36 tracks on a single
sided, single density 5 1/4 inch disk at a rotational speed of 360
rpm. Since the innermost track is not always reliable, normally
only 35 tracks are used. The data on single density disks can be
written with edge distances of 4 or 8 (and later 12) us.

2. Track layout

A Track is arranged in 9 (later 13 and 16) sectors with 256 data
bytes. The data needs to be encoded for writing on disk, so that
the 256 data bytes correspond to 512 (or 410 or 342) disk bytes.
Every sector is preceeded by a sector header containing positional
information (track, sector and volume number). Between header and
data (and of course data and next header) are gap's filled with
self sync bytes. Both disk data bytes and header are preceeded by
unique prologue bytes and end with a checksum and unique trailer
bytes.

Prologue bytes for a header:	$D5 $AA $96
Self sync bytes:		at least 5 times $FF
Prologue bytes for disk data:	$D5 $AA $AD
Trailer bytes:			$DE $AA $EB
	
+-----------------+-------------+---------------+--------+-------------+
! self sync bytes ! $D5 $AA $96 ! sector header ! Chksum ! $DE $AA $EB !
+-----------------+-------------+---------------+--------+-------------+

+-----------------+-------------+---------------+--------+-------------+
! self sync bytes ! $D5 $AA $AD ! encoded data  ! Chksum ! $DE $AA $EB !
+-----------------+-------------+---------------+--------+-------------+

+-----------------+-------------+---------------+--------+-------------+
! self sync bytes ! $D5 $AA $96 ! sector header ! Chksum ! $DE $AA $EB !
+-----------------+-------------+---------------+--------+-------------+

+-----------------+-------------+---------------+--------+-------------+
! self sync bytes ! $D5 $AA $AD ! encoded data  ! Chksum ! $DE $AA $EB !
+-----------------+-------------+---------------+--------+-------------+

and so on. The self sync bytes gap between the last sector and
sector 0 is usually much bigger than the others.

2. Data encoding

2.1. 4:4 encoding

To reliable read data back from a magnetic media, one needs to
compensate for rotational time differences. This is done with
a clock signal. In the simplest case, the clock (c) is mixed
with the data (0010110):

	0 c 0 c 1 c 0 c 1 c 1 c 0
	   ___   _     _   _   __
	__!   !_! !___! !_! !_!

Woz idea was to provide the clock from software, not hardware:
Every byte is split into two halves:

	x7 x6 x5 x4 x3 x2 x1 x0

	 0 x6  0 x4  0 x2  0 x0		even half
	x7  0 x5  0 x3  0 x1  0		odd half

The odd half is then shifted right:

	 0 x7  0 x5  0 x3  0 x1

Both halves are now OR'ed with 1010101010:

	 1 x6 1 x4  1 x2  1 x0
	 1 x7 1 x5  1 x3  1 x1

Now every 1 is interpreted as edge, every 0 as no edge. If
the bytes are written out to the disk in this fashion, a
clock is now magically included! Second, every byte on the
disk now starts with a 1 bit (remember this for later).

The recombination of the data is even easier:

	 1 x6  1 x4  1 x2  1 x0		(even byte)
   AND  x7  1 x5  1 x3  1 x1  1		(odd byte shifted left)
	-----------------------
	x7 x6 x5 x4 x3 x2 x1 x0

Generally, the shift register shifts every 4 us. This means,
that the software has to provide every disk byte in exactly
32 us (4*8 us).

Let's assume the volume number of the disk is 254, the track is
9 and the sector is 5. The header of this sector is as follows:

	$D5 $AA $96 $FF $FE $AB $BA $AB $AD chksum $DE $AA $EB

The checksum is a simple XOR of the volume, track and sector.

2.2. 5:3 and 6:2 encoding

The 4:4 encoding scheme gives about 80 kByte on the disk.
Later, Woz invented the 5:3 and 6:2 encoding schemes. They
give 110 and 140 kBytes. But the old 4:4 scheme is still
used for the sector header, because its so simple and these
three bytes aren't worth mentioning.
	
A requirement of the Sugart SA390 floppy disk drive was, that
the edge distance should not be greater than 8 us. That means,
that no disk byte could have more than one consecutive zero
bit.  Additionally, every byte should start with a 1 bit.
There are 35 byte values, that fulfill this requirement, but
only 16 are used for 4:4. Thus, one can recombine the data
bits (splitting them into 5 and 3 bits) into 410 bytes with
values between 0 and 31. These are mapped to 32 of the 35
valid disk byte values. The other values were used to get
unique prologue and trailer bytes: $D5 $AA and $DE.

When Woz found, that the Sugart drives would work reliable
with even 12 us edge distance, he changed the encoding to
6:2. Now, two consecutive zeroes can be in a disk byte.
Together with the leading 1 bit, the requirements are
fulfilled by 66 byte values. As before, $D5, $AA are used
for the unique prologue.

3. The self sync bytes

As stated before several times, every disk byte has to start
with a 1 bit. This is used to syncronize the software with
the bit data flow under the disk head. The sync bytes have
a value of $FF, but are written every 40 us. Since the shifter
writes zeroes, if he doesn't have data anymore, 5 sync bytes
look as follows:

11111111001111111100111111110011111111001111111100(more data)

Since only disk bytes with a leading 1 are accepted as valid
disk bytes, wherever the disk head might be, it will read
the data following the 5 sync bytes correct.

Example:

11111111001111111100111111110011111111001111111100(more data)
    ^       ^       ^         ^         ^	  ^
    !       !       !         !         !       
    !       !       !         !         !____ the fifth ($FF)
    !       !       !         !
    !       !       !         !____ the fourth byte overreads
    !       !       !               two zeroes (value is $FF)
    !       !       !
    !       !       !____ the third byte ($FF)
    !       !
    !       !____ the second byte starts here (value $FC)
    !
    !____ head starts here (value $F9)

4. The stepper motor

The four phases of the stepper motor are connected to
flipflops, which can be controlled by software. They are
switched on and off in a cyclic fashion to move the head
in and out. To overcome inertia, this has to be done at
specific times. Timing loops (with table values) do this
critical job.

For more details, see 'Beneath Apple DOS' from Worth & Lechner,
'The Apple II History' by Steven Weyhrich (available on anon ftp)
and the manuals for the Apple ][ and the Disk ][.