// NetDelaysEdge.bcpl
// last modified December 15, 1978

get "NetDelays.defs"

//Dorado board spacing is .625; D0 board spacing if .75
static [ BdSpacing=(70*4)/10 ] // .70 inches for now

let DoEdgeNets(netBuf) be
[
Debug = Debug - 2
Wss(screen,"*n*n")
let node = vec Lnode; Zero(node,Lnode)
let Enode = vec Lnode; Zero(Enode,Lnode)
let Enet = vec Lnet; Zero(Enet,Lnet)
for f = 0 to LastFile do FindFirstNet(f)
Msg("*n")

//now read in all the nets
Zero(netBuf,Lnet*(LastFile+1))
let BdNum = FindNextNet(netBuf)
let net = netBuf + Lnet*BdNum
[
let boardcnt = 0
let endlength = 0
Zero(Enet,Lnet)
Enode>>node.NewX = -1
let nodestr = vec 20
//new read in all the nets
[
ReadInNet(net,node,BdNum,nodestr)
if (net>>net.edgechar & (EdgePins&6)) ne 0 do
[
if Debug gr 0 then Msg("$S$D,", nodestr, BdNum)
//ComputeOnBdDelays(net)
MakeEdgeNode(Enode,node,BdNum)
ProcessEdgeNet(Enet,net,Enode,BdNum)
boardcnt = boardcnt+1
endlength = net>>net.length.end
]
Zero(net,Lnet)
BdNum = FindNextNet(netBuf); if Done then break
net = netBuf + Lnet*BdNum
if boardcnt ne 0 then
if StComp(lv net>>net.name,lv Enet>>net.name) ne 0 then break
] repeat
if Debug gr 0 then Msg("> ")
//now fix things up for funny nets

if boardcnt eq 1 then
[
Enet>>net.length.Lin=Enet>>net.length.end
Enet>>net.pins.Lin=Enet>>net.pins.end
Enet>>net.board.Lin=Enet>>net.board.end
Enet>>net.length.Lout=Enet>>net.length.end
Enet>>net.pins.Lout=Enet>>net.pins.end
Enet>>net.board.Lout=Enet>>net.board.end
]
if boardcnt gr 1 then Enet>>net.length.end = Enet>>net.length.end + endlength
if Enet>>net.inputs eq 0 then
[
Enet>>net.length.Lin=Enet>>net.length.end
Enet>>net.pins.Lin=Enet>>net.pins.end
Enet>>net.board.Lin=Enet>>net.board.end
]
if Enet>>net.outputs eq 0 then
[
Enet>>net.length.Lout=Enet>>net.length.end
Enet>>net.pins.Lout=Enet>>net.pins.end
Enet>>net.board.Lout=Enet>>net.board.end
]
ComputeEdgeDelays(Enet,boardcnt)
if Debug gr 0 then SendTab()
ListEdgeDelays(Enet,boardcnt)

TotalDelay = TotalDelay + Enet>>net.Dly
TotalLength = TotalLength + (Enet>>net.length.end+5)/10
Nets = Nets + 1
if Done then break

test screenEn
ifso unless Endofs(keys) do
[ Gets(keys);if Gets(keys) eq DEL then [ Msg("Aborted*n"); break ] ]
ifnot Puts(screen,$!)
] repeat

for f = 0 to LastFile do if fileVec!f ne 0 then Closes(fileVec!f)
]


and FindNextNet(netBuf) =valof

[
for Nnum = 0 to LastFile do //first fill in any un-used board slots
[
let net = netBuf + Lnet*Nnum
if net>>net.name.length eq 0 then //no net in this buffer, so go and get one
[
file = fileVec!Nnum; if file eq 0 then loop
FindNet(net)
if net>>net.name.char↑(net>>net.name.length) eq $! then
net>>net.name.length = net>>net.name.length-1
Done=false
]
]
let winner = 0 //nowdo an alphabetic sort on the string names
let wnet = 0
for n = 0 to LastFile do //now do an alphabet search on the net names
[
let net = netBuf + Lnet*n
if net>>net.name.length eq 0 then loop //not using this board
if wnet eq 0 then [ wnet = net; winner = n ]
if StComp(lv wnet>>net.name,lv net>>net.name) gr 0 then [ wnet = net; winner=n ]
]
if wnet eq 0 then Done=true //finished with all nets
resultis winner
]

and ProcessEdgeNet(Enet,net,Enode,BdNum) =valof

