//routepclb1.bcpl

// Board-specific Route routines for the PC version of the
// Dorado Main Logic Board

// part 1 of 3

//
last modified by D. Rumph, October 30, 1984 5:13 PM
//
to add knowledge of ICClass E4W
// last modified by E. McCreight, July 7, 1981 4:20 PM
//
to shorten bypass cap names
// modified by E. McCreight, July 7, 1981 2:46 PM
//
to correct position of GND pins at connectors to 50-mil ctrs
// modified by E. McCreight, June 24, 1981 5:45 PM
//
to move the line of holes under the DIP patterns, and insert
//
all bypass caps that fit

// Some general comments:

//
A socket position is made up of a lower-case letter followed by a
//
number, like a13 or h41. The letter designates the column, or the
//
x or first co-ordinate. Increasing letters correspond to increasing x values.
//
The number in a socket position designates the row, or y, or second
//
co-ordinate. Increasing numbers correspond to increasing y values.

//
In standard orientation the board has the component (non-wiring) side
//
up, and the connector cutouts to the left. Socket a01 is in the top left,
//
l01 in the top right, a24 in the bottom left, and l24 in the bottom right.
//
The x co-ordinate increases to the right, and the y co-ordinate increases
//
downward. In standard orientation pin 1 of each socket is the top right
//
pin of the socket. The pin numbering goes leftward, then down, then
//
rightward.

//
With certain exceptions, a given functionally equivalent group of pins
//
is ordered first downward and then rightward. For example, if we had
//
GND pins of a certain kind at {x0,y0}, {x1,y1}, {x1,y0}, and {x0,y1},
//
where x0<x1 and y0<y1, then they would appear in the GND pseudo-
//
net in the following order:
//
...{x0,y0}...{x0,y1}...{x1,y0}...{x1,y1}...

//
This means that the pseudo-net pin number is usually computed as
//
(x (horizontal) repeat)*(pinsPerColumn)+(y (vertical) repeat)+firstPinNo

//
Similarly the horizontal and vertical repeats are usually computed as
//
column = xRepeat = (pseudo-net pin number - firstPinNo)/pinsPerColumn
//
row = yRepeat = (pseudo-net pin number - firstPinNo) rem pinsPerColumn

get "route.defs"

external [ Pin1of16 ]

manifest
[
repeatRows = 12
repeatCols = 6
fullRepeatCols = 4
repeats = repeatRows*repeatCols
fullRepeats = repeatRows*fullRepeatCols
rowOffset = 16
leftColsOffset = 0
rightColsOffset = 246
rowHeight = 42
fullColWidth = 112
patternGrounds = 3*repeats+6*fullRepeats
Sockets16pin = 6*fullRepeats
Sockets24pin = 2*fullRepeats
Sockets50pin = fullRepeats
SocketsSip = 3*fullRepeats
]

static
[
maxICs = 820
boardInterfaceVersion = interfaceVersion
VCCCap
VCC2Cap
VEECap
VTTCap
]

let DeclareInitialNets(BuildTWNet, BuildTermNet, BuildConnector) be
[
BuildConnector("E", 189, EPinPos)
BuildConnector("C", 189, CPinPos)
BuildTWNet("GND", 6*fullRepeats+3*repeats+2*92, GNDPinPos)
BuildTWNet("VEE", 4*fullRepeats+2*repeats, VEEPinPos)
BuildTWNet("VTT", 3*fullRepeats, VTTPinPos)
BuildTWNet("VCC", repeats, VCCPinPos)
BuildTWNet("VDD", repeats, VDDPinPos)
VCCCap = DefineBypassType("VCCBypass", VCCBypassVoltages)
VCC2Cap = DefineBypassType("VCC2Bypass", VCC2BypassVoltages)
VEECap = DefineBypassType("VEEBypass", VEEBypassVoltages)
VTTCap = DefineBypassType("VTTBypass", VTTBypassVoltages)
BuildTermNet("Term100/8/Term100", 8, "Term100", 1008, AutoTermPinPos,"T")
let c = TryFindingNamee("F100K", typeIcclass)
if c ne empty then c>>icclass.PinOffset = DIP45Wide
c = TryFindingNamee("E4W", typeIcclass)
if c ne empty then c>>icclass.PinOffset = DIP45Wide
]

