-- DecoderImpl.mesa -- a program to run within Chipmonk -- last modified by E. McCreight, November 20, 1981 11:26 AM -- written by E. McCreight, August 7, 1981 3:52 PM DIRECTORY ChipUserInt, ppdefs, RomMakerDefs; DecoderImpl: PROGRAM IMPORTS ChipUserInt, ppdefs, RomMakerDefs EXPORTS RomMakerDefs = BEGIN OPEN ChipUserInt, ppdefs, RomMakerDefs; DecodePatternPtr: TYPE = LONG POINTER TO DecodePattern ← NIL; DecodePattern: TYPE = RECORD[ pattern: SEQUENCE max: INTEGER OF INTEGER]; BuildDecoder: PUBLIC PROCEDURE[] = BEGIN decoder: DCellPr; decoderTopLeftCorner, decoderLeftMid, decoderBottomLeftCorner: Cell; decoderLeft, decoderTop, decoderBottom, decoderRight: DCell; decoderTopMid, decoderBottomMid: Cell; decoderMidV, decoderMidH, decoderMidVH: Cell; decoderTopRightCorner, decoderRightMid, decoderBottomRightCorner: Cell; decodeCell: Cell; -- sample for measurements FindDecoderCells: PROCEDURE [cellFamily: STRING] = BEGIN decoder ← FindDCellPr[cellFamily: cellFamily, required: TRUE, memberPrefix: "Decode"L]; decodeCell ← decoder[TRUE][FALSE]; -- MidV is a vertical column of cells, MidH is a -- horizontal row of cells, and MidVH is the cell that -- happens at their intersections. decoderMidH ← FindCell[ cellFamily: cellFamily, member: "MidH"L, hCompat: decodeCell]; decoderMidV ← FindCell[ cellFamily: cellFamily, member: "MidV"L, vCompat: decodeCell]; decoderMidVH ← FindCell[ cellFamily: cellFamily, member: "MidVH"L, hCompat: decoderMidV, vCompat: decoderMidH, required: decoderMidV#NIL AND decoderMidH#NIL]; decoderLeft ← FindDCell[ cellFamily: cellFamily, memberPrefix: "Left"L, vCompat: decodeCell]; decoderLeftMid ← FindCell[ cellFamily: cellFamily, member: "LeftMid"L, vCompat: decoderMidH, required: decoderMidH#NIL]; decoderTopLeftCorner ← FindCell[ cellFamily: cellFamily, member: "TopLeftCorner"L]; decoderBottomLeftCorner ← FindCell[ cellFamily: cellFamily, member: "BottomLeftCorner"L]; decoderTop ← FindDCell[ cellFamily: cellFamily, memberPrefix: "Top"L, hCompat: decodeCell]; decoderTopMid ← FindCell[ cellFamily: cellFamily, member: "TopMid"L, hCompat: decoderMidV, required: decoderMidV#NIL]; decoderBottom ← FindDCell[ cellFamily: cellFamily, memberPrefix: "Bottom"L, hCompat: decodeCell]; decoderBottomMid ← FindCell[ cellFamily: cellFamily, member: "BottomMid"L, hCompat: decoderMidV, required: decoderMidV#NIL]; decoderRight ← FindDCell[ cellFamily: cellFamily, memberPrefix: "Right"L, vCompat: decodeCell]; decoderTopRightCorner ← FindCell[ cellFamily: cellFamily, member: "TopRightCorner"L]; decoderRightMid ← FindCell[ cellFamily: cellFamily, member: "RightMid"L, vCompat: decoderMidH, required: decoderMidH#NIL]; decoderBottomRightCorner ← FindCell[ cellFamily: cellFamily, member: "BottomRightCorner"L]; END; -- of FindDecoderCells bodyHeight, decoderRightX: locNum; decoderWidth, decoderHeight: INTEGER; midHGap, midVGap: locNum ← 0; pat: DecodePatternPtr; cellFamily, decoderName: STRING ← NIL; BEGIN ENABLE Punt => GOTO ExitDecoder; cellFamily ← RequestString["Cell family:"L]; FindDecoderCells[cellFamily]; decoderWidth ← RequestInteger["Decoder width in bits?"L]; decoderHeight ← RequestInteger["Decoder height in cells?"L]; pat ← uz.NEW[DecodePattern[decoderHeight]]; IF HeSaysYes["Is decode pattern a 'FOR' loop?"L] THEN BEGIN start: INTEGER ← RequestInteger["Starting value?"L, "(at top)"L]; step: INTEGER ← RequestInteger["Interval between values?"L, "(downward)"L]; FOR i: INTEGER IN [0..decoderHeight) DO pat.pattern[i] ← start; start ← start+step; ENDLOOP; END ELSE BEGIN pat.pattern[0] ← RequestInteger["First decode value?"L, "(at top)"L]; FOR i: INTEGER IN [1..decoderHeight) DO pat.pattern[i] ← RequestInteger["Next decode value?"L, "(downward)"L]; ENDLOOP; END; IF decoderMidH#NIL THEN midHGap ← CellSize[decodeCell].y* RequestInteger["Cells vertically per mid cell row?"L]; IF decoderMidV#NIL THEN midVGap ← CellSize[decodeCell].x* RequestInteger["Cells horizontally per mid cell column?"L]; bodyHeight ← BlockSize[cell: decodeCell, rep: [x: 1, y: decoderHeight], midCell: decoderMidH, midGap: [midVGap, midHGap]].y; decoderRightX ← BlockSize[cell: decodeCell, rep: [x: decoderWidth, y: 1], midCell: decoderMidV, midGap: [midVGap, midHGap]].x; Repeat[ cell: decoderLeft[FALSE], p: [0,0], corner: topRight, dir: down, rep: decoderHeight, midCell: decoderLeftMid, midGap: midHGap, altCell: decoderLeft[TRUE], altMod: 2]; Repeat[ cell: decoderTopLeftCorner, p: [0,0], corner: bottomRight]; Repeat[ cell: decoderBottomLeftCorner, p: [0, bodyHeight], corner: topRight]; Repeat[ cell: decoderTop[FALSE], p: [0,0], corner: bottomLeft, rep: decoderWidth, midCell: decoderTopMid, midGap: midVGap, altCell: decoderTop[TRUE], altMod: 2]; Repeat[ cell: decoderBottom[FALSE], p: [0, bodyHeight], corner: topLeft, dir: right, rep: decoderWidth, midCell: decoderBottomMid, midGap: midVGap, altCell: decoderBottom[TRUE], altMod: 2]; Repeat[cell: decoderTopRightCorner, p: [decoderRightX, 0], corner: bottomLeft]; Repeat[ cell: decoderRight[FALSE], p: [decoderRightX, 0], dir: down, rep: decoderHeight, midCell: decoderRightMid, midGap: midHGap, altCell: decoderRight[TRUE], altMod: 2]; Repeat[cell: decoderBottomRightCorner, p: [decoderRightX, bodyHeight]]; MakeDecoderBlock[cells: decoder, p: [0, 0], rep: [decoderWidth, decoderHeight], midCellSize: [x: CellSize[decoderMidV].x, y: CellSize[decoderMidH].y], midGap: [midVGap, midHGap], invertAddress: HeSaysYes["Shall I invert address inputs?L"], pat: pat]; MakeMidGrid[p: [0,0], cell: decodeCell, rep: [decoderWidth, decoderHeight], midVCell: decoderMidV, midHCell: decoderMidH, midVHCell: decoderMidVH, midGap: [midVGap, midHGap]]; decoderName ← RequestString["Name of finished cell:"L]; IF decoderName#NIL AND decoderName.length>0 THEN BEGIN DrawCell[MakeNewCell[decoderName, lpp].ob]; decoderName ← NIL; -- gave list and string body to cell END ELSE AddToMasterList[lpp]; lpp ← NIL; -- gave away the list EXITS ExitDecoder => NULL; END; flushDel[lpp]; IF pat#NIL THEN uz.FREE[@pat]; IF cellFamily # NIL THEN FreeString[cellFamily]; IF decoderName # NIL THEN FreeString[decoderName]; anyChanges ← sinceIOchanges ← TRUE; END; -- of BuildDecoder MakeDecoderBlock: PROCEDURE[cells: DCellPr, p, rep: Point, pat: DecodePatternPtr, midCellSize, midGap: Point ← [0,0], invertAddress: BOOLEAN ← FALSE] = BEGIN -- high-order bit on the left FOR iy: INTEGER IN [0..rep.y) DO loc: INTEGER ← pat.pattern[iy]; FOR ix: INTEGER DECREASING IN [0..rep.x) DO PlaceCell[p, cells[((loc MOD 2)#0)#invertAddress] [((loc MOD 2)=0)#invertAddress], [ix, iy], midCellSize, midGap]; loc ← loc/2; ENDLOOP; ENDLOOP; END; END. -- of DecoderImpl