//RouteMultiWire.bcpl

// Analysis module to produce Multi-Wire drive tapes

// last modified by McCreight, June 25, 1981 11:06 AM

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

static
[
doMultiWire=false
wiredPins; holesFile; holeSizes; holePlating; holeNet; currentHoleType
allPinsAreHoles = false; encodeTWNets = false
lastHoleType; pinsThisLine
]

manifest [ plated = true; unplated = not plated ]

let MultiWire() be
[
BPFile = GetFile(nlFileName, ".mw")
DoInSortOrder(typeNet, NetNumCompareFn, OutputMWNet)
FinishMWFile(BPFile)

let pinVecLen = (FindIndexFromCoord(-1,-1)+15)/16
wiredPins = Allocate(SilZone, pinVecLen)
Zero(wiredPins, pinVecLen)

MapNamees(typeIcinst, MarkUsedPins)

holesFile = GetFile(nlFileName, ".mh")
let hs = vec 20; holeSizes = hs
let hp = vec 20; holePlating = hp
let hn = vec 20; holeNet = hn
currentHoleType = 0
lastHoleType = 0
pinsThisLine = 0
DescribeHoles(PrintAHole)
FinishLine(holesFile, pinsThisLine)
FinishMWFile(holesFile)
Free(SilZone, wiredPins)

let indexFile = GetFile(nlFileName, ".mhi")
let netLine = vec 30
for i=1 to lastHoleType do
PutTemplate(indexFile, "*nHole type $D: $D mils, $Splated$S",
i, holeSizes!i, (holePlating!i? "","un"),
(holeNet!i eq empty? "", ExpandTemplate(netLine, ", net = $S",
FindNameesString(holeNet!i))))
PutTemplate(indexFile, "*n")
TruncateDiskStream(indexFile)
Closes(indexFile)
]

and NetNumCompareFn(n1, n2) = n2>>net.netnum-n1>>net.netnum

and OutputMWNet(net) be
[
static [ MWNetNum = 0 ]
let nodecount = 0
let pin = net>>net.pinList
while @pin ne mark do
[
pin = @pin
nodecount = nodecount+1
]

if nodecount ls 2 then return
MWNetNum = MWNetNum+1
PutTemplate(BPFile, "$5D", MWNetNum)
let pinsThisLine = 0
let pin = net>>net.pinList
while @pin ne mark do
[
let x,y = nil,nil
GetPinCoord(0, pin, lv x, lv y)
if pinsThisLine ge 5 then
[
FinishLine(BPFile, pinsThisLine)
PutTemplate(BPFile, "$5D", MWNetNum) // we re-iterate the net #
pinsThisLine = 0
]
ComputeMWCoords(lv x, lv y, false)
PutTemplate(BPFile, "$S $5D $5D", (pinsThisLine gr 0? " ",""),
x, y)
pinsThisLine = pinsThisLine+1
pin = @pin
]
FinishLine(BPFile, pinsThisLine)
]

and FinishLine(file, pins) be
[
// fill out an 80-character record, including a final CR
for col=6+12*pins+(pins gr 0? 3, 0) to 79 do Puts(file, $*s)
Puts(file, $*n)
]

and FinishMWFile(file) be
[
PutTemplate(file, "$5D*n", -1)
FinishLine(file, 0)
TruncateDiskStream(file)
Closes(file)
]

and MarkUsedPins(icinst) be
[
let icclass = Icclass(icinst)
for i=1 to Npins(icinst) do if icinst>>icinst.pin↑i ne empty %
(not icclass>>icclass.isTraceWired) then
[
let x,y = nil,nil
GetPinCoord(icinst, i, lv x, lv y)
let index = FindIndexFromCoord(x, y)
SetBit(wiredPins, index, 1)
]
]

and PrintAHole(x, y, holeSize, isPlated, isMils, alwaysDrill; numargs na) be
[
static [ allPinsAreHoles = false; encodeTWNets = false ]

DefaultArgs(lv na, 3, true, false, false, false)

let icclass, pinNo = empty, 0
let index = FindIndexFromCoord(x, y, lv icclass, lv pinNo)
if allPinsAreHoles % alwaysDrill % index eq 0 %
GetBit(wiredPins, index) ne 0 then
[
ComputeMWCoords(lv x, lv y, isMils)

let i=1
while i le lastHoleType &
(holeSize ne holeSizes!i % isPlated ne holePlating!i %
(encodeTWNets & (icclass ne holeNet!i))) do
i=i+1
if i gr lastHoleType then
[
lastHoleType = i
holeSizes!i = holeSize
holePlating!i = isPlated
holeNet!i = encodeTWNets? icclass, empty
]

if i ne currentHoleType % pinsThisLine ge 5 then
[
if pinsThisLine gr 0 then
FinishLine(holesFile, pinsThisLine)
PutTemplate(holesFile, "$5D", i)
currentHoleType = i
pinsThisLine = 0
]

PutTemplate(holesFile, "$S $5D $5D", (pinsThisLine gr 0? " ",""),
x, y)
pinsThisLine = pinsThisLine+1
]
]

and MultiWirePanic(x, y, z) be CallSwat("No board-specific multi-wire code")