SparcSoftcardOpsImpl.Mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Christophe Cuenod, September 7, 1988 10:50:51 am PDT
Bill Jackson (bj) April 19, 1988 3:34:37 am PDT
DIRECTORY
Basics USING [ BITAND, HighHalf, LowHalf ],
DoveInputOutput USING [ Peek, Poke ],
Rope USING [ ],
SparcSoftcard,
SparcSoftcardOps;
Test for the presence of a Sparc softcard and initialize the map properly for the CP and the IOP.
Daybreak range [1.5 thru 3.5 Mbytes] is mapped onto [0 thru 2.0 Mbytes] of the Sparc softcard.
SparcSoftcardOpsImpl: CEDAR PROGRAM
IMPORTS Basics, DoveInputOutput
EXPORTS SparcSoftcardOps ~ {
OPEN SparcSoftcard;
ControlBitWrite: PUBLIC PROC [ byteAddress: CARD32, polarity: Polarity, value: BOOL ] ~ {
address : CARD32 ~ byteAddress / 2;
IF ((byteAddress MOD 8) # 7) THEN ERROR;
If error here the address for the control bit is false.
SELECT TRUE FROM
( ( polarity = ActiveLow ) AND ( value ) ) =>
{ DoveInputOutput.Poke[address, 0] };
( ( polarity = ActiveLow ) AND ( NOT value ) ) =>
{ DoveInputOutput.Poke[address, commandBitMask] };
( ( polarity = ActiveHigh ) AND ( value ) ) =>
{ DoveInputOutput.Poke[address, commandBitMask] };
( ( polarity = ActiveHigh ) AND ( NOT value ) ) =>
{ DoveInputOutput.Poke[address, 0] };
ENDCASE;
};
ControlBitRead: PUBLIC PROC [ byteAddress: CARD32, polarity: Polarity ]
RETURNS [ value: BOOL ] ~ {
address : CARD32 ~ byteAddress / 2;
read: CARD16 ~ Basics.BITAND[commandBitMask, DoveInputOutput.Peek[address]];
IF ((byteAddress MOD 8) # 7) THEN ERROR;
If error here the address for the control bit is false.
SELECT TRUE FROM
( ( polarity = ActiveLow ) AND ( read = 0) ) => { value ← TRUE };
( ( polarity = ActiveLow ) AND ( read # 0) ) => { value ← FALSE };
( ( polarity = ActiveHigh ) AND ( read = 0) ) => { value ← FALSE };
( ( polarity = ActiveHigh ) AND ( read # 0) ) => { value ← TRUE };
ENDCASE;
};
SparcReset: PUBLIC PROC ~ {
ControlBitWrite[sparcResetRegisterByte, sparcResetPolarity, TRUE];
};
SparcResetAndStart: PUBLIC PROC ~ {
ControlBitWrite[sparcResetRegisterByte, sparcResetPolarity, TRUE];
ControlBitWrite[sparcResetRegisterByte, sparcResetPolarity, FALSE];
};
SparcCacheDisable: PUBLIC PROC ~ {
ControlBitWrite[sparcCacheEnableRegisterByte, sparcCacheEnablePolarity, FALSE];
};
SparcCacheFlushAndEnable: PUBLIC PROC ~ {
ControlBitWrite[sparcCacheEnableRegisterByte, sparcCacheEnablePolarity, FALSE];
ControlBitWrite[sparcCacheEnableRegisterByte, sparcCacheEnablePolarity, TRUE];
};
DMAState: TYPE = SparcSoftcardOps.DMAState;
SetDMAState: PUBLIC PROC [dMAState: DMAState] ~ {
IF dMAState = active THEN
ControlBitWrite[dMAActiveRegisterByte, dMAActivePolarity, TRUE]
ELSE
ControlBitWrite[dMAActiveRegisterByte, dMAActivePolarity, FALSE];
};
DMAMode: TYPE = SparcSoftcardOps.DMAMode;
SetDMAMode: PUBLIC PROC [dMAMode: DMAMode]~ {
SELECT dMAMode FROM
= printer => {
ControlBitWrite[dMAMode0RegisterByte, dMAMode0Polarity, FALSE];
ControlBitWrite[dMAMode1RegisterByte, dMAMode1Polarity, FALSE];
};
= display => {
ControlBitWrite[dMAMode0RegisterByte, dMAMode0Polarity, FALSE];
ControlBitWrite[dMAMode1RegisterByte, dMAMode1Polarity, TRUE];
};
= versatecOneShot => {
ControlBitWrite[dMAMode0RegisterByte, dMAMode0Polarity, TRUE];
ControlBitWrite[dMAMode1RegisterByte, dMAMode1Polarity, FALSE];
};
= versatecStream => {
ControlBitWrite[dMAMode0RegisterByte, dMAMode0Polarity, TRUE];
ControlBitWrite[dMAMode1RegisterByte, dMAMode1Polarity, TRUE];
};
ENDCASE;
};
DMAAddressRegisterLoad: PUBLIC PROC [ byteAddress: CARD32 ] ~ {
address: CARD32 ← byteAddress /8;
DoveInputOutput.Poke[dMAAddressRegisterHighByte/2, Basics.HighHalf[address]];
DoveInputOutput.Poke[dMAAddressRegisterLowByte/2, Basics.LowHalf[address]];
};
WriteMapEntry: PUBLIC PROC [ mapEntry: SparcSoftcardOps.MapEntry ] ~ {
windowNumber: CARD16;
entryAddressHighByte, entryAddressLowByte: CARD32;
mapEntryConcrete: CARD32;
[windowNumber, entryAddressHighByte, entryAddressLowByte] ← ComputeEntryAddress[mapEntry];
mapEntryConcrete ← ConcreteFromEntry[mapEntry];
DoveInputOutput.Poke[mapWindowIndexRegisterByte/2, windowNumber];
Store window number
DoveInputOutput.Poke[entryAddressHighByte/2, Basics.LowHalf[mapEntryConcrete]];
Store high part of the entry
DoveInputOutput.Poke[entryAddressLowByte/2, Basics.HighHalf[mapEntryConcrete]];
Store low part of the entry
};
ComputeEntryAddress: PROC [ mapEntry: SparcSoftcardOps.MapEntry ] RETURNS [windowNumber: CARD16, entryAddressHighByte, entryAddressLowByte: CARD32]~ {
mapEntryNumber: CARD32;
windowOffset: CARD16;
Computes the entry number into the map
SELECT mapEntry.vMSpace.name FROM
Sets the base of mapEntryNumber
= dMA => {
mapEntryNumber ← 0E000H;
IF mapEntry.virtualAddressByte >= 4000000H THEN ERROR;
Address range limited to 64 Meg.
};
= iOP => {
mapEntryNumber ← 0A000H;
IF mapEntry.virtualAddressByte >= 1000000H THEN ERROR;
Address range limited to 16 Meg.
};
= cP => {
mapEntryNumber ← 0A000H + 1000000H/softcardPageSizeByte;
CP is in the same VM than IOP but 16 Meg farther.
IF mapEntry.virtualAddressByte >= 400000H THEN ERROR;
Address range limited to 4 Meg.
};
= sparcUserData => {
mapEntryNumber ← 0;
IF mapEntry.virtualAddressByte >= 8000000H THEN ERROR;
***
*** In this first implementation the address range is limited to 128 Meg.
*** Only task 0 is implemented.
***
};
= sparcUserProgram => {
mapEntryNumber ← 4000H;
IF mapEntry.virtualAddressByte >= 8000000H THEN ERROR;
***
*** In this first implementation the address range is limited to 128 Meg.
*** Only task 0 is implemented.
***
};
= sparcSuperData => {
mapEntryNumber ← 8000H;
IF mapEntry.virtualAddressByte >= 4000000H THEN ERROR;
The supervisor address range is limited to 64 Meg.
};
= sparcSuperProgram => {
mapEntryNumber ← 0C000H;
IF mapEntry.virtualAddressByte >= 4000000H THEN ERROR;
The supervisor address range is limited to 64 Meg.
};
ENDCASE => ERROR;
mapEntryNumber ← mapEntryNumber + mapEntry.virtualAddressByte/softcardPageSizeByte;
Adds the offset.
windowNumber ← mapEntryNumber / mapEntriesPerWindow;
windowOffset ← mapEntryNumber MOD mapEntriesPerWindow;
Computes addresses
entryAddressHighByte ← mapWindowBaseByte + mapEntryHighByteOffset + windowOffset * mapEntrySizeByte;
entryAddressLowByte ← mapWindowBaseByte + mapEntryLowByteOffset + windowOffset * mapEntrySizeByte;
};
ConcreteFromEntry: PROC [ mapEntry: SparcSoftcardOps.MapEntry ] RETURNS [mapEntryConcreteCard: CARD32] ~ {
mapEntryConcrete: SparcSoftcardOps.MapEntryConcrete;
mapEntryConcrete.readOnly ← mapEntry.flags.readOnly;
mapEntryConcrete.referenced ← mapEntry.flags.referenced;
mapEntryConcrete.dirty ← mapEntry.flags.dirty;
mapEntryConcrete.nonCachable ← mapEntry.flags.nonCachable;
mapEntryConcrete.interrupt ← mapEntry.flags.interrupt;
mapEntryConcrete.task ← 0;
***
*** Now only task 0 is implemented
***
mapEntryConcrete.virtualPageHiHi ← 0;
***
*** Now only 128 Meg of VM
***
mapEntryConcrete.virtualPageHiLow ← 0;
***
*** Now only 128 Meg of VM
***
mapEntryConcrete.realPage ← mapEntry.realAddressByte/softcardPageSizeByte;
mapEntryConcreteCard ← LOOPHOLE[mapEntryConcrete];
};
}.