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
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];
};
}.