29

The Apple 2's disk drive controller and 5¼" floppy disks have the following metrics:

  • The disks is spun at (roughly) 300 RPM (Revolutions per Minute), which means it takes = 1000 ms/sec / (300 RPM / 60 sec/min) = ~200 ms / revolution,
  • Beneath Apple DOS (fourth printing) Figure 3.3 states it takes 4 μs (microseconds) to read 2 consecutive bits off the disk. This metafilter discussion also mentions this.
  • Beneath Apple DOS Figure 3.1, shows track zero is the outermost, but sadly doesn't give any dimensions. Loose empirical measurements show:
    • Track 0 (roughly) has a radius of 5"/2 = ~ 2.5"
    • Track 39 (roughly) has a radius of 1.5"/2 = ~ 0.75" (Center hole diameter measured at ~1½")

I've seen 6,250 nibbles given as the (theoretical) maximum number of nibbles on a track (encoded with 6+2) but never an explanation of where this number comes from. (Beneath Apple DOS on page 3-7 briefly mentions 50,000 bits but doesn't provide any details oh this number was calculated.) It is straight forward to see that a track has = 200 ms/revolution * 1000 μs/ms / 4 μs/bit = 50,000 bits / (8 bits/byte) = 6,250 nibbles/track.

However, since the radius (and therefore the circumference) of the outermost and innermost track differ, shouldn't track 0 be able to hold more bits then track 39? The circumference (C = 2 * π * r) for tracks:

  • Track 0 = 2*π*2.625 = ~15.7"
  • Track 39 = 2*π*0.75 = ~4.7"

shows track 0 has a whole lot more "space" then track 39.

This naturally raises a few questions. Namely,

  • Does the Apple 2 disk utilize CLV (Constant Linear Velocity) or CAV (Constant Angular Velocity)?

  • Assuming the same 4 μs/bit but the other speed type then what would be the maximum number of nibbles stored on an Apple II disk for:

    • Track 0, and
    • Track 39

respectively?

  • While Apple II disk controller is designed to write one bit every four CPU cycles, the read speed can adjust slightly according to the flux patterns on the disk, so if a disk was written with custom hardware it would be possible for it to hold somewhat more data. I wouldn't be surprised if some copy-protection schemes took advantage of that. – supercat May 14 '16 at 22:05
23

The maximum is 8309 ($2075) nibbles for track 0. Well, according to a little experiment I did. ; - )

The Disk II uses Constant Angular Velocity standardized by Shugart at 300 RPM. The earlier 8-inch drives were 360 RPM, and since the physical media was the same it's likely that 300 RPM was chosen to increase data density on the smaller disks, and perhaps reduce controller throughput for use on early computers that were less powerful and cheaper. (But I can't find a reference for this.)

Disk II spindle speed can be manually adjusted on Apple's analog controller board between approximately 190 and 320 RPM. Slower speed results in higher data density, but this will be limited by physical parameters such as magnetic (iron oxide) particle density and read/write head characteristics - e.g. weaker magnetically induced current in the read head at low speed.

Track capacity is affected by its contents: since MFM clock pulses aren't used, the data written must be carefully chosen in order to synchronize with and be reliably read by the Disk II controller. This includes restrictions on consecutive zeros, and nibbles with trailing zeroes called self-sync bytes.

However in this experiment I didn't use sync bytes, instead relying on the controller sequencer's natural tendency to quickly sync to certain patterns. A simple nibble count measures the maximum theoretical capacity of the track, ignoring the required overheads of practical data storage. Here is the nibble count code:

      ORG $8000
      LDA #$30    ;WRITE LEN
      STA $01
      LDX #$50    ;SLOT * $10
      LDA $C08D,X ;LOAD WP
      LDA $C08E,X ;READ WP
      BPL NOTWP
      RTS
NOTWP LDA #$D5    ;1ST NIBBLE
      STA $C08F,X ;WRITE MODE
      CMP $C08C,X ;4 - SHIFT
      BIT $FF     ;3
      LDY #$00    ;2
LOOP1 DEC $FF     ;5
      EOR #$7F    ;2 - D5^AA
