//route.bcpl

// Main driver module

// last modified by Taft, September 22, 1979 7:06 PM

get "sysdefs.d"
get "streams.d"
get "route.defs"

external
[
Ws
Junta
CounterJunta

UserReadOverlay
LockPendingCode
ReleaseOverlay
ReadOverlay
OverlayFirstPn
OverlayNpages

initCodeEnd
overlayCore
dsp
]

static
[
worstErrorLevel = noError
inputKf
routeVersion
]

let Main(blv,params,cfa) be
[
routeVersion = "Route - September 22, 1979"
PutTemplate(dsp, "*n*n*n*n*n$S", routeVersion)
OnceOnlyInitCode(blv,params,cfa)
Junta(levStreams,DoRoute)
]

and SayGoodbye() be
[
PutTemplate(dsp, "$S ... finished", routeVersion)
finish
]

and UserReadOverlay(od) = valof
[
static [ oldOverlay = empty ]

if oldOverlay ne empty then
[
LockPendingCode()
test ReleaseOverlay(oldOverlay, false)
ifnot CallSwat("Two overlays contending for overlay space")
ifso
[
ReleaseOverlay(oldOverlay, true)
oldOverlay = empty
]
]
ReadOverlay(OverlayFirstPn(od), overlayCore, OverlayNpages(od))
oldOverlay = od
resultis overlayCore
]

and DoRoute(arg) be
[
static [ stackNeeds = 1800 ]

AddSpace(stackNeeds)
// leave for stack
AddToZone(SilZone, OnceOnlyInitCode, initCodeEnd-OnceOnlyInitCode+1)

let fileZone = InitializeZone(Allocate(SilZone, 400), 400)

//now do the real work on all the files
inputKf = kf
until inputKf eq empty do
[
if inputKf>>KF.input then
[
let File = GetFile(lv inputKf>>KF.string, 0, 0, fileZone) //open the input file
Remark("*nReading $S", lv inputKf>>KF.string)
FileIn(File)
Closes(File)
]
inputKf = inputKf>>KF.next
]

Free(SilZone, fileZone)

Puts(ImplicitFile, $*n)
TruncateDiskStream(ImplicitFile)
Resets(ImplicitFile)
Remark("*nReading $S.inl, the implicit power wiring", nlFileName)
FileIn(ImplicitFile)
Closes(CommentsFile)
CommentsFile = empty

let oldImplicitPos = vec 2
FilePos(ImplicitFile, oldImplicitPos)
TruncateDiskStream(ImplicitFile)

if Correcting then
[
OldWlFile = GetFile(wlOldFileName,"",charItem)//For comparison
let oldBoardType = vec 20
let nchars = 0
let char = Gets(OldWlFile)
while char ne $*n do
[
nchars = nchars+1
oldBoardType>>str.char↑nchars = char
char = Gets(OldWlFile)
]
oldBoardType>>str.length = nchars
if StComp(oldBoardType, ZeroTablePoint(0)) ne 0 then
Disaster("Board type differs from original")
CorrelateOldAndNew()
Closes(OldWlFile)
OldWlFile = empty
]

unless noroute do
[
MapNamees(typeIcclass, LocateAvailTerms)
MapNamees(typeNet, RouteEarlyNets)
MapNamees(typeNet, AddEclTerminators)
MapNamees(typeNet, RouteNetIfExternal)
MapNamees(typeNet, AddEclTerminators)
]

let capsAdded = false
unless noroute do
[
MapNamees(typeNet, RouteNet)
MapNamees(typeNet, AddEclTerminators) // may add new stuff
]

until noroute do
[
let newImplicitPos = vec 2
FilePos(ImplicitFile, newImplicitPos)
if oldImplicitPos!0 eq newImplicitPos!0 &
oldImplicitPos!1 eq newImplicitPos!1 then test capsAdded
ifso break
ifnot [ AddDecouplingCaps(); capsAdded=true; loop ]

SetFilePos(ImplicitFile, oldImplicitPos) // More implicit stuff
ReadAllNetLines(ImplicitFile)
FilePos(ImplicitFile, oldImplicitPos)
TruncateDiskStream(ImplicitFile)

MapNamees(typeNet, RouteNet)
MapNamees(typeNet, AddEclTerminators) // may add new stuff
]
Closes(ImplicitFile)
ImplicitFile = empty

MapNamees(typeIcclass, FreeTermStorage) // no more terminators

if coveredAreas ne 0 then Free(SilZone, coveredAreas) // no more IC’s to insert
coveredAreas = 0

MapNamees(typeIcinst, CheckUnusedPins)

MapNamees(typeNet, AssignTWNet)

if Correcting then
CorrelateRemaining()

unless noroute do MapNamees(typeNet, RouteNet) // trace-wired stuff

unless noroute do
[
MapNamees(typeNet, ComputeLengths)
DoInSortOrder(typeNet, NLCompFn, AssignNetNumber)
]

OutFile = GetFile(wlNewFileName,"",charItem) //wire list
MakeOutputFile(OutFile, false)
Puts(OutFile, $*n); TruncateDiskStream(OutFile); Closes(OutFile)

if Correcting then
[
ADFile = GetFile(nlFileName,".ad",charItem) // add/delete list
MakeOutputFile(ADFile, true)
Puts(ADFile, $*n); TruncateDiskStream(ADFile);Closes(ADFile)
]

OutputBPFiles()


Puts(ErFile, $*n); TruncateDiskStream(ErFile); Resets(ErFile)
Gets(ErFile); Puts(ErFile, $0+worstErrorLevel); Closes(ErFile)
CounterJunta(SayGoodbye)
]

