SparcSoftcardMapInitialize.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Christophe Cuenod, April 15, 1988 5:57:46 pm PDT
DIRECTORY
Basics USING [ LowByte ],
Commander USING [ CommandProc, Register ],
DoveInputOutput USING [ Peek, Poke ],
IO USING [ PutF ];
This program tests for the presence of a Sparc softcard and initialise the Mesa map and the IOP map.
Daybreak memory range 1.5 to 3.5 Mbytes is mapped into the 2 first Mbytes of the Sparc softcard local memory.
SparcSoftcardMapInitialize: CEDAR PROGRAM
IMPORTS Basics, Commander, DoveInputOutput, IO ~ BEGIN
threePtFiveByteAddress: CARD32 ~ 0380000H;
threePtFiveWordAddress: CARD32 ~ threePtFiveByteAddress / 2;
alternatePathByteOffset: CARD32 ~ 10000H;
alternatePathWordOffset: CARD32 ~ alternatePathByteOffset / 2;
Due to the decoding the peripheral registers of the softcard appear at different locations
tRegisterByteOffset: CARD32 ~ 04C06H;
tRegisterWordOffset: CARD32 ~ tRegisterByteOffset / 2;
tRegisterWord: CARD32 ~ threePtFiveWordAddress + tRegisterWordOffset;
tRegisterAlternateWord: CARD32 ~ threePtFiveWordAddress + tRegisterWordOffset + alternatePathWordOffset;
mapWindow is a 2048 entries window to the sparc softcard map. This map contains the entries for the Sparc as well as the Mesa processor, the IOP and the DMA. In order to change the window you must write mapPageRegister.
mapWindowBaseByteOffset: CARD32 ~ 08000H;
mapWindowBaseWordOffset: CARD32 ~ mapWindowBaseByteOffset / 2;
mapWindowBaseWord: CARD32 ~ threePtFiveWordAddress + mapWindowBaseWordOffset;
mapPageRegister is a register that holds the 5 more significant bits of address of the map entries array.
IfmapPageRegister holdsthe value daybreakMapPage the window will point to the right locations for the Mesa and IO port. In this case IOP page 0 will be the iopBaseEntryInsideWindow entry and Mesa page 0 will be the mesaBaseEntryInsideWindow entry.
Currently mapPageRegister is Write only register
mapPageRegisterByteOffset: CARD32 ~ 04406H;
mapPageRegisterWordOffset: CARD32 ~ mapPageRegisterByteOffset / 2;
mapPageRegisterWord: CARD32 ~ threePtFiveWordAddress + mapPageRegisterWordOffset;
daybreakMapPage: BYTE ~ 014h; -- This number has to be stored inside mapPageRegister in order to have inside the window the map entries for the Mesa processor and the IOP.
iopBaseEntryInsideWindow: NAT ~ 0;
mesaBaseEntryInsideWindow: NAT ~ 200H;
Each entry of the map is composed of 2 non contiguous 16 bits words.
mapEntryHighPartByteOffset: NAT ~ 6;
mapEntryHighPartWordOffset: NAT ~ mapEntryHighPartByteOffset / 2;
mapEntryLowPartByteOffset: NAT ~ 0EH;
mapEntryLowPartWordOffset: NAT ~ mapEntryLowPartByteOffset / 2;
mapEntrySizeByte: NAT ~ 10H;
mapEntrySizeWord: NAT ~ mapEntrySizeByte / 2;
The high part of the map contains mostly the flags and has to be set to mapEntryHighPartPattern.
The low part of the map contains mostly the page number (limited to [0..0400H) for 8 Megabytes memory and has to be set to mapEntryLowPartPattern + the required phisical page number.
mapEntryHighPartPattern: NAT ~ 0;
mapEntryLowPartPattern: NAT ~ 0;
Size of a softcard VM page.
softcardPageSize: NAT ~ 2000H;
magic: BYTE ~ 05Ah; -- Arbitrary constant
magicNot: BYTE ~ 0A5h; -- Another arbitrary constant
MyPoke: PROC [address: CARD32, word: UNSPECIFIED] ~ {
DoveInputOutput.Poke[address, word];
};
MyPeek: PROC [address: CARD32] RETURNS [ word: UNSPECIFIED ]~ {
word ← DoveInputOutput.Peek[address];
};
SparcSoftcardMapInitializeProc: Commander.CommandProc = BEGIN
PeekPokePeekRestore: PROC [ address0: CARD32, content: CARD16, address1: CARD32 ]
RETURNS [ lowByte: BYTE ] ~ {
word0: CARD16 ~ MyPeek[address0];
MyPoke[address0, content];
{
word1: CARD16 ~ MyPeek[address1];
lowByte ← Basics.LowByte[word1];
};
MyPoke[address0, word0];
};
constant1: BYTE ~ PeekPokePeekRestore[tRegisterWord, magic, tRegisterAlternateWord];
constant2: BYTE ~ PeekPokePeekRestore[tRegisterAlternateWord, magicNot, tRegisterWord];
softcardHere: BOOL ~ SELECT TRUE FROM
( constant1 # magic ) => FALSE,
( constant2 # magicNot ) => FALSE,
ENDCASE => TRUE;
IF ( softcardHere )
THEN {
value: INT16;
addressIOPHigh: CARD32 ~ mapWindowBaseWord + mapEntrySizeWord * iopBaseEntryInsideWindow + mapEntryHighPartWordOffset;
addressIOPLow: CARD32 ~ mapWindowBaseWord + mapEntrySizeWord * iopBaseEntryInsideWindow + mapEntryHighPartWordOffset;
addressMesaHigh: CARD32 ~ mapWindowBaseWord + mapEntrySizeWord * mesaBaseEntryInsideWindow + mapEntryHighPartWordOffset;
addressMesaLow: CARD32 ~ mapWindowBaseWord + mapEntrySizeWord * mesaBaseEntryInsideWindow + mapEntryHighPartWordOffset;
startingPage: NAT ~ 180000h / softcardPageSize; -- Softcard memory starts at 1.5 meg in Daybreak adress space
endingPage: NAT ~ 380000h / softcardPageSize; -- Softcard memory starts at 3.5 meg in Daybreak adress space
MyPoke[mapPageRegisterWord, daybreakMapPage]; -- Initialize the window register
FOR i: NAT IN [startingPage..endingPage) DO
Fill the High part of the entry for IOP and Mesa
MyPoke[addressIOPHigh + mapEntrySizeWord * i, mapEntryHighPartPattern];
MyPoke[addressMesaHigh + mapEntrySizeWord * i, mapEntryHighPartPattern];
Fill the Low part of the entry for IOP and Mesa
value ← mapEntryLowPartPattern + i - startingPage;
MyPoke[addressIOPLow + mapEntrySizeWord * i, value];
MyPoke[addressMesaHigh + mapEntrySizeWord * i, value];
ENDLOOP;
IO.PutF[cmd.out,"SPARC Softcard present\n"]
}
ELSE IO.PutF[cmd.out,"SPARC Softcard NOT present\n"];
END;
Commander.Register[key: "SparcSoftcardMapInitialize", proc: SparcSoftcardMapInitializeProc, doc: "This program test the presence of a Sparc softcard.\n"];
END.