// DLSConInit.bcpl -- Initialization for DLS control program
// Code may be discarded after use
// Last modified June 20, 1982 10:45 AM by Taft
// Last modified January 17, 1985 10:06 AM by Diebert
get "DLSDriver.decl"
get "Pup.decl"
get "DLSControl.decl"
get "DLSConfig.decl"
get "SysDefs.d"
get "AltoDefs.d"
get "DLSUtil.decl"
external
[
// Procedures defined herein
DLSBeforeJuntaInit; DLSAfterJuntaInit;
// Procedures defined elsewhere
DLSAfterJunta; LoadRam; ReadDLSConfig; InitializeDLS; CreateDCLM;
DLSTop; DLSBackground; AltoCommand; StatusBackground; DspPuts;
TelnetRendezvousServer; DLSSocketNotFound; SetDLSLineSpeed;
SetTimer; Enqueue;
InitPupLevel1; SetAllocation; OpenLevel1Socket; SocketNotFound;
Max; InitRingBuffer; InitializeContext; GetFixed; Ws; Wss; Wns;
InitializeZone; Allocate; Zero;
SysErr; SysErrT; MyFrame; CallersFrame; Idle; Block;
CallSwat; Junta; PutTemplate; InitGrapevine; LoginServer
// Statics defined elsewhere
dlsName; dlsRegistry; dlsInList; dlsOutList; dlsWizardList
versionText; endInit; sysZone; mainCtx; ctxTable; @lbTable; crlf;
RamImage; stDis; nPBI; iPBI; dPSIB;
rtpStackSize; strayPupQ; logstream; loginServerCB; dcb
]
static [ dlsConfig ]
manifest [ linefeedChar = 10 ]
//----------------------------------------------------------------------------
let DLSBeforeJuntaInit() be
//----------------------------------------------------------------------------
// Called before the Junta is done, to do all operations requiring the disk.
[
endInit = @endCode
// Read the DLS configuration file
let fixedZn = vec size ZN/16
fixedZn>>ZN.Allocate = FixedAllocate
fixedZn>>ZN.Free = SysErr
dlsConfig = GetFixed(lenDLSConfig)
ReadDLSConfig(dlsConfig, fixedZn)
dlsName = dlsConfig>>DLSConfig.name
dlsRegistry = dlsConfig>>DLSConfig.thisRegistry
dlsInList = dlsConfig>>DLSConfig.thisInList
dlsOutList = dlsConfig>>DLSConfig.thisOutList
dlsWizardList = dlsConfig>>DLSConfig.thisWizardList
// Link up SysErr with the copy we load
SysErr = SysErrT
// Bye-bye OS
Junta(levBcpl, DLSAfterJunta)
]
//----------------------------------------------------------------------------
and DLSAfterJuntaInit() be
//----------------------------------------------------------------------------
[
// Make a zone out of the (up to) 32K of unused space immediately
// below the main DLSControl procedure's frame
let lenUnusedSpace = MyFrame()-600-@endCode
if lenUnusedSpace ls 0 then lenUnusedSpace = 77777B
sysZone = InitializeZone(@endCode, lenUnusedSpace)
@endCode = @endCode+lenUnusedSpace
dcb = Allocate(sysZone, lDCB, false, true)
Zero(dcb, lDCB)
dcb>>DCB.background = 1
@displayListHead = dcb
// Initialize data structures for DLS driver and microcode
mainCtx = Allocate(sysZone, 2) // Q header for context list
mainCtx!0 = 0 // Q initially empty
let lct = vec lenLCT
for line = 0 to numLines-1 do
[
lct>>LCT↑line.lineType = dlsConfig>>DLSConfig.lc↑line.lineType
lct>>LCT↑line.otherLine = dlsConfig>>DLSConfig.lc↑line.otherLine
]
unless LoadRam(RamImage, true) eq 0 do
CallSwat("Failed to load DLS microcode")
(table [ #61010; #1401 ])(nil, #20) //jump into RAM emulator
InitializeDLS(sysZone, lct)
// Initialize dialler data structures, if any
let haveDialler = false
let haveLog = false
let signalVec = vec 7
for line = 0 to numLines-1 do
[
if dlsConfig>>DLSConfig.lc↑line.lineType eq ltLog then haveLog = true
if dlsConfig>>DLSConfig.lc↑line.lineType eq ltDialler then
[
signalVec!6 = dlsConfig>>DLSConfig.lc↑line.data.diallerType
signalVec!(dlsConfig>>DLSConfig.lc↑line.dialler.signalIndex) = line
haveDialler = true
]
]
// DLSAfterJuntaInit() continued
unless haveLog do
[ CallSwat("Configuration has no log specified."); finish ]
if haveDialler then
[
let dclm = CreateDCLM(sysZone, signalVec)
for line = 0 to numLines-1 do
if dlsConfig>>DLSConfig.lc↑line.dialOut then
[
let dlb = lbTable!line
dlb>>DLB.dclm = dclm
dlb>>DLB.modemType = dlsConfig>>DLSConfig.lc↑line.data.modemType
dlb>>DLB.modemAddress = dlsConfig>>DLSConfig.lc↑line.data.modemAddress
]
]
Enqueue(mainCtx,
InitializeContext(Allocate(sysZone, 150), 150, TelnetRendezvousServer))
SocketNotFound = DLSSocketNotFound
strayPupQ = Allocate(sysZone, 2); Zero(strayPupQ, 2)
// Create and initialize a context for each data line
ctxTable = Allocate(sysZone, numLines) // Table of contexts
Zero(ctxTable, numLines)
let numDataLines = 0
for line = 0 to numLines-1 do
[
if (lbTable!line)>>LBH.lineType eq ltLog then logstream = lbTable!line
if (lbTable!line)>>LBH.lineType gr ltData then // Don't build ctx for Log file.
[
let dlb = lbTable!line
let ctx = Allocate(sysZone, lenCtxRegion) // Build context
Zero(ctx, lenCtxRegion)
InitializeContext(ctx, lenCtxRegion, DLSTop, lenCTX)
ctxTable!line = ctx
ctx>>CTX.dlb = dlb
if dlsConfig>>DLSConfig.lc↑line.data.constantBaud ne 0 then
[
ctx>>CTX.constantBaud = true
SetDLSLineSpeed(dlb, dlsConfig>>DLSConfig.lc↑line.data.constantBaud)
]
ctx>>CTX.terminalType = dlsConfig>>DLSConfig.lc↑line.data.terminalType
ctx>>CTX.terminalLength = dlsConfig>>DLSConfig.lc↑line.data.terminalLength
ctx>>CTX.terminalWidth = dlsConfig>>DLSConfig.lc↑line.data.terminalWidth
ctx>>CTX.dialOutOnly = dlsConfig>>DLSConfig.lc↑line.data.dialOutOnly
ctx>>CTX.host = dlsConfig>>DLSConfig.lc↑line.data.host
dlb>>DLB.stopBits = dlsConfig>>DLSConfig.lc↑line.data.stopBits
ctx>>CTX.noPad = dlsConfig>>DLSConfig.lc↑line.data.noPad
ctx>>CTX.eightBit = dlsConfig>>DLSConfig.lc↑line.data.eightBit
Enqueue(mainCtx, ctx) // Put on main context list
numDataLines = numDataLines+1
]
]
// Create contexts for any necessary background tasks
Enqueue(mainCtx, InitializeContext(Allocate(sysZone, 100), 100,
DLSBackground))
loginServerCB = Allocate(sysZone, lenLSCB)
Zero(loginServerCB, lenLSCB)
Enqueue(mainCtx, InitializeContext(Allocate(sysZone, 400), 400,
LoginServer))
// InitDLSControl (cont'd)
// Allocate 1 more line worth of PBIs if we have a dailler
if haveDialler then numDataLines = numDataLines + 1
// Determine how much storage is left in sysZone
let unused = nil
Allocate(sysZone, #77777, lv unused)
// Determine how much storage will be available after the
// initialization code is thrown away, and
// decide how much space can be devoted to packet buffers.
// We initially allocate only one socket allocation's worth of
// PBIs (=iPBI). Funny rshifts are to avoid numbers that look negative.
unused = unused + (endInit-DLSBeforeJuntaInit) + (CallersFrame()-@endCode-100)
nPBI = ((unused - 1000 - // Slop for breakage
numDataLines*(rtpStackSize+1)) rshift 1) / // Reserved for RTP contexts
((lenPBIOverhead+(pupOvBytes+lenPupContents)/2+1) rshift 1)
// Determine per-line PBI allocation by dividing the available PBIs equally
// among the lines. For a large configuration, overcommit the PBIs by a
// factor of two. For a very small configuration, limit the number of PBIs
// per line to avoid excess buffering.
iPBI = (nPBI-1)/numDataLines
if iPBI ls 6 then iPBI = 2*iPBI
if iPBI gr 15 then
[ iPBI = 15; nPBI = iPBI*numDataLines+1 ]
if iPBI ls 4 then CallSwat("Not enough PBIs")
// Initialize Pup software packages and allocate initial PBIs
InitPupLevel1(sysZone, mainCtx, iPBI, lenPupContents, 20)
let fakeSoc = dPSIB-offset PupSoc.psib/16
SetAllocation(fakeSoc, iPBI, iPBI-2, iPBI-2)
Idle = Block
InitGrapevine(sysZone)
PutTemplate(logstream, "*n*l*n*l*n*l*n*l*n*l$s in operation.*n*l", versionText)
]
//----------------------------------------------------------------------------
and FixedAllocate(zone, nWords) = GetFixed(nWords)
//----------------------------------------------------------------------------