//routestor1.bcpl

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

// last modified by E. McCreight, January 31, 1978 2:25 PM

// Editor’s comment: Those persons who designed this board do not receive my
// everlasting gratitude for making the trace-wired nets easy to characterize.

get "route.defs"

external [ IsConverter; InMosArea ]

static [ maxICs = 450; boardInterfaceVersion = interfaceVersion ]

let DeclareInitialNets(BuildTWNet, BuildTermNet, BuildConnector) be
[
BuildConnector("E", 189, EPinPos)
BuildConnector("C", 189, CPinPos)
BuildTWNet("GND", 312, GNDPinPos)
BuildTWNet("VEE", 192, VEEPinPos)
BuildTWNet("VTT", 24, VTTPinPos)
BuildTWNet("VCC", 244, VCCPinPos)
BuildTWNet("VDD", 144, VDDPinPos)
BuildTermNet("Term100/8/Term100", 8, "Term100", 168, AutoTermPinPos,"T")
]

and ZeroTablePoint(point) = selecton point into
[
case 0: "S" // 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 48 then
[
pin=pin-1
let row = pin rem 4
let col = pin/4
Pin1ofEcl(row, col, px, py)
@py = @py+12 // pin 16
@pInfo = noDisconnect+noReconnect+BottomLevel // for decoupling
resultis absolute
]
pin = pin-48
if pin le 24 then
[
pin=pin-1
let pattern = -1
let row,col = nil,nil
while pin ge 0 do
[
pattern = pattern+1
row = pattern rem 4
col = pattern/4
unless IsConverter(row, col) do pin=pin-1
]
Pin1ofEcl(row, col, px, py)
resultis absolute
]
pin = pin-24
if pin le 220 then
[
pin = pin-1
let row = pin rem 22
let col = pin/22
Pin1ofTTL(row, col, px, py)
test InMosArea(row, col)
ifso @py = @py+12 // pin 16
ifnot @px = @px-28 // pin 8
resultis absolute
]
pin = pin-220
if pin le 20 then
[
pin = pin-1
let row = 10+(pin rem 2)
let col = pin/2
Pin1ofTTL(row, col, px, py)
@px = @px-24 // pin 7 of rows 13&14
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 48 then
[
pin=pin-1
Pin1ofEcl(pin rem 4, pin/4, px, py)
@px = @px-28 // pin 8
@pInfo = noDisconnect+noReconnect+TopLevel
// I can’t infer the decoupling pattern, so this seems safest.
resultis absolute
]
pin = pin-48
if pin le 144 then
[
pin = pin-1
let row = 1+(pin rem 18)
if row gr 9 then row = row+2 // stay in MOS area
let col = 1+(pin/18)
Pin1ofTTL(row, col, px, py)
resultis absolute
]
resultis illegal
]

and VTTPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = noDisconnect+noReconnect+TopLevel
if pin le 0 then resultis illegal
if pin le 24 then
[
pin=pin-1
Pin1ofTerm(pin rem 2, pin/2, px, py)
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 144 then
[
pin = pin-1
let row = 1+(pin rem 18)
if row gr 9 then row = row+2 // stay in MOS area
let col = 1+(pin/18)
Pin1ofTTL(row, col, px, py)
@px = @px-28 // pin 8
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 220 then
[
pin = pin-1
let row = pin rem 22
let col = pin/22
Pin1ofTTL(row, col, px, py)
@py = @py+12 // pin 9 or 16
if InMosArea(row, col) then @px = @px-28 // pin 9
resultis absolute
]
pin = pin-220
if pin le 24 then
[
pin = pin-1
let pattern = -1
let row,col = nil,nil
while pin ge 0 do
[
pattern = pattern+1
row = pattern rem 4
col = pattern/4
if IsConverter(row, col) then pin = pin-1
]
Pin1ofEcl(row, col, px, py)
@py = @py+12 // pin 9
@px = @px-28
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 168 then
[
pin=pin-1
let package = pin/7
pin = pin rem 7
Pin1ofTerm(package rem 2, package/2, px, py)
@px = @px-4-4*pin
if pinName ne 0 then
ExpandTemplate(pinName, "$C$D.$D", $a+package/2,
41+(package rem 2), pin+2)
resultis absolute
]
resultis illegal
]

and InMosArea(row, col) = col ge 1 & col le 8 & OffsetLegal(row rem 11, 1, 1, 9)

and IsConverter(row, col) = selecton row into
[
case 0:
case 3: selecton col into
[
case 3:
case 8: true
default: false
]

case 1: selecton col into
[
case 3:
case 4:
case 7:
case 8: false
default: true
]

case 2: true
]

and FindCoordFromString(s, px, py, vop1, hop1; numargs na) = valof
[ // vop1 is the "vertical offset" 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 = nil

while i le s>>str.length & (c ls $a % c gr $z) do
[
if c eq $↑ % c eq $← % c eq $# then
[
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) = bpOffset
offsetIsVertical = true
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 2)%(num ge 25&num le 26) then
[
if num gr 22 then num = num-22
unless OffsetLegal(hop1, 12, 0, 1)&
OffsetLegal(vop1, 4, 0, 7) do resultis illegal
unless Pin1ofEcl(num-1, alph-$a, px, py) do resultis illegal
@px=@px-vop1
@py = @py+hop1
resultis absolute
]

if (num ge 3)&(num le 24) then
[
unless OffsetLegal(hop1, 12, 0, 1)&
OffsetLegal(vop1, 4, 0, 7) do resultis illegal
unless Pin1ofTTL(num-3, alph-$a, px, py) do resultis illegal
@px=@px-vop1
@py = @py+hop1
resultis absolute
]

if (num ge 41) & (num le 42) then
[
unless (hop1 eq 0)&OffsetLegal(vop1, 4, 0, 7) do resultis illegal
unless Pin1ofTerm(num-41, alph-$a, px, py) do resultis illegal
@px=@px-vop1
@py=@py+hop1
resultis absolute
]

resultis illegal
]

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

@px=28+40*col+((col ge $g-$a)? 8, 0)
@py=7+24*row+((row ge 2)? 428, 0)
resultis true
]

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

@px=28+40*col+((col ge $g-$a)? 8, 0)
@py=row eq 0? 25, 501
resultis true
]

and Pin1ofTTL(row, col, px, py) = valof
[
unless OffsetLegal(row, 1, 0, 21)&OffsetLegal(col, 1, $a-$a, $j-$a) do
resultis false

@px=28+48*col+((col ge $f-$a)? 16, 0)
@py=49+20*row-(row le 0? 0, (row ge 21? 4, 2))
// intervals 0-1 and 20-21 are only 18 units instead of 20
resultis true
]