Page Numbers: Yes X: 527 Y: -.5" First Page: 92
Heading:
Dorado Hardware ManualDisk Controller 14 September 1981
Disk Controller
This chapter describes the Dorado disk controller, which uses the Slow IO system to control up to four Century Data Trident disk drives. Either the 80x106-byte T-80 or the 300x106-byte T-300 drives can be used. An extension of the controller onto a second logic board (not designed) would allow control of up to 31 disk drives; alternatively, duplicating the present controller (with different TIOA, task, and muffler assignments) would allow independent control of four additional drives.
Keep Figure 13 in view while reading this chapter.
The disk controller uses task 148 and the first five values of the TIOA addresses in block 108 - 178 (The Ethernet controller, on the same logic board, uses two of the other three.). Either the task or TIOA block can be modified by changing a SIP component on the logic board. TIOA assignments are as follows:
108DiskControlOutput←B to control register
118DiskMuffOutput←B muffler control and Pd←Input to read muffler
128DiskDataPd←Input to read FIFO or Output←B to write FIFO data
138DiskRamOutput←B to format RAM
148DiskTagOutput←B to tag register
Note: other tasks must not select these TIOA addresses at any time; doing so may cause the disk controller to malfunction.
The controller is interfaced to the disk drives by a daisy chain cable bussed to all drives and by an independent radial cable to each drive. The radial cables contain the following signals:
data line (bidirectional, differentially driven)
data clock (from drive, differentially driven)
subsector/index line (from drive)
selected line (from drive)
select line (from controller)
sequence line (from controller, controlled by the baseboard for drive 0 and grounded
for other drives)
two VCC lines and scope trigger (from controller)
The daisy-chain cable contains the following signals:
16 control "tags" driven by the controller and received by the selected drive
9 error and status signals from the drive as follows:
CylOffset’
ReadOnly’
NoTerminator
HeadOvfl’
SeekInc’
DevCheck’
NotOnLine
NotReady
Index’
The controller or’s the NoTerminator error (which means that the daisy-chain cable isn’t terminated) into the NotOnLine error; the other error indications are discussed later.
Disk Addressing
The disk system is accessed through a many level addressing scheme. First a particular disk drive is selected. Then a data surface or head and a cylinder are selected (5 surfaces, 815 cylinders on a T-80). Each cylinder is further divided into sectors which consist of blocks.
Firmware may control the following parameters:
Sector size (1378 words max., limited by 4-bit subsector counter)
Number of blocks within one sector (1 to 4)
Block sizes (2 to 2684 words)
Note: Various limits on the sizes of blocks and sectors will be discussed. The processor interface allows a six-bit subsector counter of which only four bits are presently implemented, and this is the most significant length limit at present (1378 words). If the subsector counter were enlarged to six bits, then the block size limit imposed by the error correction algorithm (2684 data words) would apply. We are, however, unlikely to find any of these length limits significant unless we enlarge the memory page size to 4096 words. Jumpers in the disk unit could also be set to vary the spacing between subsector pulses.
Because sector formats are flexible, firmware can adjust the controller to system needs. The sector formats specifically envisioned in the design of the controller include 28 256-word sectors for Alto Diablo emulation and Pilot, 16 512-word sectors for Juniper, and 9 1024-word sectors for Alto Trident emulation.
Sector Layout Considerations
Each block within a sector can be either read, written, or checked. However, once any block is written, later blocks in that sector cannot be read during that disk revolution. (Later blocks should be readable on subsequent disk revolutions, though this is not guaranteed and no existing software depends on this.) Reading or writing must start with the first block in the sector and continue; since check bits are stored at the end of each block, the entire block must be read to verify its data or correct errors; however, one does not have to read or write subsequent blocks in the sector. After a check-block operation is started, the controller inhibits writing later blocks within a sector without a specific "OK" from the firmware.
Our general plan is to use the first block in a sector as a header identifying the disk address; all headers will be written when a disk pack is initialized; subsequently, the disk task compares the header with the disk address it thinks it is accessing. The header not only provides a useful safeguard against positioning errors but also allows faster sector determination when switching to a new drive, as discussed later.
The second block might identify information stored in the sector (e.g., the Label block in Alto format). The third block might be the data block. The fourth block could hold reference, backup, or archiving information. All of these choices are a matter of programming convention.
Feasible sector layouts are determined by several considerations. First, each disk drive is configured to generate 117 subsector pulses/revolution. The disk controller has a subsector counter for each drive that is initialized to N when an index pulse is received from the drive; it then counts down to -1, generates a sector pulse, and reinitializes itself. The firmware can specify N (0 to 178) independently for each disk drive and thus create 117/(N+1) sectors/revolution. If this division leaves any remainder, then there will be one or more unused subsectors at the end of the cylinder.
Note that the quantization of cylinders into subsectors allows a sector size to be specified in units of 10,080/117 = 86.15 words/subsector.
Various delays must be provided at the beginning and end of each block to allow for electrical and mechanical tolerances within the disk drive. To define a sector format, one simply needs a summary of "words lost" for each block:
Total words/track =10,080
Words lost for the 1st block in a sector =38
Words lost for successive blocks =14
Required gap at end of sector =(microcode-dependent)
A track is the path swept through one revolution by a single head at a single cylinder. "Words lost" for each block include 2 words of error detection and correction (32 bits of ECC code) which are always added at the end of the data written, plus preamble, postamble, and various other delays required by the controller and drive electronics. These are detailed later under "Format RAM and Sequence PROMs". Additionally, to enable the microcode to process consecutive sectors, there must be some gap between the end of the last block and the end of the sector; the number of words required depends on the amount of time the microcode requires to complete processing the last block and issue a command for the next sector.
For the Alto Trident format there is a 2-word Header block, 10-word Label block, and 1024-word data block; total words lost for disk formatting is 38 for the first block, 14 for the second, and 14 for the third; altogether, this requires 1100 words/sector. The next larger multiple of the subsector size is 86.15*13 = 1119 words, leaving 19*1.65 = 31.35 ms of gap at the end of the sector. Thus 13 subsectors/sector are required, yielding 117/13 = 9 sectors/revolution.
Using this kind of analysis, reasonable sector layouts on the T-80 are as follows:
29 sectors of data words each (4 subsectors/sector),
16 sectors of data words each (7 subsectors/sector), or
sectors of 1024 data words each (13 subsectors/sector).
Note: The 29-sector and 16-sector formats do not divide the disk evenly but rather yield an unusable leftover fraction of a sector; the 9-sector format does divide the disk evenly. The 9-sector format is compatible with the Alto Trident 9-sector format (used by BCPL Trident software such as IFS). The 16-sector format is not compatible with the Alto Trident 16-sector format (used by Juniper), though it is usable if interchangeability of disk packs with Altos is not required. The 29-sector format has no Alto analogue.
Table 23: T-80 Specifications and Characteristics
Capacity82.1 million 8-bit bytes unformatted
Transfer rate9.67 x 106 bits/sec (= one 16-bit word/1.65 ms)
Cylinder positioning time6 ms cylinder to cylinder maximum (3 ms typical)
30 ms average
55 ms maximum
Rotational speed3600 rpm (16.66 ms/revolution)
Sector length selection12-bit increments through jumpers on sector board
Densities370 cylinders/inch
6060 bits/inch max. recording density
Disk pack characteristicsIBM 3336-type components
5 recording surfaces plus 1 servo surface
815 cylinders/surface
Operating methodsModified frequency modulation recording
Linear positioning motor with cylinder following servo
Mechanical specificationsSize - 17.8" wide x 10.5" high x 32" deep
Weight - 230 lbs.
Error rateRecoverable: 1 error/1010 bits
Irrecoverable: 1 error/1013 bits
Positioning: 1 error/106 seeks
Pack start/stop time20 sec start time
20 sec stop time (with dynamic braking)
Controls and indicatorsReady Indicator
Off = disk not spinning
Flashing = spinning up/down
On = Ready
Fault Indicator
Start/Stop switch
Read-only switch
Degate switch (inside the drive; takes disk off-line for testing)
General Firmware Organization
This section gives a general overview of how the disk controller firmware is organized; more detailed descriptions follow later.
The disk drive generates subsector and index pulses on one line in the radial cable; the controller distinguishes these according to pulse width. In the normal Idle loop, the controller looks only at these pulses from the connected drives. A four-bit counter for each drive counts down subsector pulses and generates sector pulses. Upon either a sector or an index pulse from the selected drive, the controller generates a disk task wakeup. The disk task then either increments (sector wakeup) or zeroes (index wakeup) its firmware sector counter, clears the wakeup condition, checks for a new command, and blocks.
Because there are no hardware sector counters, the disk task must maintain a sector counter itself; this implies that the rotational position is generally unknown on all deselected drives.
When first selecting a drive, there are two strategies for determining the sector position: (1) Wait for an index wakeup, at which time the sector position becomes known; (2) Wait for a sector wakeup and then read the sector number stored in the header block (This can only be done if the disk is not moving to a new cyclinder.). The most efficient strategy appears to be a combination: Select the drive and start a seek to the correct cylinder; if an index wakeup arrives before the seek is finished, then the sector position is synchronized with no loss of time. If the seek finishes first, then read the next header to determine the sector number.
When a new disk operation is noted, firmware will perform the following steps:
Execute a drive-select command, if the drive differs.
Load the sector size only if different, and block until index.
Load the format RAM only if word count or commands differ.
Execute a Control Tag (seek) command only if the cylinder differs, and wait (continuing to count sectors) until the drive becomes ready again.
Execute a Head Tag command.
Block until, at a sector wakeup, the next sector is the one wanted.
Load the appropriate transfer command into the control register
Block until the next sector wakeup.
At the start of the next sector, the controller will become active and sequence through commands under control of the format RAM and two sequence proms (one for reading, one for writing).
The sequence proms define what operations the controller must go through, and the format RAM contains all parameters that might change from one implementation to another. Actual commands for the Trident disk are stored in the format RAM along with count values such as words/block, words of ECC, and words of delay before some operation; the commands are loaded into the tag register and executed by the controller during the transfer.
Once a transfer has started, the disk task will be woken according to the number of words in the FIFO, and it will send or receive the appropriate number of words. Read and compare operations are performed by firmware, as well as detecting checksum errors at the end of reading. During writing, firmware must provide one word of sync bits (2018 standard, 0018 for Alto Trident emulation) followed by the specified number of words for that block (the controller will append 2 words of checksum). During read, the controller will look for, and discard, the first word of sync bits, then firmware must accept the specified number of words for that block, followed by two words of checksum to be discarded, followed by the ECC remainder to be used for error detection/correction.
Task Wakeups
The controller may wakeup the disk task for many conditions; the disk task must detemine the cause and take appropriate action, which must in some way cause the wakeup to go away.
In general, there are two ways to determine the wakeup condition: read the wakeup condition, or assume the condition knowing the state of the disk task (which implies the state of the controller). When expecting a sector or index wakeup, the disk task must test carefully to count sectors reliably, but in the middle of word transfer operations, it will assume the wakeup reason to minimize overhead. The various conditions are as follows: IndexTW, SectorTW, TagTW, RdFifoTW, and WrFifoTW; these wakeup conditions are detailed in the "Muffler Input" section.
Control Register
The DiskControl register is a collection of flip-flops defining the state of the controller; on Output to DiskControl, IOB is interpreted as follows:
B[5]Clear EnableRun
B[6]Set DebugMode
B[7]Set BlockTilIndex
B[8:9]Operation for first block of sector, where the operations are:
0 = Done (finished with all blocks in this sector)
1 = Write
2 = Read and check
3 = Read
B[10:11]Operation for second block of sector, as above.
B[12:13]Operation for third block of sector, as above.
B[14:15]Operation for fourth block of sector, as above.
EnableRun determines whether the controller is active at all. It is initially cleared by IOReset, and can only be set by completing the loading of the format RAM (see below).
DebugMode allows the controller to be exercised by diagnostics when no disk is present; in this case, diagnostic firmware provides fake disk bit-clocks and data. The flip-flop is cleared by DisableRun.
BlockTilIndex can be set to disable sector and index task wakeups until (a) the selected drive is ready, and (b) an index pulse is received from the drive. It is cleared by an index wakeup. This is useful after switching drives or executing a ReZero operation, either of which causes the controller to lose sector synchronization with the drive. BlockTillIndex prevents the wakeup conditions from being set until these conditions are met, but does not clear any such wakeups that have already occurred. To prevent races, it is necessary to clear SectorTW and IndexTW, then set BlockTillIndex, then clear SectorTW again.
A request for a sector transfer is initiated by loading bits 8 and 9 of the control register with a non-zero value. Then the controller will wait until the next sector pulse to set the "Active" flip-flop and execute the transfer. Once a transfer has been started, it may be aborted by loading a new value into the control register twice. The first will clear the Active flip-flop, and the second will load the control register. (When Active, the control register is enabled for shifting commands rather than loading of io data.)
Format RAM and Sequence PROMs
The format RAM is a 16-word by 12-bit register that holds commands and delay counts used by the controller during a transfer. Words within the RAM are used according to the following table; the example values are appropriate for Alto Diablo disk emulation (2-word header, 8-word label, and 256-word data record).
Example
AddrDescription Value
00Word count of the first block0001
01Word count of the second block0007
02Word count of the third block0377
03Word count of the fourth block0000
04Control tag command for a read operation0104
05Control tag command for a write operation0204
06Control tag command to set Head Select0004
07Control tag command to zero the tag bus0000
08Word count to write zeroes before writing the 1st block of a sector0033
09Word count to write zeroes before writing the sucessive blocks0006
10Word count to wait before reading the 1st block of a sector0011
11Word count to wait before reading the sucessive blocks0002
12Word count of ECC words plus one0002
13Word count of 20001
14Word count of 1 (minimum count)0000
15Not used0000
Notice that the format RAM contains both word counts and tag commands. Word counts are 1 less that the desired count. Tag commands will be loaded into the tag register (see below) and then used as a "control tag function" by the Trident disk. The values in the right column are those used for the Alto Diablo emulation format. Notice that all but the first 4 values are determined by characteristics of the drive being used as opposed to the specific sector format. The meaning of the tag command values can be found in the "Tag Register" section.
The format RAM is addressed in two ways. During a transfer, sequence PROMs move data from the RAM into either a tag register or a count register. At other times, the Dorado may address the RAM with the RAM Address register, which is zeroed when the control register is written; executing an Output to the DiskRam register writes IOB into the RAM at the current address and then increments the address. Loading the last word in the format RAM turns on the EnableRun flip-flop allowing normal disk control activity. The format RAM may be read via the muffler scheme discussed later.
There are two sequence PROMs, one for reading (or checking) and one for writing. The PROMs are addressed by a program counter that is initialized to zero at the beginning of a sector and is incremented upon completion of each PROM program action. Either the read PROM or the write PROM is selected according to the operation being performed on the current block.
The sequence PROMs are clocked by WordClock, which is derived from the disk bit clock, which in turn is derived from timing information pre-recorded on the disk pack. The subsector pulses generated by the drive are also derived from this timing information. This enables very precise placement of the data on the disk, in a manner that is independent of the disk’s rotational velocity or the Dorado’s clock rate.
The read and write sequence PROMs are described in the following tables.
Write Sequence PROMDuration
AddrDescription(WordClocks)
00Issue tag command in RAM[6] (head select)1
01Delay (wait for head select to settle)RAM[13]+1
02Issue tag command in RAM[5] (write command)1
03Write long preamble for first blockRAM[8]+1
04Write sync word1
05Write data for first blockRAM[0]+1
06Write first ECC wordRAM[14]+1
07Write second ECC word and 2 postamble wordsRAM[12]+1
08Advance control register to the operation for the next blockRAM[14]+1
09Issue tag command in RAM[5] (write command)1
10Write short preamble for second blockRAM[9]+1
11Write sync word1
12Write data for second blockRAM[1]+1
13Write first ECC wordRAM[14]+1
14Write second ECC word and 2 postamble wordsRAM[12]+1
15Advance control register to the operation for the next blockRAM[14]+1
16-22Same as 09-15, except step 19 uses RAM[2]+1
23-29Same as 09-15, except step 26 uses RAM[3]+1
30Zero the tag bus1
31Not used
Read Sequence PROMDuration
AddrDescription(WordClocks)
00Issue tag command in RAM[6] (head select)1
01Delay (wait for head select to settle)RAM[13]+1
02Delay (skip over early part of preamble)RAM[10]+1
03Issue tag command in RAM[4] (read command)1
Note: WordClocks cease until controller has read sync word from disk
04Read data for first blockRAM[0]+1
05Read ECC wordsRAM[13]+1
06Compute first word of ECC remainder, issue tag command in RAM[6]1
07Compute second word of ECC remainderRAM[14]+1
08Advance control register to the operation for the next blockRAM[14]+1
09Delay (skip over early part of preamble)RAM[11]+1
10Issue tag command in RAM[4] (read command)1
Note: WordClocks cease until controller has read sync word from disk
11Read data for second blockRAM[1]+1
12Read ECC wordsRAM[13]+1
13Compute first word of ECC remainder, issue tag command in RAM[6]1
14Compute second word of ECC remainderRAM[14]+1
15Advance control register to the operation for the next blockRAM[14]+1
16-22Same as 09-15, except step 18 uses RAM[2]+1
23-29Same as 09-15, except step 25 uses RAM[3]+1
30Zero the tag bus1
31Not used
Tag Register
The 16-bit tag register drives the tag bus on the daisy-chain cable; all disk drive commands are initiated through the tag register. The tag register is sometimes loaded from IOB via an Output command to DiskTag, sometimes from the format RAM. Loading a Head Tag, Cylinder Tag, or Control Tag into the tag register (from either source) activates a timing circuit that handles all timing requirements of the Trident drive as follows: Only the tag bus bits are enabled for the first 200 ns; then the Tag[0:3] bits are also enabled for 1.2 ms; finally, the Tag[0:3] bits are disabled again and the TagTW flip-flop is set to wakeup the disk task (indicating completion of the Tag instruction). The Drive Select Tag (Tag[0]) does not activate the timing circuit, since the timer counts disk clock cycles, but disk clocks are invalid during drive select changes.
Bits 4 through 15 of the tag register are interpreted according to the following table:
Tag[0]Drive select and subsector count
Tag[4:15] are interpreted by the controller to effect drive select or subsector counter changes. The tag timing and wakeup circuit is not activated; firmware must take care of the timing by first loading Tag[4:15] as desired but with Tag[0:3] equal 0, then or-ing in the Tag[0] bit and outputting again.
4:9Subsector count
Divide the 117 subsector pulses from disk by subsector count+1 to form Sector pulses (Tag[4:5] are presently unimplemented).
Tag[4:9] = 3 yields 29 sectors large enough for 256-word data blocks
Tag[4:9] = 6 yields 16 sectors large enough for 512-word data blocks
Tag[4:9] = 148 yields 9 sectors large enough for 1024-word data blocks
10Load subsector from Tag[4:9] for the drive selected prior to the execution of this tag instruction.
11:15Drive select
The basic controller handles up to 4 disk drives; additional units may be accommodated by adding drive dependent logic on an additional board and connecting it in in place of drive 3. To allow this, the 5 bit drive select field is interpreted as follows.
0 - 3select drive 0 to 3, respectively
4 - 368select drive 3
378don’t select any drive
Tag[1]Head Tag
Loads a register in the drive that selects the head to be used during subsequent read/write commands. A Tag wakeup occurs at completion (1.6 ms).
4:7Unused
8Off Cylinder—may be activated during a read to attempt recovery of unreadable data. It causes cylinder positioning to be offset 80 micro-inches.
9Determines direction of offset if bit 8 is set.
10:15Head number—values from 0 to 4 are valid for a T-80, 0 to 19 for a T-300. The drive will turn on "EndOfCylinder" (alias HeadOverflow) error if an invalid head address is issued.
Tag[2]Cylinder Tag
Causes the drive to seek to the specified cylinder. A Tag wakeup occurs after the tag timing sequence has completed (1.6 ms), and the NotReady status bit is raised until the seek has completed (3 to 55 ms depending on the seek distance).
4:15Cylinder number (0 to 814 for Trident disks presently in use). An illegal cylinder number will cause DeviceCheck to be raised.
Tag[3]Control Tag
A Tag wakeup occurs at command completion (1.6 ms) and upon completion of the last read/write operation in a sector. Generally, Control Tag commands are issued only by the controller itself (using tag commands from the format RAM) rather than by the microcode; Device Check Reset and ReZero are an exception.
4AltoLeader—special flag to the controller that allows disks written by an Alto Tricon Controller to be read. This bit should only be used for the Alto Trident simulation.
5Unused
6Strobe Late—causes data recovery circuits within the drive to sample data early within the data bit time (for recovery when the drive is experiencing excessive read errors).
7Strobe Early—like StrobeLate except in the obvious way.
8Write—turns on the write circuits.
9Read—turns on the read circuits.
10Unused
11Reset Head register—zeroes the head address register in the drive.
12Device Check Reset—resets all latched error conditions in the drive.
13Head Select—turns on the head selection circuits, in conjunction with a Read or Write.
14ReZero—repositions the heads to cylinder 0 (if the heads are loaded) and resets the head address register; resets SeekIncomplete and DeviceCheck error conditions.
15Head Advance—increments the head address register in the drive.
FIFO Register
Data to/from the disk is buffered through a 16-word FIFO (25 ms of buffer), which is read/written with Pd←Input/Output←B when TIOA selects DiskData. Each FIFO word holds 16 data bits, 2 parity bits, and a 2-bit field indicating that the next word to be read is either write, read, or read-and-check type data. During output to the disk, the controller checks parity both when receiving data on the io bus and again when reading the FIFO. During a disk read, parity is computed before writing into the FIFO, is passed through the FIFO, and is then written on the io bus for the processor to test.
Muffler Input
Dorado uses a multiplexor scheme called the muffler system for reading miscellaneous logic signals during debugging from the Alto or baseboard. The disk controller also allows a muffler address to be specified on an Output to the DiskMuff register; in this way, any DskEth board signal available through the multiplexors (mufflers) is also available for firmware sampling. Other bits of the DiskMuff register output specify other operations as follows:
B[0]Simulate read data of 1 for 1 cycle (for use by diagnostic programs)
B[1]Simulate read clock of 1 for 1 cycle (for use by diagnostic programs)
B[2]Clear CompareErr—done by disk task if a read&compare is found to be OK
B[3]Set ReadDataErr—done by disk task to inhibit future writes
B[4]Clear the index wakeup flip-flop
B[5]Clear the sector wakeup flip-flop
B[6]Clear the tag wakeup flip-flop
B[7]Clear all error flip-flops within the controller (not the disk drive)
B[8:15]Muffler address—signals are enumerated below
Following an output to the DiskMuff register, the firmware must wait one cycle before inputting the selected muffler signal with Pd←Input. The state of the signal selected will be driven on IOB[15], and the remaining bits will be zero. For the purpose of examination from Midas, the signals are grouped into 16-bit words, as shown in the following table. The bits within each word and an appropriate explanation follow:
KSTATEvarious bits indicating the state of the controller
000TempSensesee "Dorado Debugging Interface" document
001IndexTWdisk task wakeup is due to an index pulse; index pulses occur once/disk revolution (16.7 ms) and are used to synchronize the hardware subsector counter and the firmware sector counter. An index pulse also causes a SectorTW.
002SectorTWdisk task wakeup is due to a sector pulse. To maintain a reliable sector count in a race-free manner, the microcode must (a) check for SectorTW, and upon finding it set increment the sector number and clear SectorTW; (b) check for IndexTW, and upon finding it set zero the sector number and clear both IndexTW and SectorTW.
003TagTWdisk task wakeup is due to completion of a Head Tag, Cylinder Tag, or Control Tag command. This occurs 1.6 ms after issuing an Output to the DiskTag register, and also upon completion of the last read/write transfer in a sector.
004RdFifoTWdisk task wakeup is due to presence of at least 3 words in the FIFO during a normal read or 1 word during a read-and-check. During a normal read, an Input that reduces the FIFO below 3 words will drop RdFifoTW in time for a Block to take effect on the 5th cycle following the Input; this permits a 2-cycle loop (Input, Block). During a read-and-check, an Input that empties the FIFO will drop RdFifoTW in time for a Block to take effect on the 3rd cycle following the Input; this permits a 4-cycle loop (Input, no-op, no-op, Block).
005WrFifoTWdisk task wakeup is due to space for at least 4 words in the FIFO. An Output that reduces the free space below 4 words will drop WrFifoTW in time for a Block to take effect on the 5th cycle following the Output; this permits a 2-cycle loop (Output, Block). WrFifoTW is enabled to occur by selecting TIOA[DiskData] when a write command is in progress; it is disabled by TIOA[DiskControl], which the microcode executes after outputting the last data word of a block. One more WrFifoTW will occur after all data has actually been sent to the disk.
006ReadDataData bit from the disk (available for diagnostics)
007WriteDataData bit to the disk (available for diagnostics)
010EnableRunFormat RAM has been written, and wakeups are enabled
011DebugModeController has been placed in debug mode
012RdOnlyBlock’The controller is processing a block in normal read mode
013WriteBlock’The controller is processing a block in write mode
014CheckBlock’The controller is processing a block in read and check mode
015ActiveThe controller is processing a command for the current sector
016:017Select.0..1The address of the currently selected drive unit
KSTATvarious bits indicating the status of the drive/controller. The controller will turn on WriteInhibit for the remainder of the sector after any of the following errors are detected, but will still go through all the motions of word transfers.
020SeekIncThe disk drive has not correctly positioned the heads within the last 700 ms. A ReZero command must be issued to clear this error.
021HeadOvflThe head address given to the disk drive is invalid (i.e., greater than 4 for a T-80 drive).
022DevCheckOne of the following errors occurred:
Head select, Cylinder select, or Write command and disk not ready
Illegal cylinder address.
Offset active and cylinder select command.
Read-Only and Write.
Certain errors during writing, such as more than one head selected, no transitions of encoded data or heads more than 80 micro-inches off cylinder.
A ReZero command may be necessary to clear this error.
023NotSelectedThe selected drive is in "off-line" test mode or the selected drive is not powered up
024NotOnLineThe drive is in test mode or the heads are not loaded
025NotReadyThere is a cylinder seek in progress or the heads are not loaded
026SectorOvflThe controller detected that a command was active when the next sector pulse occurred. This error implies either a hardware malfunction or a discrepancy between the sector format of the drive and the word count the program thinks is appropriate.
027FifoUnderflowEither the FIFO became empty while writing (task got behind) or the FIFO had too many words taken out of it while readng (microcode word count or wakeup error).
030FifoOverflowEither the FIFO became full while reading (task got behind) or the FIFO had too many words put into it during writing (microcode word count or wakeup error).
031ReadDataErrA flip-flop in the controller for latching one of three errors:
CompareErra read-and-check operation was executed on a block, and the microcode did not issue ClearCompareErr before the beginning of the next block.
ECCErrorthe microcode can set the ReadDataErr flag if it determines that the ECC words after reading one block are non-zero in order to inhibit future writes.
ECCComputeErrThe ECC hardware within the disk controller failed to generate a single "1" bit (i.e., a hardware malfunction).
032ReadOnlyThe "Read-Only" switch on the drive is on.
033CylinderOffsetThe cylinder position is currently offset. This is a mode used for recovery of bad data.
034IOBParityErrThe controller detected bad parity on the IOB bus.
035FifoParityErrThe controller detected bad parity on the data out of the FIFO.
036WriteErrOR of errors on muffler addresses 020-035
037ReadErrOR of errors on muffler addresses 020-031 and 034-035
KRAMcontents of the format RAM
040:043Address of format RAM word
044:057contents of format RAM word
KTAGcontents of the tag register
060:07720 bit value last loaded into the tag register
KFIFOstate of the io control logic
100ShiftInThe controller is currently shifting data into the FIFO
101ShiftOutThe controller is currently shifting data out of the FIFO
102ComputeECCThe controller is currently shifting data and computing the ECC checksum
103NextBlockOccurs between blocks within a sector
104LoadTagIndicates that the next word read from the format RAM should be loaded into the tag register as opposed to the count register
105CntDone’Indicates that the count register is again zero, and a new value from the format RAM will be loaded next
106OutRegFullThe holding register on the input to the FIFO has been loaded, but not transferred into the FIFO.
107InRegFullThe holding register out of the FIFO has been loaded, but not read via Pd←Input or loaded into the output shift register.
110:113FifoWaddrThe 4-bit address indicating where the next word will be written into the FIFO
114:117FifoRaddrThe 4-bit address indicating where the next word will be read from the FIFO. if FifoWaddr equals FifoRaddr then the FIFO is defined as empty.
Error Detection and Correction
To allow high data density and a few surface imperfections during manufacture, Trident disk packs are not required to be perfect. A disk pack is defined as suitable when no more than three bad areas occur on any data surface; a bad area is defined as one which could potentially cause read errors of no more than 11 bits in length. To correct errors arising from these imperfections as well as other (infrequent) read errors, the controller implements an error detection and correction scheme which will detect (with very high probability) errors of any length, and will allow correction of any burst error of 11 bits or less.
Warning: If an error burst longer than 11 bits occurs, there is a significant possibility that the error correction algorithm detailed below will fail and double the number of bad bits! Consequently, disk handling programs should try other methods of error recovery before invoking the error-correction algorithm.
To avoid problems, it is good practice to run diagnostic programs on new disk packs; note bad sectors and don’t use these during normal operation.
When an error does occur, the first step is to try rereading the offending sector several times. One of these reads may succeed. If not, try rereading with the cylinder position offset or with the data strobe early or late as discussed in the "Tag Register" section. If these attempts all fail, then try error correction.
Error correction is accomplished through a mixture of disk controller hardware (for ECC generation and checking) and system software/firmware (for error recovery). This is a compromise between capability, speed, and cost. The basic capabilities and restrictions of the 32-check-bit scheme are summarized below.
1) A single error burst of length less than 12 data bits (i.e., a scattering of error bits within the bit stream, all of which fit within an 11-bit span) can be corrected in blocks shorter than 2685 data words. (Example: for the data "0001100101", the data "0000101101" contains a single burst error of length 4.). The code implemented will detect errors in arbitrarily long blocks, but not enough information exists to correct longer blocks.
2) Simple error detection—two words are returned by the hardware which are both zero if the read is successful.
3) Software/firmware error correction can be completed in less than one disk revolution. The correction procedure is well suited to a mixture of software and firmware. If done entirely in firmware, error correction would take less than 1 ms.
4) Not all uncorrectable errors will be detected as such. An uncorrectable error requires two bad spots on the disk surface within one sector (the pack is bad—throw it out!), an electronic error in a sector with a bad spot, or two electronic errors within one sector. If such an error has occurred, it can, with a probability of say 20 percent, result in an error pattern and displacement that seems valid. This will result in leaving the error bits uncorrected and changing some bits which were in fact correct. This means that for high data security, a check code should be generated and imbedded as part of the data file before writing on the disk.
The error-correcting code (ECC) generated is referred to as a Fire Code (see Error-Correcting Codes by Peterson). The following is a detailed description of this code and recovery procedure.
The code calls for dividing the outgoing data stream by a polynomial of the form:
P(X) = P1(X)(Xm + 1)
Where P1(X) is an irreducible polynomial of degree n (n = burst length) and m is > 2*n. For this particular application the polynomials chosen are:
P(X) = (X11 + X2 + 1)(X21 + 1)
During a write, the two polynomials are multiplied together and implemented by hardware in the form:
P(X) = X32 + X23 + x21 + X11 + X2 + 1
The data stream is premultiplied by X32 to make room for the 2 word ECC and then reduced modulo P(X). This is accomplished by the normal feedback shift register technique with the difference that to perform premultiplication, the output of the register is exclusive-or’d with the incoming data and then fed back. After all data bits have been shifted out, the contents of the ECC shift registers are appended to the disk block.
During a read, the feedback shift register is reconfigured such that the two original polynomials are implemented separately. The incoming data stream, including the 2 appended words of ECC, is independently reduced modulo P0(X) and P1(X), where
P0(X) = X21 + 1
P1(X) = X11 + X2 + 1
After reading in all words off the disk, the contents of the two polynomial shift registers are read out of the FIFO. If the data is recovered without error, then reducing it modulo P0(X) and P1(X) results in the registers containing all zeroes.
If the data contains an error, then the two registers will be non-zero. If one but not both registers is non-zero, then the error is irrecoverable.
To recover from an error, a procedure is undertaken which determines the pattern of bits which are in error, and the displacement of this pattern from the end of the record. I am simply going to present the magic equation to be solved, and some magic constants to be used for solving this equation. Much of the polynomial implementation and the equations, which use the "Chinese Remainder Theorem" are discussed in technical reports from CALCOMP (Calcomp Technical Report TR-1035-04, by Wesley Gee and David George) and XEROX (Xerox XDS preliminary report "Error Correction Code for the R.M. Subsystem," by Greg Tsilikas, 28 March 1972.).
The basic equation is:
D = Q*LCM − (A0*M0*S0 + A1*M1*S1)
where:
Ei = modulus of the polynomial
LCM = least common multiple of E0 and E1
Mi = LCM/Ei
Ai = a constant such that Ai*Mi modulo Ei = 1
Q = smallest integer to make D positive
Si = number of shift operations to the appropriate polynomial remainders as described below.
D = displacement of right-most incorrect bit from the end of the record.
The values of E0 and E1 were found by programming the procedure outlined in the CALCOMP report, and yielded the following result:
E0 = 21 E1 = 2047
The least common multiple (LCM) of E0 and E1 is simply the product of E0 and E1 since the two numbers have no factors in common. Thus the LCM, which is also the record length which can be corrected, is 42,987 bits, or 2686−2 words.
Knowing LCM and E0 and E1, the values of M0 and M1 are easily found to be
M0 = 2047 M1 = 21
The values of A0 and A1 are next determined using a trial and error approach that I put in a small program. The results can easily be confirmed, and are given below:
A0 = 19 A1 = 195
All of the above values derived so far are constants determined for the particular polynomials chosen. The values of S0 and S1 are determined in the software from the error patterns returned at the end of a disk transfer.
S0 is first determined by a software procedure using the following steps:
1) The remainder from dividing the input data by X21 + 1 is found in ECC[11:31]; if this remainder is zero, then the error is uncorrectable.
2) Test the low order 10 bits for all zeroes, and if not then perform a left circular shift on the 21 bits. When the low order 10 bits are all zeroes, the error pattern is in the upper 11 bits of the word, and S0 is the number of times the circular shift was performed.
3) If the low order 10 bits don’t become all zeroes within 20 shifts (1 full cycle), the error is uncorrectable.
S1 is then determined in microcode as follows:
1) The remainder from dividing the input data by X11 + X2 + 1 is found in ECC[0:10]; if this remainder is zero, then the error is uncorrectable.
2) Test this number to see if it is equal to the error pattern determined in step 3 of S0, and if not reduce this number modulo X11 + X2 + 1 (left shift and XOR feedback). When the contents of this word equals the error pattern (it is guaranteed to happen before 2047 reductions), S1 is determined as the number of reductions performed (In the hardware implementation of switching from the write polynomial to the read polynomials, it was easier to implement a polynomial that premultiplied by X11. This means that the remainder returned by the hardware already has had 11 shifts performed. To compensate, when S1 has been determined by the above procedure, you must add 11 to the value, and subtract 2047 if the result is greater than or equal to 2047.).
The basic equation for the displacement now looks like
D = Q*42,987 − 19*2047*S0 − 195*21*S1
where:
0 < S0 < 20
0 < S1 < 2046
Notice that the straightforward solution to this equation cannot be done with single-precision arithmetic on the Dorado; to avoid double precision, the following manipulation of the equations is useful:
D = Q*2047*21 − 19*2047*S0 − 4095*S1
D = Q*2047*21 − 19*2047*S0 − 2*2047*S1 − S1
D’= Q*21 − 19*S0 − 2*S1
where:
0 < D’ < 20
D = 2047*D’ − S1 (add 42,987 if D’ = 0)
For some reason that we don’t understand, the actual required calculation must be D = 2047*(D’+1) − S1 in the last step. Also D’ is conveniently calculated as (215*21 − 19*S0 − 2*S1) rem 21.