and DIP45Wide(icinst, pinNo, pv, ph) = valof
[
let result = DIP3Wide(icinst, pinNo, pv, ph)
if @ph ne 0 then @ph = @ph+6
resultis result
]

and ZeroTablePoint(point) = selecton point into
[
case 0: "L" // board type
case 1: "C188"
case 2: "E6"
case 3: "E187"
case 4: "C5"
default: empty
]

and LevelTransform(level, x, y, px, py, pName, pPullComponents, pWire; numargs na) = valof
[
DefaultArgs(lv na, -1, 0, 0, lv na, lv na, lv na, lv na, lv na)
switchon level into
[
case TopLevel:
@px = x
@py = 524-y
@pName = "Component side"
@pPullComponents = true
@pWire = false
resultis true

case BottomLevel:
@px = x
@py = y
@pName = "Wiring side"
@pPullComponents = false
@pWire = true
resultis true

default: resultis false
]
]

and DefineBypassType(class, InitialWiring) = valof
[
SetupICclass(class, printUsedList, DIP3Wide, NullAttributes, InitialWiring, 2)
let type = vec 50
ExpandTemplate(type, "$S/2/$S", class, class)
let ictype = DefineNamee(type, typeIctype)
ictype>>ictype.icclass = MustFindNamee(class, typeIcclass)
ictype>>ictype.npins = 2
resultis ictype
]

and VCCBypassVoltages(icinst) be
[
let str = FindNameesString(icinst)
PutTemplate(ImplicitFile, "*nVCC: $S.1p*nGND: $S.2p", str, str)
]

and VCC2BypassVoltages(icinst) be
[
let str = FindNameesString(icinst)
PutTemplate(ImplicitFile, "*nGND: $S.1p*nVCC: $S.2p", str, str)
]

and VEEBypassVoltages(icinst) be
[
let str = FindNameesString(icinst)
PutTemplate(ImplicitFile, "*nVEE: $S.1p*nGND: $S.2p", str, str)
]

and VTTBypassVoltages(icinst) be
[
let str = FindNameesString(icinst)
PutTemplate(ImplicitFile, "*nGND: $S.1p*nVTT: $S.2p", str, str)
]

and AddDecouplingCaps() be
[
for row = 1 to 23 by 2 do
[
for col = $a to $g by ($g-$a) do
[
AddCap(VCCCap, "9", col, row)
AddCap(VEECap, "8", col, row)
AddCap(VCC2Cap, "9", col, row+1)
AddCap(VEECap, "8", col, row+1)
]
for col = $c to $l by ($f-$c) do
[
AddCap(VCCCap, "-1", col, row)
AddCap(VEECap, "-2", col, row)
for subcol = -2 to -1 do
AddCap(VTTCap, "-1←3", col+subcol, row)
AddCap(VCC2Cap, "-1", col, row+1)
AddCap(VEECap, "-2", col, row+1)
]
]
]

and AddCap(capType, offsetStr, col, row) be
[
let s = vec 20
ExpandTemplate(s, "#$S$C$2F0D", offsetStr, col, row)
InsertDeviceIfPossible(s, capType,true) // suppress warnings
]

and EPinPos(icinst, pin, px, py) = valof
[
if (pin ls 5) % (pin gr 188) then resultis illegal
@py = 524
let pg = (pin-1) rem 4
if (pg eq 0)%(pg eq 3) then resultis illegal
let xCol = (pin-5)/2
@px = 22+4*xCol+2*(xCol/2)
resultis absolute
]

