//routeboard.bcpl

// Setup for board-specific data structures.
// last modified by E. McCreight, March 28, 1980 5:11 PM

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

external [ ReadBlock ]

static
[
checkBoard = false
maxICs

DeclareInitialNets // to be filled in later with the real thing
ZeroTablePoint
LevelTransform
FindIndexFromCoord
FindCoordFromString
ComputeMWCoords
DescribeHoles
AddDecouplingCaps
]

let SetupBoard(filename) be
[
let file = OpenFile(filename, ksTypeReadWrite, wordItem, 0,
0, 0, SilZone)

DeclareAvailableNames()
ReadBoardCode(file); Closes(file)
DefineNeededNames()
DeclareInitialNets(BuildTWNet, BuildTerminatorClass, BuildConnectorClass,
SetupICclass)

if checkBoard then
[
let npins = FindIndexFromCoord(-1,-1)
let pins = Allocate(SilZone, (npins+15/16))
Zero(pins, (npins+15)/16)
for x=0 to 700 do for y = 0 to 700 do
[
let fclass,fpin = 0,0
let index = FindIndexFromCoord(x, y, lv fclass, lv fpin)
if index ne 0 then
[
if GetBit(pins, index) ne 0 then
[
for lx = 0 to 700 do for ly = 0 to 700 do
if FindIndexFromCoord(lx, ly) eq index then
[
CallSmartSwat("Duplicate pin index $D, pins are {$D,$D} and {$D,$D}.",
index, lx, ly, x, y)
break
]
]
SetBit(pins, index, 1)
if fclass ne 0 then
[
let px, py = 0,0
if (fclass>>icclass.PinOffset)(fclass, fpin, lv px, lv py) ne absolute % x ne px % y ne py do
CallSmartSwat("Board routines disagree on $S$D.",
FindNameesString(fclass),fpin)
]
]
]
Free(SilZone, pins)
]
]

and DeclareAvailableNames() be
[
DeclareName("DefaultArgs", lv DefaultArgs)
DeclareName("Usc", lv Usc)
DeclareName("OffsetLegal", lv OffsetLegal)
DeclareName("CallSwat", lv CallSwat)
DeclareName("Warning", lv Warning)
DeclareName("Serious", lv Serious)
DeclareName("Disaster", lv Disaster)
DeclareName("DefineNamee", lv DefineNamee)
DeclareName("MustFindNamee", lv MustFindNamee)
DeclareName("TryFindingNamee", lv TryFindingNamee)
DeclareName("ExpandTemplate", lv ExpandTemplate)
DeclareName("Allocate", lv Allocate)
DeclareName("Free", lv Free)
DeclareName("SilZone", lv SilZone)
DeclareName("PutTemplate", lv PutTemplate)
DeclareName("FindNameesString", lv FindNameesString)
DeclareName("ImplicitFile", lv ImplicitFile)
DeclareName("Icclass", lv Icclass)
DeclareName("Npins", lv Npins)
DeclareName("BoardPinCoord", lv BoardPinCoord)
DeclareName("TryInserting", lv TryInserting)
DeclareName("InsertDeviceIfPossible", lv InsertDeviceIfPossible)
DeclareName("DIP3Wide", lv DIP3Wide)
DeclareName("SetupICclass", lv SetupICclass)
DeclareName("NullAttributes", lv NullAttributes)

ComputeMWCoords = MultiWirePanic
// copy values
DeclareName("ComputeMWCoords", lv ComputeMWCoords)
DescribeHoles = MultiWirePanic
DeclareName("DescribeHoles", lv DescribeHoles)

AddDecouplingCaps = NoAddedCaps
DeclareName("AddDecouplingCaps", lv AddDecouplingCaps)

DeclareName("maxICs", lv maxICs, true) // board code must define
DeclareName("DeclareInitialNets", lv DeclareInitialNets, true)
DeclareName("ZeroTablePoint", lv ZeroTablePoint, true)
DeclareName("LevelTransform", lv LevelTransform, true)
DeclareName("FindIndexFromCoord", lv FindIndexFromCoord, true)
DeclareName("FindCoordFromString", lv FindCoordFromString, true)
]

and DefineNeededNames() be
[
let CheckDefined(pgmsymbol) be
[
unless pgmsymbol>>pgmsymbol.staticHasValue do
CallSmartSwat("Board code didn’t define the static $S",
FindNameesString(pgmsymbol))
]

MapNamees(typePgmsymbol, CheckDefined)
]

