// DLSDriver.decl -- Declarations for Alto DLS driver

// Last modified June 20, 1982  10:53 AM by Taft
// Last modified November 7, 1983  9:42 AM by Diebert

get "Streams.d"

manifest
[
// Maximum total number of DLS lines handled
numLines = 100B			// Multiple of 20B

// Default baud rate of all lines
defaultBaud = 300

// Internal parameters
lenDLSIRB = 2*numLines		// Length of global input buffer
lenDLSORB = numLines+2		// Length of global output buffer
lenIRB = 40			// Line input ring buffer size (words per line)
lenORB = 40			// Line output ring buffer size (words per line)

// Constants defined by hardware and microcode
typeIGCB = 1			// Identifies type of LCB for microcode
typeILCB = 0
typeOLCB = 2

stop1 = 2			// oLCB>>bitsPerChar  =  8 bits + 1 stop bit
stop2 = 6			// 8 bits + 2 stop bits

inputIntMask = 10B		// Input interrupts on channel 3
outputIntMask = 40B		// Output interrupts on channel 5
errorIntMask = 20B		// Input overflows on channel 4

dlsInBase = 177400B		// DLS input bits (16 every 20B words)
dlsOutBase = 177600B		// DLS output bits (bit 15 in each word)

dlsTicksPerSecond = 26250	// 5.88E6 / 224
				// System clock is 5.88 MHz
				// MRT runs every 224 system clock cycles

samplesPerBit = 5		// Samples per bit of fastest input line
defaultBitInterval = dlsTicksPerSecond/defaultBaud
defaultSampleInterval = defaultBitInterval/samplesPerBit

// Correspondence between EIA data and control levels
dataZero = true			// = EIA high = space
dataOne = false			// = EIA low = mark

// Error codes
ecGetsCarrierOff = 5000		// Executed DLS Gets with carrier off
ecPutsCarrierOff = 5001		// Executed DLS Puts with carrier off
ecDLSGetsTimeout = 5002		// DLS Gets timed out

ecDiallerInUse = 5010		// Values returned from DialOut
ecDiallerTimeout = 5011
ecDiallerNoAnswer = 5012

// Flow control things
Xon = 21b
Xoff = 23b
fcTimeoutTime = 30000	// 5 min
fcMinBuffSpace = 6

]

// Data structures defined by the DLS microcode

// ---------------------------------------------------------------------------
structure IGCB:		// Input group control block (even-word aligned)
// ---------------------------------------------------------------------------
[
link word		// Queue link word
type byte		// What kind of LCB
line byte		// Line number
idle word		// Ones for active lines that are idle
interval word		// Sampling interval -1 (38 us units)
active word		// Ones for active lines
]

// ---------------------------------------------------------------------------
structure ILCB:		// Input line control block (even-word aligned)
// ---------------------------------------------------------------------------
[
link word		// Queue link word
type byte		// What kind of LCB
line byte		// Line number
char word		// Character being assembled
sdMode bit 1		// 1 if in speed determination mode
bitsPerChar bit 7
interval byte		// Bit time -1 (38 us units)
sdLink word		// Next LCB ptr for speed determination
]
manifest lenILCB = size ILCB /16

// ---------------------------------------------------------------------------
structure OLCB:		// Output line control block (even-word aligned)
// ---------------------------------------------------------------------------
[
link word		// Queue link word
type byte		// What kind of LCB
line byte		// Line number
char word		// Character being disassembled
bitsPerChar byte	// Bits/char and stop bits control
interval byte		// Bit time -1 (38 us units)
]

// Structures used by DLS driver

// ---------------------------------------------------------------------------
structure LBH:		// Line block header (common to all types)
// ---------------------------------------------------------------------------
[
line word		// Line number of this line
lineType byte		// Type of this line
otherLine byte		// Line associated with this one, if relevant
]
manifest lenLBH = size LBH/16

