//routesb2.bcpl

// Board-specific Route routines for the D0 Main Logic Board
// Part 2 of 2, last modified by S. Tom Chang, August 21, 1978 5:12 PM

get "route.defs"

static [ boardInterfaceVersion = interfaceVersion ]

let 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
DefaultArgs(lv na, 3, 0, 0, 20)

let c = s>>str.char↑1
let alph = s>>str.char↑3
if (c eq $Z)&((alph eq $a)%(alph eq $i)) then
[
@px = alph eq $a?412,8
@py = 8
resultis absolute
]
let bpVOffset, bpHOffset = 0,0
let i=0
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 $%) then
[
offsetIsVertical = not (c eq $←)
if c eq $% then
[ vop1 = numpins*2 - 4 - vop1
hop1 = ((hop1 eq 0)?(numpins le 20?12,24),0) ]
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
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 8)%(num eq 12)
let Bpins = 20 + (numtemp?4,0)
let pindig = 9 + (numtemp?2,0)
if numtemp & ((alph eq $d)%(alph eq $i)) then resultis illegal
if numtemp & (numpins eq 24) then
[
vop1 = vop1 + (Bpins - numpins)*2
unless OffsetLegal(vop1, 4, 0, 11)&OffsetLegal(hop1, 12, 0, 2) do resultis illegal
unless Pin1of6W(num, alph-$a, px, py) do resultis illegal
@px = @px - vop1
@py = @py + hop1
resultis absolute
]

numtemp = (num eq 5)%(num eq 10)%(num eq 15)
pindig = pindig + (numtemp?1,0)
Bpins = Bpins + (numtemp?2,0)
if numtemp & (numpins eq 22) then
[
vop1 = vop1 + (Bpins - numpins)*2
unless OffsetLegal(vop1, 4, 0, 10)&OffsetLegal(hop1, 16, 0, 1) do resultis illegal
unless Pin1of4W(num, alph-$a, px, py) do resultis illegal
@px = @px - vop1
@py = @py + hop1
resultis absolute
]

if numtemp &((alph eq $a)%(alph eq $i)) then // 14 pins only
[
unless numpins le 14 do resultis illegal
pindig = 6
Bpins = 14
]

if (num ge 1) & (num le 19) & OffsetLegal(hop1, 12, 0, 1) then
[
unless numpins le 20 do resultis illegal
vop1 = vop1 + (Bpins - numpins)*2
unless OffsetLegal(vop1, 4, 0, pindig) do resultis illegal
unless Pin1of3W(num, alph-$a, px, py) do resultis illegal
@px = @px - vop1
@py = @py + hop1
resultis absolute
]

resultis illegal
]

and Pin1of3W(row, col, px, py) = valof
[
unless OffsetLegal(row, 1, 1, 19)&OffsetLegal(col, 1, $a-$a, $i-$a) do resultis false
@px = (9 - col)*44 + (col le $d-$a?16,0)
@py = row*24 - 16 + (row ge 8?12,0) + (row ge 12?12,0)
if ((row rem 5) eq 0) then @px = @px + 16 - col*4 - (col eq $a-$a?16,0)
if (row eq 8)%(row eq 12) then @px = @px + 32 - col*8 -(col le $c-$a?52,0)
resultis true
]

and Pin1of4W(row, col, px, py) = valof
[
unless ((row rem 5) eq 0)&OffsetLegal(col, 1, $b-$a, $h-$a) do resultis false
@px = (8 - col)*48 + 28 + (col le $d-$a?16,0)
@py = 100 + ((row/5) - 1)*132
resultis true
]

and Pin1of6W(row, col, px, py) = valof
[
unless OffsetLegal(row, 4, 2, 3)&OffsetLegal(col, 1, $a-$a, $h-$a)&(col ne $d) do resultis false
@px = (8 - col)*52 + 12 - (col le $c-$a?36,0)
@py = 176 + (row eq 12?108,0)
resultis true
]