and ReadBoardCode(file) be
[
structure desc:
[
blank bit 9
type bit 2
pgz bit
local bit 4
]

manifest [ isstatic = 1; isprocedure = 2; islabel = 3 ]

let biv = DeclareName("boardInterfaceVersion", 0)

until Endofs(file) do
[
let beginFilePos = FilePos(file)
Gets(file) // version
let length = Gets(file)

let namepos = GetPair(file)
if namepos ne #17 then CallSwat("Strange looking .br file")

let labelpos = GetPair(file)
let codepos = GetPair(file)
let chainpos = GetPair(file)
let zchainpos = GetPair(file)

SetFilePos(file, 0, 2*codepos+beginFilePos)
let codesize = Gets(file)
let code = Allocate(SilZone, codesize)
ReadBlock(file, code, codesize)

SetFilePos(file, 0, 2*namepos+beginFilePos)
let nnames = Gets(file)
let namevec = Allocate(SilZone, nnames+1)
for i=1 to nnames do
[
let descriptor = Gets(file)
let value = Gets(file)
let name = vec 20
name!0 = Gets(file)
for i=1 to name>>str.length/2 do name!i = Gets(file)

let pgmsymbol = DefineNamee(name, typePgmsymbol)
if descriptor<<desc.type ne 0 then
[
@(StaticLoc(pgmsymbol)) = (descriptor<<desc.type ge isprocedure? code, 0)+value
pgmsymbol>>pgmsymbol.staticHasValue = true
if pgmsymbol eq biv then if value ne interfaceVersion then
CallSwat("Obsolete board characterization code, recompile")
]
namevec!i = StaticLoc(pgmsymbol)
]

SetFilePos(file, 0, 2*labelpos+beginFilePos)
let nlabels = Gets(file)
for i=1 to nlabels do
[
let labelNo = Gets(file)
@(namevec!labelNo) = code+Gets(file)
]

SetFilePos(file, 0, 2*chainpos+beginFilePos)
nnames = Gets(file)
for i=1 to nnames do
[
let chainlink = Gets(file)
until chainlink eq 0 do
[
let newchainlink = code!chainlink
code!chainlink = namevec!i
chainlink = newchainlink
]
]

Free(SilZone, namevec)
SetFilePos(file, 0, 2*length+beginFilePos)
]
]

and GetPair(file) = valof
[
if Gets(file) ne 0 then CallSwat("Fishy .BR file format")
resultis Gets(file)
]

and DeclareName(name, staticAddress, valueUndefined; numargs na) = valof
[
DefaultArgs(lv na, -2, false)
let pgmsymbol = DefineNamee(name, -typePgmsymbol)
pgmsymbol>>pgmsymbol.valIsPtr = true
pgmsymbol>>pgmsymbol.staticHasValue = not valueUndefined
pgmsymbol>>pgmsymbol.value = staticAddress
resultis pgmsymbol
]

and StaticLoc(pgmsymbol) = pgmsymbol>>pgmsymbol.valIsPtr?
pgmsymbol>>pgmsymbol.value, lv (pgmsymbol>>pgmsymbol.value)

and BuildTWNet(str, npins, PinOffset) be
[
DefineNamee(str, typeNet, NewNet)>>net.isTraceWired = true
let TWclass = SetupICclass(str, isTraceWired, PinOffset, NullAttributes, Noop, npins)
let cutVecLen = npins/16+1
let cutVec = Allocate(SilZone, cutVecLen)
Zero(cutVec, cutVecLen)
TWclass>>icclass.cutPins = cutVec
cutVec = Allocate(SilZone, cutVecLen)
Zero(cutVec, cutVecLen)
TWclass>>icclass.oldCutPins = cutVec

if Correcting then DefineNamee(str, -typeOldinst)>>oldinst.ictype = TWclass

if checkBoard then for pin=1 to npins do
[
let x,y = nil,nil
if (TWclass>>icclass.PinOffset)(TWclass, pin, lv x, lv y) ne absolute then loop
let fclass,fpin = 0,0
let index = FindIndexFromCoord(x, y, lv fclass, lv fpin)
if (index ne 0)&(TWclass eq fclass)&(pin eq fpin) then loop
CallSmartSwat("*nBoard routines disagree on $S$D.",
FindNameesString(TWclass),pin)
]
]