LOOP2 DEC $FF     ;5
      CMP $FFFF   ;4
      NOP         ;2
      STA $C08D,X ;5 - LOAD
      CMP $C08C,X ;4 - SHIFT
      DEY         ;2
      BNE LOOP1   ;3 OR 2
      DEC $01     ;5
      BNE LOOP2   ;3 OR 2
      DEC $FF     ;5
      DEC $FF     ;5
MARK  LDA #$FF    ;2 - MARK
      STA $C08D,X ;5 - LOAD
      CMP $C08C,X ;4 - SHIFT
      JSR RTS     ;12
      LDA #$20    ;2 - ADDR
      STA STORE+2 ;4
      STA COUNT+2 ;4
      LDY $01     ;3
      STY $00     ;3
      LDA $C08E,X ;READ MODE
READ  LDA $C08C,X
      BPL READ
STORE STA $2000,Y
      INY
      BNE READ
      INC STORE+2
      BPL READ    ;TO $8000
      STA $C088,X ;MOTOR OFF
      LDX #$00
COUNT LDA $2000,X
      CMP MARK+1
      BNE NEXT
      LDA COUNT+2 ;PRINT ADDR
      JSR $FDDA
      TXA
      JSR $FDDA
      LDA #$A0
      JSR $FDED
      LDA $01     ;1ST MARK?
      BEQ COPY
      TXA         ;NO
      SEC         ;CALC LEN
      SBC $00
      PHA
      JSR $FE80   ;SETINV
      LDA COUNT+2
      SBC $01
      JSR $FDDA   ;PRINT LEN
      PLA
      JSR $FDDA
      JSR $FE84   ;SETNORM
      LDA #$8D
      JSR $FDED
COPY  LDA COUNT+2
      STA $01
      STX $00
NEXT  INX
      BNE COUNT
      INC COUNT+2
      BPL COUNT   ;TO $8000?
RTS   RTS         ;YES, DONE

Assembled at $8000, there are some defaults that can be optionally adjusted:

  • 8001: The number of nibbles to write to the track in units of $100 (Default $30 = $3000 nibbles)
  • 8005: The drive slot number times $10 (Default $50 - safer than $60!)
  • 8010: The first nibble value; this gives a pair sequence via XOR with $7F (Default D5/AA)
  • 801E: The XOR value; bit 8 should be 0 (Default $7F)
  • 8037: The nibble count mark value (Default $FF)
  • 8042: The page to start storing track data when read back and nibble counted (Default $20)

The routine assumes the drive is on and up-to-speed, and that the head is already positioned on the desired track. The defaults as given will write $3000 nibbles of "D5AA" followed by one "FF" mark to the selected drive in slot 5. The track will then be read into memory at $2000-$7FFF and the data scanned for the mark value. Mark locations will be printed in normal text, and length between marks in inverse.

Here is an image of a sample run which uses boot 0 to seek track 0 of drive 1 in slot 6 in AppleWin:

Sample run of nibble count routine

Adjusting a real drive's speed (measured with Copy II Plus 8.4) I obtained the following results:

Speed (ms)  Speed (RPM)  Max length  Length (Hex)
188         319          6015        177F
200         300          6400        1900
210         286          6715        1A3B
220         273          7045        1B85
230         261          7360        1CC0
240         250          7680        1E00
250         240          8004        1F44
260         231          8309        2075
270         222          -           -
280         214          -           -
317         189          -           -

At 270ms and above the sequencer would not auto-sync to simple nibble patterns, though Copy II Plus could still measure drive speed. Its exclusive use of selected sync byte values would likely explain this.

Tracks written at one speed can be read at another speed that is +/-10ms. I didn't test how far this tolerance extends. Roland Gustafsson (who wrote the copy protection for many Brøderbund titles) says he tried slowing the drive speed but "never used that technique due to compatibility problems. In fact, [he] wrote a speed calibrator that was used at Broderbund to keep the disk drives in spec".

When speculating about an alternative Constant Linear Velocity capacity you would need to specify the exact hardware being used, since that big a change would probably extend from the controlling software to the magnetic media - and everything in between. There is a good list of existing floppy disk formats on Wikipedia.

