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 11, 1988 8:11:53 am PST
RapunzelTestServer:
CEDAR
PROGRAM
IMPORTS Basics
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: { none, short, long } ← none;
memProcs:
RECORD [
fetch16: PROC [ address: CARD16 ] RETURNS [ word: CARD16 ],
smash16: PROC [ address: CARD16, word: CARD16 ],
fetch32: PROC [ address: CARD32 ] RETURNS [ word: CARD16 ],
smash32: PROC [ address: CARD32, 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]] };
Shorten:
PROC [ full: Rapunzel4.Address ]
RETURNS [ short: Rapunzel4.Address ] ~
INLINE {
IF ( address >= memSize ) THEN ERROR Fault[nonexistent, address];
short ← LOOPHOLE[full MOD memSize];
};
MemFetch:
PROC [ address: Rapunzel4.Address ]
RETURNS [ word:
CARD16 ] ~
INLINE {
SELECT registeredProcs
FROM
none => { word ← mem[Shorten[address]] };
short => { word ← memProcs.fetch16[Basics.LowHalf[address]] };
long => { word ← memProcs.fetch32[address] };
ENDCASE => ERROR;
};
MemSmash:
PROC [ address: Rapunzel4.Address, word:
CARD16 ] ~
INLINE {
SELECT registeredProcs
FROM
none => { mem[Shorten[address]] ← word };
short => { memProcs.smash16[Basics.LowHalf[address], word] };
long => { memProcs.smash32[address, word] };
ENDCASE => ERROR;
};
Fault: PUBLIC ERROR [ code: Rapunzel4.FaultCode, address: Rapunzel4.Address ] ~ CODE;
DoCmds:
PUBLIC
PROC [ h: CrRPC.Handle, cmdSeq: Rapunzel4.SeqCmd ]
RETURNS [ resultSeq: Rapunzel4.SeqResult ] ~ {
resIndex: CARDINAL ← 0;
cmdIndex: CARDINAL ← 0;
this: Rapunzel4.Cmd ~ cmdSeq[0];
resLength:
CARDINAL ~
WITH this: this
SELECT
FROM
returnLength => this.returnLength.returnLength,
ENDCASE => cmdSeq.length;
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;
TRUSTED {
res: Rapunzel4.PeekShortResult ← [MemFetch[fullAddr]];
resultSeq[resIndex] ← NEW[ Rapunzel4.ResultObject ← [peekShort[res]] ];
resIndex ← resIndex + 1;
};
};
pokeShort => {
fullAddr: Rapunzel4.Address ~ this.pokeShort.address;
MemSmash[fullAddr, this.pokeShort.value];
resultSeq[resIndex] ← NEW[ Rapunzel4.ResultObject ← [pokeShort[NULL]] ];
resIndex ← resIndex + 1;
};
pokeLong =>
TRUSTED {
fullAddr: Rapunzel4.Address ~ this.pokeLong.address;
val: CARD32 ~ this.pokeLong.value;
MemSmash[fullAddr, LOOPHOLE[val, Basics.LongNumber].hi];
MemSmash[fullAddr+1, LOOPHOLE[val, Basics.LongNumber].lo];
resultSeq[resIndex] ← NEW[ Rapunzel4.ResultObject ← [pokeLong[NULL]] ];
resIndex ← resIndex + 1;
};
shftRead => {
fullAddr: Rapunzel4.Address ~ this.shftRead.address;
numRepeats: Rapunzel4.Short ~ this.shftRead.numRepeats;
res: Rapunzel4.ShftReadResult ~ [numRepeats];
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[fullAddr]];
TRUSTED { resultSeq[resIndex] ← NEW[ Rapunzel4.ResultObject ← [peekShort[res]] ] };
resIndex ← resIndex + 1;
ENDLOOP;
};
shftWrite => {
fullAddr: Rapunzel4.Address ~ this.shftWrite.address;
numRepeats: Rapunzel4.Short ~ this.shftWrite.numRepeats;
res: Rapunzel4.ShftWriteResult ~ [numRepeats];
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[fullAddr, 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 ← shftA;
shftBAddr ← shftB;
};
PeekShort:
PUBLIC
PROC [ h: CrRPC.Handle, address: Rapunzel4.Address ]
RETURNS [ result: Rapunzel4.Short ] ~ {
RETURN [MemFetch[address]];
};
PokeShort:
PUBLIC
PROC [ h: CrRPC.Handle,
address: Rapunzel4.Address, value: Rapunzel4.Short ] ~ {
MemSmash[address, 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 ] ~ {
resultSeq ← NEW[ Rapunzel4.SeqLongObject[count] ];
FOR i:
CARDINAL
IN [0..count)
DO
nextAddress: Rapunzel4.Address ~ address+(2*i);
xx: Basics.LongNumber;
xx.hi ← MemFetch[nextAddress];
xx.lo ← MemFetch[nextAddress+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;
TRUSTED { x.hi ← MemFetch[address]; x.lo ← MemFetch[address+1]; result ← x.lc };
};
PokeLong:
PUBLIC
PROC[ h: CrRPC.Handle,
address: Rapunzel4.Address, value: Rapunzel4.Long ] ~ {
x: Basics.LongNumber;
x.lc ← value; MemSmash[address, x.hi]; MemSmash[address+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
nextAddress: Rapunzel4.Address ~ startingAddress+(2*i);
x.lc ← seq[i]; MemSmash[nextAddress, x.hi]; MemSmash[nextAddress+1, x.lo];
ENDLOOP;
};
Init[];