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

//Run BLDR with "BLDR/f NetDelays NetDelaysUtil template

get "Streams.d"
get "NetDelays.defs"


manifest MaxFiles=30

static
[
screen=0; file=0; Done=0; disko=0; screenEn=true; WLout=0; Fposn
Nets=0; Terminators = 0
DlyTable; ICtable; TermTable=0; MaxBoard
TotalLength=0; TotalDelay=0
Manhatten = 0; Debug = 0
Tb0; Tb1; Tb2; Tb3; Tb4; Tb5; LastFile=MaxFiles; fileVec; EdgePins=0
printedDly
]


let NetDelays(parm) be
[
Ws("*n*nNetDelays.run of January 7, 1979*n")

//first some data tables
let x = vec 2; Fposn = x
let x = vec 100; DlyTable = x; Zero(DlyTable,100)

let v = vec MaxFiles; Zero(v,MaxFiles)
fileVec = v
let v = vec (MaxFiles+1)*Lnet; Zero(v,(MaxFiles+1)*Lnet)
let FileName = v
let OutName = vec 40
let WLFileName = vec 40


file = OpenFile("Com.cm",ksTypeReadOnly,charItem)
let chr = GetStr(FileName,$/)
if chr eq $/ then //check for possible switches
[
chr = Char() & #137
if chr eq $M then Manhatten = true
if chr eq $D then screenEn = false
if chr eq $V then Debug = 3
if chr eq $W then WLout = true
if chr eq $E then EdgePins = EdgePins % $e
if chr eq $C then EdgePins = EdgePins % $c
if chr le #40 then break
] repeat

for i = 0 to MaxFiles do
[
if i ge MaxFiles then [ Wss(dsp,"To Many Files!!!(30 max)"); finish ]
let str = FileName+40*i
fileVec!i = str
GetStr(str)
if str>>str.char↑(str>>str.length-1) eq $/ then
[ ReadInTerminators(str); i=i-1; loop ]
if Done then [ LastFile = i; break ] //LastFile is left 1 to big
]
Closes(file) //close com.cm
//I now know how many files I will have to process

let wordsForICtable= (26*100)/8
if EdgePins ne 0 then wordsForICtable = wordsForICtable*LastFile
ICtable = GetSomeMem(wordsForICtable); Zero(ICtable,wordsForICtable)

//now set things up for back-pannel wiring
let FileZone = GetSomeMem(400*LastFile)
FileZone = InitializeZone(FileZone,400*LastFile)

//now set up the display window
let DCB = @#420
let fontHeight = DCB>>DCB.height*2
let Nlines = (700/fontHeight) - 6
let w = lv parm - 1000 - @#335
if w ls 0 then w = 30000
let v = GetSomeMem(w)
screen = CreateDisplayStream(Nlines,v, w)
ShowDisplayStream(screen,DSbelow)
if Debug eq 4 then PutTemplate(screen,"*nwords for screen buffer =$D.",w)

LastFile = LastFile-1 //new set it to be really right
file = 0
for i = 0 to LastFile do
[
if StEq(fileVec!i,"Blank") then [ fileVec!i = 0; loop ]
let S = OpenFile(fileVec!i,ksTypeReadOnly,charItem,0,0,0,FileZone)
if S eq 0 then [ PutTemplate(dsp,"Couldn’t find WL file $S *n",fileVec!i); return ]
if (S ne 0) & StEq(FileName,"Blank") then
[ FileName!0=0; AppendS(FileName,fileVec!i) ]
fileVec!i = S
]
Done = 0
file = fileVec!0


//Now make up the Output file name "FOO.wl = FOO.nd"
let extn = ".nd"
if EdgePins ne 0 then extn = ".End" //if E or (E and C) pins
if EdgePins eq $c then extn = ".Cnd" //juct C pins

MakeFileName(FileName,OutName,extn)
disko = OpenFile(OutName,ksTypeWriteOnly,charItem)

//Now make up the Output file name "FOO.wl = FOO.Ewl"
if EdgePins ne 0 then WLout = 0 //can’t handle WLout on muljtiple files
if WLout eq true then
[
MakeFileName(FileName,WLFileName,".Ewl")
WLout = OpenFile(WLFileName,ksTypeWriteOnly,charItem)
]

test Debug eq 0
ifso [ Tb0=90-Bf; Tb1=200-Bf; Tb2=220-Bf; Tb3=240-Bf ]
ifnot test EdgePins eq 0
ifso [ Tb0=310-Bf; Tb1=330-Bf; Tb2=435-Bf; Tb3=455-Bf ]
ifnot [ Tb0=300-Bf; Tb1=320-Bf; Tb2=425-Bf; Tb3=445-Bf ]
//first put on Bravo control stuff for two collumn printing
InitBravoFile(OutName)

test EdgePins ne 0
ifso DoEdgeNets(FileName+Lnet)
ifnot DoBoardNets()

//come back here on backpannel nets
Msg(" *n")
UnusedTerminators()
TypeResults()
Wss(disko,"*032\f1*n") //Bravo Paragraph break
Closes(disko)
if WLout then Closes(WLout)
PutTemplate(dsp,"Results written on file $S*n",OutName)
if WLout then PutTemplate(dsp,"Edge nets written on file $S*n",WLFileName)
PutTemplate(screen,"*n*nResults written on file $S. --- Type any character to quit.*n",OutName)
if screenEn then Gets(keys)
finish
]

