//routemwsb2.bcpl

// Board-specific Route routines for the D0 MultiWire Main Logic Board
// Part 2 of 2, last modified by S. Tom Chang, November 29, 1978 10:44 AM

get "route.defs"

static [ boardInterfaceVersion = interfaceVersion ]

external [ Pin1of3W; Pin1of4W; Pin1of6W ]

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 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 ge 56 then xoff = xoff - 5
if (xoff rem 10 eq 0) then resultis 0 // GND Pins
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 204?12,0) - (y ge 312?12,0)
if (((yoff rem 24) eq 0)&(y le 444))%(y eq 460) then // ..VDD pin
[
if y eq 460 then yoff = 456
yoff = yoff/24
@picclass = MustFindNamee("VDD", typeIcclass)
if ((yoff eq 8)%(yoff eq 12)) then
[
unless (y eq 180)%(y eq 288) do resultis 0
unless (x ge 60)&(x le 388) do resultis 0
unless ((xcd -60) rem 52 eq 0) do resultis 0
xoff = (xcd - 8)/52
]
if ((yoff rem 5) eq 0) then
[
unless (x ge 72)&(x le 376) do 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
[
unless (x ge 40)&(x le 408) do 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 le 448))%(y eq 192)%(y eq 300)%(y eq 468) then // ..VEE pin
[
if y eq 468 then yoff = 456
yoff = yoff/24
@picclass = MustFindNamee("VEE", typeIcclass)
if (yoff eq 8)%(yoff eq 12) then
[
unless (y eq 192)%(y eq 300) do resultis 0
unless (x ge 28)&(x le 356) do resultis 0
unless ((xcd -28) rem 52 eq 0) do resultis 0
xoff = (xcd + 24)/52
]
if ((yoff rem 5) eq 0) then
[
unless (x ge 40)&(x le 344) do resultis 0
unless (((xcd -40) rem 48) eq 0) do resultis 0
xoff = (xcd + 8)/48
]
if ((yoff rem 5) ne 0)&(yoff ne 8)&(yoff ne 12) then
[
unless (x ge 12)&(x le 380) do 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)&(x ge 64)&(x le 392) 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)&(x le 348) then powp = 1
if yodd &(((xcd - 48) rem 48) eq 0)&(x le 352) then powp = 1
vpin = (((xcd - 8) rem 44) eq 0)&((yoff rem 24) eq 0)&(y le 476)
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 pins
[
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 pins
[
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 // ...3W pins
if (y ls 0)%(y gr 476) then 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)
]