| improve this answer | |
  • Hi Nick! :-) Thanks for the nibble code -- with ADTPro I'll get that transferred to a real disk image. What should $FF be initialized with? $00? – Michaelangel007 May 29 '16 at 1:12
  • 2
    Hi Michael. References to $FF or $FFFF are time-wasting code. All disk accesses are in 32-cycle blocks. – Nick Westgate May 29 '16 at 2:02
  • 2
    In trying to work out why everyone was talking about nibbles (I'd never heard the term in this context before) I came across diskii.nibbles which goes into all sorts of gory details that someone may find useful. – TripeHound Apr 20 '18 at 12:57
  • 1
    Woz called them disk nibbles because originally the disk controller would write 4-bits as an 8-bit value with every other bit being one (for timing.) – Michaelangel007 Apr 23 '18 at 5:48
11

Apple ][ used an ordinary disk transport and fixed bit-rate in the controller. In order to fit more bits on the outer track it would need to vary the spin rate of the disk so that the controller had time to put the extra bits on.

CD drives use variable spin rate, but floppy disks (mostly) use a fixed spin rate (like gramophone records).

Early Apple Macintosh's used a custom disk transport with variable spin rate, so it could fit more data on the outer tracks of the disk, getting 800K on a "720K" (3.5" DSDD) floppy.

| improve this answer | |
  • 4
    Actually, the 1.4 MB format was the same on the Mac as on PCs. The variable rate was used on double-density 720K disks to get 800K onto them on the Mac (and the Apple IIgs). – Eric Shepherd May 17 '16 at 21:48
  • @Jasen there is quick discussion of zone bit recording that alludes to Apple's techniques to get single and double density 3.5" floppies to store 400/800k instead of 360/720k. Unfortunately modern USB 3.5" drives can't read these disks since they require a Mac/IIgs disk drive. – Michael Shopsin May 19 '16 at 18:50
3

You might also find this discussion interesting: https://groups.google.com/forum/#!topic/comp.sys.apple2/7srpWGp1pCs

Although the Apple II could only write at 4 cycles per bit, it can read faster: if you slow the drive down, you can write more densely.

| improve this answer | |
  • Already participating there, but thanks. :-) – Michaelangel007 May 19 '16 at 14:33
  • Your answer would be more useful if you could summarize the discussion from that group that's relevant to the question here. – cjs Jul 16 '19 at 8:56
2

Summary

I come up with 6298 raw bytes (or "nibbles") per track at 300 RPM with tolerance for speed variation of 1.5%.

Below I discuss:

  • drive speed,
  • how many bits can fit on a track,
  • what "nibbles" really are,
  • compare my theoretical capacity calculations for various rotational speeds with Nick Westgate's experimental results (spoiler: they're within 0.2%), and
  • calculate the actual maximum data storage of an Apple II diskette.

Drive Speed

The Disk II system uses a Shugart SA400 drive which rotates at a fixed rate of 300 RPM, so it is constant angular velocity. (Actually, it's the SA400 drive mechanism with a custom analog electronics board; the drive without Shugart's electronics is sometimes called the SA390. But that makes no difference for this question.)

Bits per Track

Beneath Apple DOS on page 3-7 briefly mentions 50,000 bits but doesn't provide any details oh this number was calculated.

That number comes from either a simple calculation based on the IBM-standard FM and MFM data rates for floppy drives or just directly from the Shugart specification for the SA400 drive.

  • The IBM 3740 single-density format data bit rate is 125 kHz. Since this uses FM encoding that's 125,000 pairs per second of clock bit followed by data bit, which works out to 8 μs per pair or 4 μs per bit of clock or data.
  • The IBM System 34 double-density format uses MFM which irregularly intersperses clock bits with data bits. So in this case they specify the "data + clock" rate as 250 kHz, which works out to the same result: 4 μs per bit of clock or data. (Simply using fewer clock bits is why "double-density" stores more data.)
  • Page 4 of the SA400 Service Manual gives the number of bits per track as 25,000. This would clearly have been just the data bits that could be stored with FM encoding, since they mention later on that page a soft-sector format of 18 sectors × 128 bytes, which would be 36,864 bits on the diskette after FM encoding. (Plus overhead of well over 2000 bits, from the diagram on the following page.) That manual appears to be too early to have mentioned MFM encoding.

"Nibbles"

Before going further we need to discuss these so-called "nibbles."