and GetFile(fname,ext,byteword,zone; numargs na) = valof //1 for bytes,0 for words
[
DefaultArgs(lv na, -1, "", charItem, SilZone)
let v = vec 128
ExpandTemplate(v, "$S$S", fname, ext) //add the extension
let kfIndex = kf
while kfIndex ne empty do
[
let d = StComp(v, lv kfIndex>>KF.string)
if d gr 1 % d ls -1 then
[
kfIndex = kfIndex>>KF.next
loop
]
let file = CreateDiskStream(lv kfIndex>>KF.fp, ksTypeReadWrite,
byteword, 0, 0, zone)
if file eq 0 then CallSwat("Can’t open file ", lv kfIndex>>KF.string)
resultis file
]
CallSwat("Unanticipated file: ", v)
]

and WeAre(doingWhat) be
[
static [ lastThing=0; lastX=0; lastY=0 ]
if doingWhat ne lastThing then // change cursor
[
manifest [ A=1; B=2; C=4; D=#10; E=#20; F=#40; G=#100 ]
let segments =
table
[
A+B+C+D+E+F// 0
B+C
// 1
A+B+G+E+D
// 2
A+B+G+C+D
// 3
F+G+B+C // 4
A+F+G+C+D
// 5
A+F+E+D+C+G
// 6
A+B+C
// 7
A+B+C+D+E+F+G // 8
A+F+G+B+C
// 9
]!doingWhat

@#431 = (segments&A) ne 0? #77000, 0
for i=1 to 6 do @(#431+i) =
((segments&F) ne 0? #100000, 0)+((segments&B) ne 0? #400, 0)
@(#431+7) = (segments&G) ne 0? #77000, 0
for i=8 to 13 do @(#431+i) =
((segments&E) ne 0? #100000, 0)+((segments&C) ne 0? #400, 0)
@(#431+14) = (segments&D) ne 0? #77000, 0
@(#431+15) = 0

lastThing = doingWhat
]
lastX = lastX+4
if lastX gr 400 then
[
lastX = 0
lastY = lastY+16
if lastY gr 600 then lastY = 0
]
@#426 = lastX+100
@#427 = lastY+100
]