! SDA: a Simple Design Aid for the BEPI Solderwrap Machine ! RWT Sept 1988 %begin %externalintegerfnspec heapget(%integer n) %externalintegerfnspec stoi(%string(255)s) %externalstring(255)%fnspec itos(%integer n,p) ! Simple list and stack processing %recordformat cellfm(%record(cellfm)%name next,%integer item) %recordformat stackfm(%record(cellfm)%name head,%integer size) %predicate empty(%record(stackfm)%name stack) %trueif stack_head==nil; %false %end %routine push(%integer item,%record(stackfm)%name stack) %record(cellfm)%name cell cell == new(cell) cell_next == stack_head cell_item = item stack_head == cell stack_size = stack_size+1 %end %integerfn pop(%record(stackfm)%name stack) %record(cellfm)%name cell %integer item cell == stack_head item = cell_item stack_head == cell_next stack_size = stack_size-1 dispose(cell) %result = item %end %record(*)%map reverse(%record(*)%name list) ! Reverse an arbitrary list, assuming its links are in the first field. %recordformat f(%record(f)%name next) %record(f)%name h == list, t == nil, c %while h##nil %cycle c == h; h == c_next; c_next == t; t == c %repeat %result == t %end %routine invert(%record(stackfm)%name stack) ! Invert a stack (i.e. reverse its list) stack_head == reverse(stack_head) %end %routine lengthen(%record(stackfm)%name stack,%integer size) ! Replicate the top of STACK until SIZE items are on it. push(stack_head_item,stack) %while stack_size='a' h = h+h+k %if num#0 %start num = 0 %unless 0<=k-'0'<=9 %if num#0 %start num = 0 %if n<=-3276 %or (n=-3276 %and k>'7') n = n*10-k+'0' %if num#0 %finish %finish i = i+1 %repeatuntil i>length(s) %result = n-1 %unless num=0 %if initialised=0 %start initialised = 1 hashtable(i) == nil %for i = 0,1,hashmax-1 %finish h = h&(hashmax-1); n = 0; rec == hashtable(h) %while rec##nil %cycle %result = addr(rec_s) %if rec_s=s rec == rec_next %repeat rec == new(rec) rec_s == newstring(s) rec_next == hashtable(h); hashtable(h) == rec %result = addr(rec_s) %end %string(255)%fn decode(%integer n) ! Reconstitute a string from its encoded value. %string(255)s s = "" %if n<0 %start s = itos(-1-n,0) %elseif n>0 s = string(n) %finish %result = s %end %routine increment(%string(255)%name item, %string(255)from,to,%integer by) ! ITEM is incremented by the amount specified in BY (usually 1). ! The increment is either added or subtracted depending on the ! values in the starting and ending items FROM and TO. This ! proceeds by "field", starting from the end of the string. Fields ! are either numeric or not. It is assumed that corresponding fields ! in FROM, ITEM, and TO are compatible, but should ITEM or TO be ! incomplete (fields missing on the left), they will inherit the ! appropriate fields from FROM. ! Calling this with BY=0 may therefore be used to "complete" a string. ! Whenever a field "wraps round", a carry is made to the next ! (preceeding) field. Non-numeric fields are incremented a character ! at a time, numeric fields are always taken as a whole (and are assumed ! to be in decimal). Fields which are the same in FROM and TO are ! skipped, e.g. with FROM="ABACD" and TO="ABZCD", "ABPCD"+1 would be ! "ABQCD". The direction (add/subtract) of incrementation is field ! specific, and it is quite possible for one field to count up and ! another to count down. %string(255)tail="" %bytename i==length(item),f==length(from),t==length(to) %integer ni,nf,nt,wi,wf,wt %routine strip off(%string(*)%name s,%integername n,w) ! S is a string which ends in a numeric field. ! Extract that field into N and note its width in W. The string ! is shortened by W, i.e. the field is stripped off. %integer k,r=1 w = 0; n = 0 %while length(s)>0 %cycle k = charno(s,length(s))-'0' %exitif k<0 %or k>9 n = k*r+n; r = r*10; w = w+1 length(s) = length(s)-1 %repeat %end %while f>0 %cycle to = from %if to="" {inherit} item = from %if item="" {inherit} ni = charno(item,i) {inspect last character in each} nf = charno(from,f) nt = charno(to,t) %if nf<'0' %or nf>'9' %start {non-numeric} i = i-1; f = f-1; t = t-1 {strip off} %unless by=0 %start %if nfnt %elseif nf>nt {subtract} ni = ni-by; by = 0 ni = ni-nt+nf+1 %and by = by+1 %while nint %else ni = ni-by; by = 0 ni = ni-nt+nf+1 %and by = by+1 %while ni sf.("/").st %cycle process name list(sf,stack); si = st %repeat %if si -> sf.(":").st %start si = "1" %unless st -> si.(":").st %if compatible(sf,st) %start by = number(si) %if by=0 %start push(encode(sf),stack) push(encode(st),stack) %else si = sf increment(st,sf,st,0) push(encode(sf),stack) %unless sf=st %start %cycle increment(si,sf,st,by) push(encode(si),stack); limit = limit-1 %repeatuntil limit<0 %or si=st %if limit<=0 %start error; printstring("Sequence "); printstring(sf); printsymbol(':') printstring(st); printstring(" is excessively long") newline by = pop(stack) %for limit = 1,1,max push(encode(st),stack) %return %finish %finish %finish %else error; printstring(sf); printstring(" and ") printstring(st); printstring(" are not compatible "); newline push(encode(sf),stack) push(encode(st),stack) %finish %else push(encode(si),stack) %finish %end %routine process number list(%string(255)si,%record(stackfm)%name stack) ! Similar to above but with numbers instead of names %string(255)sf,st %constinteger max=128 %integer f,i,t,by,limit=max %while si -> sf.("/").st %cycle process number list(sf,stack); si = st %repeat %if si -> sf.(":").st %start si = "1" %unless st -> si.(":").st f = number(sf) t = number(st) by = number(si) %if by=0 %start push(f,stack) push(t,stack) %unless f=t %else i = f push(f,stack) %unless f=t %start %cycle %if f' ' s = tostring(pendsym) %if special(pendsym) %then pendsym = -1 %elsestart %cycle readsym(pendsym) %exitif pendsym<=' ' %or special(pendsym) s = s.tostring(pendsym) %repeat pendsym = -1 %if pendsym<=' ' %finish %finish %end ! Main program variables %constinteger collim=100,rowlim=200 %integerarray colpos(1:collim),rowpos(1:rowlim) %integer maxcol=0,maxrow=0 %string(255)item %constinteger implicit=0,in=1,inout=2,out=3 {pin types} %conststring(8)%array pin type(0:3)=- "implicit","input","in/out","output" %recordformat packpinfm (%record(packpinfm)%name next, %integer name,x,y) %recordformat chippinfm (%record(chippinfm)%name next, %integer signal,type, %record(packpinfm)%name pin) %recordformatspec netfm %recordformat comppinfm (%record(comppinfm)%name next, %record(chippinfm)%name pin, %record(netfm)%name net) %recordformatspec compfm %recordformat netpinfm (%record(netpinfm)%name next, %record(compfm)%name comp, %record(comppinfm)%name pin) %recordformat packfm (%record(packfm)%name next, %integer name, %record(packpinfm)%name pins) %recordformat chipfm (%record(chipfm)%name next, %integer name, %record(packfm)%name pack, %record(chippinfm)%name pins) %recordformat compfm (%record(compfm)%name next, %integer name,x,y,angle, %record(chipfm)%name chip, %record(comppinfm)%name pins) %recordformat netfm (%record(netfm)%name next, %integer name, %record(netpinfm)%name pins) %record(packfm)%name packs==nil %record(chipfm)%name chips==nil %record(compfm)%name comps==nil %record(netfm)%name nets==nil,netnets==nil,pagnets==nil %routine position(%record(compfm)%name c,%record(packpinfm)%name p, %integername x,y) ! Set X,Y to the position of pin P of component C taking ! into account the rotation specified for the component. %integer s %switch sw(0:3) ->sw(c_angle) sw(0): x = c_x+p_x; y = c_y+p_y; ->check sw(1): x = c_x-p_y; y = c_y+p_x; ->check sw(2): x = c_x-p_x; y = c_y-p_y; ->check sw(3): x = c_x+p_y; y = c_y-p_x check: %unless 00 %return %finish %exitif item="," process number list(item,stack) %repeat invert(stack) %whilenot empty(stack) %cycle last = -1; last = colpos(maxcol) %unless maxcol=0 maxcol = maxcol+1 this = pop(stack) colpos(maxcol) = this %if maxcol=1 %and this<=0 %start error; printstring("Column coordinates must be positive"); newline %elseif maxcol&1#0 %and this-last<2 error; printstring("Even/odd column spacing must be at least 2, not ") write(this-last,0); printstring(" as between ") write(maxcol-1,0); printstring(" and "); write(maxcol,0); newline %elseif maxcol&1=0 %and this-last#3 error; printstring("Odd/Even column spacing must be 3, not ") write(this-last,0); printstring(" as between ") write(maxcol-1,0); printstring(" and "); write(maxcol,0); newline %finish %repeat ! Read row data stack = 0 %cycle readitem(item) %until item#"," %exitif item="]" process number list(item,stack) %repeat invert(stack) %whilenot empty(stack) %cycle last = 0; last = rowpos(maxrow) %unless maxrow=0 maxrow = maxrow+1 this = pop(stack) rowpos(maxrow) = this %if maxrow=1 %and this<=0 %start error; printstring("Row coordinates must be positive"); newline %elseif maxrow>1 %and this-last#1 error; printstring("Row spacing must be 1, not ") write(this-last,0); printstring(" as at "); write(maxrow-1,0) printstring(" and "); write(maxrow,0); newline %finish %repeat readitem(item) %end %routine read package data ! Note that the first item has already been read. %string(255)packname,pinname,xname,yname %record(stackfm)pin,x,y %record(packfm)%name pack %record(packpinfm)%name packpin %predicate duplicated %record(packpinfm)%name duppin %string(255)s,t duppin == pack_pins %cycle %falseif duppin==nil %if packpin_name=duppin_name %start s = decode(packpin_name) error; printstring("Duplicate pin "); printstring(s); newline %true %finish %if packpin_x=duppin_x %and packpin_y=duppin_y %start s = decode(packpin_name) t = decode(duppin_name) error; printstring("Coincident pins ") printstring(s); printstring(" and "); printstring(t); newline %true %finish duppin == duppin_next %repeat %end packname = item %while packname#";" %cycle readitem(item) %until item="(" line; printstring(packname); newline pack == new(pack); pack_pins == nil; pack_name = encode(packname) pack_next == packs; packs == pack pin = 0; x = 0; y = 0 %cycle readitem(pinname) %until pinname#"," %exitif pinname=")" process name list(pinname,pin) readitem(item); xname = item %if item=")" %or item="," %start error; printstring("No XY for "); printstring(pinname); newline %exitif item=")" %finishelse process number list(xname,x) lengthen(x,pin_size) readitem(item); yname = item %if item=")" %or item="," %start error; printstring("No Y for "); printstring(pinname); newline %exitif item=")" %finishelse process number list(yname,y) lengthen(y,pin_size) %while x_size>pin_size %cycle error; printstring("Spurious X offset "); write(pop(x),0) printstring(" in package "); printstring(packname); newline %repeat %while y_size>pin_size %cycle error; printstring("Spurious Y offset "); write(pop(y),0) printstring(" in package "); printstring(packname); newline %repeat %repeat invert(pin); invert(x); invert(y) %whilenot empty(pin) %cycle packpin == new(packpin) packpin_name = pop(pin) packpin_x = pop(x) packpin_y = pop(y) %unless duplicated %start packpin_next == pack_pins; pack_pins == packpin %finish %repeat readitem(packname) %repeat newline %end %routine read chip data %string(255)chipname,packname,signalname,pinname %record(stackfm)signal,pin %record(chipfm)%name chip %record(chippinfm)%name chippin %integer type %record(packfm)%map findpack(%integer name) %record(packfm)%name pack == packs %cycle %if pack==nil %start error; printstring("Unknown package ") printstring(decode(name)); newline %result == nil %finish %result == pack %if pack_name=name pack == pack_next %repeat %end %record(packpinfm)%map findpin(%integer name,%record(packfm)%name pack) %record(packpinfm)%name pin %result == nil %if pack==nil pin == pack_pins %cycle %if pin==nil %start error; printstring("Unknown pin ") printstring(decode(name)); newline %result == nil %finish %result == pin %if pin_name=name pin == pin_next %repeat %end %predicate duplicated %record(chippinfm)%name duppin %string(255)s duppin == chip_pins %cycle %falseif duppin==nil %if chippin_signal=duppin_signal %start %falseif chippin_type=implicit {allow multiple power/ground} s = decode(chippin_signal) error; printstring("Duplicate signal "); printstring(s); newline %true %finish %trueif duppin_pin==nil %if chippin_pin==duppin_pin %start s = decode(chippin_pin_name) error; printstring("Duplicate pin "); printstring(s); newline %true %finish duppin == duppin_next %repeat %end %cycle readitem(chipname); %exitif chipname=";" readitem(packname) readitem(item) %until item="(" line; printstring(chipname); space; printstring(packname); newline chip == new(chip) chip_name = encode(chipname) chip_pack == findpack(encode(packname)) chip_pins == nil chip_next == chips; chips == chip type = implicit %cycle signal = 0; pin = 0 %cycle readitem(item) %until item#"," %exitif item=";" %or item=")" signalname = item process name list(signalname,signal) readitem(item) pinname = item pinname = signalname %if item="," %or item=";" %or item=")" process name list(pinname,pin) lengthen(signal,pin_size) %while signal_size>pin_size %cycle signalname = decode(pop(signal)) error; printstring("Spurious signal name ") printstring(signalname); newline %repeat %exitif item=";" %or item=")" %repeat invert(signal); invert(pin) %whilenot empty(signal) %cycle chippin == new(chippin) chippin_signal = pop(signal) chippin_type = type chippin_pin == findpin(pop(pin),chip_pack) %unless duplicated %start chippin_next == chip_pins; chip_pins == chippin %finish %repeat %exitif item=")" %if type=out %start error; printstring("Too many ';'s"); newline readitem(item) %until item=")" %exit %finish type = type+1 %repeat %unless type=out %start error; printstring("Not enough ';'s"); newline %finish chip_pins == reverse(chip_pins) %repeat newline %end %routine read component data %string(255)compname,chipname,signalname,netname %integer col,row,x,y,angle,nc = encode("nc") %record(stackfm)signal,net %record(compfm)%name comp %record(netfm)%map findnet(%integer name) %record(netfm)%name n == nets %cycle %if n==nil %start n == new(n); n_name = name; n_pins == nil n_next == nets; nets == n %result == n %finish %result == n %if n_name=name n == n_next %repeat %end %routine findpin(%integer signal,%record(netfm)%name net) %record(chippinfm)%name chippin %record(comppinfm)%name comppin %record(netpinfm)%name netpin %string(255)s comppin == comp_pins %while comppin##nil %cycle %if comppin_pin_signal=signal %start s = decode(signal) error; printstring("Duplicate connection for ") printstring(s); newline %return %finish comppin == comppin_next %repeat chippin == comp_chip_pins %cycle %if chippin==nil %start s = decode(signal) error; printstring("Unknown pin "); printstring(s); newline %return %finish %exitif chippin_signal=signal chippin == chippin_next %repeat comppin == new(comppin) comppin_pin == chippin comppin_net == net comppin_next == comp_pins; comp_pins == comppin netpin == new(netpin) netpin_comp == comp netpin_pin == comppin netpin_next == net_pins; net_pins == netpin %end %routine findchip %integer name = encode(chipname) %record(chipfm)%name chip == chips %record(netpinfm)%name netpin %record(chippinfm)%name chippin %record(comppinfm)%name comppin comp == nil %cycle %if chip==nil %start error; printstring("Unknown chip "); printstring(chipname); newline %return %finish %exitif chip_name=name chip == chip_next %repeat comp == new(comp) comp_chip == chip comp_pins == nil comp_next == comps comps == comp chippin == chip_pins %while chippin##nil %cycle %if chippin_type=implicit %start comppin == new(comppin) comppin_pin == chippin comppin_net == findnet(chippin_signal) comppin_next == comp_pins; comp_pins == comppin netpin == new(netpin) netpin_comp == comp netpin_pin == comppin netpin_next == comppin_net_pins comppin_net_pins == netpin %finish chippin == chippin_next %repeat %end %routine check used %record(chippinfm)%name chippin == comp_chip_pins %record(comppinfm)%name comppin %string(255)s %while chippin##nil %cycle %unless chippin_type=implicit %start comppin == comp_pins %cycle %if comppin==nil %start s = decode(chippin_signal) error; printstring("Unused ") printstring(pintype(chippin_type)) printstring(" pin "); printstring(s) newline; %exit %finish %exitif comppin_pin==chippin comppin == comppin_next %repeat %finish chippin == chippin_next %repeat comppin == comp_pins %while comppin##nil %cycle comppin_net == nil %if comppin_net_name=nc comppin == comppin_next %repeat %end %cycle readitem(item) %exitif item=";" x = 0; y = 0; angle = 0 %if item="[" %start readitem(item) col = number(item) x = colpos(col) %unless col=0 readitem(item) %until ","#item#";" row = number(item) y = rowpos(row) %unless row=0 readitem(item) %if item="," %start readitem(item); angle = number(item); readitem(item) angle = angle//90 %if angle>3 {0/90/180/270 -> 0/1/2/3} angle = angle&3 %finish readitem(item) %while item#"]" readitem(item) %finish compname = item readitem(chipname) readitem(item) %until item="(" line; printstring(compname); space; printstring(chipname); newline findchip %if comp==nil %start readitem(item) %until item=")" %continue %finish comp_name = encode(compname) comp_x = x; comp_y = y; comp_angle = angle signal = 0; net = 0 %cycle readitem(item) %until item#"," %exitif item=")" signalname = item process name list(signalname,signal) readitem(netname) item = netname netname = signalname %if item="," %or item=")" process name list(netname,net) lengthen(net,signal_size) %while net_size>signal_size %cycle netname = decode(pop(net)) error; printstring("Spurious net "); printstring(netname); newline %repeat %exitif item=")" %repeat invert(signal); invert(net) %whilenot empty(signal) %cycle findpin(pop(signal),findnet(pop(net))) %repeat check used %repeat comps == reverse(comps) %end %routine write lis file(%string(255)file) ! This also has the side-effect of splitting the single list NETS ! into the two lists NETNETS and PAGNETS. A net is put into the ! latter category if any of the pins it visits is implicit. ! Single-pin nets are eliminated and I/O checks are made. %integerfn dif(%string(*)%name a,b) ! Returns -1/0/1 if ab %integer pa=1,pb=1,na,nb %cycle %if pa>length(a) %start %result = 0 %if pb>length(b) %result = -1 %finish %result = 1 %if pb>length(b) na = charno(a,pa)-'0'; pa = pa+1 nb = charno(b,pb)-'0'; pb = pb+1 %if 0<=na<=9 %and 0<=nb<=9 %start na = na*10+charno(a,pa)-'0' %and pa = pa+1 - %while pa<=length(a) %and '0'<=charno(a,pa)<='9' nb = nb*10+charno(b,pb)-'0' %and pb = pb+1 - %while pb<=length(b) %and '0'<=charno(b,pb)<='9' %finish %result = na-nb %unless na=nb %repeat %end %predicate netleq(%record(*)%name c,d) %record(netfm)%name a == c, b == d %string(255)na = decode(a_name), nb = decode(b_name) %trueif dif(na,nb)<=0; %false %end %predicate compleq(%record(*)%name c,d) %record(compfm)%name a == c, b == d %string(255)na = decode(a_name), nb = decode(b_name) %trueif dif(na,nb)<=0; %false %end %predicate npleq(%record(*)%name c,d) %record(netpinfm)%name a == c, b == d %string(255)na = decode(a_pin_pin_signal), nb = decode(b_pin_pin_signal) %trueif dif(na,nb)<=0; %false %end %predicate npcleq(%record(*)%name c,d) %record(netpinfm)%name a == c, b == d %string(255)na = decode(a_comp_name), nb = decode(b_comp_name) %trueif dif(na,nb)<=0; %false %end %predicate cpleq(%record(*)%name c,d) %record(comppinfm)%name a == c, b == d %string(255)na = decode(a_pin_signal), nb = decode(b_pin_signal) %trueif dif(na,nb)<=0; %false %end %record(*)%map sort(%record(*)%name list,%predicate leq(%record(*)%name a,b)) ! General purpose list sort using balanced merging algorithm. ! It is assumed the list is singly linked by its first field. %recordformat f(%record(f)%name next) %record(f)%name l==list,a==nil,b==nil,c %record(f)%map merge(%record(f)%name a,b) %record(f)%name h==nil,t %routine add(%record(f)%name c) %if h==nil %then h == c %else t_next == c; t == c %end %cycle %if b==nil %start %exitif a==nil add(a); a == a_next; t_next == nil %elseif a==nil add(b); b == b_next; t_next == nil %elseif leq(a,b) add(a); a == a_next; t_next == nil %else add(b); b == b_next; t_next == nil %finish %repeat %result == h %end %result == l %if l==nil %or l_next==nil %cycle c == l; %exitif c==nil; l == c_next; c_next == a; a == c c == l; %exitif c==nil; l == c_next; c_next == b; b == c %repeat a == sort(a,leq) b == sort(b,leq) %result == merge(a,b) %end %string(255)%fn padleft(%string(255)s,%integer n) s = " ".s %until length(s)>=n %result = s %end %string(255)%fn padright(%string(255)s,%integer n) s = s." " %until length(s)>=n %result = s %end %integerfn row(%integer y) ! Convert Y coordinate to row number, result 0 for invalid Y. %integer row %result = 0 %unless rowpos(1)<=y<=rowpos(maxrow) row = y-rowpos(1)+1 %result = row %if rowpos(row)=y %result = 0 %end %integerfn column(%integer x) ! Convert X coordinate to column number, result 0 for invalid X. ! Result negative for "extended" pins. %integer col,dif col = 1 %cycle %result = 0 %if col>maxcol dif = colpos(col)-x %result = col %if dif=0 %result = -col %if dif=-1 col = col+1 %result = 0 %if col>maxcol dif = colpos(col)-x %result = col %if dif=0 %result = -col %if dif=1 col = col+1 %repeat %end %routine netlist %string(255)netname %record(netfm)%name net %record(netpinfm)%name pin %integerarray n(implicit:out) %integername imps,ins,inouts,outs %integer x,y,pins,nc = encode("nc") imps == n(implicit) ins == n(in) inouts == n(inout) outs == n(out) nets == sort(nets,netleq) %cycle net == nets; %exitif net==nil; nets == net_next %continueif net_name=nc imps = 0; ins = 0; inouts = 0; outs = 0 pins = 0 netname = decode(net_name) selectoutput(1) newline; printstring(" Net "); printstring(netname) newline; newline net_pins == sort(net_pins,npleq) net_pins == sort(net_pins,npcleq) pin == net_pins %while pin##nil %cycle pins = pins+1 printstring(padleft(decode(pin_comp_chip_name),14)); space printstring(padright(decode(pin_pin_pin_signal),14)) printstring(padleft(padright(pintype(pin_pin_pin_type),9),11)) printstring(padleft(decode(pin_comp_name),11)); space printstring(padright(decode(pin_pin_pin_pin_name),5)) printstring(padleft(decode(pin_comp_chip_pack_name),9)) position(pin_comp,pin_pin_pin_pin,x,y) write(column(x),5); write(row(y),3); newline n(pin_pin_pin_type) = n(pin_pin_pin_type)+1 pin == pin_next %repeat selectoutput(0) %if pins=1 %start printstring("Ignoring single-pin net "); printstring(netname); newline net_pins == nil %elseif imps#0 net_next == pagnets; pagnets == net %if outs#0 %or inouts#0 %start printstring("Outputs drive implicit net "); printstring(netname); newline %finish %else net_next == netnets; netnets == net %if outs>1 %or (outs=1 %and inouts#0) %start printstring("Multiple outputs drive net "); printstring(netname); newline %finish %if ins+inouts=0 %start printstring("No inputs driven from net "); printstring(netname); newline %finish %finish %repeat %end %routine complist %integer x,y %record(compfm)%name comp == comps %record(comppinfm)%name pin comp == sort(comp,compleq) %while comp##nil %cycle newline printstring("Component "); printstring(decode(comp_name)) printstring(" (of type "); printstring(decode(comp_chip_name)) printstring(" in package "); printstring(decode(comp_chip_pack_name)) printsymbol(')'); newline; newline comp_pins == sort(comp_pins,cpleq); pin == comp_pins %while pin##nil %cycle printstring(padleft(decode(pin_pin_pin_name),6)); space printstring(padright(pintype(pin_pin_type),11)) printstring(padleft(decode(pin_pin_signal),12)); space %if pin_net==nil %start printstring("Not connected") %else printstring(padright(decode(pin_net_name),12)) position(comp,pin_pin_pin,x,y) write(column(x),5); write(row(y),3) %finish newline pin == pin_next %repeat comp == comp_next %repeat %end printstring("Writing "); printstring(file); newline openoutput(1,file); selectoutput(1) complist netlist selectoutput(1); closeoutput; selectoutput(0) %end %routine write crd file(%string(255)file) %integer i printstring("Writing "); printstring(file); newline openoutput(1,file); selectoutput(1) %for i = 1,1,maxcol %cycle write(colpos(i),0); newline %repeat closeoutput; selectoutput(0) %end %routine write cpl file(%string(255)file) %record(compfm)%name comp == comps %record(comppinfm)%name cp %record(packpinfm)%name pp %integer x,y %string(255)cn,pn %returnif maxcol=0 %or maxrow=0 printstring("Writing "); printstring(file); newline openoutput(1,file); selectoutput(1) %while comp##nil %cycle cn = decode(comp_name) %if comp_x=0 %or comp_y=0 %start selectoutput(0) printstring("Unplaced component "); printstring(cn); newline selectoutput(1) %else cp == comp_pins %while cp##nil %cycle pp == cp_pin_pin pn = decode(pp_name) printstring(cn); space; printstring(pn); space position(comp,pp,x,y) write(x*100,5); write(y*100,5); newline cp == cp_next %repeat %finish comp == comp_next newline %unless comp==nil %repeat closeoutput; selectoutput(0) %end %routine write net file(%string(255)file) %record(netpinfm)%name pin %string(255)nn,cn,pn printstring("Writing "); printstring(file); newline openoutput(1,file); selectoutput(1) %while nets##nil %cycle nn = decode(nets_name) pin == nets_pins %while pin##nil %cycle cn = decode(pin_comp_name) pn = decode(pin_pin_pin_pin_name) printstring(nn); space; printstring(cn); printsymbol('-') printstring(pn); newline pin == pin_next %repeat nets == nets_next newline %unless nets==nil %repeat closeoutput; selectoutput(0) %end openinput(1,cliparam.".sda") read column and row data read package data read chip data read component data write crd file(cliparam.".crd") write cpl file(cliparam.".cpl") write lis file(cliparam.".lis") nets == reverse(netnets); write net file(cliparam.".net") nets == reverse(pagnets); write net file(cliparam.".pag") %end