//routeinit.bcpl
// Initialization and driver module
// last modified by Rumph, March 8, 1985 3:53 PM
// to add files and limits for split wirelist output and IC’s
// modified by McCreight, September 15, 1982 11:31 AM
// to initialize the complete random table, so we’ll get identically the
// same results on successive identical runs.
get "sysdefs.d"
get "streams.d"
get "altofilesys.d"
get "route.defs"
external
[
fpComCm
fpSysDir
sysDisk
dsp
UNPACKDT // in CTime.br
CONVUDT
OverlayScan
GenerateOverlays
OverlayNpages
LookupEntries
LoadRam
InitBcplRuntime
RamImage
initCodeEnd
PrintTWPins
PrintHoles
MakeBuzzLists
overlayCore
npBiggestOverlay
]
static
[
Correcting = false
noroute = false
whereTW = false
buzzLists = false
nlFileName = empty
board = empty
rev = empty
time = empty
pctext = empty
boardLocation = empty
wlNewFileName = empty
wlOldFileName = empty
outLimit = 1500
outThreshold = infinity
savedOutThreshold = 1000
ImplicitFile
ADFile
ErFile
CommentsFile
OldWlFile
OutFile
charTab
dontCareNet
StandardMetric
SilZone = 0
initCodeEnd
kf = empty
epvec
epsize
overlayCore
npBiggestOverlay
randomTable
randomIndex
randomTrailer
]
let OnceOnlyInitCode(blv,params,cfa) be
[ // sets up, also handles board type checking.
initCodeEnd = @#335
AddSpace(3000)// leave for stack
@#420 = 0 //turn off display for speed
let e = vec 100
epvec = e
epsize = 0
AddDynamicEntry(lv AddEclTerminators) // in RouteTerm
AddDynamicEntry(lv LocateAvailTerms)
AddDynamicEntry(lv FreeTermStorage)
AddDynamicEntry(lv AssignTWNet)// RouteTWNetAssign
AddDynamicEntry(lv ManhattanDistFn) // in Routec
AddDynamicEntry(lv EuclideanDistFn)
AddDynamicEntry(lv CheckUnusedPins) // in Routea
AddDynamicEntry(lv NLCompFn) // in Routeb
AddDynamicEntry(lv AssignNetNumber)
AddDynamicEntry(lv ReportRepairedPins) // in RouteCorrect
AddDynamicEntry(lv ReportNewCutPins)
AddDynamicEntry(lv PrintNewNet)
AddDynamicEntry(lv MakeConnInstFile) // in RouteBackpanel
AddDynamicEntry(lv MultiWirePanic)
AddDynamicEntry(lv PCPanic)
AddDynamicEntry(lv RouteEarlyNets) // in RouteNet
AddDynamicEntry(lv RouteNetIfExternal)
AddDynamicEntry(lv RouteNet)
AddDynamicEntry(lv ComputeLengths)
OverlayScan(lv (cfa>>CFA.fp), Allocate(SilZone, 200), 200, lv (cfa>>CFA.fa),
0, 0, 0, 0, sysDisk, epvec, epsize)
npBiggestOverlay = 0
GenerateOverlays(HowBig)
overlayCore = Allocate(SilZone, 256*npBiggestOverlay)
ReadTime(lv time)
charTab = Allocate(SilZone, 256)
Zero(charTab, 256)
AddAttribute(upperCaseMask%letterMask, $A, $Z)
AddAttribute(lowerCaseMask%letterMask, $a, $z)
AddAttribute(digitMask, $0, $9)
AddAttribute(colonMask, ":")
AddAttribute(breakMask, " :,;*t*n")
AddAttribute(legalSpecialCharMask, "$#()’[]↑←?/\|+-=&**~")
let comcm = OpenFile("COM.CM",ksTypeReadOnly,charItem,0,fpComCm,0,SilZone)
if comcm eq 0 then CallSwat("Can’t open COM.CM")
let fn = vec 128
ReadNext(comcm,fn) //throw away name
let fnl = fn>>str.length
let i=1
while i le fnl do test fn>>str.char↑i eq $/
ifso [ i=i+1; break ]
ifnot i=i+1
while i le fnl do
[
switchon fn>>str.char↑i into
[
case $C:
case $c:
Correcting = true
endcase
case $M:
case $m:
doMultiWire = true
endcase
case $T:
case $t:
whereTW = true
endcase
case $B:
case $b:
buzzLists = true
endcase
case $R:
case $r:
doResistances = true
endcase
case $P:
case $p:
if doPC then PCPrototype = true
doPC = true
endcase
default:
]
i=i+1
]
StandardMetric = ManhattanDistFn
DefaultString(lv boardLocation, "c1")
if LoadRam(RamImage) eq 0 then InitBcplRuntime() // fire up microcode
SetupSpace()
DeclareAvailableNames() // for dynamic loader
let nlFileCount = 0
until Endofs(comcm) do
[
let filestring = vec 20
unless ReadNext(comcm,filestring) then break
unless IsFunnyParameter(filestring) do
[
NeedFile(filestring, 0, true) // input file
if nlFileCount eq 0 & nlFileName eq empty then
[
DefaultString(lv nlFileName, filestring)
let lastGoodChar = nlFileName>>str.length
for i=1 to nlFileName>>str.length do
[
if nlFileName>>str.char↑i eq $. then
lastGoodChar = i-1
]
nlFileName>>str.length = lastGoodChar
]
nlFileCount = nlFileCount+1
]
]
Closes(comcm)
dontCareNet = DefineNamee("Whatever", typeNet, NewNet)
dontCareNet>>net.hasBeenRouted = true
dontCareNet>>net.dontTerminate = true
SetupICclasses() // build icclass objects for all known IC classes
SetupBoard() // assuming dynamic loader has loaded board characterization,
//plug edge connectors and trace-wired nets into data structures
SetupMoreICClasses() // in the board file
if whereTW then PrintTWPins()
if buzzLists then MakeBuzzLists()
if nlFileCount le 0 then finish
let ts = vec 30
test Correcting & (wlOldFileName eq empty)
ifso
[
ExpandTemplate(ts, "$S.wl", nlFileName)
DefaultString(lv wlOldFileName, ts)
ExpandTemplate(ts, "$S.wlNew", nlFileName)
DefaultString(lv wlNewFileName, ts)
]
ifnot
[
ExpandTemplate(ts, "$S.wl", nlFileName)
DefaultString(lv wlNewFileName, ts)
]
NeedFile(wlNewFileName)
NeedFile(wlNewFileName, "1")// if we need to split the wirelist
NeedFile(wlNewFileName, "2")// ditto
NeedFile(nlFileName, ".ics")
NeedFile(nlFileName, ".inl")
NeedFile(nlFileName, ".re")
NeedFile(nlFileName, ".bp")
NeedFile(nlFileName, ".lc")
NeedFile(nlFileName, ".comments")
if Correcting then
[
NeedFile(wlOldFileName, "", false, false)
NeedFile(nlFileName, ".ad")
NeedFile("route.dpf")
]
if doMultiWire then
[
NeedFile(nlFileName, ".mw")
NeedFile(nlFileName, ".mh")
NeedFile(nlFileName, ".mhi")
]
if doPC then
[
NeedFile(nlFileName, ".apc")
]
if doResistances then
[
NeedFile(nlFileName, ".resist")
]
MapNamees(typeIcinst, NeedConnInstFiles)
FindOrMakeNeededFiles()
ErFile = GetFile(nlFileName,".re",charItem) //routing errors
PutTemplate(ErFile, "[0] = worst error severity*n")
ImplicitFile = GetFile(nlFileName,".inl", charItem) // implicit net list
PutTemplate(ImplicitFile, "; Implicitly generated wiring ...*n@")
CommentsFile = GetFile(nlFileName,".comments",charItem)
TruncateDiskStream(CommentsFile)
InitRandom()
]
and DefaultString(sp, s) be
[
if @sp ne empty then Free(SilZone, @sp)
@sp = Allocate(SilZone, (s>>str.length rshift 1)+1)
MoveBlock(@sp, s, (s>>str.length rshift 1)+1)
]
and AddDynamicEntry(p) be
[
epvec!epsize = p
epsize = epsize+1
]
and HowBig(od) be
[
let npThisOverlay = OverlayNpages(od)
if npThisOverlay gr npBiggestOverlay then
npBiggestOverlay = npThisOverlay
]
and NeedConnInstFiles(icinst) be
[
unless Icclass(icinst)>>icclass.isConnector do return
let filename = vec 20
ExpandTemplate(filename, "$S-$S.nl", nlFileName, FindNameesString(icinst))
NeedFile(filename)
]
and AddAttribute(attributeMask, first, last) be
[
test first le 255
ifso for char=first to last do charTab!char = charTab!char%attributeMask
ifnot for i=1 to first>>str.length do AddAttribute(attributeMask, first>>str.char↑i,
first>>str.char↑i)
]
and ReadNext(stream,string) = valof
[
let ch = $*s
if Endofs(stream) then resultis false
until (Endofs(stream)%(ch gr $*s))do ch = Gets(stream)
if ch le $*s then resultis false
string>>str.length = 1
string>>str.char↑1 = ch
[
if Endofs(stream) then break
ch = Gets(stream)
if ch le $*s then break
let sl = string>>str.length+1
string>>str.char↑sl = ch
string>>str.length = sl
] repeat
resultis true
]
and IsFunnyParameter(string) = valof
[
let lastSlashPos = 0
for i=1 to string>>str.length do
if string>>str.char↑i eq $/ then lastSlashPos = i
if lastSlashPos eq 0 then resultis false
string>>str.length = lastSlashPos-1
switchon string>>str.char↑(lastSlashPos+1) into
[
case $h:
case $H:
heuristicWork = CSN(string)
endcase
case $m:
case $M:
StandardMetric = selecton string>>str.char↑1 into
[
case $M:
case $m:ManhattanDistFn
case $E:
case $e:EuclideanDistFn
default:ManhattanDistFn
]
endcase
case $E:
case $e:
exhaustThresh = CSN(string)
endcase
case $L:
case $l:
DefaultString(lv boardLocation, string)
endcase
case $B:
case $b:
ReadBoardCode(string)
endcase
case $C:
case $c:
Correcting = true
DefaultString(lv wlOldFileName, string)
endcase
case $F:
case $f:
DefaultString(lv nlFileName, string)
endcase
case $I:
case $i:
DefaultString(lv board, string)
endcase
case $R:
case $r:
DefaultString(lv rev, string)
endcase
case $P:
case $p:
[
let file = OpenFile(string, ksTypeReadOnly, charItem, 0,
0, 0, SilZone)
let length = 0
until Endofs(file) do [ Gets(file); length = length+1]
pctext = Allocate(SilZone, (length rshift 1)+1)
pctext>>string.length = length
Resets(file)
length = 0
until Endofs(file) do
[
length = length+1
pctext>>string.char↑length = Gets(file)
]
Closes(file)
]
endcase
case $S:
case $s:
outLimit = CSN(string)
endcase
case $T:
case $t:
savedOutThreshold = CSN(string)
endcase
default:
]
resultis true
]
and CSN(string) = valof
[
let value = 0
for i=1 to string>>str.length do
[
let c = string>>str.char↑i
unless (charTab!c&digitMask)ne 0 do
[
CallSwat("*nIllegal number in command file.",
string)
finish
]
value = value*10+c-$0
]
resultis value
]
and NeedFile(fn, suffix, isInput, okToCreate; numargs na) be
[
DefaultArgs(lv na, -1, "", false, false)
let filename = vec 20
ExpandTemplate(filename, "$S$S", fn, suffix)
let fnwords = (filename>>str.length rshift 1)+1
let newkf = Allocate(SilZone, offset KF.string/16+fnwords)
MoveBlock(lv newkf>>KF.string, filename, fnwords)
newkf>>KF.input = isInput
newkf>>KF.oktocreate = na gr 3? okToCreate, not isInput
newkf>>KF.next = kf
kf = newkf
]
and FindOrMakeNeededFiles() be
[
let kfCount = 0
let kfIndex = kf
let kfRev = empty// reversed list
until kfIndex eq empty do
[
kfCount = kfCount+1
let kfTemp = kfIndex>>KF.next
kfIndex>>KF.next = kfRev
kfRev = kfIndex
kfIndex = kfTemp
]
kf = kfRev
let names = Allocate(SilZone, kfCount)
let kfCount = 0
let kfIndex = kf
until kfIndex eq empty do
[
names!kfCount = lv kfIndex>>KF.string
kfCount = kfCount+1
kfIndex = kfIndex>>KF.next
]
let dvs = Allocate(SilZone, kfCount*lDV)
Zero(dvs, kfCount*lDV)
let q = OpenFile(0,0,0,0,fpSysDir,0,SilZone)
if q eq 0 then CallSwat("Can’t open SysDir")
LookupEntries(q, names, dvs, kfCount, true)
Closes(q)
kfIndex = kf
kfCount = 0
until kfIndex eq empty do
[
test dvs!(kfCount*lDV) eq 0
ifnot
[
MoveBlock(lv kfIndex>>KF.fp,
lv dvs!(kfCount*lDV+offset DV.fp/16), lFP)
]
ifso
[
if not kfIndex>>KF.oktocreate then CallSwat("Can’t find input file ",
lv kfIndex>>KF.string)
let file = OpenFile(lv kfIndex>>KF.string,ksTypeReadWrite,
0,0,0,0,SilZone)
let cfa = vec lCFA
GetCompleteFa(file, cfa)
MoveBlock(lv kfIndex>>KF.fp, lv cfa>>CFA.fp, lFP)
Closes(file)
]
kfCount = kfCount+1
kfIndex = kfIndex>>KF.next
]
]
and AddSpace(stackNeeds) be
[
static [ malFormed = 0 ]
let Space = FixedLeft()
while Usc(Space, stackNeeds+20) gr 0 do
[
let grab = Space-stackNeeds
if Usc(grab, #77777) gr 0 then grab = #77777 //+ infinity
test SilZone eq 0
ifso SilZone = InitializeZone(GetFixed(grab), grab, SysErr, malFormed)
ifnot AddToZone(SilZone, GetFixed(grab), grab)
Space = FixedLeft()
]
]
and ReadTime(ps) be
[
let uv = vec 7
UNPACKDT(0, uv)
@ps = Allocate(SilZone, 12) // for date and time
CONVUDT(@ps, uv)
]
and InitRandom() be
[
randomTable = Allocate(objectZone, degree+1)
for i=0 to degree do randomTable!i = #101011
randomIndex = 0
randomTrailer = degree-midPower
for i=1 to 2000 do Random(1)
]