//RoutePC.bcpl

// Analysis module to produce printed circuit routing drive tapes for
// PRANCE of Automated Systems, Inc.

// last modified by McCreight, July 7, 1981 4:22 PM

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

manifest [ doingPC = 7 ]

static
[
doPC=false; PCPrototype = false; netHasEcl
]

let PC() be
[
BPFile = GetFile(nlFileName, ".apc")
let t1 = vec 20
let t2 = vec 50
let text = vec 50

// write a record of textual boiler plate at the beginning
t1>>string.length = 0
t2>>string.length =0
if board ne empty & rev ne empty then
ExpandTemplate(t1, "$S-APCRev-$S ", board, rev)
if pctext ne empty then
ExpandTemplate(t2, "// $S", pctext)
ExpandTemplate(text, "$S$S$S", t1, time, t2)
PutFixedAlpha(BPFile, text, 79)
Puts(BPFile, $*n)

if not PCPrototype then
[
twPartNo = 0
DoInSortOrder(typeNet, NameCompareFn, OutputPCNet)
MapNamees(typeIcinst, OutputUnwiredPins)
]
OtherPCHoles(PCPrototype, PrintPCSite)
TruncateDiskStream(BPFile)
Closes(BPFile)
]

and PutFixedAlpha(stream, s, fieldLen) be
[
let i=1
while i le fieldLen & i le s>>string.length do
[
let c = s>>string.char↑i
if c ge $a & c le $z then c = c+$A-$a
c = selecton c into
[
case $!: $|
default: c
]
Puts(stream, c)
i = i+1
]
while i le fieldLen do
[
Puts(stream, $*S)
i = i+1
]
]

and OutputPCNet(net) be
[
let netName = vec 30
test net>>net.isPartialNet
ifso
[
ExpandTemplate(netName, "$S$D", FindNameesString(net),
twPartNo)
twPartNo = twPartNo+1
]
ifnot netName = FindNameesString(net)
netHasEcl = false
let pin = net>>net.pinList
while @pin ne mark do
[
let pinNo,icinst = pin,nil
FindIcinst(lv icinst, lv pinNo)
let icclass = Icclass(icinst)
let pa = (icclass>>icclass.PinAttributes)(icinst, pinNo)
if pa<<pinattributes.isEcl then netHasEcl = true
pin = @pin
]
pin = net>>net.pinList
while @pin ne mark do
[
OutputPCPin(netName, pin, true)
pin = @pin
]
]

and OutputPCPin(netName, pin, reallyWire) be
[
let pinName = vec 20
let typeName = vec 40
let pinNo,icinst,x,y = pin,nil,nil,nil
FindIcinst(lv icinst, lv pinNo)
ExpandTemplate(pinName, "$D", pinNo)
let locName = FindNameesString(icinst)
BoardPinCoord(locName, icinst, pinNo, lv x, lv y)
ComputePCCoords(lv x, lv y, false)
let icclass = Icclass(icinst)
let pa = (icclass>>icclass.PinAttributes)(icinst, pinNo)
let icTypeName =
(icclass>>icclass.isTraceWired % icclass>>icclass.isConnector)? "",
FindTypeString(typeName, icinst>>icinst.ictype)
let family = reallyWire? (netHasEcl? $E, $N), $X
let func = (reallyWire & netHasEcl)?
(pa<<pinattributes.isOutput? $S,
(pa<<pinattributes.isTerminator? $T, $*S)), $*S
OutputPCData(netName, locName, pinName,
icTypeName, x, y, family, func)
]

and FindTypeString(s, t) = valof
[
let temps = FindNameesString(t)
let len = 0
while len ls temps>>string.length & temps>>string.char↑(len+1) ne $/ do
[
len = len+1
s>>string.char↑len = temps>>string.char↑len
]
s>>string.length = len
resultis s
]

and OutputPCData(netName, locName, pinName, typeName, x, y, family, func) be
[
WeAre(doingPC)
PutFixedAlpha(BPFile, netName, 16)
Puts(BPFile, $*s)
PutFixedAlpha(BPFile, locName, 8)
Puts(BPFile, $*s)
PutFixedAlpha(BPFile, pinName, 3)
Puts(BPFile, $*s)
PutFixedAlpha(BPFile,typeName, 10)
PutTemplate(BPFile, "$6D$6D",x,y)
PutFixedAlpha(BPFile, "", 18)
Puts(BPFile,family)
Puts(BPFile,func)
PutFixedAlpha(BPFile, "", 7)
Puts(BPFile, $*n)
]

and OutputUnwiredPins(icinst) be
[
let icclass = Icclass(icinst)
let boardLoc = FindNameesString(icinst)
unless icclass>>icclass.isTraceWired do
[
let x,y = nil,nil
for i=1 to Npins(icinst) do
[
if icinst>>icinst.pin↑i eq empty &
BoardPinCoord(boardLoc, icclass, i, lv x, lv y) then
OutputPCPin("###UNUSED", lv icinst>>icinst.pin↑i, false)
]
]
]

and PrintPCSite(x, y, mustDrill, sigName, isMils, typeName, locName, pinName; numargs na) be
[

DefaultArgs(lv na, 2, false, "VIASITE", false, "", "", "", "")

let s = vec 40
ExpandTemplate(s, "###$S", sigName)
let t = vec 40
CopyString(typeName, t)
let l = vec 40
CopyString(locName, l)
let p = vec 40
CopyString(pinName, p)
let icclass, pinNo = empty, 0
let index = FindIndexFromCoord(x, y, lv icclass, lv pinNo)
if icclass ne empty & icclass>>icclass.isTraceWired then
[
ExpandTemplate(s, "###$S", FindNameesString(icclass))
if p>>string.length eq 0 then ExpandTemplate(p, "$D", pinNo)
]
ComputePCCoords(lv x, lv y, isMils)
OutputPCData(s, l, p, t, x, y, (mustDrill? $X, $V), $*S)
]

and PCPanic(x, y, z) be CallSwat("No board-specific PC code")