RapunzelTestServer.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Demers, September 18, 1986 6:09:28 pm PDT
Willie-Sue, April 9, 1987 5:00:11 pm PDT
Bill Jackson (bj) January 8, 1988 5:11:01 pm PST
DIRECTORY
Basics USING [ LongNumber ],
CrRPC USING [ Handle ],
RapunzelP2200V4;
RapunzelTestServer: CEDAR PROGRAM
EXPORTS RapunzelP2200V4 ~ BEGIN
OPEN Rapunzel4: RapunzelP2200V4;
memSize: CARD ~ 2048;
Mem: TYPE ~ ARRAY [0..memSize) OF CARDINAL;
mem: REF Mem ← NIL;
shftAAddr: Rapunzel4.Address ← 0;
shftBAddr: Rapunzel4.Address ← 0;
registeredProcs: BOOLFALSE;
memProcs: RECORD [
fetch: PROC [ address: CARD16 ] RETURNS [ word: CARD16 ],
smash: PROC [ address: CARD16, word: CARD16 ]
];
NOTE: Rapunzel4.Long is a mesa CARD32; it will get stored as a dragon word
Init: PROC ~ { IF ( mem = NIL ) THEN mem ← NEW[Mem ← ALL[0]] };
MemFetch: PROC [ address: CARD16 ] RETURNS [ word: CARD16 ] ~ INLINE {
IF ( registeredProcs )
THEN word ← memProcs.fetch[address]
ELSE word ← mem[address];
};
MemSmash: PROC [ address: CARD16, word: CARD16 ] ~ INLINE {
IF ( registeredProcs )
THEN memProcs.smash[address, word]
ELSE mem[address] ← word;
};
Fault: PUBLIC ERROR [ code: Rapunzel4.FaultCode, address: Rapunzel4.Address ] ~ CODE;
DoCmds: PUBLIC PROC [ h: CrRPC.Handle, cmdSeq: Rapunzel4.SeqCmd ]
RETURNS [ resultSeq: Rapunzel4.SeqResult ] ~ {
resLength: CARDINAL;
resIndex: CARDINAL ← 0;
cmdIndex: CARDINAL ← 0;
BEGIN
this: Rapunzel4.Cmd ~ cmdSeq[0];
WITH this: this SELECT FROM
returnLength => resLength ← this.returnLength.returnLength;
ENDCASE => resLength ← cmdSeq.length;
END;
resultSeq ← NEW[ Rapunzel4.SeqResultObject[resLength] ];
WHILE ( cmdIndex < cmdSeq.length ) DO
this: Rapunzel4.Cmd ~ cmdSeq[cmdIndex];
cmdIndex ← cmdIndex + 1;
WITH this: this SELECT FROM
peekShort => {
fullAddr: Rapunzel4.Address ~ this.peekShort.address;
testAddr: Rapunzel4.Address ~ Shorten[fullAddr];
IF ( address >= memSize ) THEN ERROR Fault[nonexistent, address];
TRUSTED {
res: Rapunzel4.PeekShortResult ← [MemFetch[testAddr]];
resultSeq[resIndex] ← NEW[ Rapunzel4.ResultObject ← [peekShort[res]] ];
resIndex ← resIndex + 1;
};
};
pokeShort => {
fullAddr: Rapunzel4.Address ~ this.pokeShort.address;
testAddr: Rapunzel4.Address ~ Shorten[fullAddr];
IF ( address >= memSize ) THEN ERROR Fault[nonexistent, address];
MemSmash[testAddr, this.pokeShort.value];
resultSeq[resIndex] ← NEW[ Rapunzel4.ResultObject ← [pokeShort[NULL]] ];
resIndex ← resIndex + 1;
};
pokeLong => TRUSTED {
fullAddr: Rapunzel4.Address ~ this.pokeLong.address;
testAddr: Rapunzel4.Address ~ Shorten[fullAddr];
val: CARD32 ~ this.pokeLong.value;
IF ( address >= memSize ) THEN ERROR Fault[nonexistent, address];
MemSmash[testAddr, LOOPHOLE[val, Basics.LongNumber].hi];
MemSmash[testAddr+1, LOOPHOLE[val, Basics.LongNumber].lo];
resultSeq[resIndex] ← NEW[ Rapunzel4.ResultObject ← [pokeLong[NULL]] ];
resIndex ← resIndex + 1;
};
shftRead => {
fullAddr: Rapunzel4.Address ~ this.shftRead.address;
testAddr: Rapunzel4.Address ~ Shorten[fullAddr];
numRepeats: Rapunzel4.Short ~ this.shftRead.numRepeats;
res: Rapunzel4.ShftReadResult ~ [numRepeats];
IF ( address >= memSize ) THEN ERROR Fault[nonexistent, address];
TRUSTED { resultSeq[resIndex] ← NEW[ Rapunzel4.ResultObject ← [shftRead[res]] ] };
resIndex ← resIndex + 1;
FOR j: CARDINAL IN [0..numRepeats) DO
res: Rapunzel4.PeekShortResult;
res ← [MemFetch[shftAAddr]];
res ← [MemFetch[shftBAddr]];
IF ( j = numRepeats-1 ) THEN res ← [177777B] ELSE res ← [MemFetch[testAddr]];
TRUSTED { resultSeq[resIndex] ← NEW[ Rapunzel4.ResultObject ← [peekShort[res]] ] };
resIndex ← resIndex + 1;
ENDLOOP;
};
shftWrite => {
fullAddr: Rapunzel4.Address ~ this.shftWrite.address;
testAddr: Rapunzel4.Address ~ Shorten[fullAddr];
numRepeats: Rapunzel4.Short ~ this.shftWrite.numRepeats;
res: Rapunzel4.ShftWriteResult ~ [numRepeats];
IF ( address >= memSize ) THEN ERROR Fault[nonexistent, address];
TRUSTED { resultSeq[resIndex] ← NEW[ Rapunzel4.ResultObject ← [shftWrite[res]] ] };
resIndex ← resIndex + 1;
FOR j: CARDINAL IN [0..numRepeats) DO
writeVal: Rapunzel4.Cmd ~ cmdSeq[cmdIndex];
cmdIndex ← cmdIndex + 1;
WITH writeVal: writeVal SELECT FROM
pokeShort => {
res: Rapunzel4.PeekShortResult;
MemSmash[testAddr, writeVal.pokeShort.value];
res ← [MemFetch[shftAAddr]];
res ← [MemFetch[shftBAddr]];
};
ENDCASE => ERROR Fault[nonexistent, 0];
ENDLOOP;
};
returnLength => NULL;
ENDCASE => ERROR Fault[nonexistent, 0];
ENDLOOP;
};
SetShftAddrs: PUBLIC PROC [ h: CrRPC.Handle, shftA, shftB: Rapunzel4.Address ] ~ {
shftAAddr ← Shorten[shftA];
shftBAddr ← Shorten[shftB];
};
PeekShort: PUBLIC PROC [ h: CrRPC.Handle, address: Rapunzel4.Address ]
RETURNS [ result: Rapunzel4.Short ] ~ {
testAddr: Rapunzel4.Address ~ Shorten[address];
IF ( address >= memSize ) THEN ERROR Fault[nonexistent, address];
RETURN [MemFetch[testAddr]];
};
PokeShort: PUBLIC PROC [ h: CrRPC.Handle,
address: Rapunzel4.Address, value: Rapunzel4.Short ] ~ {
testAddr: Rapunzel4.Address ~ Shorten[address];
IF ( address >= memSize ) THEN ERROR Fault[nonexistent, address];
MemSmash[testAddr, value];
};
PeekSeqShort: PUBLIC PROC [ h: CrRPC.Handle, address: Rapunzel4.Address, count: CARDINAL ]
RETURNS [ resultSeq: Rapunzel4.SeqShort ] ~ {
ERROR Fault[nonexistent, 0];
};
PeekSeqLong: PUBLIC PROC [ h: CrRPC.Handle, address: Rapunzel4.Address, count: CARDINAL ] RETURNS [ resultSeq: Rapunzel4.SeqLong ] ~ {
testAddr: Rapunzel4.Address ~ Shorten[address];
resultSeq ← NEW[ Rapunzel4.SeqLongObject[count] ];
FOR i: CARDINAL IN [0..count) DO
xx: Basics.LongNumber;
xx.hi ← MemFetch[testAddr+2*i];
xx.lo ← MemFetch[testAddr+2*i + 1];
resultSeq[i] ← xx.lc;
ENDLOOP;
};
PokeSeqShort: PUBLIC PROC [ h: CrRPC.Handle,
address: Rapunzel4.Address, valueSeq: Rapunzel4.SeqShort ] ~ {
ERROR Fault[nonexistent, 0];
};
PeekLong: PUBLIC PROC [ h: CrRPC.Handle,
address: Rapunzel4.Address ] RETURNS [ result: Rapunzel4.Long ] ~ {
x: Basics.LongNumber;
testAddr: Rapunzel4.Address ~ Shorten[address];
IF testAddr >= (memSize - 1) THEN ERROR Fault[nonexistent, address];
TRUSTED { x.hi ← MemFetch[testAddr]; x.lo ← MemFetch[testAddr+1]; result ← x.lc };
};
PokeLong: PUBLIC PROC[ h: CrRPC.Handle,
address: Rapunzel4.Address, value: Rapunzel4.Long ] ~ {
x: Basics.LongNumber;
testAddr: Rapunzel4.Address ~ Shorten[address];
IF testAddr >= (memSize - 1) THEN ERROR Fault[nonexistent, address];
x.lc ← value; MemSmash[testAddr, x.hi]; MemSmash[testAddr+1, x.lo];
};
WriteSequential: PUBLIC PROC [ h: CrRPC.Handle,
startingAddress: Rapunzel4.Address, count: CARD16, seq: Rapunzel4.SeqLong ] ~ {
x: Basics.LongNumber;
FOR i: CARD16 IN [0..count) DO
testAddr: Rapunzel4.Address ~ Shorten[startingAddress+2*i];
x.lc ← seq[i]; MemSmash[testAddr, x.hi]; MemSmash[testAddr+1, x.lo];
ENDLOOP;
};
Shorten: PROC [ full: Rapunzel4.Address ] RETURNS [ short: Rapunzel4.Address ] ~ INLINE
{ short ← LOOPHOLE[full MOD memSize] };
Init[];
END...