--functions for Alto and D0 Microcode
DIRECTORY
AltoMicrocodeDefs: FROM "AltoMicrocodeDefs",
D0MicrocodeDefs: FROM "D0MicrocodeDefs",
MiscDefs: FROM "MiscDefs" USING [DestroyFakeModule],
Mopcodes: FROM "Mopcodes" USING [zMISC],
RamDefs: FROM "RamDefs",
SegmentDefs: FROM "SegmentDefs";

Microcode: PROGRAM IMPORTS AltoMicrocodeDefs, D0MicrocodeDefs, MiscDefs, RamDefs, SegmentDefs EXPORTS AltoMicrocodeDefs, D0MicrocodeDefs =
BEGIN

LRJBlock
: TYPE = RECORD
[
VersionID: CARDINAL,--current version is 0
AllOnes: CARDINAL,--high order 12 bits must be all ones
CheckSum: CARDINAL, --unused
StartAddr: CARDINAL
];

EndBlock: LRJBlock ← [0,177777B,0,0];

LoadRamAndJump: PROCEDURE [LONG POINTER, BOOLEAN] =
MACHINE CODE BEGIN
Mopcodes.zMISC,3;
END;

LoadRamAndJumpArg: PROCEDURE [UNSPECIFIED, LONG POINTER, BOOLEAN] =
MACHINE CODE BEGIN
Mopcodes.zMISC,3;
END;

LoadRamAndJumpRslt: PROCEDURE [LONG POINTER, BOOLEAN] RETURNS [UNSPECIFIED] =
MACHINE CODE BEGIN
Mopcodes.zMISC,3;
END;

LoadRamAndJumpArgRslt: PROCEDURE [UNSPECIFIED, LONG POINTER, BOOLEAN] RETURNS [UNSPECIFIED] =
MACHINE CODE BEGIN
Mopcodes.zMISC,3;
END;

JumpRam: PUBLIC PROCEDURE [RAMAddress: [0..7777B]] =
BEGIN
EndBlock.StartAddr ← RAMAddress;
LoadRamAndJump[@EndBlock,TRUE];
END;

JumpRamArg
: PUBLIC PROCEDURE [RAMAddress: [0..7777B],Argument: UNSPECIFIED] =
BEGIN
EndBlock.StartAddr ← RAMAddress;
LoadRamAndJumpArg[Argument,@EndBlock,TRUE];
END;

JumpRamRslt
: PUBLIC PROCEDURE [RAMAddress: [0..7777B]] RETURNS [UNSPECIFIED] =
BEGIN
EndBlock.StartAddr ← RAMAddress;
RETURN[LoadRamAndJumpRslt[@EndBlock,TRUE]];
END;

JumpRamArgRslt
: PUBLIC PROCEDURE [RAMAddress: [0..7777B],Argument: UNSPECIFIED]
RETURNS [UNSPECIFIED] =
BEGIN
EndBlock.StartAddr ← RAMAddress;
RETURN[LoadRamAndJumpArgRslt[Argument,@EndBlock,TRUE]];
END;
--Kludge to make sure module is started from alto
LoadRam
: PUBLIC PROCEDURE =
BEGIN
END;

uImageFile: SegmentDefs.FileSegmentHandle;
uCode: POINTER;
offset: CARDINAL;
memType: SegmentDefs.MemoryConfig ← SegmentDefs.GetMemoryConfig[];
machine: SegmentDefs.MachineType ← memType.AltoType;

IF machine IN [AltoIIXM..D0) THEN
-- should be D0].
-- this has been hacked so it won’t load the D0 microcode. see [McGregor]

BEGIN
[uImageFile,offset] ←
MiscDefs.DestroyFakeModule[LOOPHOLE[
(IF machine = D0 THEN D0MicrocodeDefs.MicrocodeImage
ELSE AltoMicrocodeDefs.MicrocodeImage)]];
SegmentDefs.SwapIn[uImageFile];
uCode ← SegmentDefs.FileSegmentAddress[uImageFile]+offset;

IF machine = D0 THEN NULL --LoadRamAndJump[uCode,FALSE]--

ELSE
BEGIN
[] ← RamDefs.LoadRamAndBoot[LOOPHOLE[uCode],FALSE];
END;
SegmentDefs.Unlock[uImageFile];
SegmentDefs.SwapOut[uImageFile];
END;

END.