//routepm1.bcpl
// Board-specific Route routines for the PimLico Logic Board

// Part 1 of 2, last modified by S. Tom Chang, February 22, 1979 1:29 PM

get "route.defs"

external [ Check; Pin1of3W; Pin1of6W; VCCPinPos ]

static [ Check = 0; maxICs = 180; boardInterfaceVersion = interfaceVersion ]

let DeclareInitialNets(BuildTWNet, BuildTermNet, BuildConnector) be
[
BuildConnector("E", 100, EPinPos)
BuildConnector("C", 85, CPinPos)
BuildTWNet("GND", 508, GNDPinPos)
BuildTWNet("VCC", 508, VCCPinPos)
BuildTWNet("VDD", 500, VDDPinPos)
BuildTWNet("VEE", 500, VEEPinPos)
]

and ZeroTablePoint(point) = selecton point into
[
case 0: "Pm" // board type
case 1: "Z-a20.20"
case 2: "Z-a2.1"
case 3: "Z-g2.8"
case 4: "Z-g20.9"
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 = 504-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
[
@px = 350; @py = 550
if (pin ls 1) % (pin gr 100) then resultis illegal
if ((pin eq 50)%(pin eq 100)) then resultis illegal // +12 volts
let pg = pin rem 50
if (pg eq 9) then resultis illegal // -5 volts
if ((pg eq 3)%(pg eq 4)) then resultis illegal // +5 volts
if ((pg eq 6)%(pg eq 7)%(pin eq 76)%(pin eq 96)) then resultis illegal // ground Epins
@px = 304 + (pin le 50?4,0)
@py = 387 - pg*5
resultis absolute
]

and CPinPos(icinst, pin, px, py) = valof
[
@px = 350; @py = 550 // outside of the board
if (pin ls 1) % (pin gr 85) then resultis illegal
if (Check ge 2) then resultis illegal // Had dip in locations a2 to d2
let pn = pin rem 2
let pvtgd = pin rem 22
if ((pvtgd eq 0)%(pvtgd eq 2)) then resultis illegal // +5 volts Cpins
if ((pvtgd eq 19)%(pvtgd eq 21)) then resultis illegal // Gnd Cpins
@px = ((pin-1)/2)*4
@py = 468 + pn*12
if ((Check rem 2) eq 0) then Check = Check + 1
resultis absolute
]

and VDDPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = noDisconnect+noReconnect+TopLevel
@px = 350; @py = 550
if (pin ls 1)%(pin gr 526) then resultis illegal
let alph =
(pin - 1) rem 26
let num =
(pin - 1)/26 + 1
let alf = alph + $a
let Top = ((alf ge $a)&(alf le $d)&(num ge 2)&(num le 20))
let Bot = ((alf ge $e)&(alf le $g)&(num ge 1)&(num le 20))
let Col7s = ((num eq 7)%(num eq 11)%(num eq 14))
if (not Top)&(not Bot) then resultis illegal
if (Col7s &((alf eq $d)%(alf ge $g)))%(Bot &(not Col7s)) then resultis illegal
@px = 4 + alph*44
// basic coords for dips in Top and Regular
@py = 524 - num*24 - ((num ge 8)?12,0) - ((num ge 12)?12,0) - ((num ge 15)?12,0)
let cmpsat = (num eq 11?108,0) + (num eq 14?192,0)
if (Col7s) then
[
@px = 44 +(alf eq $b?52,0)+(alf eq $c?104,0)+(alf eq $e?172,0)+(alf eq $f?224,0)
@py = 356 - cmpsat
]
resultis absolute
]

and VEEPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = noDisconnect+noReconnect+TopLevel
@px = 350; @py = 550 // outside of the board
if (pin ls 1)%(pin gr 526) then resultis illegal
let alph =
(pin - 1) rem 26
let num =
(pin - 1)/26 + 1
let alf = alph + $a
let Top = ((alf ge $a)&(alf le $d)&(num ge 2)&(num le 20))
let Bot = ((alf ge $e)&(alf le $g)&(num ge 1)&(num le 20))
let Col7s = ((num eq 7)%(num eq 11)%(num eq 14))
if (not Top)&(not Bot) then resultis illegal
if (Col7s &((alf eq $d)%(alf ge $g)))%(Bot &(not Col7s)) then resultis illegal
@px = 36 + alph*44
// basic coords for dips in Top and Regular
@py = 520 - num*24 - ((num ge 8)?12,0) - ((num ge 12)?12,0) - ((num ge 15)?12,0)
let cmpsat = (num eq 11?108,0) + (num eq 14?192,0)
if (Col7s) then
[
@px = 36 +(alf eq $b?60,0)+(alf eq $c?104,0)+(alf eq $e?172,0)+(alf eq $f?224,0)
@py = 344 - cmpsat
]
resultis absolute
]
and GNDPinPos(icinst, pin, px, py, pInfo; numargs na) = valof
[
DefaultArgs(lv na, -4, lv na)
@pInfo = Disconnect+noReconnect+BottomLevel
@px = 350; @py = 550 // outside of the board
if (pin ls 1)%(pin gr 532) then resultis illegal
let alph =
(pin - 1) rem 26
let num =
(pin - 1)/26 + 1
let alf = alph + $a
let Col7s = ((num eq 7)%(num eq 11)%(num eq 14))
let Top = (((alf ge $a)&(alf le $d))%((alf ge $h)&(alf le $k)))&(num ge 2)&(num le 20)
let preBot = (not Col7s)&((((alf ge $e)&(alf le $g))%((alf ge $l)&(alf le $m)))&(num ge 1)&(num le 20))
let Bot = preBot %(Col7s &(((alf ge $e)&(alf le $f))%((alf ge $l)&(alf le $o))))
if ((not Top)&(not Bot))%(Col7s &((alf eq $d)%(alf eq $g))) then resultis illegal
@px = 36 + alph*44
// basic coords for dips in Top and Regular
@py = 528 - num*24 - ((num ge 8)?12,0) - ((num ge 12)?12,0) - ((num ge 15)?12,0)
if (Bot &(not Col7s)) then @px = @px +16 - (alf - $d)*8
if (not Col7s)&(alf ge $h)&(alf le $m) then
[
@px = 40 +(alf - $h)*44+(alf eq $l?8,0)
]
if (Col7s) then
[
@px = alph*52 +(alf ge $b?24,0)-(alf ge $e?36,0)
if (alf eq $h)%(alf eq $j) then @px = 68
if (alf eq $i)%(alf eq $k) then @px = 120
if (alf eq $l)%(alf eq $n) then @px = 240
if (alf eq $m)%(alf eq $o) then @px = 292
let cmpsat = (num eq 11?108,0) + (num eq 14?192,0)
let hori = (alf eq $h)%(alf eq $i)%(alf eq $l)%(alf eq $m)
let jork = (alf eq $j)%(alf eq $k)%(alf eq $n)%(alf eq $o)
@py = 352 - cmpsat -(hori?4,0)+(jork?8,0)
]
resultis absolute
]

