DIRECTORY ESCAlpha USING [ alpha ], Heap USING [ systemZone ], Inline USING [ HighHalf, LowHalf, LongNumber ], Mopcodes USING [ zESC ], Put USING [ LongNumber, Text ], System USING [ NetworkAddress ], Rapunzel; RapunzelServiceImpl: PROGRAM IMPORTS Heap, Inline, Put, Rapunzel EXPORTS Rapunzel = { OPEN Rapunzel; pMemFetch: ESCAlpha.alpha = 3EH; pMemSmash: ESCAlpha.alpha = 3FH; firstPhysical: Rapunzel.Address = 0; lowestGuarded: Rapunzel.Address = (LONG[12]*256*256); -- 1.5MB lastPhysical: Rapunzel.Address = ((LONG[32]*256*256)-1); -- 2^(5+8+8) words = 4MB lowerBound: CARDINAL = 0; upperBound: CARDINAL = 1023; Mem: TYPE = ARRAY [lowerBound..upperBound] OF WORD; memMod: CARDINAL = 1024; mem: Mem; nilHandle: BindHandle; simulation: BOOLEAN _ FALSE; historyBuffer: BOOLEAN _ FALSE; debugging: BOOLEAN _ FALSE; shftAAddr: Rapunzel.Address; shftBAddr: Rapunzel.Address; Fault: PUBLIC ERROR [ bH: BindHandle, code: Rapunzel.FaultCode, address: Rapunzel.Address ] = CODE; HistoryBufferFetch: PROC [ p: LONG CARDINAL ] RETURNS [ b: WORD ] = MACHINE CODE { }; HistoryBufferSmash: PROC [ p: LONG CARDINAL, b: WORD ] = MACHINE CODE { }; MemFetch: PROC [ LONG CARDINAL ] RETURNS [ WORD ] = MACHINE CODE { Mopcodes.zESC, pMemFetch }; MemSmash: PROC [ LONG CARDINAL, WORD ] = MACHINE CODE { Mopcodes.zESC, pMemSmash }; Display: PROC [ lead: LONG STRING, value: LONG CARDINAL ] = { IF ( NOT debugging ) THEN RETURN; Put.Text[NIL, lead]; Put.LongNumber[NIL, value, [base: 8]]; Put.Text[NIL, "B\n"]; }; PeekOpCode: PROC [ bH: BindHandle, addr: LONG CARDINAL ] RETURNS [ word: WORD ] = INLINE { phys: CARDINAL = Inline.LowHalf[addr]; SELECT TRUE FROM ( simulation ) => { word _ mem[phys MOD memMod]; } ( historyBuffer ) => { word _ HistoryBufferFetch[addr]; } ENDCASE => { IF NOT ( addr IN [lowestGuarded..lastPhysical] ) THEN ERROR Fault[bH, IF ( addr < lowestGuarded ) THEN protection ELSE nonexistent, addr]; word _ MemFetch[addr]; }; }; PokeOpCode: PROC [ bH: BindHandle, addr: LONG CARDINAL, word: WORD ] = INLINE { phys: CARDINAL = Inline.LowHalf[addr]; SELECT TRUE FROM ( simulation ) => { mem[phys MOD memMod] _ word; } ( historyBuffer ) => { HistoryBufferSmash[addr, word]; } ENDCASE => { IF NOT ( addr IN [lowestGuarded..lastPhysical] ) THEN ERROR Fault[bH, IF ( addr < lowestGuarded ) THEN protection ELSE nonexistent, addr]; MemSmash[addr, word]; }; }; SetShftAddrs: PUBLIC PROC [ bH: BindHandle, shftA, shftB: Rapunzel.Address ] = { shftAAddr _ shftA; shftBAddr _ shftB; }; PeekShort: PUBLIC PROC [ bH: BindHandle, address: Rapunzel.Address ] RETURNS [ result: Rapunzel.Short ] = { Display["PeekShort - address: ", address]; result _ PeekOpCode[bH, address]; Display[" result: ", result]; }; PokeShort: PUBLIC PROC [ bH: BindHandle, address: Rapunzel.Address, value: Rapunzel.Short ] = { Display["PokeShort - address: ", address]; Display[" value: ", value]; PokeOpCode[bH, address, value]; }; PeekLong: PUBLIC PROC [ bH: BindHandle, address: Rapunzel.Address ] RETURNS [ result: Rapunzel.Long ] = { xx: Inline.LongNumber; Display["PeekLong - address: ", address]; xx.high _ PeekOpCode[bH, address]; xx.low _ PeekOpCode[bH, (address+1)]; result _ xx.lc; Display[" result: ", result]; }; PokeLong: PUBLIC PROC [ bH: BindHandle, address: Rapunzel.Address, value: Rapunzel.Long ] = { Display["PokeLong - address: ", address]; Display[" value: ", value]; PokeOpCode[bH, address, Inline.HighHalf[value]]; PokeOpCode[bH, (address+1), Inline.LowHalf[value]]; }; PeekSeqShort: PUBLIC PROC [ bH: BindHandle, address: Rapunzel.Address, count: CARDINAL ] RETURNS [ results: LONG POINTER TO Rapunzel.SeqShort ] = { Chunk: TYPE = RECORD [ SEQUENCE COMPUTED Rapunzel.SeqShortIndex OF Rapunzel.Short ]; zone: UNCOUNTED ZONE = Heap.systemZone; chunk: LONG POINTER = zone.NEW [Chunk[count]]; Display["PeekSeqShort - address: ", address]; Display[" count: ", count]; results _ zone.NEW [Rapunzel.SeqShort _ DESCRIPTOR[chunk, count]]; FOR i: CARDINAL IN [0..count) DO results[i] _ PeekOpCode[bH, (address+i)]; Display[" ", results[i]]; ENDLOOP; }; PeekSeqLong: PUBLIC PROC [ bH: BindHandle, address: Rapunzel.Address, count: CARDINAL ] RETURNS [ results: LONG POINTER TO Rapunzel.SeqLong ] = { Chunk: TYPE = RECORD [ SEQUENCE COMPUTED Rapunzel.SeqShortIndex OF Rapunzel.Long ]; zone: UNCOUNTED ZONE = Heap.systemZone; chunk: LONG POINTER = zone.NEW [Chunk[count]]; Display["PeekSeqLong - address: ", address]; Display[" count: ", count]; results _ zone.NEW [Rapunzel.SeqLong _ DESCRIPTOR[chunk, count]]; FOR i: CARDINAL IN [0..count) DO xx: Inline.LongNumber; xx.high _ PeekOpCode[bH, address+2*i]; xx.low _ PeekOpCode[bH, (address+2*i+1)]; results[i] _ xx.lc; Display[" ", results[i]]; ENDLOOP; }; PokeSeqShort: PUBLIC PROC [ bH: BindHandle, address: Rapunzel.Address, valueSeq: LONG POINTER TO Rapunzel.SeqShort ] = { Display["PokeSeqShort - address: ", address]; Display[" count: ", LENGTH[valueSeq^]]; FOR i: CARDINAL IN [0..LENGTH[valueSeq^]) DO Display[" ", valueSeq[i]]; PokeOpCode[bH, (address+i), valueSeq[i]]; ENDLOOP; }; DoCmds: PUBLIC PROC [ bH: BindHandle, cmdSeq: LONG POINTER TO Rapunzel.SeqCmd ] RETURNS [ resultSeq: LONG POINTER TO Rapunzel.SeqResult ] = { Chunk: TYPE = RECORD [SEQUENCE COMPUTED Rapunzel.SeqResultIndex OF Rapunzel.Result]; zone: UNCOUNTED ZONE = Heap.systemZone; chunk: LONG POINTER; 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; chunk _ zone.NEW [Chunk[resLength]]; resultSeq _ zone.NEW [Rapunzel.SeqResult _ DESCRIPTOR[chunk, resLength]]; Display["DoCmds -- count: ", cmdSeq^.LENGTH]; WHILE ( cmdIndex < cmdSeq^.LENGTH ) DO this: Rapunzel.Cmd = cmdSeq[cmdIndex]; cmdIndex _ cmdIndex + 1; WITH this: this SELECT FROM peekShort => { address: Rapunzel.Address = this.peekShort.address; res: Rapunzel.PeekShortResult ¬ NULL; res _ [PeekOpCode[bH, address]]; IF ( debugging ) THEN { Display[" address: ", address]; Display[" peekShort: ", res]; }; resultSeq[resIndex] _ [peekShort[res]]; resIndex _ resIndex + 1; }; pokeShort => { address: Rapunzel.Address = this.pokeShort.address; IF ( debugging ) THEN { Display[" address: ", address]; Display[" pokeShort: ", this.pokeShort.value]; }; PokeOpCode[bH, address, this.pokeShort.value]; resultSeq[resIndex] _ [pokeShort[NULL]]; resIndex _ resIndex + 1; }; pokeLong => { address: Rapunzel.Address = this.pokeLong.address; IF ( debugging ) THEN { Display[" address: ", address]; Display[" pokeShort: ", this.pokeLong.value]; }; PokeOpCode[bH, address, Inline.HighHalf[this.pokeLong.value]]; PokeOpCode[bH, address+1, Inline.LowHalf[this.pokeLong.value]]; resultSeq[resIndex] _ [pokeLong[NULL]]; resIndex _ resIndex + 1; }; shftRead => { address: Rapunzel.Address = this.shftRead.address; numRepeats: Rapunzel.Short = this.shftRead.numRepeats; res: Rapunzel.ShftReadResult = [numRepeats]; IF ( debugging ) THEN { Display[" address: ", address]; Display[" shiftRead - numRepeats: ", numRepeats]; }; resultSeq[resIndex] _ [shftRead[res]]; resIndex _ resIndex + 1; FOR j: CARDINAL IN [0..numRepeats) DO res: Rapunzel.PeekShortResult ¬ NULL; [] _ PeekOpCode[bH, shftAAddr]; [] _ PeekOpCode[bH, shftBAddr]; res _ [PeekOpCode[bH, address]]; resultSeq[resIndex] _ [peekShort[res]]; resIndex _ resIndex + 1; ENDLOOP; }; shftWrite => { address: Rapunzel.Address = this.shftWrite.address; numRepeats: Rapunzel.Short = this.shftWrite.numRepeats; res: Rapunzel.ShftWriteResult = [numRepeats]; IF ( debugging ) THEN { Display[" address: ", address]; Display[" shiftWrite - numRepeats: ", numRepeats]; }; resultSeq[resIndex] _ [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 => { PokeOpCode[bH, address, writeVal.pokeShort.value]; [] _ PeekOpCode[bH, shftAAddr]; [] _ PeekOpCode[bH, shftBAddr]; }; ENDCASE => ERROR Fault[bH, nonexistent, 0]; ENDLOOP; }; returnLength => NULL; ENDCASE => ERROR Fault[bH, nonexistent, 0]; ENDLOOP; }; WriteSequential: PUBLIC PROC [ bH: BindHandle, startingAddress: Address, count: CARDINAL, seq: LONG POINTER TO Rapunzel.SeqLong ] = { FOR i: CARDINAL IN [0..count) DO address: Rapunzel.Address = startingAddress + 2*i; value: Long = seq[i]; PokeOpCode[bH, address, Inline.HighHalf[value]]; PokeOpCode[bH, address+1, Inline.LowHalf[value]]; ENDLOOP; }; FreePeekSeqShortResults: PUBLIC PROC [ bH: BindHandle, resultSeq: LONG POINTER TO SeqShort ] = { zone: UNCOUNTED ZONE = Heap.systemZone; zone.FREE [@(resultSeq^.BASE)]; zone.FREE [@(resultSeq)]; }; FreePeekSeqLongResults: PUBLIC PROC [ bH: BindHandle, resultSeq: LONG POINTER TO SeqLong ] = { zone: UNCOUNTED ZONE = Heap.systemZone; zone.FREE [@(resultSeq^.BASE)]; zone.FREE [@(resultSeq)]; }; FreeDoCmdsResults: PUBLIC PROC [ bH: BindHandle, resultSeq: LONG POINTER TO SeqResult ] = { zone: UNCOUNTED ZONE = Heap.systemZone; zone.FREE [@(resultSeq^.BASE)]; zone.FREE [@(resultSeq)]; }; Init: PROC = { trash: System.NetworkAddress _ TRASH; mem _ ALL[0]; nilHandle _ Rapunzel.RemoteBind[trash, NIL]; IF ( nilHandle # NIL ) THEN ERROR; }; Shutdown: PROC = { nilHandle _ Rapunzel.RemoteUnbind[nilHandle]; IF ( nilHandle # NIL ) THEN ERROR; }; Init[]; }.  RapunzelServiceImpl.mesa Copyright Σ 1986, 1988 by Xerox Corporation. All rights reserved. Bill Jackson (bj) January 8, 1988 4:33:06 am PST Willie-Sue, April 9, 1987 6:54:04 pm PDT Types & Magic #'s Global State b _ IOPOps.GetByte[p ! IOPOps.Error => { Fault[bH, xx, xx] } ]; IOPOps.PutByte[p, b ! IOPOps.Error => { Fault[bH, xx, xx] } ]; IF NOT (phys IN [lowerBound..upperBound]) THEN ERROR Fault[bH, nonexistent, addr]; IF NOT (phys IN [lowerBound..upperBound]) THEN ERROR Fault[bH, nonexistent, addr]; returnLength => resLength _ this.returnLength.returnLength * SIZE[Rapunzel.Result]; res: Rapunzel.PokeShortResult ¬ NULL; res: Rapunzel.PokeShortResult ¬ NULL; Κ Ÿ˜codešœ™KšœB™BKšœ0™0Kšœ(™(—K˜šΟk ˜ Kšœ œ ˜Kšœœ˜Kšœœ#˜/Kšœ œ ˜Kšœœ˜Kšœœ˜ K˜ —K˜šΟnœ˜Kšœ˜#Kšœ ˜Kšœ ˜headšΟz™K˜ ˜ K˜—K˜$Kšœ#œΟc˜>šœ#œ ˜QK˜—Kšœ œ˜šœ œ˜K˜—Kš œœœœœ˜3Kšœœ˜—šŸ ™ K˜ K˜Kšœ œœ˜Kšœœœ˜Kšœ œœ˜Kšœ˜Kšœ˜K˜—šžœœœKœ˜cK˜—šžœœœœœœœœ˜RKšœ?™?K˜K˜—šžœœœœœœœ˜GKšœ>™>K˜K˜—šžœœœ œœœœœ˜BK˜K˜K˜—šžœœœœœœœ˜7K˜K˜K˜—š žœœ œœ œœ˜=Kšœœ œœ˜!Kšœ œ˜Kšœœ˜&Kšœ œ ˜K˜K˜—šž œœœœ œœœœœ˜ZKšœœ˜&š˜šœ˜Kš œœœœœ™RKšœœ ˜K˜—šœ˜Kšœ ˜ K˜—šœ˜ šœœœ ˜0Kš œœ œœ œ˜Y—K˜K˜——K˜K˜—š ž œœœœœœ˜OKšœœ˜&š˜šœ˜Kš œœœœœ™RKšœ œ˜K˜—šœ˜Kšœ˜K˜—šœ˜ šœœœ ˜0Kš œœ œœ œ˜Y—K˜K˜——K˜—K˜šž œœœ7˜PKšœ˜Kšœ˜Kšœ˜K˜—šž œœœ.˜DKšœœ˜'K˜*K˜!K˜K˜K˜—šž œœœI˜_K˜*K˜K˜K˜K˜—šžœœœ.˜CKšœœ˜&K˜K˜)K˜"K˜%K˜K˜K˜K˜—šžœœœH˜]K˜)K˜K˜0K˜3K˜K˜—šž œœœ5œ˜XKš œœ œœœ˜;Kš œœœœœœ˜TKšœ œœ˜'Kšœœœœ˜.K˜-K˜Kšœœ œ˜Bšœœœ ˜ K˜)K˜Kšœ˜—K˜K˜—šž œœœ5œ˜WKš œœ œœœ˜:Kš œœœœœœ˜SKšœ œœ˜'Kšœœœœ˜.K˜,K˜Kšœœ œ˜Ašœœœ ˜ K˜K˜&K˜)K˜K˜Kšœ˜—K˜K˜—šž œœœœ5œœœœ˜xK˜-Kšœœ ˜'š œœœœ ˜,K˜K˜)Kšœ˜—K˜—K˜š žœœœœœœ˜OKšœœœœ˜>Kš œœœœœœ˜TKšœ œœ˜'Kšœœœ˜Kšœ œ˜Kšœ œ˜Kšœ œ˜š˜K˜šœ œ˜KšœS™SKšœ;˜;Kšœœ˜&—Kšœ˜—K˜Kšœ œ˜$Kšœœ œ˜IK˜Kšœ%œ˜-šœœœ˜&Kšœ&˜&Kšœ˜šœ œ˜˜K˜3Kšœ œ˜%K˜ šœœ˜K˜K˜K˜—Kšœ'˜'Kšœ˜K˜—˜K˜3Kšœ%™%šœœ˜K˜K˜.K˜—K˜.Kšœ!œ˜(Kšœ˜K˜—˜ K˜2Kšœ%™%šœœ˜K˜K˜-K˜—K˜>K˜?Kšœ œ˜'Kšœ˜K˜—šœ ˜ Kšœ2˜2Kšœ6˜6Kšœ,˜,šœœ˜Kšœ˜Kšœ1˜1K˜—Kšœ&˜&Kšœ˜šœœœ˜%Kšœ œ˜%K˜K˜Kšœ ˜ Kšœ'˜'Kšœ˜Kšœ˜—K˜—šœ˜Kšœ3˜3Kšœ7˜7Kšœ-˜-šœœ˜Kšœ˜Kšœ2˜2K˜—Kšœ'˜'Kšœ˜šœœœ˜%Kšœ*˜*Kšœ˜šœœ˜#˜K˜2K˜K˜K˜—Kšœœ˜+—Kšœ˜—K˜—Kšœœ˜Kšœœ˜+—Kšœ˜—K˜K˜—šžœœœ4œœœœ˜…šœœœ ˜ Kšœ2˜2K˜K˜0K˜1Kšœ˜—K˜K˜—š žœœœœœœ˜`Kšœ œœ˜'Kšœœœ˜Kšœœ˜K˜K˜—š žœœœœœœ˜^Kšœ œœ˜'Kšœœœ˜Kšœœ˜K˜K˜—š žœœœœœœ˜[Kšœ œœ˜'Kšœœœ˜Kšœœ˜K˜—K˜šžœœ˜Kšœœ˜%Kšœœ˜ Kšœ'œ˜,Kšœœœœ˜"K˜K˜—šžœœ˜K˜-Kšœœœœ˜"K˜—K˜K˜K˜K˜——…—$2Ο