and BuildTerminatorClass(typeStr, npins, classStr, nPotentialPins, LocatePotentialPin, likeClassStr) be
[
let likeClass = MustFindNamee(likeClassStr, typeIcclass)
let termClass = SetupICclass(classStr, likeClass>>icclass.classattributes,
likeClass>>icclass.PinOffset, likeClass>>icclass.PinAttributes,
likeClass>>icclass.ImplicitICNets, likeClass>>icclass.npins)
termClass>>icclass.nPotentialPins = nPotentialPins
termClass>>icclass.LocatePotentialPin = LocatePotentialPin
let ictype = DefineNamee(typeStr, -typeIctype)
ictype>>ictype.npins = npins
ictype>>ictype.icclass = termClass
]

and BuildConnectorClass(str, npins, PinOffset) be
[
let classStr = vec 20
let icclass = SetupICclass(ExpandTemplate(classStr, "Conn-$S", str),
isConnector, PinOffset, NullAttributes, Noop, npins)
DefineNamee(str, -typeIcinst, Noop, npins-1)>>icinst.ictype = icclass
if Correcting then DefineNamee(str, -typeOldinst)>>oldinst.ictype = icclass
]

and SetupICclasses() be
[
SetupICclass("E", printUsedList, DIP3Wide, Ecl2GAttributes, Ecl2Gnd, 16)
SetupICclass("E1G", printUsedList, DIP3Wide, Ecl1GAttributes, Ecl1Gnd, 16)
SetupICclass("E3G", printUsedList, DIP3Wide, Ecl3GAttributes, Ecl3Gnd, 16)
SetupICclass("TEC", printUsedList, DIP3Wide, TECAttributes, EclConverter, 16)
SetupICclass("ETC", printUsedList, DIP3Wide, ETCAttributes, EclConverter, 16)
SetupICclass("E6W", printUsedList, DIP6Wide, Ecl2GAttributes, Ecl2Gnd, 24)
SetupICclass("F100K", printUsedList, DIP4Wide, F100KAttributes, F100K, 24)
SetupICclass("EQP",printUsedList, QITPlat, Ecl4GAttributes, Ecl4Gnd, 26)
SetupICclass("EQPB",printUsedList, QITPlat, Ecl4GAttributes, Ecl4Gnd, 26)

SetupICclass("T", printUsedList, SIP, EclTermAttributes, EclTerm, 8)

SetupICclass("F4W", printUsedList, DIP4Wide, NullAttributes, FTTL, 22)
SetupICclass("N", printUsedList, DIP3Wide, NullAttributes, TTL, 16)
SetupICclass("S", printUsedList, DIP3Wide, NullAttributes, TTL, 16)
SetupICclass("L", printUsedList, DIP3Wide, NullAttributes, TTL, 16)
SetupICclass("N6W", printUsedList, DIP6Wide, NullAttributes, TTL, 16)
SetupICclass("S6W", printUsedList, DIP6Wide, NullAttributes, TTL, 16)
SetupICclass("L6W", printUsedList, DIP6Wide, NullAttributes, TTL, 16)

SetupICclass("J", printUsedList, DIP3Wide, NullAttributes, Noop, 16)
SetupICclass("J1W", printUsedList, SIP, NullAttributes, Noop, 8)
SetupICclass("J4W", printUsedList, DIP4Wide, NullAttributes, Noop, 22)
SetupICclass("J6W", printUsedList, DIP6Wide, NullAttributes, Noop, 24)
SetupICclass("J9W", printUsedList, DIP9Wide, NullAttributes, Noop, 32)

SetupICclass("M", printUsedList, DIP3Wide, NullAttributes,
DynamicRam3Supply, 16)
SetupICclass("LargeM", printUsedList, DIP3Wide, NullAttributes,
DynamicRam1Supply, 16)
]

and SetupICclass(str, attributes, PinOffset, PinAttributes, ImplicitICNets, npins; numargs na) = valof
[
DefaultArgs(lv na, -1, 0, CallSwat, NullAttributes, Noop, 0)
let icclass = DefineNamee(str, -typeIcclass) // must be new
icclass>>icclass.classattributes = attributes
icclass>>icclass.PinOffset = PinOffset
icclass>>icclass.PinAttributes = PinAttributes
icclass>>icclass.ImplicitICNets = ImplicitICNets
icclass>>icclass.npins = npins
icclass>>icclass.nPotentialPins = -1 // not a terminator class
resultis icclass
]