<> <> <> <> <> 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; <> Init: PROC ~ { IF ( mem = NIL ) THEN mem _ NEW[Mem _ ALL[0]] }; MemFetch: PROC [ address: CARD16 ] RETURNS [ word: CARD16 ] ~ INLINE { word _ mem[address]; }; MemSmash: PROC [ address: CARD16, word: CARD16 ] ~ INLINE { 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]; <= 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]; <= 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; <= 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]; <= 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]; <= 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]; <= 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]; <= 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... <<>>