// ---------------------------------------------------------------------------
structure DLB:		// Data Line Block
// ---------------------------------------------------------------------------
[
@ST =			// Every DLB is also a stream
   [
   @LBH			//  =  DLB>>ST.par1 and .par2
   blank word offset ST.type/16 - lenLBH
   position word	//  =  DLB>>ST.type: Typehead position (TI)
   flags word = 	//  =  DLB>>ST.par3: Control flags used by driver
      [
      blank bit 15
      outActive bit 	//  =  DLB>>ST.par3: Output is active
      ]
   ]
flowControl word	// Flow Controler
flowControlAction word = 	// What flow control has to do
   [
   fcSendXoff bit	// set by asm stuff to force an Xoff to be sent
   fcSendXon bit	// set by asm stuff to force an Xon to be sent
   fcStop bit		// Stop sending chars
   blank bit 11
   fcTimerGoing bit	// set if a timer has started
   fcXoffSent bit	// set if inputs sent Xoff to the other machine
   ]
oRBD word 4		// Output ring buffer descriptor
iRBD word 4		// Input ring buffer descriptor
oLCB: @OLCB		// Output line control block
iLCB: @ILCB		// Input line control block
oBuf word lenORB	// Output buffer
iBuf word lenIRB	// Input buffer
statusA word =
   [
   carrierOff bit 1
   stopBits bit 2	// 1 or 2; 0 => default based on baud rate
   noPad bit 1		// No padding for CR delay
   baud bit 12		// Baud rate of line
   ]
statusB word =
   [
   blank byte
   blank bit
   eightBit bit		// used for this session
   modemType bit 2	// 0 => Va3400, 1 => 103, 2 => illegal, 3 => 212
   modemAddress bit 4	// = (Vadic card cage slot #)-1
   ]
timeout word		// Gets timeout interval (-1 = none)
fcTimer word		// Xoff timeout timer
dclm word = 		// -> Dialler Control Line Map (0 if none)
   [ logBusy word ]	// Alias for log busy
]
manifest lenDLB = size DLB/16

manifest
[
ltBell103 = 1
ltVadic3400 = 0
ltBell212 = 3
ltIllegal = 2
]

// Ensure agreement with assembly-language code.
compileif offset DLB.flags/16 ne 11 %
 offset DLB.oRBD/16 ne 14 % offset DLB.iRBD/16 ne 18 %
 offset DLB.oLCB/16 ne 22 % offset DLB.iLCB/16 ne 26 %
 offset DLB.iLCB.interval/16 ne 29 then
   [ Barf("DLB structure disagrees with assumptions in DLSDriverA.asm") ]

// Ensure relative even-word alignment.  Initialization ensures that
// DLB.iLCB is even-word aligned.
compileif ((offset DLB.iLCB - offset DLB.oLCB) & 37B) ne 0 %
 ((offset DLB.iLCB - offset DLB.oRBD) & 37B) ne 0 %
 ((offset DLB.iLCB - offset DLB.iRBD) & 37B) ne 0 then
   [ Barf("DLB impossible alignment constraint") ]

// ---------------------------------------------------------------------------
structure CLB:		// Control Line Block (for dataset or dialler)
// ---------------------------------------------------------------------------
[
@LBH
lastState word		// Previous state of input line
]
manifest lenCLB = size CLB/16

manifest
[  // LineType assignments
ltUnused = 0		// Not used for anything
ltControl = 1		// Dataset or Telenet control line
ltDialler = 2		// Dialler control line
ltData = 3		// All types ge ltData imply data line
   ltLog = 3		// This is the Dialout log
   ltHardwired = 4	// Hardwired data line
   ltDataSet = 5	// Dataset data line
   ltTelenet = 6	// Telenet data line
]

// ---------------------------------------------------------------------------
structure LCT ↑0,numLines-1:  // Line Configuration Table
// ---------------------------------------------------------------------------
[			// (passed to InitializeDLS)
lineType byte
otherLine byte
]
manifest lenLCT = size LCT/16

// ---------------------------------------------------------------------------
structure DCLM:		// Dialler Control Line Map
// ---------------------------------------------------------------------------
[
inUse word		// 0 or -> ctx currently using this dialler
signalLines↑0,5 byte =
   [
   lineCRQ byte =	// Call Request (output)
      linePND byte	// Present Next Digit (input)
   lineDPR byte =	// Digit Present (output)
      lineACR byte	// Abort Call and Retry (input)
   lineNB↑0,3 byte =	// Digit bits NB1, NB2, NB4, NB8 (output)
      lineDSS byte	// Data Set Status (input)
   ]
diallerType word	// Dialler type
]
manifest lenDCLM = size DCLM/16