and CPinPos(icinst, pin, px, py) = valof
[
if (pin ls 5) % (pin gr 188) then resultis illegal
@py = 0
let pg = (pin-1) rem 4
if (pg eq 1)%(pg eq 2) then resultis illegal
let xCol = (188-pin)/2
@px = 22+4*xCol+2*(xCol/2)
resultis absolute
]

and GNDPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = noDisconnect+noReconnect+BottomLevel
if pin le 0 then resultis illegal
if pin le patternGrounds then
[
Repeat(lv pin, 3, 6, px, py)
let xtable = table [ 0;0;4;40;40;72;76;76;108 ]
@px = @px+xtable!pin
let ytable = table [ 12;24;36;0;12;12;0;12;36 ]
@py = @py+ytable!pin
resultis absolute
]
pin = pin-patternGrounds
if pin le 2*92 then
[
pin = pin-1
@py = pin ls 92? 0+4, 524-4
let seq = pin rem 92
@px = 22+4*seq+2*(seq/2)
resultis absolute
]
resultis illegal
]

and VEEPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = noDisconnect+noReconnect+BottomLevel
if pin le 0 then resultis illegal
if pin le 4*fullRepeats+2*repeats then
[
Repeat(lv pin, 2, 4, px, py)
let xtable = table [ 4;44;80 ]
@px = @px+xtable!(pin/2)
@py = @py+24*(pin rem 2)
resultis absolute
]
resultis illegal
]

and VTTPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = noDisconnect+noReconnect+BottomLevel
if pin le 0 then resultis illegal
if pin le 3*fullRepeats then
[
Repeat(lv pin, 0, 3, px, py)
let xtable = table [ 40;76;108 ]
@px = @px+xtable!pin
let ytable = table [ 24;24;18 ]
@py = @py+ytable!pin
resultis absolute
]
resultis illegal
]

and VDDPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = noDisconnect+noReconnect+BottomLevel
if pin le 0 then resultis illegal
if pin le repeats then
[
Repeat(lv pin, 1, 0, px, py)
@px = @px+4
@py = @py+18
resultis absolute
]
resultis illegal
]

and VCCPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = noDisconnect+noReconnect+BottomLevel
if pin le 0 then resultis illegal
if pin le repeats then
[
Repeat(lv pin, 1, 0, px, py)
@py = @py+36
resultis absolute
]
resultis illegal
]

and AutoTermPinPos(icinst, pin, px, py, pInfo, pinName; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na, 0)
if pin le 0 then resultis illegal
if pin le 1008 then
[
pin=pin-1
let package = pin/7
pin = pin rem 7
Pin1of8(package rem 12, package/12, px, py)
@px = @px-4-4*pin
if pinName ne 0 then
ExpandTemplate(pinName, "$C$D.$D", $a+package/12,
41+(package rem 12), pin+2)
resultis absolute
]
resultis illegal
]

