<> <> <> <> 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; <> 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]; <= 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]; <= 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; <= 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]; <= 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]; <= 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]; <= 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]; <= 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... <<>>