//routemlb1.bcpl

// Board-specific Route routines for the Dorado Main Logic Board
// part 1 of 2

//
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"

static [ maxICs = 450; boardInterfaceVersion = interfaceVersion ]

let DeclareInitialNets(BuildTWNet, BuildTermNet, BuildConnector) be
[
BuildConnector("E", 189, EPinPos)
BuildConnector("C", 189, CPinPos)
BuildTWNet("GND", 1024, GNDPinPos)
BuildTWNet("VEE", 504, VEEPinPos)
BuildTWNet("VTT", 240, VTTPinPos)
BuildTWNet("VCC", 304, VCCPinPos)
BuildTWNet("VDD", 168, VDDPinPos)
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("EQP", typeIcclass)
if c ne empty then c>>icclass.PinOffset = QITPlatRevA
]

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 QITPlatRevA(icinst, pinNo, pv, ph) = valof // old revision
[
let npins = Npins(icinst)
if npins ne 26 then CallSwat("QIT ne 26 pins")
if pinNo le 0 % pinNo gr npins then resultis illegal
@ph = (table
[
0; 0; 0; 0; 0; 0; 0; 0; 12; 12; 18; 18;// pins 1-12
30; 30; 30; 30; 30; 30; 30; 18; 18; 12; 12; 12; 18; 30
// pins 13-26
])!(pinNo-1)
@pv = (table
[
0; 4; 8; 12; 16; 20; 24; 28; 28; 20; 28; 20;// pins 1-12
28; 24; 20; 16; 12; 8; 4; 12; 8; 8; 12; 0; 0; 0
// pins 13-26
])!(pinNo-1)
resultis relative
]

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 = 525-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 EPinPos(icinst, pin, px, py) = valof
[
if (pin ls 5) % (pin gr 188) then resultis illegal
@py = 525
let pg = (pin-1) rem 4
if (pg eq 0)%(pg eq 3) then resultis illegal
@px = 22+5*((pin-5)/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
@px = 22+5*((188-pin)/2)
resultis absolute
]

and GNDPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = Disconnect+noReconnect+BottomLevel
if pin le 0 then resultis illegal
if pin le 576 then
[
pin=pin-1
let isPin1 = (pin rem 2) eq 0
pin = pin/2
Pin1of16(pin rem 24, pin/24, px, py)
unless isPin1 do @py = @py+12 // pin 16
resultis absolute
]
pin = pin-576
if pin le 64 then
[
pin = pin-1
let isPin1 = (pin rem 2) eq 0
pin = pin/2
Pin1of24(pin rem 4, pin/4, px, py)
unless isPin1 do @py = @py+24 // pin 24
resultis absolute
]
pin = pin-64
if pin le 96 then
// removable VTT bypass cap
[
@pInfo = Disconnect+noReconnect+BottomLevel+usedForDecoupling
pin = pin-1
Pin1of8(pin rem 12, 3*(pin/24)+((pin/12) rem 2), px, py)
@px = @px+4
@py = @py+6
resultis absolute
]
pin = pin-96
if pin le 144 then
// removable VEE bypass cap
[
@pInfo = Disconnect+noReconnect+BottomLevel+usedForDecoupling
pin = pin-1
Pin1of16(pin rem 24, 6*(pin/72), px, py)
@px = @px+112*((pin/24) rem 3)-36
@py = @py+12
resultis absolute
]
pin = pin-144
if pin le 144 then
// removable VCC bypass cap
[
@pInfo = Disconnect+noReconnect+BottomLevel+usedForDecoupling
pin = pin-1
Pin1of16(pin rem 24, 6*(pin/72), px, py)
@px = @px+112*((pin/24) rem 3)-32
resultis absolute
]
resultis illegal
]

and VEEPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = Disconnect+noReconnect+TopLevel
if pin le 0 then resultis illegal
if pin le 288 then
[
pin=pin-1
Pin1of16(pin rem 24, pin/24, px, py)
@px = @px-28 // pin 8
resultis absolute
]
pin = pin-288
if pin le 32 then
[
pin = pin-1
Pin1of24(pin rem 4, pin/4, px, py)
@px = @px-44 // pin 12
resultis absolute
]
pin = pin-32
if pin le 16 then // 40-pin sockets
[
pin = pin-1
Pin1of24(pin rem 4, 2*(pin/4), px, py)
@px = @px+4
@py = @py+24
resultis absolute
]
pin = pin-16
if pin le 144 then // removable bypass caps
[
@pInfo = Disconnect+noReconnect+TopLevel+usedForDecoupling
pin = pin-1
Pin1of16(pin rem 24, 6*(pin/72), px, py)
@px = @px+112*((pin/24) rem 3)-36
resultis absolute
]
pin = pin-144
if pin le 24 then
[
pin=pin-1
let colHalf = pin/12
pin = pin-12*colHalf
let col = pin/12
let row = pin rem 12
Pin1of8(row, 6*colHalf+5, px, py)
@pInfo = Disconnect+noReconnect+BottomLevel+
usedForDecoupling
// don’t connect to this pin because
// trace can be cut.
@px = @px+4
resultis absolute
]
resultis illegal
]

and VTTPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = Disconnect+Reconnect+TopLevel
if pin le 0 then resultis illegal
if pin le 144 then
[
pin=pin-1
Pin1of8(pin rem 12, pin/12, px, py)
if pin/12 eq 0 then @pInfo =
noDisconnect+noReconnect+TopLevel+BottomLevel
resultis absolute
]
pin = pin-144
if pin le 96 then
// removable VTT bypass cap
[
@pInfo = Disconnect+noReconnect+TopLevel+usedForDecoupling
pin = pin-1
Pin1of8(pin rem 12, 3*(pin/24)+((pin/12) rem 2), px, py)
@px = @px+4
@py = @py-6
resultis absolute
]
resultis illegal
]

and VDDPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = Disconnect+noReconnect+TopLevel
if pin le 0 then resultis illegal
if pin le 72 then
[
pin=pin-1
let colHalf = pin/36
pin = pin-36*colHalf
let col = pin/12
let row = pin rem 12
Pin1of8(row, 6*colHalf, px, py)
@px = @px-36+112*col
if col rem 3 eq 2 then @px = @px+4
if col eq 5 then // col l where feedthrus are
@pInfo = Disconnect+noReconnect+BottomLevel
resultis absolute
]
pin = pin-72
if pin le 96 then
[
pin=pin-1
let row = pin rem 12
let col = pin/12
col = col+1+(col/2)
// 1,2,4,5,7,8,10,11
Pin1of8(row, col, px, py)
@px = @px-32
@py = @py-18
if col eq 11 then // col k where feedthrus are
@pInfo = noDisconnect+noReconnect+TopLevel+BottomLevel
resultis absolute
]
resultis illegal
]

and VCCPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = Disconnect+noReconnect+TopLevel
if pin le 0 then resultis illegal
if pin le 48 then
[
pin=pin-1
let colHalf = pin/24
pin = pin-24*colHalf
let col = pin/12
let row = pin rem 12
Pin1of8(row, 6*colHalf, px, py)
@pInfo = Disconnect+noReconnect+BottomLevel+
usedForDecoupling
// don’t connect to this pin because
// trace can be cut.
@px = @px-32+112*col
resultis absolute
]
pin = pin-48
if pin le 96 then
[
pin=pin-1
let row = pin rem 12
let col = pin/12
col = col+1+(col/2)
// 1,2,4,5,7,8,10,11
Pin1of8(row, col, px, py)
@px = @px-32
@py = @py+18
resultis absolute
]
pin = pin-96
if pin le 16 then // 40-pin sockets
[
pin = pin-1
Pin1of24(pin rem 4, 2*(pin/4), px, py)
@px = @px+4
resultis absolute
]
pin = pin-16
if pin le 144 then // removable bypass caps
[
@pInfo = Disconnect+noReconnect+BottomLevel+
TopLevel+usedForDecoupling
pin = pin-1
Pin1of16(pin rem 24, 6*(pin/72), px, py)
@px = @px+112*((pin/24) rem 3)-32
@py = @py+12
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
]

if (num ge 60)&(num le 63) then
[
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
]
unless Pin1of24(num-60, col, px, py) do resultis illegal
@px = @px-vop1
@py = @py+hop1
resultis absolute
]

resultis illegal
]

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

@px=37+36*col+((col ge \$g-\$a)? ((col ge \$j-\$a)? 35, 31),
((col ge \$d-\$a)? 4, 0))
@py=16+18*row+6*((row+1)/2)
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

@px=37+36*col+((col ge \$g-\$a)? ((col ge \$j-\$a)? 35, 31),
((col ge \$d-\$a)? 4, 0))
@py=34+42*row
resultis true
]

and Pin1of24(row, col, px, py) = valof
[
unless OffsetLegal(row, 1, 0, 3)&OffsetLegal(col, 1, 0, 7) do resultis false
@px = 55+52*col+((col ge 4)? 39, 0)+((col rem 4 ge 2)? 8, 0)
@py = 64+row*126
resultis true
]