-- wiresCreate3.mesa DIRECTORY SystemDefs:FROM"SystemDefs", AltoFileDefs:FROM"AltoFileDefs", DirectoryDefs:FROM"DirectoryDefs", DisplayDefs:FROM"DisplayDefs", SegmentDefs:FROM"SegmentDefs", StreamDefs:FROM"StreamDefs", StringDefs:FROM"StringDefs", WiresDefs:FROM"WiresDefs", IODefs:FROM"IODefs"; WiresCreate:PROGRAM IMPORTS SystemDefs, IODefs, StreamDefs, DirectoryDefs,StringDefs,WiresDefs EXPORTS WiresDefs =BEGIN OPEN WiresDefs; Error:SIGNAL=CODE; nullLoc: Location=[NULL,127,127]; EnumerateCircuit:PROCEDURE[call:OnI]= BEGIN i:INTEGER; FOR i IN [0..topCircuit) DO call[i]; ENDLOOP; END; --//////////////WIRE LIST Stuff/////////////// wireListArray:TYPE=ARRAY [0..maxWireNo] OF Wire; wireList:POINTER TO wireListArray_NIL; maxWireNo:INTEGER=3*maxSide*maxSide; topWire:INTEGER; EnumerateWires:PUBLIC PROCEDURE[call:PROCEDURE[INTEGER,WirePtr]]=BEGIN i:INTEGER; FOR i IN [0..topWire) DO call[i,@wireList[i]]; ENDLOOP; END; WireLength:PUBLIC PROCEDURE[i,j:Location] RETURNS[INTEGER]=BEGIN RETURN[ABS[i.i-j.i]+ABS[i.j-j.j]]; END; MakeWireList:PUBLIC PROCEDURE[print:BOOLEAN]= BEGIN MakeTrack[]; -- chain the transistors topWire_0; EnumerateCircuit[WireListOneCircuit]; SortWireList[]; IF print THEN PrintWireList; END; AddToWireList:PROCEDURE[w:Wire]=BEGIN wireList[topWire]_w; topWire_topWire+1; IF topWire>maxWireNo THEN Error; END; PrintWireList:PUBLIC PROCEDURE=BEGIN EnumerateWires[PrintWireListEntry]; END; PrintWireListEntry:PROCEDURE[i: INTEGER, w:WirePtr]=BEGIN OPEN IODefs; WriteNumber[i,[10,FALSE,TRUE,4]]; WriteString[" Circuit"]; WriteNumber[w.circuit,[10,FALSE,TRUE,3]]; WriteString[" length"]; WriteNumber[w.l,[10,FALSE,TRUE,3]]; WriteString[" from "]; WriteLocation[w.a]; WriteString[" to "]; WriteLocation[w.b]; WriteChar[CR]; END; colorStrings:ARRAY Color OF STRING=["none "," red ","green","blue ","yel. "]; WriteLocation:PROCEDURE[l:Location]=BEGIN OPEN IODefs; WriteNumber[l.i,[10,FALSE,TRUE,2]]; WriteChar[',]; WriteNumber[l.j,[10,FALSE,TRUE,2]]; WriteString[SELECT l.contact FROM chanA=>" chanA", gate=>" gate", chanB=>" chanB", ENDCASE=>ERROR]; END; thisW:INTEGER; WireListOneCircuit:PROCEDURE[i:INTEGER]=BEGIN -- IF i=vdd OR i=gnd THEN RETURN; thisW_i; InitTemp[]; EnumerateTrack[i,AddToTemp]; EnumerateTemp[InitSep]; EnumerateTemp[FindAndUseNextSmallestTemp]; END; SortWireList:PROCEDURE=BEGIN i,j:INTEGER; FOR i IN [0..topWire) DO FOR j IN (i..topWire) DO IF ShorterWire[j,i] THEN BEGIN temp:Wire_wireList[i]; wireList[i]_wireList[j]; wireList[j]_temp; END; ENDLOOP; ENDLOOP; END; ShorterWire:PROCEDURE[i,j:INTEGER] RETURNS[BOOLEAN]=BEGIN wi:WirePtr_@wireList[i]; wj:WirePtr_@wireList[j]; nonGreeni:BOOLEAN_wi.a.contact=gate OR wi.b.contact=gate; nonGreenj:BOOLEAN_wj.a.contact=gate OR wj.b.contact=gate; circuiti:INTEGER_SELECT wi.circuit FROM gnd=>3,vdd=>2,ENDCASE=>1; circuitj:INTEGER_SELECT wj.circuit FROM gnd=>3,vdd=>2,ENDCASE=>1; RETURN[IF circuiti#circuitj THEN circuitimaxTemp THEN Error; END; FindAndUseNextSmallestTemp:PROCEDURE[i:INTEGER]=BEGIN bestj:INTEGER; best:INTEGER_10000; k:INTEGER=i; FindClosest:OnI=BEGIN l:INTEGER_WireLength[wireTemp[i],wireTemp[k]]; IF wireSep[k]#wireSep[i] AND ltrack[l.i][l.j].a , gate=>track[l.i][l.j].b, chanB=>track[l.i][l.j].c, ENDCASE => ERROR UNTIL l=nullLoc DO Call[l]; ENDLOOP; END; ValidCircuit:PROCEDURE[i:INTEGER] RETURNS[BOOLEAN]= BEGIN RETURN[circuits[i]#nullLoc];END; ClearCircuit:PROCEDURE[i:INTEGER]=BEGIN circuits[i]_nullLoc; END; ClearTrack:PROCEDURE[i,j:INTEGER]= BEGIN track[i][j]_[nullLoc,nullLoc,nullLoc]; END; BuildTrack:PROCEDURE[i,j:INTEGER]=BEGIN s,t,w:Circuit; [s,t,w]_grid[i][j]; IF s ~IN [0..topCircuit] OR t ~IN [0..topCircuit] OR w ~IN [0..topCircuit] THEN Error; track[i][j]_[circuits[s],circuits[t],circuits[w]]; IF t=s THEN track[i][j].b_[chanA,i,j] -- Handle pullups ELSE IF t=w THEN track[i][j].b_[chanB,i,j]; circuits[s]_[chanA,i,j]; circuits[w]_[chanB,i,j]; circuits[t]_[gate,i,j]; -- If s=t or w=t this will override. It's OK. END; --//////////////INPUT STUFF/////////////// GetInput:PUBLIC PROCEDURE[print:BOOLEAN,circuitName: STRING]=BEGIN OPEN AltoFileDefs,IODefs,DirectoryDefs,StreamDefs, SegmentDefs,StringDefs; kbdStream,otherStream,currentStream: StreamHandle; pInFileFP: POINTER TO FP; inFileFP: FP; fileNameValid,readFromKbd: BOOLEAN; inFileName: STRING _ [40]; inputLine: STRING _ [80]; tempString: STRING_[10]; inputTail: SubString; ChompDecimal: PROCEDURE[src: SubString] RETURNS[INTEGER]=BEGIN OPEN StringDefs; i,j,sign,wall: INTEGER; wall _src.offset+src.length-1; -- mark the end of line i _ src.offset; j _ 0; WHILE IF i<= wall THEN src.base.text[i]=' ELSE FALSE DO i _ i+1; ENDLOOP; -- skip blanks IF src.base.text[i]='- THEN BEGIN sign_-1; i_i+1 END ELSE sign_1; IF src.base.text[i] NOT IN ['0..'9] THEN Error; WHILE IF i<= wall THEN src.base.text[i] IN ['0..'9] ELSE FALSE DO j _ 10*j+(src.base.text[i]-'0); i _ i + 1; ENDLOOP; src.length_src.length-(i-src.offset); src.offset_i; RETURN[sign*j]; END; ChompID: PROCEDURE[src: SubString, dest:STRING]=BEGIN OPEN StringDefs; i,wall: INTEGER; temp: SubString; tempD: SubStringDescriptor; temp _ @tempD; tempD.base_src.base; dest.length_0; wall _src.offset+src.length-1; -- mark the end of line i _ src.offset; WHILE IF i<= wall THEN src.base.text[i]=' ELSE FALSE DO i _ i+1; ENDLOOP; -- skip initial blanks tempD.offset_i; tempD.length_0; WHILE IF i<= wall THEN src.base.text[i]#' ELSE FALSE DO i _ i + 1; tempD.length_tempD.length+1; ENDLOOP; AppendSubString[dest,temp]; src.length_src.length-(i-src.offset); src.offset_i; END; ParseTransistor: PRIVATE PROCEDURE RETURNS[BOOLEAN]=BEGIN OPEN IODefs, StreamDefs, StringDefs; a,b,c: INTEGER; i,j: INTEGER; IF (IF currentStream#kbdStream THEN TRUE ELSE ~currentStream.endof[currentStream]) -- blame kbdStream lossage THEN BEGIN -- parse a line -- ReadLine[inputLine]; inputTail^ _SubStringDescriptor[inputLine,0,inputLine.length]; i _ ChompDecimal[inputTail]; IF i < 0 THEN RETURN[FALSE]; j _ ChompDecimal[inputTail]; IF (i NOT IN [1..side]) OR (j NOT IN [1..side]) THEN Error; ChompID[inputTail,tempString]; a _ CPTI[tempString]; ChompID[inputTail,tempString]; b _ CPTI[tempString]; ChompID[inputTail,tempString]; c _ CPTI[tempString]; grid[i][j]_[a,b,c]; END ELSE RETURN[FALSE]; RETURN[TRUE]; END; -- of ParseTransistor -- -- begin body of GetInput pInFileFP_@inFileFP; fileNameValid _ readFromKbd _ FALSE; UNTIL fileNameValid DO WriteString["Enter the Name of the File for Input:"]; ReadID[inFileName]; WriteChar[CR]; IF inFileName.length=0 THEN fileNameValid _ readFromKbd _ TRUE ELSE fileNameValid_DirectoryLookup[pInFileFP,inFileName,FALSE]; ENDLOOP; circuitName.length_0; WHILE circuitName.length<20 AND inFileName.text[circuitName.length]#'. DO circuitName.text[circuitName.length]_inFileName.text[circuitName.length]; circuitName.length_circuitName.length+1; ENDLOOP; currentStream _ kbdStream _ GetInputStream[]; IF readFromKbd THEN WriteLine["Input from Keyboard Requested. Proceed."] ELSE BEGIN currentStream _ otherStream _NewByteStream[inFileName,Read]; SetInputStream[otherStream]; END; -- Get first line to decide on the size -- ReadLine[inputLine]; inputTail^ _[inputLine,0,inputLine.length]; side _ ChompDecimal[inputTail]; IF side>maxSide THEN BEGIN IODefs.WriteLine["ABORT!! side>maxSide. You have to recompile."]; ERROR; END; InitAtoms[]; EnumerateGrid[ClearGrid]; WHILE ParseTransistor[] DO NULL; ENDLOOP; IF ~readFromKbd THEN BEGIN SetInputStream[kbdStream]; otherStream.destroy[otherStream]; END; IF print THEN PrintG[]; END; --///////////////PRINTING////////////// PrintG:PUBLIC PROCEDURE=BEGIN OPEN IODefs,StreamDefs; i,j: INTEGER; output: StreamHandle; output_GetOutputStream[]; printGrid_grid; IODefs.WriteChar[CR]; -- Write a Header Line IODefs.WriteString["j(y)\i(x)"]; FOR i IN (0..side] DO IODefs.OutNumber[output,i, NumberFormat[10,FALSE,FALSE,11] ]; ENDLOOP; IODefs.WriteChar[CR]; IODefs.WriteChar[CR]; -- Write out the Grid. FOR j DECREASING IN (0..side] DO -- handle the y's IODefs.OutNumber[output,j,NumberFormat[10,FALSE,FALSE,11] ]; FOR i IN (0..side] DO -- x coordinate PrintGrid[i,j]; ENDLOOP; IODefs.WriteChar[CR]; ENDLOOP; END; PrintGSection:PUBLIC PROCEDURE=BEGIN printGrid_grid; IODefs.WriteChar[CR]; EnumerateGrid[PrintGridSection]; END; PrintGrid:PROCEDURE[i,j:INTEGER]=BEGIN OPEN IODefs; WriteChar[' ]; WriteId[printGrid[i][j].a]; WriteId[printGrid[i][j].b]; WriteId[printGrid[i][j].c]; WriteChar[' ]; END; PrintGridSection:PROCEDURE[i,j:INTEGER]=BEGIN OPEN IODefs; x:INTEGER; IF j=0 THEN WriteChar[CR]; x_MAX[FindSectionId[printGrid[i][j].a], FindSectionId[printGrid[i][j].b], FindSectionId[printGrid[i][j].c]]; WriteChar[SELECT x FROM -1=>'x,0=>'0,1=>'1,2=>'2,3=>'3,4=>'4, 5=>'5,6=>'6,7=>'7,8=>'8,ENDCASE=>'9]; END; WriteId:PROCEDURE[a:INTEGER]=BEGIN IF a=nullCircuit THEN IODefs.WriteString[" "] ELSE BEGIN IODefs.WriteChar[' ]; IODefs.WriteChar[atoms[a].a]; IODefs.WriteChar[atoms[a].b]; END; END; FindSectionId:PROCEDURE[a:INTEGER] RETURNS[INTEGER]=BEGIN IF a=gnd THEN RETURN[-1]; RETURN[SELECT atoms[a].a FROM '0,' =>0, '1=>1, '2=>2, '3=>3, '4=>4, '5=>5, '6=>6, '7=>7, '8=>8, ENDCASE=>-1]; END; --/////////////ATOMS////////////// Id:TYPE=RECORD[a,b:CHARACTER]; atoms:ARRAY[0..maxAtom+3] OF Id; maxAtom:INTEGER=200; topAtom,vdd,gnd:INTEGER; tempString:STRING_[6]; InitAtoms:PROCEDURE=BEGIN gd: STRING="gd"; vd: STRING="vd"; topAtom_0; gnd_CPTI["gd"]; vdd_CPTI["vd"]; END; CPTI:PROCEDURE[inStr:STRING] RETURNS[b:INTEGER]=BEGIN id: Id; i:INTEGER; IF inStr.length=1 THEN id _[' ,inStr.text[0]] ELSE id _[inStr.text[0],inStr.text[1]]; FOR i IN [0..topAtom) DO IF id=atoms[i] THEN RETURN[i]; ENDLOOP; atoms[topAtom]_id; topAtom_topAtom+1; IF topAtom>maxAtom THEN Error; RETURN[topAtom-1]; END; END.. (1792)\i3I12i6I866b14B240b12B192b13B2179b13B89b8B72b9B110b26B