<> <> <> <<>> DIRECTORY CrRPC USING [Error, Handle, CreateClientHandle, DestroyClientHandle], HostNickNameTable USING [LookUp], DragOpsCross, DragOpsCrossUtils, RapunzelP2200V0, Rope USING [ROPE], SoftcardOps, SoftcardPrivate, XNS USING [unknownSocket], XNSName USING [Address, AddressFromRope]; SoftcardOpsImpl: CEDAR PROGRAM IMPORTS CrRPC, DragOpsCrossUtils, HostNickNameTable, Rapunzel: RapunzelP2200V0, XNSName, SoftcardOps EXPORTS SoftcardOps = BEGIN OPEN SoftcardPrivate; ROPE: TYPE = Rope.ROPE; Addr: TYPE = SoftcardOps.Addr; EUPBusCmd: TYPE = SoftcardOps.EUPBusCmd; -- tbd IFUPBusCmd: TYPE = SoftcardOps.IFUPBusCmd; EUInternal: TYPE = SoftcardOps.EUInternal; -- tbd IFUInternalState: TYPE = SoftcardOps.IFUInternalState; -- tbd ClockControl: TYPE = SoftcardOps.ClockControl; ControlBit: TYPE = SoftcardOps.ControlBit; StatusBit: TYPE = SoftcardOps.StatusBit; OneBit: TYPE = SoftcardPrivate.OneBit; Control1Bits: TYPE = SoftcardPrivate.Control1Bits; Control2Bits: TYPE = SoftcardPrivate.Control2Bits; StatusBits: TYPE = SoftcardPrivate.StatusBits; <> FullWordeuPBusCmd: TYPE = MACHINE DEPENDENT RECORD [ unspecifiedAsYet (0: 0..7): [0..377B] _ 0, unused (0: 8..15): [0..377B] _ 0 ]; FullWordifuPBusCmd: TYPE = MACHINE DEPENDENT RECORD [ reserved (0: 0..2): [0..7B] _ 0, ifuPBusCmd (0: 3..3): IFUPBusCmd _ noAccess, r1 (0: 4..6): [0..7B] _ 0, userMode (0: 7..7): BOOL _ FALSE, r2 (0: 8..15): [0..377B] _ 0 ]; crHandle: CrRPC.Handle; <<-- various CmdSeqences to be shared>> <> <> Error: PUBLIC SIGNAL[code: ATOM, explanation: ROPE _ NIL] = CODE; EstablishConnection: PUBLIC PROC[host: ROPE] RETURNS[ok: BOOL] = { Ec: PROC = { netAddr: ROPE = HostNickNameTable.LookUp[host]; socket: XNSName.Address = XNSName.AddressFromRope[netAddr, XNS.unknownSocket]; crHandle _ CrRPC.CreateClientHandle[$SPP, socket, 0]; }; CarefullyApply[proc: Ec, nilHandleOK: TRUE]; RETURN[crHandle # NIL]; }; CloseConnection: PUBLIC PROC = { CrRPC.DestroyClientHandle[crHandle]; crHandle _ NIL; }; SetEUBrkPtAddr: PUBLIC PROC[addr: Addr] = { Seu: PROC = { [] _ Rapunzel.PokeLong[crHandle, BkptEUH, addr ] }; CarefullyApply[Seu]; }; SetIFUBrkPtAddr: PUBLIC PROC[addr: Addr] = { Sifu: PROC = { [] _ Rapunzel.PokeLong[crHandle, BkptIFUH, addr] }; CarefullyApply[Sifu]; }; ReadEUCmd: PUBLIC PROC RETURNS[euPBusCmd: EUPBusCmd] = { Reuc: PROC = { user: FullWordifuPBusCmd = LOOPHOLE[ReadShort[SpyCmd2]]; most: FullWordeuPBusCmd = LOOPHOLE[ReadShort[SpyCmd1]]; euPBusCmd.userMode _ user.userMode; euPBusCmd.unspecifiedAsYet _ most.unspecifiedAsYet; }; CarefullyApply[Reuc]; }; ReadIFUCmd: PUBLIC PROC RETURNS[ifuPBusCmd: IFUPBusCmd] = { ifuPBusCmd _ LOOPHOLE[ReadShort[SpyCmd2], FullWordifuPBusCmd].ifuPBusCmd }; ReadEUPBusData: PUBLIC PROC RETURNS[value: DragOpsCross.Word] = { Reup: PROC = { value _ DragOpsCrossUtils.CardToWord[Rapunzel.PeekLong[crHandle, SpyEUDataH] ] }; CarefullyApply[Reup]; }; ReadIFUPBusData: PUBLIC PROC RETURNS[value: DragOpsCross.Word] = { Rifup: PROC = { value _ DragOpsCrossUtils.CardToWord[Rapunzel.PeekLong[crHandle, SpyEUDataH] ] }; CarefullyApply[Rifup]; }; ReadClock: PUBLIC PROC RETURNS[value: LONG CARDINAL] = { <> Rc: PROC = { value _ Rapunzel.PeekLong[crHandle, ClockH] }; CarefullyApply[Rc]; }; <<*************************>> <<>> ReadEUInternalRegsiter: PUBLIC PROC[which: EUInternal] RETURNS[value, extra: DragOpsCross.Word] = { <> RETURN[DragOpsCross.ZerosWord, DragOpsCross.ZerosWord] }; WriteEUInternalRegsiter: PUBLIC PROC[ which: EUInternal, value, extra: DragOpsCross.Word] = { <> }; <<>> ReadIFUInternalState: PUBLIC PROC RETURNS[ifuState: IFUInternalState] = { <> <> <> <> <> <> <<>> <> <> <<>> <> <=resultSeq.length DO>> <> <> < {>> <> <> <> <<};>> < ERROR;>> < ERROR;>> <> <<};>> <> }; WriteIFUInternalState: PUBLIC PROC[ifuState: IFUInternalState] = { <> <> <> <> <> <> <> <> <> <<>> <> <=write32BitsSeq.length DO>> <> <> <> <> <<>> <> <<};>> <> }; <<>> <<*************************>> ReadClockControl: PUBLIC PROC RETURNS[clockControl: ClockControl] = { Rcc: PROC = { clockControl _ LOOPHOLE[Rapunzel.PeekShort[crHandle, ClockControlAddr]] }; CarefullyApply[Rcc]; }; WriteClockControl: PUBLIC PROC[clockControl: ClockControl] = { Wcc: PROC = { Rapunzel.PokeShort[crHandle, ClockControlAddr, LOOPHOLE[clockControl, CARDINAL]] }; CarefullyApply[Wcc]; }; <<*************************>> <> ReadControlBit: PUBLIC PROC[which: ControlBit] RETURNS[current: BOOL] = { isControl1: BOOL = IsControl1[which]; value: CARDINAL = ReadShort[IF isControl1 THEN Consult1 ELSE Consult2]; RETURN[ReturnBit[which, isControl1, value]]; }; SetControlBit: PUBLIC PROC[which: ControlBit] RETURNS[previous: BOOL] = { value: CARDINAL = ReadShort[GetControlResetAddr[which] + 2]; RETURN[ReturnBit[which, IsControl1[which], value]]; }; ResetControlBit: PUBLIC PROC[which: ControlBit] RETURNS[previous: BOOL] = { value: CARDINAL = ReadShort[GetControlResetAddr[which]]; RETURN[ReturnBit[which, IsControl1[which], value]]; }; ResetIFUCacheStateMachine: PUBLIC PROC = {}; ResetEUCacheStateMachine: PUBLIC PROC = {}; DisableIFUCache: PUBLIC PROC = { [] _ ReadShort[CarIFUCache] }; DisableEUCache: PUBLIC PROC = { [] _ ReadShort[CarEUCache] }; FlushIFUCache: PUBLIC PROC = { [] _ ReadShort[CarIFUCache]; [] _ ReadShort[CasIFUCache] }; FlushEUCache: PUBLIC PROC = { [] _ ReadShort[CarEUCache]; [] _ ReadShort[CasEUCache] }; ResetCounter: PUBLIC PROC = { [] _ ReadShort[CarCounter] }; <<***** ***** ***** ***** ***** ***** ***** ***** >> IsControl1: PROC[which: ControlBit] RETURNS[BOOL] = { SELECT which FROM iopIntToDragon, mesaIntToDragon => RETURN[FALSE]; ENDCASE => RETURN[TRUE]; }; GetControlResetAddr: PROC[which: ControlBit] RETURNS[Addr] = { SELECT which FROM interruptDragonToIOP => RETURN[CarInterrurptDragonToIOP]; interruptDragonToMesa => RETURN[CarInterruptDragonToMesa]; writeParity => RETURN[CarWriteParity]; virtualMemAccessIOP => RETURN[CarVirtualMemAccessIOP]; virtualMemAccessMesa => RETURN[CarVirtualMemAccessMesa]; virtualMemAccessIFU => RETURN[CarVirtualMemAccessIFU]; virtualMemAccessEU => RETURN[CarVirtualMemAccessEU]; ifuBreakpointEnabled => RETURN[CarEnableIFUBkpt]; euBreakpointEnabled => RETURN[CarEnableEUBkpt]; iopIntToDragon => RETURN[CarIOPIntToDragon]; mesaIntToDragon => RETURN[CarMesaIntToDragon]; ENDCASE => ERROR; }; ReturnBit: PROC[which: ControlBit, isControl1: BOOL, value: CARDINAL] RETURNS[BOOL] = { control1Bits: Control1Bits; control2Bits: Control2Bits; IF isControl1 THEN control1Bits _ LOOPHOLE[value] ELSE control2Bits _ LOOPHOLE[value]; SELECT which FROM interruptDragonToIOP => RETURN[control1Bits.interrurptDragonToIOP]; interruptDragonToMesa => RETURN[control1Bits.interrurptDragonToMesa]; writeParity => RETURN[control1Bits.writeParity]; virtualMemAccessIOP => RETURN[control1Bits.virtualMemAccessIOP]; virtualMemAccessMesa => RETURN[control1Bits.virtualMemAccessMesa]; virtualMemAccessIFU => RETURN[control1Bits.virtualMemAccessIFU]; virtualMemAccessEU => RETURN[control1Bits.virtualMemAccessEU]; ifuBreakpointEnabled => RETURN[control1Bits.enableIFUBkpt]; euBreakpointEnabled => RETURN[control1Bits.enableEUBkpt]; iopIntToDragon => RETURN[control2Bits.iopIntToDragon]; mesaIntToDragon => RETURN[control2Bits.mesaIntToDragon]; ENDCASE => ERROR; }; <<>> <<*************************>> ReadStatusBit: PUBLIC PROC[which: StatusBit] RETURNS[current: BOOL] = { all: StatusBits = LOOPHOLE[ReadShort[ConsultStatusAddr]]; RETURN[SelectStatusBit[which, all] ]; }; ResetStatusBit: PUBLIC PROC[which: StatusBit] RETURNS[previous: BOOL] = { all: StatusBits = LOOPHOLE[ReadShort[SelectStatusResetAddr[which]]]; RETURN[SelectStatusBit[which, all] ]; }; SelectStatusBit: PROC[which: StatusBit, all: StatusBits] RETURNS[BOOL] = { SELECT which FROM periodicIntToDragon => RETURN[all.periodicIntToDragon]; memoryError => RETURN[all.memoryError]; euBkptReached => RETURN[all.euBkptReached]; ifuBkptReached => RETURN[all.ifuBkptReached]; mapError => RETURN[all.mapError]; ENDCASE => ERROR; }; SelectStatusResetAddr: PROC[which: StatusBit] RETURNS[Addr] = { SELECT which FROM periodicIntToDragon => RETURN[CarPeriodicIntToDragon]; memoryError => RETURN[CarMemoryError]; euBkptReached => RETURN[CarEUBrkptReached]; ifuBkptReached => RETURN[CarIFUBrkptReached]; mapError => RETURN[CarMapError]; ENDCASE => ERROR; }; <<>> <<*************************>> <> MesaMapIndex: TYPE = SoftcardOps.MesaMapIndex; MesaMapEntry: TYPE = SoftcardOps.MesaMapEntry; ReadMesaMap: PUBLIC PROC[index: MesaMapIndex] RETURNS[value: MesaMapEntry] = { RETURN[LOOPHOLE[ReadShort[MesaMapAddr + 2*LONG[index] + 1], MesaMapEntry] ] }; WriteMesaMap: PUBLIC PROC[index: MesaMapIndex, value: MesaMapEntry] = { WriteShort[MesaMapAddr+2*LONG[index]+1, LOOPHOLE[value, CARDINAL] ] }; <<>> <<*************************>> <> DragonMapIndex: TYPE = SoftcardOps.DragonMapIndex; DragonMapEntry: TYPE = SoftcardOps.DragonMapEntry; ReadDragonMap: PUBLIC PROC[index: DragonMapIndex] RETURNS[value: DragonMapEntry] = { RETURN[LOOPHOLE[ReadShort[DragonMapAddr+2*index+1], DragonMapEntry] ] }; WriteDragonMap: PUBLIC PROC[index: DragonMapIndex, value: DragonMapEntry] = { WriteShort[DragonMapAddr+2*index+1, LOOPHOLE[value, CARDINAL] ] }; <<*************************>> <> <<>> CarefullyApply: PROC[proc: PROC, nilHandleOK: BOOL _ FALSE] = { cText: ROPE; BEGIN ENABLE CrRPC.Error => { cText _ text; GOTO error; }; IF ~nilHandleOK AND crHandle = NIL THEN SIGNAL SoftcardOps.Error[$noConnection, "open a connection first"]; proc[]; EXITS error => SIGNAL SoftcardOps.Error[$crRPCError, cText]; END; }; <<>> ReadShort: PROC[addr: Addr] RETURNS[value: CARDINAL] = { Rs: PROC = { value _ Rapunzel.PeekShort[crHandle, addr] }; CarefullyApply[Rs]; }; WriteShort: PROC[addr: Addr, value: CARDINAL] = { Ws: PROC = { Rapunzel.PokeShort[crHandle, addr, value] }; CarefullyApply[Ws]; }; ConstructReadnBitSeq: PROC[num: CARDINAL] RETURNS[tSeq: Rapunzel.SeqCmd] = { <> index: CARDINAL _ 1; psDragonRun: Rapunzel.PeekShortCmd = [CarDragonRun]; psShiftA: Rapunzel.PeekShortCmd = [DebugShiftA]; psShiftB: Rapunzel.PeekShortCmd = [DebugShiftB]; psConsultStatus: Rapunzel.PeekShortCmd = [ConsultStatusAddr]; tSeq _ NEW[Rapunzel.SeqCmdObject[1+1+3*num]]; TRUSTED { tSeq[0] _ [peekShort[psDragonRun]]; -- stop the Dragon first <> <<>> <> FOR i: CARDINAL IN [0..num) DO tSeq[index _ index + 1] _ [peekShort[psShiftA]]; tSeq[index _ index + 1] _ [peekShort[psShiftB]]; tSeq[index _ index + 1] _ [peekShort[psConsultStatus]]; -- read the bit ENDLOOP; }; }; ConstructWritenBitSeq: PROC[num: CARDINAL] RETURNS[tSeq: Rapunzel.SeqCmd] = { <> index: CARDINAL _ 0; psDragonRun: Rapunzel.PeekShortCmd = [CarDragonRun]; psShiftA: Rapunzel.PeekShortCmd = [DebugShiftA]; psShiftB: Rapunzel.PeekShortCmd = [DebugShiftB]; tSeq _ NEW[Rapunzel.SeqCmdObject[1+1+3*num]]; TRUSTED { <<>> <> FOR i: CARDINAL IN [0..num) DO tSeq[index _ index + 1] _ [peekShort[psShiftA]]; tSeq[index _ index + 1] _ [peekShort[psShiftB]]; index _ index + 1; -- write the bit goes here ENDLOOP; tSeq[1+1+3*num-1-1] _ [peekShort[psDragonRun]]; -- stop the Dragon before the write <> }; }; <<***********************************>> <<>> END.