//routedc2.bcpl
// Board-specific Route routines for the De/Compress ECL Logic Board

// Part 2 of 2, last modified by S. Tom Chang, October 17, 1978 7:18 AM
// all co-ordinates are described with respect to the bottom or
// wiring side of the board. LevelTransform fixes these as necessary.

get "route.defs"

static [ boardInterfaceVersion = interfaceVersion ]

external [ Pin1of8 ] // defined here

let 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 (vertical pin-offset from pin #1)
// a special form "Z-s" is for ZeroTable point
DefaultArgs(lv na, 3, 0, 0)

let zchar = s>>str.char↑1
let letter = s>>str.char↑3
let znum = s>>str.char↑4
if (zchar eq $Z)&((letter eq $E)%(letter eq $V)%(letter eq $j)) then
[
@px = (letter eq $E?(znum eq $3?400,8),(letter eq $j?8,400))
@py = letter eq $E?508,24
resultis absolute
]
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
let c = s>>str.char↑i
if (c ls $0) % (c gr $9) then resultis illegal
num = 10*num+(c-$0)
]

if (num eq 0)&((alph eq $a)%(alph eq $j)) then resultis illegal

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

if (num ge 30)&(num le 42)&(alph ge $a)&(alph le $j) then// Term
[
unless OffsetLegal(vop1, 4, 0, 7)&(hop1 eq 0) do resultis illegal
unless Pin1of8(num-30, 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, 0, 22)&OffsetLegal(col, 1, $a-$a, $j-$a) do resultis false
let RowGp = (row+1)/2
let RowR = (row+1) rem 2
if (row eq 0)&((col eq $a-$a)%(col eq $j)) then resultis false
@px = (10 - col)*36 + ((col le $d-$a)?28,0)
@px = @px + ((col le $g-$a)?4,0) + ((col eq $a-$a)?4,0)
@py = RowGp*42 - 18 + (RowR eq 1?24,0)
resultis true
]

and Pin1of8(row, col, px, py) = valof
[
unless OffsetLegal(row, 1, 0, 11)&OffsetLegal(col, 1, $a-$a, $j-$a) do resultis false
@px = (10 - col)*36 + ((col le $d-$a)?28,0)
@px = @px + ((col le $g-$a)?4,0) + ((col eq $a-$a)?4,0)
@py = row*42
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
firstVCCPin = firstEPin+200
firstSipPin = firstVCCPin+154
first3WPin = firstSipPin+960
firstUnusedPin = first3WPin+3680
]

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, 408)&OffsetLegal(y, 1, 0, 508) do resultis 0

let xoff = 0
let yoff = 0
let xcd = x
if (y le 18)&((x ls 32)%(x gr 364)) then resultis 0 // board extractors area
if y eq 504 % y eq 508 then //...edge pin
[
if x rem 4 ne 0 then resultis 0
xoff = x/4
if xoff ls 0 % ((xoff gr 47)&(xoff ls 55)) % xoff gr 102 then resultis 0
if xoff ge 55 then xoff = xoff - 5
if ((xoff + 2) rem 10) eq 0 then resultis 0 // GND Pins
resultis 98 - xoff + (y eq 508?0,100)
]
if (x gr 228)&(x ls 248) then resultis 0
if x ge 248 then xcd = x - 28
if x ge 116 then xcd = xcd - 4 - (x ge 364?4,0)
if (y rem 42) eq 0 then // ..Sip socket
[
unless OffsetLegal(x, 4, 2, 99) do resultis 0
if (y eq 0)&((x le 32)%(x ge 360)) then resultis 0
yoff = (y+42)/42
if (xcd rem 36) eq 0 then // VTT pins
[
@picclass = MustFindNamee("VTT", typeIcclass)
@pPinNo = yoff*10 - (xcd/36) + 1
]
xoff = (xcd - 4)/4
if (xoff rem 9) eq 0 then resultis 0
resultis firstSipPin + yoff*80 - (xoff/9)*8 - (xoff rem 9)
]

let ygp = 0
let hop = 0
if (((y - 24) rem 42) eq 0)%(((y - 36) rem 42) eq 0) then hop = 1
if (((y - 6) rem 42) eq 0)%(((y - 18) rem 42) eq 0) then hop = 1
if hop eq 1 then // ..3W socket
[
if (x ls 8)%(x gr 400) then resultis 0
unless OffsetLegal(x-4, 4, 1, 99) do resultis 0
xcd = x - (x gr 228?16,0)
xoff = (xcd - 4)/4
if (xoff eq 27)%(xoff eq 28)%(xoff eq 55)%(xoff eq 56) then resultis 0
if (xoff eq 57)%(xoff eq 58)%(xoff eq 85)%(xoff eq 86) then resultis 0
ygp = (y + 18)/42
yoff = ((y + 18) rem 42)/12
let vpin = 0
if (xoff eq 9)%(xoff eq 18)%(xoff eq 37)%(xoff eq 46) then vpin = 1
if (xoff eq 67)%(xoff eq 76)%(xoff eq 95) then vpin = 1
if (vpin eq 1)&((yoff eq 1)%(yoff eq 2)) then resultis 0
if xoff ge 28 then xoff = xoff - 1
if xoff ge 56 then xoff = xoff - 3
if xoff ge 83 then xoff = xoff - 1
if (vpin eq 1)&((yoff eq 0)%(yoff eq 3)) then // VCC pin
[
@picclass = MustFindNamee("VCC", typeIcclass)
if ((xoff/9) eq 1)%((xoff/9) eq 2) then vpin = 8 - (xoff/9)
if ((xoff/9) eq 4)%((xoff/9) eq 5) then vpin = 9 - (xoff/9)
if ((xoff/9) eq 7)%((xoff/9) eq 8) then vpin = 10 - (xoff/9)
@pPinNo = ygp*14 - (yoff eq 3?0,7) + vpin
resultis (firstVCCPin + ygp*14 - (yoff eq 3?0,7) + vpin - 1)
]
if ((xoff rem 9) eq 1)&((yoff eq 0)%(yoff eq 2)) then // VEE pin
[
@picclass = MustFindNamee("VEE", typeIcclass)
@pPinNo = ygp*20 + (yoff eq 2?10,0) - (xoff/9)
]
if ((xoff rem 9) eq 8)&((yoff eq 1)%(yoff eq 3)) then // GND pin
[
@picclass = MustFindNamee("GND", typeIcclass)
@pPinNo = ygp*20 + (yoff eq 3?10,0) - (xoff/9)
]
resultis (first3WPin + ygp*320 + yoff*80 -80-(xoff/9)*8-(xoff rem 9))
]
resultis 0

]