DragonImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Auxiliary functions for Dragon Rosemary simulations
last edited by E. McCreight, March 10, 1986 6:29:35 pm PST
last edited by Curry, September 8, 1985 7:12:34 pm PDT
DIRECTORY
AMBridge,
AMTypes,
BitOps,
Dragon,
DragonRosemary,
DragonRoseExtras,
DragOpsCross,
IO,
Rope,
RoseRun,
RoseTypes;
DragonImpl: CEDAR PROGRAM IMPORTS AMBridge, AMTypes, BitOps, IO, Rope, RoseRun, RoseTypes EXPORTS DragonRosemary, DragonRoseExtras =
BEGIN
Assert: PUBLIC PROC [ condition: BOOL, message: Rope.ROPENIL ] =
BEGIN
IF condition THEN RETURN;
RoseRun.DisableableStop[Assert, "", $FailedAssertion ! RoseTypes.Stop => GOTO NotifyUser ];
EXITS
NotifyUser =>
BEGIN
SIGNAL AssertionFailed[IO.PutFR["%g. OK to proceed or abort.", IO.rope[IF message # NIL THEN message ELSE "Logic assertion failed. Consult code for details"]]];
RoseRun.DisableableStop[Assert, IO.PutFR["%g. ""Disable"" disables just this one assertion. ""Proceed"" continues the simulation in any case.",
IO.rope[IF message # NIL THEN message ELSE "Control got here from debugger"]], $FailedAssertion];
END;
END;
AssertionFailed: PUBLIC SIGNAL [ message: Rope.ROPE ] = CODE;
OpName: PUBLIC ARRAY Dragon.Opcode OF Rope.ROPE = GenOpNames[];
OpLength: PUBLIC PROC [ op: Dragon.Opcode ] RETURNS [ length: [0..5] ] =
{RETURN[instructionLengths[op/16]]};
instructionLengths: ARRAY [0..16) OF [0..5] = [ -- see /Indigo/Dragon/Doc/DragOps
1, 1,  -- [ 0.. 1]
5, 5,  -- [ 2.. 3]
1, 1, 1, 1, -- [ 4.. 7]
2, 2, 2, 2, -- [ 8..11]
3, 3, 3, 3 -- [12..15]
];
OneOf:    PUBLIC PROC [ a, b, c, d, e, f, g, h, i, j: BOOLFALSE ] RETURNS[ BOOL ] =
{RETURN[Count[a,b,c,d,e,f,g,h,i,j]=1]};
MoreThanOneOf: PUBLIC PROC [ a, b, c, d, e, f, g, h, i, j: BOOLFALSE ] RETURNS[ BOOL ] =
{RETURN[Count[a,b,c,d,e,f,g,h,i,j]>1]};
Count:    PUBLIC PROC [ a, b, c, d, e, f, g, h, i, j: BOOLFALSE ] RETURNS[ NAT ] = {
RETURN[
(IF a THEN 1 ELSE 0) +
(IF b THEN 1 ELSE 0) +
(IF c THEN 1 ELSE 0) +
(IF d THEN 1 ELSE 0) +
(IF e THEN 1 ELSE 0) +
(IF f THEN 1 ELSE 0) +
(IF g THEN 1 ELSE 0) +
(IF h THEN 1 ELSE 0) +
(IF i THEN 1 ELSE 0) +
(IF j THEN 1 ELSE 0) ]};
LTD, LongToDouble:  PUBLIC PROC[word: Dragon.HexWord] RETURNS[BitOps.BitDWord] =
{ RETURN[ BitOps.ILID[word,[0,0],32,0,32]] };
LFD, LongFromDouble: PUBLIC PROC[bdw: BitOps.BitDWord] RETURNS[Dragon.HexWord] =
{ RETURN[ BitOps.ELFD[bdw,32,0,32]] };
PRtoByte: PUBLIC PROC[pr: DragOpsCross.ProcessorRegister] RETURNS [byte: Dragon.HexByte]={
byte ← LOOPHOLE[pr]};
BytetoPR: PUBLIC PROC[byte: Dragon.HexByte] RETURNS [pr: DragOpsCross.ProcessorRegister]={
pr ← LOOPHOLE[byte]};
GenOpNames: PUBLIC PROC RETURNS[names: ARRAY Dragon.Opcode OF Rope.ROPE]= TRUSTED{
instRef: REF DragOpsCross.Inst ← NEW[DragOpsCross.Inst];
tv:   AMTypes.TV  ← AMBridge.TVForReferent[instRef];
type:  AMTypes.Type ← AMTypes.UnderType[AMTypes.TVType[tv]];
FOR tv: AMTypes.TV ← AMTypes.First[type], AMTypes.Next[tv] WHILE tv#NIL DO
card:  CARDINAL ← AMBridge.TVToCardinal[tv];
op:  Dragon.Opcode ← card MOD 256;
IF op # card THEN ERROR;
names[op] ← NIL;
names[op] ← AMTypes.TVToName[tv ! AMTypes.Error => CONTINUE];
IF names[op] = NIL THEN
names[op] ← IO.PutFR["dxop%02", [cardinal[op]]]; -- remove H at end
names[op] ← Rope.Substr[names[op],1];
ENDLOOP };
END.