<> <> <> <> <> 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 ] ]; <> Init: PROC ~ { IF ( mem = NIL ) THEN mem _ NEW[Mem _ ALL[0]] }; Shorten: PROC [ full: Rapunzel4.Address ] RETURNS [ short: Rapunzel4.Address ] ~ INLINE { <= 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... <<>>