and BoardPinCoord(string, icinst, pinNo, px, py) = valof
[
let vop1, hop1 = nil, nil
let numpins = Npins(icinst)
switchon (Icclass(icinst)>>icclass.PinOffset)(icinst, pinNo, lv vop1, lv hop1) into
[
case absolute:
@px = vop1
@py = hop1
resultis true

case relative: resultis (FindCoordFromString(string, px, py, vop1, hop1, numpins) eq absolute)

default: resultis false
]
]

and FindCoordFromString(s, px, py, vop1, hop1, numpins; 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 (vertically offset)
// a special form "Z-s" is for ZeroTable point
// % s for insert IC upside down
// - s for negative vertical offset
DefaultArgs(lv na, 3, 0, 0, 20)

let c = s>>str.char↑1
let alph = s>>str.char↑3
let num = s>>str.char↑5
if (c eq $Z)&((alph eq $a)%(alph eq $g)) then
[
@px = alph eq $g?292,0
@py = num eq $0?0,480
resultis absolute
]
let bpVOffset, bpHOffset = 0,0
let i=0
let Negative = false
c = $#
let offsetIsVertical = nil

while i le s>>str.length & (c ls $a % c gr $z) do
[
if (c eq $↑)%(c eq $←)%(c eq $#)%(c eq $%)%(c eq $-) then
[
offsetIsVertical = not (c eq $←)
if c eq $% then
[ vop1 = numpins*2 - 4 - vop1
hop1 = ((hop1 eq 0)?(numpins le 20?12,24),0) ]
if c eq $- then Negative = true
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
]

if (vop1 ls 0)%(vop1 gr (numpins*2 - 4)) then resultis illegal
if (hop1 ls 0)%(hop1 gr ((numpins gr 20)?24,12)) then resultis illegal

vop1 = vop1 - 4*bpVOffset
if Negative then vop1 = vop1 + 8*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
alph = c
let num = 0
while i ls s>>str.length do
[
i = i + 1
let c = s>>str.char↑i
if (c ls $0) % (c gr $9) then resultis illegal
num = 10*num+(c-$0)
]

let numtemp = (num eq 7)%(num eq 11)%(num eq 14)
if numtemp &(alph ge $a)&(alph le $f)&(numpins le 40) then
[
if (alph ne $d)&(numpins gr 24) then
[
if alph eq $b then resultis illegal
unless Pin1of6W(num, alph-$a, px, py) do resultis illegal
vop1 = vop1 + (40 - numpins)*2
@px = @px + vop1 - (alph eq $a?12,0) - (alph eq $c?32,0)
@py = @py - hop1
resultis absolute
]
if (alph ne $d)&(numpins gr 20) then
[
unless Pin1of6W(num, alph-$a, px, py) do resultis illegal
vop1 = vop1 + (24 - numpins)*2
@px = @px + vop1
@py = @py - hop1
resultis absolute
]
if (numpins le 20) then
[
unless Pin1of3W(num, alph-$a, px, py) do resultis illegal
vop1 = vop1 + (20 - numpins)*2
@px = @px + vop1
@py = @py - hop1
resultis absolute
]
resultis illegal
]

if (num ge 1)&(num le 20)&(alph ge $a)&(alph le $g) then
[
unless numpins le 20 do resultis illegal
if (num eq 1)&(alph le $d) then resultis illegal
let a2d2 = (num eq 2)&(alph ge $a)&(alph le $d)
if a2d2 &(Check eq 0) then Check = 2
if a2d2 &(Check eq 1) then resultis illegal
if alph le $d then vop1 = vop1 + (20 - numpins)*2
if alph ge $e then vop1 = vop1 + (16 - numpins)*2
unless Pin1of3W(num, alph-$a, px, py) do resultis illegal
@px = @px + vop1
@py = @py - hop1
resultis absolute
]

resultis illegal
]