<> <> <> DIRECTORY Atom USING [PropList, PutPropOnList], DragOpsCross USING [Byte, bytesPerWord, FourBytes, Inst, JBBformat, JDist8, LRRBformat, QRformat, RJBformat, RRformat, ShortRegQR, TrapBase, TrapWidthBytes, Word, wordsPerPage, XopBase, ZerosWord], DragOpsCrossUtils USING [BytePCToWordAddress, CardToByte, CardToHalf, CardToWord, WordToBytes, WordToCard], HandCoding USING [drJ1, drJ2, drJ3, IllegalDst, IllegalMix, IllegalSrc, Lit16, Lit8, RegSpec, ShortRegSpec], HandCodingSupport USING [Area, AreaRep, GetProc, ProcList, PutProc], ProcessProps USING [AddPropList, GetPropList]; HandCodingSupportImpl: CEDAR PROGRAM IMPORTS Atom, DragOpsCrossUtils, HandCoding, ProcessProps EXPORTS HandCodingSupport = BEGIN OPEN DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingSupport; CARD: TYPE = LONG CARDINAL; initInst: CARD = TrapBase*bytesPerWord+64*TrapWidthBytes; <> initData: CARD = XopBase*bytesPerWord*2; <> <> DummyGet: GetProc = {RETURN [ZerosWord]}; DummyPut: PutProc = {}; <> NewArea: PUBLIC PROC [name: ATOM, getWord: GetProc, putWord: PutProc, data: REF _ NIL] RETURNS [Area] = { <> RETURN [NEW[AreaRep _ [ name: name, props: NIL, currentPC: initInst, currentData: initData, currentWord: ZerosWord, currentDirty: FALSE, getWord: getWord, putWord: putWord, data: data]]]; }; GenWithArea: PUBLIC PROC [area: Area, list: ProcList] = { <> inner: PROC = { FOR each: ProcList _ list, each.rest WHILE each # NIL DO each.first[]; ENDLOOP }; Gen1WithArea[area, inner]; }; <<>> Gen1WithArea: PUBLIC PROC [area: Area, proc: PROC] = { <> inner: PROC = { proc[]; ForceOut[area]; }; IF area = NIL THEN area _ GetCurrentArea[]; ProcessProps.AddPropList[ Atom.PutPropOnList[NIL, $CurrentArea, area], inner]; }; <<>> ForceOut: PUBLIC PROC [area: Area] = { <> addr: INT; index: [0..bytesPerWord); IF area = NIL THEN area _ GetCurrentArea[]; [addr, index] _ ConvertCurrentPC[area]; IF area.currentDirty THEN { area.putWord[area.data, addr, area.currentWord]; area.currentDirty _ FALSE; }; }; <<>> EmptyArea: PUBLIC ERROR = CODE; GetCurrentArea: PUBLIC PROC [nilOK: BOOL _ FALSE] RETURNS [area: Area _ NIL] = { <> FOR each: Atom.PropList _ ProcessProps.GetPropList[], each.rest WHILE each # NIL DO IF each.first.key = $CurrentArea THEN {area _ NARROW[each.first.val]; EXIT}; ENDLOOP; IF NOT nilOK AND area = NIL THEN ERROR EmptyArea; }; <> InstToByte: PROC [inst: Inst] RETURNS [Byte] = INLINE {RETURN [LOOPHOLE[inst]]}; OQBcommon: PUBLIC PROC [op: Inst, rest: Word] = { area: Area = GetCurrentArea[]; OutputByte[area, InstToByte[op]]; OutputAlphaBetaGammaDelta[area, rest]; }; OIcommon: PUBLIC PROC [op: Inst] = { OutputByte[GetCurrentArea[], InstToByte[op]]; }; LRcommon: PUBLIC PROC [op: Inst, reg: RegSpec] = { WITH r: reg SELECT FROM reg => {op _ LOOPHOLE[LOOPHOLE[op, CARDINAL] + r.reg]}; ENDCASE => ERROR IllegalSrc; OutputByte[GetCurrentArea[], InstToByte[op]]; }; QRcommon: PUBLIC PROC [op: Inst, left: DragOpsCross.ShortRegQR, right: RegSpec] = { form: QRformat _ LOOPHOLE[0]; form.aOp _ VAL[ORD[left]]; WITH r: right SELECT FROM dstStack => ERROR IllegalSrc; reg => {form.reg _ r.reg}; aux => {form.reg _ r.aux; form.aux _ TRUE}; const => {form.reg _ r.const; form.opt _ TRUE}; srcStack => {form.reg _ r.stack; form.opt _ TRUE}; ENDCASE => ERROR IllegalSrc; form.op _ op; OutputAlphaBeta[GetCurrentArea[], LOOPHOLE[form, CARDINAL]]; }; OBcommon: PUBLIC PROC [op: Inst, lit: Lit8] = { area: Area = GetCurrentArea[]; OutputByte[area, InstToByte[op]]; OutputByte[area, CardToByte[lit]]; }; LRBcommon: PUBLIC PROC [op: Inst, reg: RegSpec, lit: Lit8] = { area: Area = GetCurrentArea[]; WITH r: reg SELECT FROM reg => {op _ LOOPHOLE[LOOPHOLE[op, CARDINAL] + r.reg]}; ENDCASE => ERROR IllegalSrc; OutputByte[area, InstToByte[op]]; OutputByte[area, CardToByte[lit]]; }; RRcommon: PUBLIC PROC [op: Inst, c: RegSpec, a,b: RegSpec] = { <> useAux: BOOL _ FALSE; useReg: BOOL _ FALSE; form: RRformat _ LOOPHOLE[ZerosWord]; WITH c: c SELECT FROM reg => {useReg _ TRUE; form.c _ c.reg}; aux => {useAux _ TRUE; form.c _ c.aux}; dstStack => {form.c _ c.stack; form.cOpt _ TRUE}; const => {form.c _ c.const; form.cOpt _ TRUE}; srcStack => ERROR IllegalDst; ENDCASE; WITH a: a SELECT FROM reg => {useReg _ TRUE; form.a _ a.reg}; aux => {useAux _ TRUE; form.a _ a.aux}; dstStack => ERROR IllegalSrc; const => {form.a _ a.const; form.aOpt _ TRUE}; srcStack => {form.a _ a.stack; form.aOpt _ TRUE}; ENDCASE; WITH b: b SELECT FROM reg => {useReg _ TRUE; form.b _ b.reg}; aux => {useAux _ TRUE; form.b _ b.aux}; dstStack => ERROR IllegalSrc; const => {form.b _ b.const; form.bOpt _ TRUE}; srcStack => {form.b _ b.stack; form.bOpt _ TRUE}; ENDCASE; IF useAux THEN { IF useReg THEN ERROR IllegalMix; form.aux _ TRUE; }; form.op _ op; OutputBytes[GetCurrentArea[], LOOPHOLE[form], 0, 3]; }; RJBcommon: PUBLIC PROC [op: Inst, left: ShortRegSpec, right: RegSpec, dist: JDist8] = { form: RJBformat _ LOOPHOLE[ZerosWord]; form.aOp _ VAL[ORD[left]]; WITH r: right SELECT FROM reg => {form.reg _ r.reg}; aux => {form.aux _ TRUE; form.reg _ r.aux}; dstStack => ERROR IllegalSrc; const => {form.reg _ r.const; form.opt _ TRUE}; srcStack => {form.reg _ r.stack; form.opt _ TRUE}; ENDCASE; form.op _ op; form.dist _ dist; OutputBytes[GetCurrentArea[], LOOPHOLE[form], 0, 3]; }; ODBcommon: PUBLIC PROC [op: Inst, lit: Lit16] = { area: Area = GetCurrentArea[]; OutputByte[area, InstToByte[op]]; OutputAlphaBeta[area, lit]; }; LRRBcommon: PUBLIC PROC [op: Inst, reg1,reg2: RegSpec, disp: Lit8] = { area: Area = GetCurrentArea[]; form: LRRBformat _ LOOPHOLE[ZerosWord]; form.op _ op; form.disp _ disp; WITH r: reg1 SELECT FROM reg => {form.reg1 _ r.reg}; aux => {form.reg1 _ r.aux}; ENDCASE => ERROR IllegalSrc; WITH r: reg2 SELECT FROM reg => {form.reg2 _ r.reg}; aux => {form.reg2 _ r.aux}; ENDCASE => ERROR IllegalSrc; OutputBytes[GetCurrentArea[], LOOPHOLE[form], 0, 3]; }; JBBcommon: PUBLIC PROC [op: Inst, dist: JDist8, lit: Lit8] = { form: JBBformat _ LOOPHOLE[ZerosWord]; form.op _ op; form.dist _ dist; form.lit _ lit; OutputBytes[GetCurrentArea[], LOOPHOLE[form], 0, 3]; }; <> GetOutputPC: PUBLIC PROC [area: Area _ NIL] RETURNS [CARD] = { <> IF area = NIL THEN area _ GetCurrentArea[]; RETURN [area.currentPC]; }; SetOutputPC: PUBLIC PROC [pc: CARD, area: Area _ NIL] = { <> addr: CARD; index: [0..bytesPerWord); IF area = NIL THEN area _ GetCurrentArea[]; [addr, index] _ ConvertCurrentPC[area]; IF area.currentDirty THEN { <> area.putWord[area.data, addr, area.currentWord]; area.currentDirty _ FALSE; }; area.currentPC _ pc; [addr, index] _ ConvertCurrentPC[area]; }; WordAlign: PUBLIC PROC [area: Area _ NIL] = { <> addr: CARD; index: [0..bytesPerWord); IF area = NIL THEN area _ GetCurrentArea[]; [addr, index] _ ConvertCurrentPC[area]; SELECT index FROM 1 => {HandCoding.drJ3[]; HandCoding.drJ1[]; HandCoding.drJ1[]}; 2 => {HandCoding.drJ2[]; HandCoding.drJ1[]}; 3 => HandCoding.drJ1[]; ENDCASE => {}; }; ReserveData: PUBLIC PROC [words: CARD, area: Area _ NIL] RETURNS [pc: CARD] = { <> old: CARD; IF area = NIL THEN area _ GetCurrentArea[]; old _ area.currentPC; SetOutputPC[area.currentData, area]; WordAlign[area]; pc _ area.currentPC; area.currentData _ area.currentData + words*bytesPerWord; OutputWord[area, ZerosWord, FALSE]; WHILE words > wordsPerPage DO SetOutputPC[pc+(words-1)*bytesPerWord, area]; OutputWord[area, ZerosWord, FALSE]; words _ words - wordsPerPage; ENDLOOP; SetOutputPC[old, area]; }; OutputByte: PUBLIC PROC [area: Area, byte: Byte] = { <> addr: CARD; index: [0..bytesPerWord); IF area = NIL THEN area _ GetCurrentArea[]; [addr, index] _ ConvertCurrentPC[area]; IF NOT area.currentDirty THEN { area.currentWord _ area.getWord[area.data, addr]; area.currentDirty _ TRUE; }; LOOPHOLE[area.currentWord, FourBytes][index] _ byte; area.currentPC _ area.currentPC + 1; IF index = bytesPerWord-1 THEN { area.putWord[area.data, addr, area.currentWord]; area.currentDirty _ FALSE; }; }; <<>> OutputOneByte: PUBLIC PROC [area: Area, word: Word] = { <> OutputByte[area, WordToBytes[word][3]]; }; <<>> OutputAlphaBeta: PUBLIC PROC [area: Area, lit: Lit16] = { <> IF area = NIL THEN area _ GetCurrentArea[]; OutputByte[area, LOOPHOLE[lit / 256]]; OutputByte[area, LOOPHOLE[lit MOD 256]]; }; <<>> OutputAlphaBetaGammaDelta: PUBLIC PROC [area: Area, word: Word] = { <> IF area = NIL THEN area _ GetCurrentArea[]; OutputByte[area, WordToBytes[word][0]]; OutputByte[area, WordToBytes[word][1]]; OutputByte[area, WordToBytes[word][2]]; OutputByte[area, WordToBytes[word][3]]; }; <<>> OutputWord: PUBLIC PROC [area: Area, word: Word, align: BOOL _ FALSE] = { <> addr: CARD; index: [0..bytesPerWord); IF area = NIL THEN area _ GetCurrentArea[]; [addr, index] _ ConvertCurrentPC[area]; IF area.currentDirty THEN { area.putWord[area.data, addr, area.currentWord]; area.currentDirty _ FALSE; }; SELECT TRUE FROM index = 0 => { area.putWord[area.data, addr, word]; area.currentPC _ area.currentPC + 4; }; align => { area.putWord[area.data, addr+1, word]; area.currentPC _ area.currentPC + (bytesPerWord - index) + 4 }; ENDCASE => OutputBytes[area, WordToBytes[word], 0, 4]; }; <> OutputBytes: PROC [area: Area, bytes: FourBytes, start: NAT, len: NAT] = { <> addr: CARD; index: NAT; [addr, index] _ ConvertCurrentPC[area]; THROUGH [0..len) DO IF NOT area.currentDirty THEN { area.currentWord _ area.getWord[area.data, addr]; area.currentDirty _ TRUE; }; LOOPHOLE[area.currentWord, FourBytes][index] _ bytes[start]; start _ start + 1; index _ index + 1; IF index = bytesPerWord THEN { area.putWord[area.data, addr, area.currentWord]; area.currentDirty _ FALSE; addr _ addr + 1; index _ 0; }; ENDLOOP; area.currentPC _ area.currentPC + len; }; ConvertCurrentPC: PROC [area: Area] RETURNS [addr: CARD, index: NAT] = INLINE { <> word: Word _ DragOpsCrossUtils.CardToWord[area.currentPC]; [word, index] _ DragOpsCrossUtils.BytePCToWordAddress[[word]]; addr _ DragOpsCrossUtils.WordToCard[word]; }; END.