and FindFirstNet(Bd) be
//skip over the location assignments noting MU10164 chips
[
if EdgePins ne 0 then Msg("$D=",Bd)
file = fileVec!Bd
if file eq 0 then [ Msg(";Blank*n"); return ]
Fposn!0=0; Fposn!1=0
FindChar($;) //skip to the first comment line
let c = $;
//first find and copy the first comment line of the input file to all other files
[
Puts(disko,c); Puts(screen,c)
if c eq $*n then break
c = Gets(file)
] repeat
//now skip the other comments, and note the parts list for special chips
[
let alpha = Char()
if alpha eq $*n then loop //its a blank line
if alpha eq $; then [ FindChar($*n); loop ] //its a comment line
if alpha eq $@ then break //done with IC location assignments
let num = GetNum()
FindChar($()
let str = vec 128
GetStr(str,$/)
if StEq(str,"TERM") then //a terminator
[
WhatICtype(alpha,num,Bd,Term)
Terminators = Terminators+1
]
if StEq(str,"MU10164") then
[
WhatICtype(alpha,num,Bd,MU)
if Debug ge 3 then Msg("Muffler at $C$D*n",alpha,num)
]
if StEq(str,"SE102") then //Selected Ecl 200 series gate
[
WhatICtype(alpha,num,Bd,SE)
if Debug ge 3 then Msg("Clock at $C$D*n",alpha,num)
]
FindChar($*n)
] repeat
if (Debug ge 3)&(Terminators ne 0) then Msg("Found $D Terminator ICs*n",Terminators)
FindChar($*n)
if WLout then CopyToWLFile()
]

and TypeResults() be
[
let aveLength = MulDiv(TotalLength,1000,Nets)
let aveDly = MulDiv(TotalDelay,100,Nets)
Msg("Total Nets = $D*n",Nets)
Msg("Average Net Length = $D.$3F0D",aveLength/1000, aveLength rem 1000)
test Manhatten
ifso Msg(" (based on Manhatten wire routing)*n")
ifnot Msg(" (based on Euclidean wire routing)*n")
Msg("Average Net Delay = $D.$3F0D*n*n",aveDly/1000, aveDly rem 1000)

for L = 0 to 60 do if DlyTable!L do
Msg("Total Nets with delays between $D and $D ns = $D*n",L,L+1,DlyTable!L)
]

and ReadInTerminators(name) be

[
let length = name>>str.length
if (name>>str.char↑length ‰) ne $T then [ Wss(dsp,"Invalid local switch"); finish ]
length = length - 2
name>>str.length = length
let S = file
file = OpenFile(name,ksTypeReadOnly,charItem)
if file eq 0 then [ PutTemplate(dsp,"Couldn’t find Terminator file $S *n",name); CallSwat() ]
TermTable = GetSomeMem(26); Zero(TermTable,26*MaxFiles)
MaxBoard = 0
let str = vec 128
[
let board = GetNum(); if Done then break
if board gr MaxBoard then MaxBoard = board
if board gr MaxFiles then [ Wss(dsp,"Invalid board terminator number"); finish ]
let lastC = LastChar
[
let ch = Char()
if (ch eq $*n) & (lastC eq $*n) then break; lastC = ch
if Done then break
ch = ch % #40 //convert to upper case
if (ch ne $e) & (ch ne $c) then loop
let num = GetNum(); lastC = LastChar
EdgePinTermination(ch,num,board,1)
] repeat
] repeat
Closes(file)
file = S; Done = false
GetSomeMem(26*MaxBoard)
]

and UnusedTerminators() be //report any remaning un-used terminators

[
if TermTable eq 0 then [ Msg("*n*n*n"); return ]
for Bd = 0 to MaxBoard do
[
let ch = $E
[
for pin = 0 to 199 do
[
if EdgePinTermination(ch%#40,pin, Bd) ne 0 then
Msg("*nUnused backpannel terminator on Board $D Pin $C$D.",Bd,ch,pin)
]
if ch eq $C then break
ch = $C
] repeat
]
Msg("*n*n*n")
]