The Disk II controller always reads an 8-bit chunk of data every 32 cycles; I call this a "raw byte." For various reasons, there are only 66 different 8-bit sequences that the disk controller can read while maintaining synchronization (or fewer for the older controller PROMs and DOS ≤3.2), which is why we need to encode our data.

(If you want more detail, this answer goes a bit deeper into the reasons for this. The truly gory details are in Chapter 9 of Jim Sather's Understanding the Apple II; see page 9-27 for a list of the raw byte values that can be used while maintaining sync.)

Because Woz originally used an FM encoding to store 4 bits of data in every raw byte written to the diskette, he originally called these post-encoding raw bytes, "nibbles." Before the first Apple II DOS release the encoding system for data bytes was changed to store 5 bits of data in every raw byte (and eventually 6 bits, with DOS 3.3 and a controller PROM change), but the name appears to have stuck. However, to avoid confusion with the other standard terminology of a "nibble" as a 4-bit chunk of data, I will henceforth refer to the 8-bit chunks stored on the diskette and read by the controller as "raw bytes."

Bits and Raw Bytes per Track

Beneath Apple DOS (fourth printing) Figure 3.3 states it takes 4 μs (microseconds) to read 2 consecutive bits off the disk.

No, it's 4 μs for a single bit. The figure in the fourth printing is incorrect; this was fixed in the fifth printing. More details are given in this answer.

This is no doubt where the 6,250 raw byte (or so-called nibble) figure came from: 200 ms for a track rotation at 300 RPM divided by 4 μs gives 50,000 bits per track, and that divided by eight bits gives 6,250.

But even that's not quite correct: it's really 4 clock cycles per bit. Since the Apple II clock is 1.023 MHz, that's 3.91 μs per bit, which gives us a track capacity at 300 RPM of 51,150 bits, or 6393 raw bytes. We can do the calculations for other rotational speeds as well, which I have done in the following table. I've chosen the same speed values as Nick Westgate did in his answer; you'll note how close my calculated values are to his experimentally determined values in the raw exp column.

1 rotation  RPM   bits   raw bytes  raw exp  difference
-------------------------------------------------------
   188 ms   319   48081    6010      6015      +0.08%
   200 ms   300   51150    6393      6400      +0.11%
   210 ms   286   53708    6713      6715      +0.03%
   220 ms   273   56265    7033      7045      +0.17%
   230 ms   261   58823    7352      7360      +0.11%
   240 ms   250   61381    7672      7680      +0.10%
   250 ms   240   63938    7992      8004      +0.15%
   260 ms   231   66496    8312      8309      -0.04%

Maximum "Safe" Raw Bytes per Track

I've not seen any documents that discuss the acceptable speed ranges for Disk II drives, but I can try a rough calculation. The read output signal for a 1 bit from the drive is a 1 μs pulse that must be detected within 4 μs of the previous bit (see page 9-29 of Understanding the Apple II for details, and correct me if I'm wrong).

The drive will fully resync at the starting 1 bit of a raw byte (see the discussion of byte framing in, again, this answer), so that that means that the drive can't slow more than about half a microsecond over the course of 8 bits, or about 1.5%.

Using this figure, we get a minimum drive speed of 197 ms per rotation: 50383 bits or 6298 raw bytes per track.

Maximum data storage per track.

Since we've done all this, it's interesting and easy enough to calculate the maximum number of (encoded) data bytes we can store on a track. If we decide to go with a full-track format (one huge sector per track) we need just 50 bits for synchronization (details again in this question and answer) and the rest can be data. At 50383 bits per track we have 50333 remaining after the sync bits, all of which we can use to store GCR 6+2 encoded data:

      50,333 bits
÷ 8 =  6,291 raw bytes
× 6 = 37,749 encoded bits
÷ 8 =  4,718 encoded bytes

Multiply by 35 tracks and this would give us a total capacity of 161.25 KB/disk. Round down just a bit for safety and it seems that 160 KB is the maximum you could ever pack on to an Apple II floppy.

| improve this answer | |
  • 2
    A pulse which occurs less than 6us after the previous pulse will be recorded as a 1; a pulse which occurs 6-10us after the previous pulse will be recorded as a zero then a 1; a pulse which occurs 10-14us after the previous pulse will recorded as two zeroes and a 1. Timings aren't nearly as tight as what you're suggesting. – supercat Apr 15 at 22:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.