1
0
mirror of https://github.com/livingcomputermuseum/Darkstar.git synced 2026-03-02 10:06:45 +00:00
Files
livingcomputermuseum.Darkstar/D/CP/Source/SAx000InitialLabelled.mc,v
2023-09-27 16:17:41 -07:00

39 lines
27 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
head 1.1;
branch 1.1.1;
access ;
symbols start:1.1.1.1 Xerox:1.1.1;
locks ; strict;
comment @# @;
1.1
date 2001.08.12.22.22.28; author freier; state Exp;
branches 1.1.1.1;
next ;
1.1.1.1
date 2001.08.12.22.22.28; author freier; state Exp;
branches ;
next ;
desc
@@
1.1
log
@Initial revision
@
text
@{File name: [Iris]<WMicro>DLion>SAx000Initial.mc
Copyright (C) 1981, 1982, 1983, 1984, 1986, 1987 by Xerox Corporation. All rights reserved.
Description: first microcode read from the disk, gets emulator microcode into CP memory,
Last Edited by:
RDH 22-Apr-87 10:21:35 Add last edit line to reflect MDS relief.
AHL 9-Aug-86 18:09:14 MDS relieve. See comment at label GFT. (This line added by RDH to satisfy my need for order.)
Dennis DEG 1-Sep-84 22:20:25 Add copyright notice.
JMM 1-Nov-83 12:57:00 Added support for Quantum Q2080.
AeF AEF 7-Oct-83 11:24:58 Use IOPage offsets from Dandelion.df!
JMM 19-Sep-83 18:49:21 - fixed Germ request initialization to get correct location.
JMM 28-Jul-83 13:57:57 - remove addressing bug caused by growth of germ request-data address offset beyond byte size.
JMM 22-Jul-83 11:07:00 - Accomodate changes for Germ as a result of going over to 32-bit procedure descriptors.
Last Edited by JXF August 14, 1982 11:18 AM New test for quantum drive.
Last Edited by FXH 18-May-82 14:27:42 add sa1000/quantum determination.
Last Edited by ETN Jan 14, 1982 14:40 change cons. for extracting filePageHi from BootId from 7 to 7F.
Last Edited by JGS Nov 18, 1981 8:58 move germ to mds 0.
Last Edited by JXF Oct 22, 1981 13:12 If diagnostics are not installed, boot Emulator instead of crashing.
Last Edited by AEF Jun 18, 1981 10:30 delete SetGerm1000 at
Last Edited by DD Feb 14, 1981 16:35
Last Edited by PXJ Mar 24, 1981 11:46
Last Edited by PXJ August 25, 1980}
{disk definitions}
{null findSectorCmd for SA1000}
Set[SA1000FindSectCmd, 20];
{have SA1000 reject Label and Data fields when looking for Headers}
Set[SA1000HeaderLoopMsk, 43];
{KControl bits, low byte}
Set[stepBit, 80],
Set[inBit, 40],
Set[firmwareEnable, 20];
Set[SA4FindSect, 6],
Set[SA1FindSect, 0];
{KControl bits, high byte}
Set[driveSelectBit, 4],
Set[faultClearBit, 2];
{KStatus bits, high byte}
Set[track00Bit, 2],
Set[seekCompleteBit, 4];
{IOCB status error indicators}
Set[badBits, 3F];
Set[verifyBit, 1];
{IOCB page offsets}
Set[statusAddr, 3]; {status word}
{ 4 not used, used to be pointer to next IOCB, always 0}
Set[seekAddr, 5]; {pointer to seek IOCB}
Set[transferAddr, 6]; {pointer to transfer IOCB}
Set[vrrAddr, 7]; {pointer to vrr parameter area}
Set[vvrAddr, 8]; {pointer to vrr parameter area}
Set[headerAddr, 9]; {header -- 2 words}
Set[labelAddr, 0B]; {label -- 0A words}
Set[labelPageLow, 10]; {low 16 bits of file page number}
Set[miscBitsAddr, 11]; {filePageHi[0..6], unused[0..5], immutable[0], temporary[0], zeroSize[0]}
Set[bootLink, 13]; {disk address of next run of pages in boot file}
Set[labelSize, 0A];
{parameter area offsets}
Set[sectors, 0]; {number of sectors to transfer}
Set[headerLoopMsk, 6]; {specifies non-fatal errors when looking for a header}
Set[dataPage, 0D]; {page number of data area in main storage}
Set[haltWord, 0F]; {requires head in high 5 bits}
Set[findWord, 10]; {requires head in high 5 bits}
{transfer IOCB offsets}
Set[parameters, 1]; {pointer to parameter area}
{seek IOCB offsets}
Set[cylinders, 0]; {-(number of cylinders to move heads)}
Set[stepHigh, 6]; {set step level high}
Set[stepLow, 8]; {set step level low}
{Miscellaneous disk constants}
Set[SA1000HeadCount, Sub[4,1]];
Set[SA4000HeadCount, Sub[4,1]];
Set[Q2040HeadCount, Sub[8,1]];
Set[Q2080HeadCount, Sub[7,1]];
{physical volume boot files}
{useful data formats extracted from Boot.mesa
BootFileType: TYPE= {hardMicrocode, softMicrocode, germ, pilot, debugger, debugee};
DiskFileID: TYPE= RECORD[fID: File.ID, firstPage: File.PageNumber, da: DiskAddress];
PVBootFiles: POINTER TO ARRAY BootFileType[hardMicrocode..pilot] OF DiskFileID= 2;
After reading from the disk, PVBootFiles moved to memory location 2}
Set[bootingInfo, 8]; {origin of PVBootFiles in physical volume root page}
Set[DiskFileIDSize, 9]; {number of words in DiskFileID}
Set[bootingInfoSize, Mul[DiskFileIDSize, 4]]; {size of PVBootFiles}
{things salted away in page 0}
Set[availableDevices, 0]; {devices available for booting, set up by Phase 0}
Set[bootReadyFlag, 1]; {non-zero indicates boot file is ready}
Set[hardFileID, 2]; {hard microcode DiskFileID, copied from physical volume root page}
Set[emulatorFileID, 0B]; {emulator microcode DiskFileID, copied from physical volume root page}
Set[germFileID, 14]; {germ DiskFileID, copied from physical volume root page}
Set[bootFileID, 1D]; {working DiskFileID, copied from one of the above fileID's}
Set[bootPage, 22];
Set[bootDiskAddr, 24];
Set[labelTemplate, 26]; {template label used by boot loading routines}
{germ definitions}
Set[germMapOffset, 2];
Set[germPageHigh, 0]; {virtual page number of origin of germ -- 1B}
Set[germPageLow, 1];
Set[sFirstGermRequestHigh, 001'b]; {start of germ request in SD - high byte}
Set[sFirstGermRequestLow, 240'b]; {start of germ request in SD - low byte}
Set[sLastGermRequest, Add[sFirstGermRequestLow, 57'b]]; {end of germ request in SD}
Set[RequestSize, 60'b]; {size of germ request in SD}
Set[SD.Request.version, Add[sFirstGermRequestLow, 00'b]];
Set[RequestVersionHigh, 7];
Set[RequestVersionLow, 56'b];
Set[SD.Request.action, Add[sFirstGermRequestLow, 01'b]];
Set[bootPhysicalVolume, 2];
Set[SD.Request.location, Add[sFirstGermRequestLow, 02'b]];
Set[SD.Request.location.deviceType, Add[sFirstGermRequestLow, 02'b]];
Set[germPilotDisk, 64'd];
Set[SD.Request.location.deviceOrdinal, Add[sFirstGermRequestLow, 03'b]];
DoneOnceOnlyInit:
{For the four disk drives, the following applies:
Q2040 - ~HeadSlelect16 = ~Sector. The two pins are connected physically.
Q2040 - ~Sector = TRUE. Using positive logic.
SA4000- ~SA1000/SA4000 = TRUE. Positive logic.
SA1000- ~SA1000/SA4000 = FALSE & ~Sector = FALSE. Also positive logic.}
{First modify the IOCB for an SA1000 if necessary}
Xbus ¬ KStatus, XwdDisp, c1; {what type of disk is this?}
acR ¬ 0FF+1, DISP2[SetSA1IOCB, 2], c2; {Point to table of IOCBs}
{there is an SA1000 drive connected. Set the LabelDataTag bit in the HeaderLoopMsk
and turn off the "Wait for Sector mark" command in the FindWord}
SetSA1IOCB:
{Test for SA1000 or Quantum depending on bit 9 of KTest after writing to
bit H16 of KCtl:
KTest[9]=0 => SA1000
KTest[9]=1 => Quantum Q2040. For the Quantum Q2080 KCtl[0]=~KTest[9]}
rB ¬ 80, c3, at[2,4,SetSA1IOCB];
KCtl ¬ rB LRot8, c1; {Test for an SA1000 or Quantum}
Xbus ¬ KTest, XwdDisp, c2;
DISP2[IsSA1000orQuantum,1], c3;
IsSA1000orQuantum:
rB ¬ SA1000HeadCount {sa1000}, GOTO[FinishIsSA1000orQuantum], c1, at[1,4,IsSA1000orQuantum];
KCtl ¬ 0, c1, at[3,4,IsSA1000orQuantum]; {Test for a Quantum Q2040 or Q2080}
Xbus ¬ KTest, XwdDisp, c2;
DISP2[IsQ2040orQ2080,1], c3;
IsQ2040orQ2080:
rB ¬ Q2080HeadCount {Q2080}, GOTO[FinishIsSA1000orQuantum], c1, at[1,4,IsQ2040orQ2080];
rB ¬ Q2040HeadCount {Q2040}, GOTO[FinishIsSA1000orQuantum], c1, at[3,4,IsQ2040orQ2080];
FinishIsSA1000orQuantum:
uQuantumSA1000MaxHeadNum ¬ rB, c2;
acRrh ¬ 0 {Point to table of IOCBs}, c3;
MAR ¬ [acRrh, vrrAddr+0], c1; {get addr of vrr parameters}
rE ¬ SA1FindSect, c2; {prepare to set FindSectCmd}
acR ¬ MD, c3;
MAR ¬ [acRrh, acR+headerLoopMsk], c1; {set up new HeaderLoopMsk}
MDR ¬ SA1000HeaderLoopMsk,
LOOPHOLE[wok], CANCELBR[$,2], c2;
UFindSect ¬ rE c3; {set FindSect mark cmd for SA1000.}
MAR ¬ [acRrh, vvrAddr+0], c1; {get addr of vvr parameters}
rE ¬ 0, c2; {set up source of 0 for below}
acR ¬ MD, c3;
MAR ¬ [acRrh, acR+headerLoopMsk], c1; {set up new HeaderLoopMsk}
MDR ¬ SA1000HeaderLoopMsk, LOOPHOLE[wok],
CANCELBR[DiskInitDone, 2], c2;
{Connected to an SA4000 so set the Find Sector Mark command properly}
SetSA4IOCB:
acR ¬ SA4FindSect, c3, at[3,4,SetSA1IOCB];
UFindSect ¬ acR, c1;
rE ¬ 0, c2; {source of 0}
DiskInitDone:
germStart ¬ rE, c3;
Noop, c1;
currentCylinder ¬ rE, c2;
acR ¬ badBits, c3;
uBadBits ¬ acR, c1;
acR ¬ driveSelectBit, c2;
acR ¬ acR LRot8, c3;
acR ¬ acR or firmwareEnable, c1;
seekMask ¬ acR, c2; {seek Mask ¬ drive select or firmwareEnable}
acR ¬ 4, c3;
acR ¬ acR LRot8, c1;
acR ¬ acR or 20, c2;
haltBits ¬ acR, c3; {halt bits ¬ 420}
acR ¬ 0F8, c1;
acR ¬ acR LRot8, c2;
headMask ¬ acR, c3; {headMask ¬ F800}
acR ¬ 2, c1;
acR ¬ acR LRot8, c2;
uBootStart ¬ acR, c3; {boot file starts at 200}
{map virtual pages 0-255 to real pages 0-255, first we must save the current
mapping of the lowest virtual pages}
rBrh¬ 1, c1;
rCrh¬ 1, c2;
rB¬ 0, c3;
rC¬ topPage, L0¬ 4, c1;
acR¬ 0FF+1, CALL[BLT3], c2;
acR¬ present, c1, at[4, 10, subrRet];
rC¬ 0FF+1, c2;
rB¬ 0, c3;
{set up identity map for benefit of the disk microcode}
identityMap:
MAR¬ [rBrh, rB+0], BRANCH[$, rootPage], c1;
MDR¬ acR, rB¬ rB+1, c2;
acR¬ acR+rC, CarryBr,
GOTO[identityMap], c3;
{Start flailing away at the disk. First read the physical volume root page}
rootPage:
Noop, c2;
Noop, c3;
rBrh ¬ 0, c1;
rCrh ¬ 0, c2;
rDrh ¬ 0, c3;
rErh ¬ 1, c1;
rD ¬ 0FF+1, c2; {base address of IOCB page}
rE ¬ headerAddr, c3;
MAR ¬ [rDrh, rE+0], c1; {cylinder 0}
MDR ¬ 0, c2;
rB ¬ 2, c3; {read starting at page 2}
MAR ¬ [rDrh, rE+1], c1; {head 0, sector 0}
MDR ¬ 0, CANCELBR[$, 0], L1 ¬ 0, c2;
acR ¬ 1, CALL[doVrr], c3; {read 1 sector}
transferRet:
[]¬ acR and uBadBits, ZeroBr, c1, at[0, 10, transferRet];
transferIOCB¬ rE, BRANCH[$, here1], c2;
acR¬ bootDeviceError,
GOTOABS[Maintenance1Loc], c3;
{save the useful stuff from the physical volume root page}
here1: rC¬ 2, c3; {copy PVBootFiles}
rB¬ rC LRot8, c1;
rB¬ rB+bootingInfo, L0¬ 0, c2;
acR¬ bootingInfoSize, CALL[BLT], c3;
{read the emulator boot file or the hard microcode}
emuHard:
[]¬ uDiagnostic, ZeroBr, c1, at[0, 10, subrRet];
rC¬ bootFileID, BRANCH[$, emuHard0], c2;
rB¬ hardFileID, L0¬ 8, GOTO[emuHard1], c3;
emuHard0:
rB¬ emulatorFileID, L0¬ 8, c3;
emuHard1:
acR¬ DiskFileIDSize, CALL[BLT2], c1;
acR¬ 2, L2¬ 0, c1, at[8, 10, subrRet];
nextPage¬ acR, CALL[readBoot3], c2;
rC¬ uDiagnostic, ZeroBr, c1, at[0, 10, readBootRet];
acR¬ nextPage, BRANCH[$, readGerm], c2;
{hard microcode (quick exit), pick up diagnostic table entry from first page of boot file}
rB¬ 2, c3; {boot file starts at 200}
rB¬ rB LRot8, c1;
rC¬ rC+1, c2;
Noop, c3;
MAR¬ [rBrh, rC+0], c1;
Noop, c2;
rC¬ MD, c3;
rC¬ rC+rB, c1;
uBootStart¬ rC, c2;
GOTO[exitToEmulator], c3;
{read the germ}
readGerm:
germStart¬ acR, c3;
rB¬ germFileID, c1;
rC¬ bootFileID, L0¬ 9, c2;
acR¬ DiskFileIDSize, CALL[BLT], c3;
L2¬ 1, c1, at[9, 10, subrRet];
CALL[readBoot3], c2;
{We now have the germ in real memory. Restore the map for pages 0-255. Then
move the germ to MDS 0, starting at page 1. Initialize the Request in the germ's
SD.}
RestoreMap:
rBrh¬ 1, c1, at[1,10,readBootRet];
rCrh¬ 1, c2;
rB¬ topPage, c3;
rC¬ 0, L0¬ 5, c1;
acR¬ 0FF+1, CALL[BLT3], c2;
{vacate the pages just used to restore the low ones}
rB¬ topPage, c1, at[5, 10, subrRet];
rC¬ rB+1, c2;
acR¬ 0FF+1, c3;
MAR¬ [rBrh, rB+0], c1;
MDR¬ vacant, L0¬ 0B, c2;
acR¬ acR-1, CALL[BLT], c3;
{Move germ to MDS 0, page 1}
rC ¬ germStart, c1, at[0B, 10, subrRet];
rB ¬ rC LRot8, c2;
rBrh ¬ 0, c3;
rD ¬ nextPage, c1;
rD ¬ rD - rC, ZeroBr, c2;
transferCount ¬ rD,
BRANCH[moveGerm1, $], c3; {number pages in germ}
acR¬ bootNullGerm,
GOTOABS[Maintenance2Loc], c1;
moveGerm1:
germStart¬ acR xor ~acR, c1;
rFrh ¬ germPageHigh,
rF ¬ 0 + germPageLow, c2;
rF ¬ rF LRot8, c3;
mg2: Map ¬ [rFrh, rF], c1;
Noop, c2;
rCrh ¬ rC ¬ MD, c3;
acR ¬ 0FF + 1, c1;
rC ¬ rC and ~0FF, L0 ¬ 0C, c2;
CALL[BLT], c3;
rF ¬ rF + 0FF + 1, c1, at[0C, 10, subrRet];
rD ¬ rD - 1, ZeroBr, c2;
rE ¬ LShift1 0FF, SE ¬ 1,
BRANCH[mg2, GFT { InitRequest }], c3;
{ The germ is in memory, but the map is wrong. The first page of the germ is its GFT. We move it from virtual page 1 to virtual page 200. Then shift virtual pages down by 1. The Remap loop stops at page FE, but I dont think the germ will ever get bigger. AHL }
GFT: rBrh ¬ 1, rB ¬ 1, c1;
Noop, c2;
rCrh ¬ 2, rC ¬ 0, c3;
MAR ¬ [rBrh, rB], { read page 1 map } c1;
rB ¬ 0FE, CANCELBR[$,2], c2;
rS ¬ MD, c3;
Map ¬ [rCrh, rC], { page 200 ¬ old page 1 } c1;
MDR ¬ rS, c2;
rS ¬ MD, c3;
Remap: MAR ¬ [rBrh, rB], { FE ¬ 200, FD ¬ FE, 1 ¬ 2 } c1;
MDR ¬ rS, rB ¬ rB - 1, CANCELBR[$,2], ZeroBr, WriteOK, c2;
rS ¬ MD, BRANCH[Remap, DoneRemap], c3;
DoneRemap:
{ end AHL }
{Initialize Request in germ's SD}
InitRequest: {rE has 1FF = start of SD -1}
rC ¬ sFirstGermRequestHigh, c1;
rC ¬ rC LRot8, c2; {Constants use an 8-bit data path.}
rE ¬ rE + rC + 1, {correct page} c3;
Map ¬ rF ¬ [rFrh, rE + 0], c1;
rC ¬ sFirstGermRequestLow, c2;
rBrh ¬ rB ¬ MD, c3;
ZeroReq:
MAR ¬ [rBrh, rC+0], c1;
MDR ¬ rD, rC ¬ rC + 1, PgCarryBr, c2; {rD zero from above}
BRANCH[ZeroReq, $], c3;
rD ¬ RequestVersionHigh, c1;
rD ¬ rD LRot8, c2;
rD ¬ rD or RequestVersionLow, c3;
MAR ¬ [rBrh, SD.Request.version + 0], c1;
MDR ¬ rD, c2;
Noop, c3;
MAR ¬ [rBrh, SD.Request.action + 0], c1;
MDR ¬ bootPhysicalVolume, c2;
Noop, c3;
MAR ¬ [rBrh, SD.Request.location.deviceType + 0], c1;
MDR ¬ germPilotDisk, c2;
doneReq:
GOTO[exitToEmulator], c3;
{Read the first page of the bootFile. Calculate the proper label by reading the label from
the disk and filing in the correct fileID and page number}
readBoot3:
Noop, c3;
readBoot:
rB¬ bootDiskAddr, c1;
rC¬ rD+headerAddr, L0¬ 1, c2; {disk address of boot}
acR¬ 2, CALL[BLT], c3;
Noop, c1, at[1, 10, subrRet];
Noop, c2;
rB¬ bootDiskAddr, c3; {nil disk address?}
MAR¬ [rBrh, rB+0], c1;
rB¬ rB+1, c2;
acR¬ MD, c3;
MAR¬ [rBrh, rB+0], c1;
Noop, c2;
acR¬ acR or MD, c3;
[]¬ acR, ZeroBr, c1;
BRANCH[$, nilBootFile], c2;
rB¬ nextPage, L1¬ 1, c3;
acR¬ 1, CALL[doVrr2], c1; {read 1 starting at page 2}
[]¬ acR and uBadBits, ZeroBr, c1, at[1, 10, transferRet];
rC¬ rD+labelAddr, BRANCH[$, here2], c2; {write fileID into label}
acR¬ bootDeviceError,
GOTOABS[Maintenance1Loc], c3;
here2: rB¬ bootFileID, L0¬ 2, c3;
acR¬ 6, CALL[BLT2], c1; {+low 16 bits of page #}
rE¬ rE and 7F, c1, at[2, 10, subrRet];
rE¬ rE LRot8, c2; {rE¬ high bits of page#}
rE¬ LShift1 rE, c3;
MAR¬ [rCrh, rC+0], c1;
acR¬ 7, c2;
acR¬ MD and acR, c3;
MAR¬ [rCrh, rC+0], c1;
MDR¬ acR or rE, c2;
rC¬ rC-1, c3;
MAR¬ [rCrh, rC+0], c1; {read low 16 bits of page #}
rB¬ bootDiskAddr, c2;
rC¬ MD, c3;
rC¬ rC+1, c1; {reading first page is a special case}
filePage¬ rC, c2; {restore disk address}
rC¬ rD+headerAddr, L0¬ 3, c3;
acR¬ 2, CALL[BLT2], c1;
rB¬ nextPage, L1¬ 5, c1, at[3, 10, subrRet];
acR¬ 1, CALL[doVvr3], c2; {read 1 starting at page 2}
[]¬ acR and uBadBits, ZeroBr, c1, at[5, 10, transferRet];
acR¬ nextPage, BRANCH[$, here3], c2;
acR¬ bootDeviceError,
GOTOABS[Maintenance1Loc], c3;
here3: acR¬ acR+1, c3;
nextPage¬ acR, c1; {label template}
acR¬ labelSize, c2;
rB¬ rD+labelAddr, L0¬ 6, c3;
rC¬ labelTemplate, CALL[BLT2], c1;
{read the rest of the file from the Pilot Volume}
readLoop:
L1¬ 1, c1, at[6, 10, subrRet];
CALL[pagesLeftInCylinder3], c2;
transferCount¬ acR, ZeroBr, c1, at[1, 10, miscRet];
L1¬ 4, BRANCH[readRun, $], c2;
{no pages left in cylinder, advance to next cylinder}
Noop, c3; {step in one cylinder}
MAR¬ [rDrh, headerAddr+1], c1;
MDR¬ 0, CANCELBR[$, 0], c2; {start at head 0, sector 0}
Noop, c3;
MAR¬ [rDrh, headerAddr+0], c1;
Noop, c2;
acR¬ MD, c3;
MAR¬ [rDrh, headerAddr+0], L1¬ 2, c1;
MDR¬ acR+1, CALL[pagesLeftInCylinder3], c2;
Noop, c1, at[2, 10, miscRet];
transferCount¬ acR, L1¬ 4, c2;
readRun:
rB¬ nextPage, CALL[doVvr], c3;
rE¬ acR and uBadBits, ZeroBr, c1, at[4, 10, transferRet];
rB¬ transferCount, BRANCH[readBurp, $], c2;
acR¬ filePage, c3;
acR¬ acR+rB, c1; {next page in file}
filePage¬ acR, c2;
acR¬ nextPage, c3;
acR¬ acR+rB, c1; {next page in memory}
nextPage¬ acR, c2;
GOTO[readLoop], c3;
{burped while reading run of pages, status in acR. rB has number of sectors requested}
readBurp:
[]¬ rE and ~verifyBit, ZeroBr, c3;
MAR¬ [rDrh, vvrAddr+0],
BRANCH[$, verifyError], c1; {get # of sectors remaining}
acR¬ bootDeviceError,
GOTOABS[Maintenance3Loc], c2; {not a verify error}
verifyError:
rC¬ acR LRot4, c2; {shift field bits}
rE¬ MD, c3; {parameter area}
MAR¬ [rDrh, rE+sectors], c1;
rC¬ rC and 0C, c2;
acR¬ MD, c3; {number sectors remaining}
[]¬ rC xor 8, ZeroBr, c1; {label verify error?}
acR¬ rB-acR, BRANCH[$, verErr1], c2; {number sectors transferred}
acR¬ bootDeviceError,
GOTOABS[Maintenance1Loc], c3; {not in label}
verErr1:
transferCount¬ acR, c3; {zero is okay}
rE¬ filePage, c1;
rE¬ rE+acR+1, c2; {file page for next label}
filePage¬ rE, c3;
rB¬ nextPage, c1;
rB¬ rB+acR+1, c2; {next available page for vvr}
nextPage¬ rB, c3;
rB¬ rB-1, L1¬ 6, c1; {page used by vrr}
acR¬ 1, CALL[doVrr3], c2; {transfer 1 page}
[]¬ acR and uBadBits, ZeroBr, c1, at[6, 10, transferRet];
BRANCH[$, verErr3], c2;
acR¬ bootDeviceError,
GOTOABS[Maintenance1Loc], c3;
verErr3:
Noop, c3;
{Copy boot link to header, and check for end of file, FFFF in both words of boot link.}
MAR¬ [rDrh, bootLink+0], c1;
Noop, c2;
acR¬ MD, c3;
MAR¬ [rDrh, headerAddr+0], c1;
MDR¬ acR, c2;
Noop, c3;
MAR¬ [rDrh, bootLink+1], c1;
CANCELBR[$, 0], c2;
rB¬ MD, c3;
MAR¬ [rDrh, headerAddr+1], c1;
MDR¬ rB, CANCELBR[$, 0], c2;
[]¬ acR or rB, ZeroBr, c3;
acR¬ acR+1, BRANCH[rdBurp1, $], c1;
acR¬ bootBrokenChain,
GOTOABS[Maintenance3Loc], c2; {boot chain link is zero}
rdBurp1:
rB¬ rB+1, c2;
[]¬ acR or rB, ZeroBr, c3;
rC¬ rD+labelAddr, BRANCH[rdBurp2, $], c1;
GOTO[endRead], c2; {found end of chain, return}
rdBurp2:
rB¬ labelTemplate, L0¬ 7, c2;
acR¬ labelSize, CALL[BLT], c3;
MAR¬ [rDrh, labelPageLow+0], c1, at[7, 10, subrRet];
MDR¬ filePage, c2;
GOTO[readLoop], c3;
endRead:
Noop, c3;
Noop, c1;
pRet2, c2;
RET[readBootRet], c3;
{here if boot file pointer was zero}
nilBootFile:
[]¬ uDiagnostic, ZeroBr, c3;
acR¬ 1 {disk Boot},
BRANCH[noDiagnostics, $], c1;
[]¬ germStart, ZeroBr, c2;
BRANCH[noGerm, noEmulator], c3;
noEmulator:
acR¬ bootNoEmulator,
GOTOABS[Maintenance2Loc], c1;
noGerm: acR¬ bootNoGerm,
GOTOABS[Maintenance2Loc], c1;
{this code tries a disk boot if no hard microcode is installed}
noDiagnostics:
uDiagnostic¬ 0, c2;
bootDevice ¬ acR {disk Boot},
GOTO[emuHard], c3;
{subroutines}
doVvr3: Noop, c3;
doVvr: MAR¬ [rDrh, vvrAddr+0], c1;
GOTO[doTransfer], c2;
{does verify, read, read operation to the disk. Takes number of sectors in acR, page
number in rB, and disk address in header area. Returns status in acR; Clobbers rE}
doVrr2: Noop, c2;
doVrr3: Noop, c3;
doVrr: MAR¬ [rDrh, vrrAddr+0], c1; {base of vrr parameters}
CANCELBR[$, 0], c2;
doTransfer:
rE¬ MD, c3;
MAR¬ [rDrh, rE+sectors], c1; {set up paramter area}
MDR¬ acR, c2; {sector count}
Noop, c3;
MAR¬ [rDrh, rE+dataPage], c1;
MDR¬ rB - 1, CANCELBR[$, 0], c2; {first page in main storage}
Noop, c3;
MAR¬ [rDrh, rD+ transferAddr], c1; {base of transferIOCB}
acR¬ rE, CANCELBR[$, 0], c2; {base of vrr parameter area}
rE¬ MD, c3;
MAR¬ [rDrh, rE+parameters], c1;
MDR¬ acR, CANCELBR[$, 0], c2;
rC¬ acR, c3;
MAR¬ [rDrh, headerAddr+1], c1; {read head}
CANCELBR[$, 0], c2;
acR¬ MD, c3;
acR¬ acR LRot4, c1;
acR¬ acR RRot1, c2;
acR¬ acR and headMask, c3;
acR¬ acR or haltBits, c1;
Noop, c2;
Noop, c3;
MAR¬ [rDrh, rC+haltWord], c1; {write halt word}
MDR¬ acR, CANCELBR[$, 0], c2;
acR¬ acR or UFindSect, c3;
MAR¬ [rDrh, rC+findWord], c1; {write find word}
MDR¬ acR, CANCELBR[$, 0], L0¬ 2, c2;
rC¬ rE, CALL[seek], c3;
[]¬ acR and uBadBits, ZeroBr, L0¬ 3, c1, at[2, 10, transferRet];
BRANCH[transferError, $], c2;
rE¬ rC, CALL[diskOp], c3;
transferRet1:
Noop, c1, at[3, 10, transferRet];
pRet1, c2;
transferRet2:
RET[transferRet], c3;
transferError:
GOTO[transferRet1], c3;
{call with IOCB in rE, returns when disk operation complete with status in acR}
diskOp:
Noop, c1;
acRrh ¬ IOPageHigh, c2;
{AEF 9/14/83 - why is this instruction at[2, 4]?}
acR ¬ uIOPage, c3, at[2, 4];
MAR¬ [acRrh, DiskCSBOffsetIOCB+0], c1;
MDR¬ rE, c2;
Noop, c3;
MAR¬ [rDrh, statusAddr+0], c1; {set invalid status}
MDR¬ badBits, c2;
acR¬ firmwareEnable, c3; {start the transfer}
KCtl¬ acR LRot0, c1;
transferWait:
acR¬ ~KStatus, CANCELBR[$, 0], c2, at[0F, 10, transferWait];
[]¬ acR LRot8, XDisp, c3; {test firmware busy}
MAR¬ [rDrh, statusAddr+0],
BRANCH[$, transferWait], c1;
pRet0, LOOPHOLE[natc], c2, at[0E, 10, transferWait];
acR¬ MD, RET[transferRet], c3; {return status in acR}
{call with current cylinder in currentCylinder, and desired cylinder in cylinder field of header}
seek: MAR¬ [rDrh, headerAddr+0], c1;
rB¬ currentCylinder, CANCELBR[$, 0], c2;
acR¬ MD, c3; {target}
rB¬ rB-acR, ZeroBr, c1; {delta number of cylinders}
currentCylinder¬ acR, BRANCH[$, noSeek],c2;
[]¬ rB, NegBr, c3;
acR¬ 0, BRANCH[seekOut, $], c1;
acR¬ inBit, GOTO[seek1], c2;
seekOut:
rB¬ -rB, c2;
seek1: acR¬ acR or seekMask, c3; {enable firmware, drive select}
MAR¬ [rDrh, seekAddr+0], c1; {address of seek IOCB}
CANCELBR[$, 0], c2;
rE¬ MD, c3;
MAR¬ [rDrh, rE+cylinders], c1;
MDR¬ rB, c2;
Noop, c3;
MAR¬ [rDrh, rE+stepHigh], c1;
MDR¬ acR or stepBit, CANCELBR[$, 0], c2;
Noop, c3;
MAR¬ [rDrh, rE+stepLow], c1;
MDR¬ acR, CANCELBR[$, 0], c2;
rE¬ rE+1, GOTO[diskOp], c3;
noSeek: acR¬ 0, c3;
Noop, c1;
pRet0, GOTO[transferRet2], c2;
{Be careful, these routines are device dependent! Only routines for SA1004 and SA4008 are supplied}
{Uses data left in last header to compute pages left in cylinder, returns result in acR.}
pagesLeftInCylinder3:
Noop, c3;
pagesLeftInCylinder:
Noop, c1; {SA4000 or SA1000?}
Xbus¬ KStatus, XwdDisp, c2;
BRANCH[SA1000Left, $, 2], c3;
{SA4008, pages left in cylinder= (28-sector)+(8-head-1)*28}
MAR¬ [rDrh, headerAddr+1], c1, at[3,4,SA1000Left];
rB¬ 7, CANCELBR[$, 0], c2;
rE¬ MD, c3;
acR¬ rE LRot8, c1;
acR¬ acR and 0FF, c2; {head}
rE¬ rE and 0FF, c3; {sector}
acR¬ rB-acR, NegBr, L0¬ 0, c1;
rB¬ 28'd, BRANCH[multiply, $], c2;
acR¬ 0, c3; {off the end of the cylinder}
OffEnd: rE¬ 0, c1;
pRet1, GOTO[pgLft1], c2;
{return from multiply}
divMultRet:
acR¬ Q+28'd, pRet1, GOTO[pgLft1], c2, at[0, 10, divMultRet];
{SA1004, pages left in cylinder= (16-sector)+(uQuantumSA1000MaxHeadNum-head)*16}
SA1000Left:
MAR¬ [rDrh, headerAddr+1], c1, at[2,4,SA1000Left];
rB¬ uQuantumSA1000MaxHeadNum,
CANCELBR[$, 0], c2;
rE¬ MD, c3;
acR¬ rE LRot8, c1;
acR¬ acR and 0FF, c2; {head}
rE¬ rE and 0FF, c3; {sector}
acR¬ rB-acR, NegBr, c1;
rB¬ acR LRot4, BRANCH[SA1000More, $], c2; {(4-head-1)*16}
acR¬ 0, GOTO[OffEnd], c3; {off the end of the cylinder}
SA1000More:
Noop, c3;
Noop, c1;
acR¬ rB+16'd, pRet1, c2;
pgLft1: acR¬ acR-rE, RET[miscRet], c3;
{multiply, call with multiplier in rB, multiplicand in acR, uses rC, result left in Q
timing:
45 cycles main loop is 3 cycles times 15 iterations
4 cycles last iteration
3 cycles preamble
1 cycles postamble
total 53 cycles (2 MOD 3)}
multiply:
Q¬ acR, c*;
acR¬ 0'x, c2;
rC¬ 10'x, c3;
mult0: []¬ Q and 1, ZeroBr, c1;
rC¬ rC-1, ZeroBr, BRANCH[mult1, mult2], c2;
mult1: acR¬ DARShift1 (acR+rB), BRANCH[mult0, mult3], c3;
mult2: acR¬ acR DARShift1, BRANCH[mult0, mult3], c3;
mult3: Q¬ ~Q, pRet0, c1;
RET[divMultRet], c*;
{divide, call with dividend in acR, divisor in rB, uses rC, result left in Q
remainder in acR
timing:
64 cycles main loop is 4 cycles times 16 iterations
3 cycles preamble
2 cycles postamble
total 69 cycles (0 MOD 3)}
{divide:
Q¬ acR, c*;
acR¬ 0, c2;
rC¬ 10'x, c3;
div0: acR¬ acR DALShift1, Cin¬ 1, c*; {shifts in a zero!!!!!}
acR¬ acR-rB, NegBr, c2;
rC¬ rC-1, ZeroBr, BRANCH[div1, div2], c3;
div1: Q¬ Q or 1, BRANCH[div0, div3], c1;
div2: acR¬ acR+rB, BRANCH[div0, div3], c1;
div3: pRet0, c2;
RET[divMultRet], c*;}
{compare two blocks of memory, takes count in acR, and addresses in rB, and rC, clobbers rE,
returns count in acR where compare first lost, (acR=0)=> compare succeeded}
{compare3:
Noop, c3;
compare:
MAR¬ [rBrh, rB+0], c1;
[]¬ acR, ZeroBr, c2;
rE¬ MD, BRANCH[comp1, $], c3;
GOTO[endBLT1], c1;
comp1: MAR¬ [rCrh, rC+0], c1;
Noop, c2;
rE¬ rE xor MD, c3;
Noop, c1;
Noop, c2;
[]¬ rE, ZeroBr, c3;
acR¬ acR-1, BRANCH[$, comp2], c1;
acR¬ acR+1, pRet0, GOTO[endBLT2], c2;
comp2: rB¬ rB+1, c2;
rC¬ rC+1, GOTO[compare], c3;}
{increments header}
{incrHdr:
MAR¬ [rDrh, headerAddr+1], c1;
CANCELBR[$, 0], c2;
rE¬ MD, c3;
acR¬ rE and 0FF, c1; {sector}
acR¬ acR+1, c2;
[]¬ acR-27'd, NegBr, c3;
rE¬ rE and ~0FF, BRANCH[incHd, $], c1; {head}
rE¬ rE or acR, c2;
incHdr0:
Noop, c3;
incHdr1:
MAR¬ [rDrh, headerAddr+1], c1;
MDR¬ rE, pRet0, CANCELBR[$, 0], c2;
RET[subrRet], c3;
incHd: rE¬ rE LRot8, c2;
rE¬ rE+1, c3;
[]¬ rE-7, NegBr, c1;
rE¬ rE LRot8, BRANCH[$, incHdr0], c2;
incCyl: rE¬ 0, c3;
MAR¬ [rDrh, headerAddr+0], c1;
Noop, c2;
acR¬ MD, c3;
MAR¬ [rDrh, headerAddr+0], c1;
MDR¬ acR+1, GOTO[incHdr0], c2;}
{am I a sa1000 or quantum???
assume on cyl 0, disk ready;
send 257 step pulses, one back; if on cyl 0 => sa1000}
@
1.1.1.1
log
@first add
@
text
@@