[
//if 1st entry of Enet, then set start of Edge net and start of board net
if Enet>>net.length.end eq 0 then
[
AppendS(lv Enet>>net.name,lv net>>net.name) //copy net name into Enet name
Enet>>net.length.end = net>>net.length.end
]

let NetLength = Enet>>net.length.end + Enode>>node.Distance
Enet>>net.length.end = NetLength
Enet>>net.board.end = BdNum

let NetPins = Enet>>net.pins.end
Enet>>net.pins.end = NetPins + net>>net.pins.end - 1 //subtract of the edge pin
Enet>>net.terms = Enet>>net.terms + net>>net.terms
let LengthToFin,PinsToFin,LengthToFout,PinsToFout = nil,nil,nil,nil
test net>>net.edgefirst
ifso //net looks like "eoi...oit"
[
LengthToFin = net>>net.length.Lin
PinsToFin = net>>net.pins.end - net>>net.pins.Lin + 1
LengthToFout = net>>net.length.Lout
PinsToFout = net>>net.pins.end - net>>net.pins.Lout + 1
if net>>net.terms gr 0 then net>>net.stubl = net>>net.length.end - net>>net.stubl
]
ifnot //net looks like "toi...oie"
[
LengthToFin = net>>net.length.end - net>>net.length.Fin
PinsToFin = net>>net.pins.Fin
LengthToFout = net>>net.length.end - net>>net.length.Fout
PinsToFout = net>>net.pins.Fout
]

if net>>net.stubl gr Enet>>net.stubl then
[
Enet>>net.stubl = net>>net.stubl
Enet>>net.stubp = net>>net.pins.end
]

if net>>net.inputs gr 0 then
[
if Enet>>net.inputs eq 0 then //put first one on the front
[
Enet>>net.length.Fin = NetLength - LengthToFin
Enet>>net.pins.Fin = NetPins + PinsToFin
Enet>>net.board.Fin = BdNum
]

//always put on the end
Enet>>net.length.Lin = NetLength + LengthToFin
Enet>>net.pins.Lin = Enet>>net.pins.end - PinsToFin + 1
Enet>>net.board.Lin = BdNum

Enet>>net.inputs = Enet>>net.inputs + net>>net.inputs
]
if net>>net.outputs gr 0 then
[
if Enet>>net.outputs eq 0 then //put first one on the front
[
Enet>>net.length.Fout = NetLength - LengthToFout
Enet>>net.pins.Fout = NetPins + PinsToFout
Enet>>net.board.Fout = BdNum
]

//always put on the end
Enet>>net.length.Lout = NetLength + LengthToFout
Enet>>net.pins.Lout = Enet>>net.pins.end - PinsToFout + 1
Enet>>net.board.Lout = BdNum

Enet>>net.outputs = Enet>>net.outputs + net>>net.outputs
]
]

and MakeEdgeNode(Enode,node,BdNum) be

[
Enode>>node.OldX = Enode>>node.NewX; Enode>>node.OldY = Enode>>node.NewY
Enode>>node.NewX = node>>node.NewX; Enode>>node.NewY = BdNum*BdSpacing
FindDistance(Enode)
]

and ComputeEdgeDelays(net, boardcnt) be
[
let Dly,otherDly = 0,0
let L = net>>net.stubl
let P = net>>net.stubp
let WOrDly = FindDelay(L, P,"s")

Debug = Debug+1
if (net>>net.board.Lin - net>>net.board.Fout) ge (boardcnt gr 1? 1, 0) then
[
L = net>>net.length.Lin - net>>net.length.Fout
P = (net>>net.pins.Lin - net>>net.pins.Fout) + 1
Dly = FindDelay(L, P,"f")
]

if (net>>net.board.Lout - net>>net.board.Fin) ge (boardcnt gr 1? 1, 0) then
[
L = net>>net.length.Lout - net>>net.length.Fin
P = (net>>net.pins.Lout - net>>net.pins.Fin) + 1
otherDly = FindDelay(L, P,"r")
]

if otherDly gr Dly then Dly = otherDly //use the greater
net>>net.WOrDly = WOrDly
net>>net.Dly = Dly
net>>net.length.end = net>>net.length.end
Debug = Debug-1
]

and ListEdgeDelays(net,
boardcnt) be
[
let DlyInt, DlyFraction = net>>net.Dly/10, net>>net.Dly rem 10
let StubInt, StubFraction = net>>net.WOrDly/5, (net>>net.WOrDly*2) rem 10//2*StubDly
let LenInt, LenFraction = net>>net.length.end/10, net>>net.length.end rem 10
DlyTable!DlyInt = DlyTable!DlyInt+1
let Fok = true
if Fok then if boardcnt ls 2 then [ Msg("$DB ",boardcnt); Fok=0 ]
if Fok then if net>>net.terms gr 2 then [ Msg("$DT ",net>>net.terms); Fok=0 ]
if Fok then if net>>net.inputs eq 0 then [ Msg("0L "); Fok=0 ]
if Fok then if net>>net.outputs eq 0 then [ Msg("0S "); Fok=0 ]
if Fok then if (net>>net.clocknet) & (StubInt ge 1) then [ Msg("$Dsc", StubInt); Fok=0 ]
if Fok then if StubInt ge 3 then [ Msg("$Ds ", StubInt); Fok=0 ]
if Fok then if (net>>net.clocknet) & (DlyInt ge 3) then [ Msg("$Ddc", DlyInt); Fok=0 ]
if Fok then if DlyInt ge 5 then [ Msg("$Dd ", DlyInt); Fok=0 ]
if Fok then Msg(" ")
Msg("$S($D.$D)",lv net>>net.name, LenInt, LenFraction); SendTab()
Msg ("Dly=$D.$D; ",DlyInt, DlyFraction)
Msg ("S=$D; ",net>>net.outputs)
Msg ("L=$D",net>>net.inputs + net>>net.mufpins)
if net>>net.terms gr 0 then Msg ("; T=$D",net>>net.terms)
if net>>net.WOrDly gr 20 then Msg ("; Stub=$D.$D",StubInt, StubFraction)
Msg("*n")
]