and FindIndexFromCoord(x, y, picclass, pPinNo; numargs na) = valof
[
static [ hotIndex = -1; firstUnusedPin = 0 ]

DefaultArgs(lv na, -2, lv na, lv na)

if firstUnusedPin eq 0 then firstUnusedPin = FIFC(-1,-1)
let result = FIFC(x, y, picclass, pPinNo)
if result ls 0 % result gr firstUnusedPin then CallSwat("Illegal index..")
if result eq hotIndex then CallSwat("Hot index computed...")
resultis result
]

and FIFC(x, y, picclass, pPinNo; numargs na) = valof
[
manifest
[
firstEPin = 1
firstCPin = firstEPin + 200
first4WPin = firstCPin+100
first6WPin = first4WPin+249
firstGNDPin = first6WPin+180
firstVCCPin = firstGNDPin+203
firstVDDPin = firstVCCPin+171
firstVEEPin = firstVDDPin+171
first3WPin = firstVEEPin+171
firstUnusedPin = first3WPin+3762
]

if x eq -1 & y eq -1 then resultis firstUnusedPin

DefaultArgs(lv na, -2, lv na, lv na)
@picclass = empty

unless OffsetLegal(x, 1, 4, 412)&OffsetLegal(y, 1, 0, 500) do resultis 0

let xoff = 0
let yoff = 0
let xcd = x
if y eq 0 % y eq 4 then // ..cable pin
[
if (x-84) rem 4 ne 0 then resultis 0
xoff = (x-84)/4
if xoff ls 1 % ((xoff gr 25)&(xoff ls 37)) % xoff gr 61 then resultis 0
if xoff eq 9 % xoff eq 17 % xoff eq 45 % xoff eq 54 then resultis 0
if (y eq 4) & (xoff eq 8 % xoff eq 53) then resultis 0
if xoff ge 37 then xoff = xoff + 14
resultis xoff + (y eq 4?25,0)
]

if y eq 496 % y eq 500 then //...edge pin
[
if x rem 4 ne 0 then resultis 0
xoff = x/4
if xoff ls 1 % ((xoff gr 48)&(xoff ls 56)) % xoff gr 103 then resultis 0
if (xoff + 1) rem 10 eq 0 then resultis 0 // GND Pins
if xoff ge 56 then xoff = xoff - 5
resultis 100 - xoff + (y eq 500?0,100)
]

if (x gr 220)&(x ls 244) then resultis 0
if x ge 244 then xcd = x - 16
yoff = y + 12 - (y ge 216?12,0) - (y ge 324?12,0)
if (((yoff rem 24) eq 0)&(y ne 468))%(y eq 460) then // ..VDD pin
[
if y eq 460 then y = 468
yoff = yoff/24
@picclass = MustFindNamee("VDD", typeIcclass)
if ((yoff eq 8)%(yoff eq 12)) then
[
if x gr 388 then resultis 0
unless ((xcd -60) rem 52 eq 0) do resultis 0
xoff = (xcd - 8)/52
]
if ((yoff rem 5) eq 0) then
[
if x gr 376 then resultis 0
unless (((xcd -72) rem 48) eq 0) do resultis 0
xoff = (xcd - 24)/48
]
if ((yoff rem 5) ne 0)&(yoff ne 8)&(yoff ne 12) then
[
if x gr 408 then resultis 0
unless ((xcd - 40) rem 44 eq 0) do resultis 0
xoff = (xcd + 4)/44
]
@pPinNo = yoff*9 + 1 - xoff
resultis firstVDDPin + yoff*9 - xoff
]

yoff = yoff - 4
if (((yoff rem 24) eq 0)&(y ne 472))%(y eq 192)%(y eq 300)%(y eq 468) then // ..VEE pin
[
if y eq 468 then y = 472
yoff = yoff/24
@picclass = MustFindNamee("VEE", typeIcclass)
if (y eq 192)%(y eq 300) then
[
if x gr 356 then resultis 0
unless ((xcd -28) rem 52 eq 0) do resultis 0
xoff = (xcd + 24)/52
]
if ((yoff rem 5) eq 0) then
[
if x gr 344 then resultis 0
unless (((xcd -40) rem 48) eq 0) do resultis 0
xoff = (xcd + 8)/48
]
if ((yoff rem 5) ne 0)&(y ne 192)&(y ne 300) then
[
if x gr 380 then resultis 0
unless ((xcd - 12) rem 44 eq 0) do resultis 0
xoff = (xcd + 32)/44
]
@pPinNo = yoff*9 + 1 - xoff
resultis firstVEEPin + yoff*9 - xoff
]

// note if x ge 244 then xcd = xcd - 16
yoff = y + 4 - (y ge 200?12,0) - (y ge 308?12,0)
let powp = 0
let row = yoff/24
let row5v = (y eq 116)%(y eq 248)%(y eq 380)
let row8v = (y eq 200)%(y eq 308)
let row5g = (y eq 104)%(y eq 236)%(y eq 368)
let row8g = (y eq 176)%(y eq 188)%(y eq 284)%(y eq 296)
let row5 = row5v % row5g
let row8 = row8v % row8g
let yodd = (y eq 100)%(y eq 232)%(y eq 364)
let vpin = ((xcd rem 44) eq 0)&((yoff rem 24) eq 0)
if row5v &((((xcd - 28) rem 48) eq 0)%(xcd eq 396)) then powp = 1
if row8v &(((xcd - 64) rem 52) eq 0) then powp = 1
if (not row5)&(not yodd)&(not row8)& vpin then powp = 1
if powp then // ..VCC pin
[
unless ((yoff rem 24) eq 0) do resultis 0
@picclass = MustFindNamee("VCC", typeIcclass)
if row5v then xoff = (xcd + 56)/48
if row8v then xoff = (xcd + 40)/52
if (row8v)&(xoff ge 6) then xoff = xoff + 1
if (not row5v)&(not row8v) then xoff = xcd/44
@pPinNo = row*9 + 1 - xoff
resultis (row*9 - xoff + firstVCCPin)
]

powp = 0
yoff = y + 16 - (y ge 188?12,0) - (y ge 296?12,0)
unless (((yoff rem 12) eq 0)% yodd) do resultis 0
row = yoff/24
if row5g &((((xcd - 36) rem 48) eq 0)%(xcd eq 4)) then powp = 1
if row8g &(((xcd - 20) rem 52) eq 0) then powp = 1
if yodd &(((xcd - 48) rem 48) eq 0) then powp = 1
vpin = (((xcd - 8) rem 44) eq 0)&((yoff rem 24) eq 0)
if (not row5)&(not yodd)&(not row8)& vpin then powp = 1
if powp then // ..GND pin
[
@picclass = MustFindNamee("GND", typeIcclass)
if row5g then xoff = (xcd + 60)/48
if row8g then
[ xoff = (xcd + 84)/52
if xoff ge 6 then xoff = xoff + 1
if y eq 176 then row = 20
if y eq 284 then row = 21
]
if (not row5g)&(not row8g)&(not yodd) then xoff = (xcd + 36)/44
if yodd then
[ xoff = (xcd/48) + 1
row = 22 + (y - 100)/132
]
@pPinNo = row*9 + 1 - xoff
resultis (row*9 - xoff + firstGNDPin)
]

if y eq 176 % y eq 284 then // ..6W pin
[
yoff = y/177
unless OffsetLegal(x, 4, 5, 98) do resultis 0
xoff = (xcd - 16)/4
if ((xoff rem 13) eq 0) then resultis 0
resultis xoff + yoff*90 + first6WPin - 1
]

if y eq 100 % y eq 232 % y eq 364 then // ..4W pin
[
yoff = y/182
unless OffsetLegal(x, 4, 9, 95) do resultis 0
xoff = (xcd - 32)/4
if ((xoff rem 12) eq 0) then resultis 0
resultis xoff + yoff*83 + first4WPin - 1
]

unless ((xcd rem 4) eq 0) do resultis 0
row = (yoff - 12)/12
if row8 &((xcd ls 20)%(xcd gr 376)) then resultis 0
if row5 &((xcd ls 4)%(xcd gr 396)) then resultis 0
if (not row5)&((xcd ls 8)%(xcd gr 396)) then resultis 0
if row8 &(((xcd - 68) rem 52) eq 0) then resultis 0
if row5 &(((xcd - 32) rem 48) eq 0) then resultis 0
if (not row5)&(not row8)&(((xcd - 48) rem 44) eq 0) then resultis 0
xoff = xcd/4
resultis (row*99 - xoff + first3WPin)
]