*-----------------------------------------------------------
Title[InitialDisk.mc...June 18, 1982  3:14 PM...Taft];
* Disk boot loader for "hard" disk microcode from the reserved Initial region
* of the disk.
*-----------------------------------------------------------

* Hard disk microcode file format.
* Note: this is a private Dorado convention, shared only with FormatTridentImpl
* in Othello.

* The microcode file always starts at page:
	MC[firstHardUCodePage, 4];	* i.e., cylinder 0, head 0, sector 4

* Its FileID is:
*   [processor (0): [0, 0, 0], serial (3): [hardUCodeSerial, hardUCodeSerial]]
	MC[hardUCodeSerial, 064732];
* Its type is zero and it is not temporary and not immutable.

* Though it is not actually contained in any Pilot logical volume,
* this file looks more-or-less like a standard Pilot boot file, containing
* the microcode image in .eb format (including initial overhead page).


Set[XTask, IP[EMU]];
KnowRBase[AEmRegs];
TopLevel;

*-----------------------------------------------------------
DiskHardMicrocodeBoot:
* Enter: BootDataPtr = address of base of block (in first 64K of memory)
*	   into which to load the microcode image
*	RBase = AEmRegs
*	MemBase = IOBR
* Real memory has been mapped contiguously at the bottom of virtual
* memory, and zeroed.  Base registers have been set up.
* I/O devices have been initialized and are quiescent.
* Call by: SCall[DiskHardMicrocodeBoot]
* Returns +1: Failed
*	+2: Succeeded; BootDataPtr updated to point to last word loaded +1 (mod 2↑16)
* Clobbers T, Q, BTemp0, BTemp1, and BTemp2
* Also clobbers memory page 0.
*-----------------------------------------------------------

Subroutine;
	DMBLink← Link;
TopLevel;
	T← (R400)+(31C);		* IOCB at 431 (cursor location, odd)
	IOCB← T;
	T← CSB.cylinder;
	Store← T, BTemp0← NOT (DBuf← 77777C); * Don't know where disk is positioned
					* BTemp0← 100000 (incrementDataPtr)

* Transfer page zero of the file, containing the .eb file overhead page,
* into page zero of memory.
* Know all of IOCB is zero at this point, so only set nonzero entries.
* In particular, drive = diskAddress = dataPtr = 0
	T← (IOCB)+(IOCB.pageCount);
	T← (Store← T)+1, DBuf← 1C;	* One page
	BTemp0← (BTemp0) OR (254C);	* command ← [check, check, read]
	Store← T, DBuf← BTemp0;
	BTemp0← HighByte[hardUCodeSerial]; * label.fileID.serial ← hardUCodeSerial
	BTemp0← (BTemp0) OR (LowByte[hardUCodeSerial]);
	T← (IOCB)+(Add[IOCB.diskLabel!, 3]C);
	T← (Store← T)+1, DBuf← BTemp0;
	Store← T, DBuf← BTemp0;
	T← (IOCB)+(IOCB.diskAddress)+1;	* Word containing head and sector
	Store← T, DBuf← firstHardUCodePage,
		SCall[BootTransfer];	* Transfer the page
	 PD← T-T, Branch[DiskMBootRet];	* Failed, Carry← 1

* Perhaps see if the overhead page contains something reasonable --
* if the overhead page of an .eb file ever contains anything worth checking!

* Set up to transfer the remainder of the file into memory starting at BootDataPtr.
	T← (IOCB)+(IOCB.pageCount);
	Store← T, DBuf← 77777C;		* Transfer as many pages as exist
	T← BTemp2← T+(Sub[IOCB.dataPtr!, IOCB.pageCount!]C);
	Store← T, DBuf← BootDataPtr, SCall[BootTransfer];
	 PD← T-T, Branch[DiskMBootRet];	* Failed, Carry← 1
	PD← Fetch← BTemp2;		* Get updated dataPtr; Carry← 0

* Carry=0 if completed successfully, 1 if unsuccessfully.
DiskMBootRet:
	Link← DMBLink, T← MD;
Subroutine;
	BootDataPtr← T, Return[Carry'];	* This clobbers BootDataPtr on fail return