and FindCoordFromString(s, px, py, vop1, hop1; numargs na) = valof
[ // vop1 is the "vertical" from pin 1, that is, the offset along the 0.1"
// spacing; hop1 is the "horizontal offset" from pin 1. In a standard 16-pin
// DIP, for pin 2 vop1=4 and hop1=0, and for pin 16, vop1=0 and hop1=12. For
// this board, vop1 grows in the -x direction, and hop1 grows in the +y direction.

// s can be of the form <lower-case letter><number> or
//
<number> s (meaning vertically offset <number>*0.1") or
//
↑<number> s (meaning vertically offset <number>*0.1") or
// ←<number> s (meaning horizontally offset <number>*0.1") or
// # s
DefaultArgs(lv na, -3, 0, 0)

let bpVOffset, bpHOffset = 0,0
let i=0
let c = $#
let offsetIsVertical = true
let sign = 1

while i le s>>str.length & (c ls $a % c gr $z) do
[
if c eq $↑ % c eq $← % c eq $# % c eq $- then
[
test c eq $-
ifso sign = -sign
ifnot offsetIsVertical = not (c eq $←)

i=i+1
c = s>>str.char↑i
loop
]

if c ge $0 & c le $9 then
[
let bpOffset = 0
while i le s>>str.length & c ge $0 & c le $9 do
[
bpOffset = 10*bpOffset+c-$0
i = i+1
c = s>>str.char↑i
]
@(offsetIsVertical? lv bpVOffset, lv bpHOffset) =
sign*bpOffset
offsetIsVertical = true
sign = 1
loop
]

resultis illegal
]

vop1 = vop1+4*bpVOffset
hop1 = hop1+4*bpHOffset

// IC position of the form <letter><number>

if i gr s>>str.length % c ls $a % c gr $z then resultis illegal
let alph = c

let num = 0
while i ls s>>str.length do
[
i=i+1
c = s>>str.char↑i
if (c ls $0) % (c gr $9) then resultis illegal
num = 10*num+(c-$0)
]

if (num ge 1)&(num le 24) then
[
unless Pin1of16(num-1, alph-$a, px, py) do resultis illegal
@px=@px-vop1
@py = @py+hop1
resultis absolute
]

if (num ge 41) & (num le 52) then
[
unless Pin1of8(num-41, alph-$a, px, py) do resultis illegal
@px=@px-vop1
@py=@py+hop1
resultis absolute
]

let col = selecton alph into
[
case $b: 0
case $c: 1
case $e: 2
case $f: 3
case $h: 4
case $i: 5
case $k: 6
case $l: 7
default: -1
]
let row = selecton num into
[
case 60: 1
case 61: 4
case 62: 7
case 63: 10

case 64: 0
// new numbers
case 65: 2
case 66: 3
case 67: 5
case 68: 6
case 69: 8
case 70: 9
case 71: 11

default: -1
]

unless Pin1of24(row, col, px, py) do resultis illegal
@px = @px-vop1
@py = @py+hop1
resultis absolute
]

and Pin1of16(row, col, px, py) = valof
[
unless OffsetLegal(row, 1, 0, 23)&OffsetLegal(col, 1, $a-$a, $l-$a) do
resultis false

BasicPattern(row/2, col/3+col/6, px, py)
@py=@py+24*(row rem 2)
@px=@px+36+36*(col rem 3)
resultis true
]

and Pin1of8(row, col, px, py) = valof
[
unless OffsetLegal(row, 1, 0, 11)&OffsetLegal(col, 1, $a-$a, $l-$a) do
resultis false

BasicPattern(row, col/3+col/6, px, py)
@py=@py+18
@px=@px+36+36*(col rem 3)
resultis true
]

and Pin1of24(row, col, px, py) = valof
[
unless OffsetLegal(row, 1, 0, 11)&OffsetLegal(col, 1, 0, 7) do resultis false

BasicPattern(row, col/2+col/4, px, py)
@py=@py+8
@px=@px+52+56*(col rem 2)
resultis true
]
and Pin1of50(row, col, px, py) = Pin1of24(row, 2*col, px, py)

and Repeat(ppin, pinsPerBasicRepeat, extraPinsPerFullRepeat, px, py) be
[
let pin = @ppin-1
let pinsPerSide = repeatRows*
((repeatCols/2)*pinsPerBasicRepeat+
(fullRepeatCols/2)*extraPinsPerFullRepeat)
let side = pin/pinsPerSide
pin = pin rem pinsPerSide
let pinsPerFullCol = repeatRows*(pinsPerBasicRepeat+extraPinsPerFullRepeat)
let col = pin/pinsPerFullCol
pin = pin rem pinsPerFullCol
let pinsPerRepeat = pinsPerBasicRepeat+
(col ls fullRepeatCols/2? extraPinsPerFullRepeat, 0)
let row = pin/pinsPerRepeat
@ppin = pin rem pinsPerRepeat
BasicPattern(row, 3*side+col, px, py)
]

and BasicPattern(row, col, px, py) be
[
@py = rowOffset+rowHeight*row
@px = (col ls 3? leftColsOffset, rightColsOffset)+
fullColWidth*(col rem 3)
]