-- Copyright (C) 1983, 1985 by Xerox Corporation. All rights reserved. -- EERomDicentra.mesa, HGM, 6-Apr-85 11:38:58 DIRECTORY Environment USING [Byte, bytesPerWord], Inline USING [LowByte, HighByte], Process USING [Pause], System USING [GetClockPulses, Pulses, PulsesToMicroseconds], DicentraInputOutput USING [Input, IOAddress, Output], EERom USING [BootLocation, bytesPerChip, Data, WholeEERom], MultibusAddresses USING [eprom, timeout]; EERomDicentra: MONITOR IMPORTS Inline, Process, System, DicentraInputOutput EXPORTS EERom = BEGIN eprom: DicentraInputOutput.IOAddress = MultibusAddresses.eprom; timeout: DicentraInputOutput.IOAddress = MultibusAddresses.timeout; -- Port A on Timeout CIO was enabled by Microcode/ProcessorHead. eeRom: POINTER TO EERom.WholeEERom = LOOPHOLE[0]; writePulse: WORD = 0800H; -- NB: Low TRUE firstChip: CARDINAL = 4; ReadByte: PROCEDURE [loc: POINTER, offset: CARDINAL] RETURNS [data: Environment.Byte] = BEGIN byteIndex, chip, byteWithinChip: CARDINAL; byteIndex ← Environment.bytesPerWord*LOOPHOLE[loc, CARDINAL] + offset; chip ← firstChip + (byteIndex / EERom.bytesPerChip); byteWithinChip ← byteIndex MOD EERom.bytesPerChip; byteWithinChip ← byteWithinChip + writePulse; DicentraInputOutput.Output[Inline.HighByte[byteWithinChip], eprom + 00DH]; -- Port A Data DicentraInputOutput.Output[Inline.LowByte[byteWithinChip], eprom + 00EH]; -- Port B Data DicentraInputOutput.Output[0FFH, timeout + 023H]; -- Port A Direction ← All in DicentraInputOutput.Output[000H, eprom + 00FH]; -- Port C Data ← Output Enable DicentraInputOutput.Output[chip, timeout + 00EH]; -- Port B Data data ← DicentraInputOutput.Input[timeout + 00DH]; -- Port A Data DicentraInputOutput.Output[008H, eprom + 00FH]; -- Port C Data ← No Output Enable DicentraInputOutput.Output[00FH, timeout + 00EH]; -- Port B Data ← Idle END; WriteByte: PROCEDURE [loc: POINTER, offset: CARDINAL, data: Environment.Byte] = BEGIN byteIndex, chip, byteWithinChip: CARDINAL; IF data = ReadByte[loc, offset] THEN RETURN; byteIndex ← Environment.bytesPerWord*LOOPHOLE[loc, CARDINAL] + offset; chip ← firstChip + (byteIndex / EERom.bytesPerChip); byteWithinChip ← byteIndex MOD EERom.bytesPerChip; byteWithinChip ← byteWithinChip + writePulse; DicentraInputOutput.Output[Inline.HighByte[byteWithinChip], eprom + 00DH]; -- Port A Data DicentraInputOutput.Output[Inline.LowByte[byteWithinChip], eprom + 00EH]; -- Port B Data DicentraInputOutput.Output[008H, eprom + 00FH]; -- Port C Data ← No Output Enable DicentraInputOutput.Output[000H, timeout + 023H]; -- Port A Direction ← All out DicentraInputOutput.Output[chip, timeout + 00EH]; -- Port B Data ← High Byte DicentraInputOutput.Output[data, timeout + 00DH]; -- Port A Data byteWithinChip ← byteWithinChip - writePulse; DicentraInputOutput.Output[Inline.HighByte[byteWithinChip], eprom + 00DH]; -- Port A Data byteWithinChip ← byteWithinChip + writePulse; DicentraInputOutput.Output[Inline.HighByte[byteWithinChip], eprom + 00DH]; -- Port A Data WaitTenMs[]; DicentraInputOutput.Output[0FFH, timeout + 023H]; -- Port A Direction ← All in DicentraInputOutput.Output[00FH, timeout + 00EH]; -- Port B Data ← Idle END; StoreBootLocation: PUBLIC ENTRY PROCEDURE [bits: LONG POINTER TO EERom.BootLocation] = BEGIN info: LONG POINTER TO PACKED ARRAY [0..0) OF Environment.Byte ← LOOPHOLE[bits]; address: POINTER ← @eeRom.bootLocation; FOR i: CARDINAL IN [0..Environment.bytesPerWord*SIZE[EERom.BootLocation]) DO WriteByte[address, i, info[i]]; ENDLOOP; END; FetchBootLocation: PUBLIC ENTRY PROCEDURE [bits: LONG POINTER TO EERom.BootLocation] = BEGIN info: LONG POINTER TO PACKED ARRAY [0..0) OF Environment.Byte ← LOOPHOLE[bits]; address: POINTER ← @eeRom.bootLocation; FOR i: CARDINAL IN [0..Environment.bytesPerWord*SIZE[EERom.BootLocation]) DO info[i] ← ReadByte[address, i]; ENDLOOP; END; StoreData: PUBLIC ENTRY PROCEDURE [bits: LONG POINTER TO EERom.Data] = BEGIN info: LONG POINTER TO PACKED ARRAY [0..0) OF Environment.Byte ← LOOPHOLE[bits]; address: POINTER ← @eeRom.data; FOR i: CARDINAL IN [0..Environment.bytesPerWord*SIZE[EERom.Data]) DO WriteByte[address, i, info[i]]; ENDLOOP; END; FetchData: PUBLIC ENTRY PROCEDURE [bits: LONG POINTER TO EERom.Data] = BEGIN info: LONG POINTER TO PACKED ARRAY [0..0) OF Environment.Byte ← LOOPHOLE[bits]; address: POINTER ← @eeRom.data; FOR i: CARDINAL IN [0..Environment.bytesPerWord*SIZE[EERom.Data]) DO info[i] ← ReadByte[address, i]; ENDLOOP; END; SmashData: PUBLIC ENTRY PROCEDURE = BEGIN address: POINTER ← @eeRom.data; FOR i: CARDINAL IN [0..Environment.bytesPerWord*SIZE[EERom.Data]) DO WriteByte[address, i, 0]; ENDLOOP; END; -- Spec says we need to wait 10ms. That seemed to fail occasionally. -- Spinning for 20ms lets the watchdog timer go off. This will probably take 50ms. WaitTenMs: PROCEDURE = BEGIN start: System.Pulses = System.GetClockPulses[]; DO now: System.Pulses = System.GetClockPulses[]; IF System.PulsesToMicroseconds[[now-start]] > 20000 THEN EXIT; Process.Pause[1]; ENDLOOP; END; END.