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