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 28, 1988 0:48:57 am PST
DIRECTORY
Basics USING [ LongNumber, LowHalf ],
CrRPC USING [ Handle ],
RapunzelP2200V4;
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 ] ~ {
resultSeq ← NEW[ Rapunzel4.SeqShortObject[count] ];
FOR i: CARDINAL IN [0..count) DO
resultSeq[i] ← MemFetch[address+i];
ENDLOOP;
};
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 ] ~ {
count: CARDINAL ~ valueSeq.length;
FOR i: CARDINAL IN [0..count) DO
MemSmash[address+i, valueSeq[i]];
ENDLOOP;
};
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[];
END...