// Tfs.decl - special version of TFS.d for CopyDisk
// Copyright Xerox Corporation 1979, 1980
// Last modified April 20, 1980  1:56 AM by Boggs

manifest
[
lFID = 3			// length of a FID
packID = 0			// part of FID

TFSmNTracks = 815
T80mNHeads = 5
T300mNHeads = 19
TFSmNSectors = 9
TFSwordsPerPage = 1024

// error codes
ecTfsQueue = 2404
ecReadOnly = 2410
ecDriveHung = 2411
ecUnRecovDiskError = 2412

// Disk actions (all have some "magic" bits to avoid accidents):
diskMagic = 153000b		// High order bits.

// Fields not explicitly mentioned are "checked":
DCreadHLD = 0 + diskMagic	// Read header,label,data
DCreadLD = 1 + diskMagic	// Read label,data
DCreadD = 2 + diskMagic		// Read data

DCwriteHLD = 3 + diskMagic	// Write header,label,data
DCwriteLD = 4 + diskMagic	// Write label,data
DCwriteD = 5 + diskMagic	// Write data

DCseekOnly = 6 + diskMagic	// Just seek to spot
DCdoNothing = 7 + diskMagic	// No-op

KBLK = 640b			// Trident controller CB address
dcbID = 122645b			// disk command seal

// Hardware command bit assignments
CheckData = 4000b
WriteBit = 200b
ReadBit = 100b
HeadSelect = 4
ReZero = 12b
CheckReset = 10b

// Hardware disk commands used in conjunction with above
diskRead = ReadBit + HeadSelect
diskWrite = WriteBit + HeadSelect
diskCheck = CheckData + ReadBit + HeadSelect
diskReset = CheckReset
diskRestore = ReZero
diskNoop = HeadSelect
]

manifest
[
// Mask bits for status word
DSTrestoreBits = 160100b
DSTerrorBits = 177717b		// ignore ReadOnly and Offset

// Status word values
DSTfreeStatus = 17b		// init state set by software
DSTgoodStatus = 1		// set by microcode after transfer
]

// Disk status word.  See hardware manual for detailed definitions
structure DST:
[
Status word =
   [
   Errors bit 10 =
      [  // * = may require a restore to clear
      SeekInc bit	// 100000 *
      CylOvfl bit	//  40000 -misnamed, really bad head #
      DeviceCk bit	//  20000 *
      NotSelected bit	//  10000
      NotOnLine bit	//   4000
      NotReady bit	//   2000
      SecOvfl bit	//   1000
      DataLate bit 2 =
         [
         WrLate bit	//    400
         RdLate bit	//    200
         ]
      CompErr bit	//    100
      ]
   ReadOnly bit		//     40
   Offset bit		//     20
   ECCerror bit =	//     10 -- reported only in CB
   Sector bit 4		// -- reported only in #643 
   ]
]

// Trident Controller Control Block format
structure KBLK:
[
ptr word	// KBLK+0 = #640 = pointer to command block
drive word	// KBLK+1 = #641 = number of currently selected drive
cylinder word	// KBLK+2 = #642 = cylinder number in last command
@DST		// KBLK+3 = #643 = status at last sector pulse
aborted word	// KBLK+4 = non-zero if a command was aborted
]


//Header,Label,Data formats on disk

// Hardware disk address - same as disk address used in the KCB
structure DA:
[
cylinder word
head byte
sector byte
]

// Disk header - must be the same as DA
structure DH: @DA
manifest lDH = size DH/16

// Disk label.
structure DL:
[
fileId word lFID
blank word 7
]
manifest lDL = size DL/16

// Disk command block -- one for each sector transfer
structure KCB:
[
diskAddress @DH = @DH		// +0 + 1
drive word			// +2
nextKCB word			// +3
ID word				// +4 command seal
CommH word			// +5 header command block 
CountH word			// +6
AddrH word			// +7
ECC0H word			// +10
ECC1H word			// +11
StatusH @DST			// +12
CommL word			// +13 label command block 
CountL word			// +14
AddrL word			// +15
ECC0L word			// +16
ECC1L word			// +17
StatusL @DST			// +20
CommD word			// +21 data command block 
CountD word			// +22
AddrD word			// +23
ECC0D word			// +24
ECC1D word			// +25
StatusD @DST			// +26
endWord word			// +27
blank word			// +30
normalWakeups word		// +31
]
manifest lKCB = size KCB/16

// Command format for each block within a sector
structure KCBblock:
[
Comm word
Count word
Addr word
ECC0 word
ECC1 word
Status word
]
manifest lKCBbl = size KCBblock/16

structure CBZ:
[
length word
cleanup word
error word
retry word
errorCount word
head word		// * -> first CB on queue (0 = empty)
tail word		// * -> last CB on queue
CBs word 0
]
manifest lCBZ = size CBZ/16	// fixed part of CBZ

// each CBZ contains a CB for each possible transfer enqueued
// a free CB must have status=DSTfreeStatus (initialization does that)
structure CB:
[
@KCB			// hardware oriented control block  (27 words)
// remaining words are not zeroed by TFSGetCb
cbz word
nextCB word
]
manifest
[ 
lCB = size CB/16
lVarCB = offset CB.cbz/16
]

// bad page list (on physical page 0 of pack)
structure BPL:
[
seal word		// indicates presence of bad page list
nBadPages word		// number of bad pages
da↑0,0 @DA		// real disk addresses of bad pages
]
manifest bplSeal = 123456b

// CopyDisk stuff
manifest
[
maxDsk = 7		// max drives per trident controller
badPageSeal = 123456b
errorThreshold = 25

numCBs = 9
lenCBZ = lCBZ + numCBs*lCB

lenTFSData = 1024
lenTFSLabel = 10
lenTFSHeader = 2

// disk type
AltoTrident = 2

// error types
EtSoft = 2B8
EtHard = 1B8
EtRead = 1
EtWrite = 2
]

//----------------------------------------------------------------------------
structure TFSSS:
//----------------------------------------------------------------------------
[
@SS
drive word
model word
cbz word
retryCount word
currentDA @DA

//Normally we do not write headers, that is Triex's job, but
//if we can't seem to write a sector, we try writing the header too.
//If this happens more than 25 times in a copy, then
//we assume that the disk is unformatted, and always write headers.
//Writing headers while switching drives is risky since the sector
//counters in Trident multi-drive controllers tend to glitch if the
//drive is selected at the time a sector pulse arrives.
checkErrors word
action word
]
manifest lenTFSSS = size TFSSS/16

//----------------------------------------------------------------------------
structure TFSBuffer:
//----------------------------------------------------------------------------
[
@Buffer
header @DH
label @DL
data word lenTFSData
]
manifest
[
lenTFSBuffer = size TFSBuffer/16
lenFreePage = (offset TFSBuffer.data - offset TFSBuffer.length)/16
]

//----------------------------------------------------------------------------
structure TFSErrors:
//----------------------------------------------------------------------------
[
hardError word
softError word
]
manifest lenTFSErrors = size TFSErrors/16

//----------------------------------------------------------------------------
structure TFSXferParams:
//----------------------------------------------------------------------------
[
firstDA @DA
lastDA @DA
]
manifest lenTFSXferParams = size TFSXferParams/16

//----------------------------------------------------------------------------
structure TFSDiskParams:
//----------------------------------------------------------------------------
[
nCylinders word
nHeads word
nSectors word
]
manifest lenTFSDiskParams = size TFSDiskParams/16