MicroOutputImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Willie-sue, July 29, 1987 4:24:08 pm PDT
taken from micout.bcpl
DIRECTORY
Basics USING [ShortNumber],
FS USING [Error, OpenFile, Create, StreamFromOpenFile],
IO,
List USING [CompareProc, LORA, Sort],
Rope,
MicroDefs,
MicroGlobalVars,
MicroOps USING [FilterSyms, GetSymbol],
MicroUtils USING [FullNameWithExt];
MicroOutputImpl: CEDAR PROGRAM
IMPORTS
FS, IO, List, Rope,
MicroGlobalVars, MicroOps, MicroUtils
EXPORTS
MicroOps, MicroUtils
= BEGIN OPEN MicroDefs, MicroGlobalVars;
oldMemory: Memory ← NIL;
oldLoc: INTEGER ← 0;
ListingReport: PUBLIC PROC[msg1, msg2: ROPENIL] = {
reportStrm.PutRope[msg1];
reportStrm.PutRope[msg2];
reportStrm.PutChar['\n];
};
WriteWord: PUBLIC PROC[accWord: WordSeq, mem: Memory, loc: INTEGER] = {
write data word
IF ~writeBinaryFlag THEN RETURN;
IF binaryFile.strm = NIL THEN {
OpenBinary[];
oldMemory ← NIL;
};
IF mem # oldMemory OR (loc # oldLoc+1) THEN {
PutInteger[binaryFile.strm, MBseta];
PutInteger[binaryFile.strm, mem.memoryNum];
PutInteger[binaryFile.strm, loc];
oldMemory ← mem;
};
oldLoc ← loc;
PutInteger[binaryFile.strm, MBdata];
PutInteger[binaryFile.strm, stmtLineCount];
FOR i: INTEGER IN [0..accWord.length) DO
PutWord[binaryFile.strm, accWord[i]];
ENDLOOP;
};
WriteFixup: PUBLIC PROC[memIndex, loc, feIndex, symIndex: INTEGER] = {
Write a fixup
IF fixupsFileRec.strm = NIL THEN OpenOutputStream[fixupsFileRec];
PutInteger[fixupsFileRec.strm, memIndex];
PutInteger[fixupsFileRec.strm, loc];
PutInteger[fixupsFileRec.strm, feIndex];
PutInteger[fixupsFileRec.strm, symIndex];
PutInteger[fixupsFileRec.strm, labelSymIndex];
PutInteger[fixupsFileRec.strm, stmtLineCount - labelLineCount];
};
WriteSymName: PUBLIC PROC[symIndex: INTEGER] =
{ SymName[MicroOps.GetSymbol[symIndex]]};
SymName: PROC[sObj: SymbolObj] = {
Write a fixup
name: ROPE;
len: INT;
IF ~writeBinaryFlag THEN RETURN;
IF binaryFile.strm = NIL THEN OpenBinary[];
IF sObj = NIL THEN RETURN;
name ← sObj.name;
len ← name.Length[];
**** starts writing on word boundary
FOR i: INT IN [0..len) DO
binaryFile.strm.PutChar[name.Fetch[i]];
ENDLOOP;
IF len MOD 2 = 1 THEN binaryFile.strm.PutChar['\000]
ELSE PutWord[binaryFile.strm, 0];  -- end marker for name
};
WriteMemoryDef: PUBLIC PROC[mem: Memory] = {
write memory definition
IF ~writeBinaryFlag THEN RETURN;
IF binaryFile.strm = NIL THEN OpenBinary[];
IF mem = NIL THEN RETURN;
PutInteger[binaryFile.strm, MBmemdef];
PutInteger[binaryFile.strm, mem.memoryNum];
PutInteger[binaryFile.strm, mem.widthInBits];
WriteSymName[mem.symIndex];
};
EndListing: PUBLIC PROC[xListFlag: BOOL] = { };
EndOutput: PUBLIC PROC[symDumpStartIndex: INTEGER] = {
lSyms: LIST OF SymbolObj;
SymbolCompareProc: List.CompareProc = {
s1: SymbolObj = NARROW[ref1];
s2: SymbolObj = NARROW[ref2];
RETURN[Rope.Compare[s1.name, s2.name, FALSE]];
};
IF binaryFile.strm = NIL THEN RETURN;
CopyFixups[];
lSyms ← MicroOps.FilterSyms[addressType, symDumpStartIndex];
TRUSTED
{ lSyms ← LOOPHOLE[List.Sort[LOOPHOLE[lSyms, List.LORA], SymbolCompareProc], LIST OF SymbolObj] };
FOR ls: LIST OF SymbolObj ← lSyms, ls.rest UNTIL ls = NIL DO
sym: SymbolObj = ls.first;
mem: Memory = NARROW[MicroOps.GetSymbol[sym.sMisc].sData];
PutInteger[binaryFile.strm, MBsymbol];
PutInteger[binaryFile.strm, mem.memoryNum];
PutInteger[binaryFile.strm, sym.sVal];
SymName[sym];
ENDLOOP;
PutInteger[binaryFile.strm, MBend];
binaryFile.strm.Close[ ! IO.Error, FS.Error => CONTINUE];
binaryFile.strm ← NIL;
};
CopyFixups: PROC = {
-- Copy fixups to output file
IF fixupsFileRec.strm = NIL THEN RETURN;
fixupsFileRec.strm.SetLength[fixupsFileRec.strm.GetIndex[]];
fixupsFileRec.strm.SetIndex[0];
UNTIL fixupsFileRec.strm.EndOf[] DO
memIndex: INTEGER = GetInteger[fixupsFileRec.strm];
loc: INTEGER = GetInteger[fixupsFileRec.strm];
feIndex: INTEGER = GetInteger[fixupsFileRec.strm];
symIndex: INTEGER = GetInteger[fixupsFileRec.strm];
labelSymIndex: INTEGER = GetInteger[fixupsFileRec.strm];
lineCount: INTEGER = GetInteger[fixupsFileRec.strm];
memSym: SymbolObj = MicroOps.GetSymbol[memIndex];
mem: Memory = NARROW[memSym.sData];
fSym: SymbolObj = MicroOps.GetSymbol[feIndex];
sym: SymbolObj = MicroOps.GetSymbol[symIndex];
bits: INTEGER = (fSym.sMisc * 256) + fSym.sMisc + LOOPHOLE[fSym.sVal, INTEGER] - 1;
val: INTEGER;
IF sym.sType = undefnType THEN {
PutInteger[binaryFile.strm, MBext];
PutInteger[binaryFile.strm, mem.memoryNum];
PutInteger[binaryFile.strm, loc];
PutInteger[binaryFile.strm, bits];
WriteSymName[symIndex];
LOOP;
};
IF sym.sType = addressType OR sym.sType = integerType THEN val ← sym.sVal
ELSE {
lSym: SymbolObj = MicroOps.GetSymbol[labelSymIndex];
reportStrm.PutF["\n** Undefined symbol %g in field %g of %g at %g",
IO.rope[sym.name], IO.rope[fSym.name], IO.rope[memSym.name],
IO.rope[lSym.name]];
SELECT TRUE FROM
lineCount = 0 => NULL;
lineCount > 0 => reportStrm.PutF["+%g", IO.int[lineCount]];
lineCount < 0 => reportStrm.PutF["%g", IO.int[lineCount]];
ENDCASE => NULL;
reportStrm.PutChar['\n];
LOOP;
};
PutInteger[binaryFile.strm, MBfixup];
PutInteger[binaryFile.strm, mem.memoryNum];
PutInteger[binaryFile.strm, loc];
PutInteger[binaryFile.strm, bits];
PutInteger[binaryFile.strm, val];
ENDLOOP;
fixupsFileRec.strm.SetLength[0];
fixupsFileRec.strm.Close[];
fixupsFileRec.strm ← NIL;
};
the following are exported to MicroUtils
PutWord: PUBLIC PROC[strm: STREAM, val: WORD] = {
sn: Basics.ShortNumber ← LOOPHOLE[val];
strm.PutChar[LOOPHOLE[sn.hi, CHAR]];
strm.PutChar[LOOPHOLE[sn.lo, CHAR]];
};
PutInteger: PUBLIC PROC[strm: STREAM, val: INTEGER] = {
sn: Basics.ShortNumber ← LOOPHOLE[val];
strm.PutChar[LOOPHOLE[sn.hi, CHAR]];
strm.PutChar[LOOPHOLE[sn.lo, CHAR]];
};
GetWord: PUBLIC PROC[strm: STREAM] RETURNS[val: WORD] = {
sn: Basics.ShortNumber;
sn.hi ← LOOPHOLE[strm.GetChar[], BYTE];
sn.lo ← LOOPHOLE[strm.GetChar[], BYTE];
RETURN[LOOPHOLE[sn, WORD]];
};
GetInteger: PUBLIC PROC[strm: STREAM] RETURNS[val: WORD] = {
sn: Basics.ShortNumber;
sn.hi ← LOOPHOLE[strm.GetChar[], BYTE];
sn.lo ← LOOPHOLE[strm.GetChar[], BYTE];
RETURN[LOOPHOLE[sn, WORD]];
};
OpenBinary: PROC = {
binaryFile.fullName ← MicroUtils.FullNameWithExt[binaryFile.fullName, NIL, NIL, mbExtn];
OpenOutputStream[binaryFile];
};
OpenOutputStream: PUBLIC PROC[rec: OutputFile] = {
of: FS.OpenFile = FS.Create[name: rec.fullName, setKeep: TRUE, keep: 2];
rec.strm ← FS.StreamFromOpenFile[of, $write];
};
END.