*----------------------------------------------------------- Title[DiskBootSoft.mc...December 14, 1983 4:14 PM...Taft]; * Pilot "soft" boot -- loads a microcode or germ file designated by * one of the pointers in the physical volume root page. *----------------------------------------------------------- TopLevel; RBase_ RBase[AEmRegs]; Set[XTask, IP[EMU]]; *----------------------------------------------------------- DiskBootSoft: * Enter: BootDataPtr = address of base of block (in first 64K of memory) * into which to load the boot file * BTemp2 = Descriptor-relative offset of BootingInfo for file to be booted * RBase = AEmRegs * MemBase = IOBR * Real memory has been mapped contiguously at the bottom of virtual memory, * and IOBR contains zero. * I/O devices have been initialized and are quiescent. * Call by: SCall[DiskBootSoft] * Returns +1: Failed * +2: Succeeded; BootDataPtr updated to point to last word loaded +1 (mod 2^16) * Clobbers T, Q, BTemp0, BTemp1 * Also clobbers memory page 0 by reading the physical volume root page into it. *----------------------------------------------------------- Subroutine; DMBLink_ Link; TopLevel; T_ (R400)+(31C); * IOCB at 431 (cursor location, odd) IOCB_ Sub[sizeIOCB!, 1]C; IOCB_ T, Cnt_ IOCB; T_ (Store_ T)+1, DBuf_ 0C, Branch[., Cnt#0&-1]; * Zero out the IOCB T_ CSB.cylinder; Store_ T, DBuf_ 77777C; * Don't know where disk is positioned * Transfer the Descriptor. * 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 Store_ T, DBuf_ 274C; * command _ [check, read, read] SCall[BootTransfer]; * Transfer the Descriptor PD_ T-T, Branch[DiskSBootRet]; * Failed, Carry_ 1 * Make sure the seal and version are ok T_ (Fetch_ Add[Desc.seal!]S)+1; Fetch_ T, T_ MD, BTemp0_ HighByte[DescSealValue]; BTemp0_ (BTemp0) OR (LowByte[DescSealValue]); BTemp0_ (BTemp0) XOR T, T_ MD; T_ T XOR (DescCurrentVersionValue); PD_ (BTemp0) OR T; T_ (IOCB)+(IOCB.pageCount), Branch[.+2, ALU=0]; PD_ T-T, Branch[DiskSBootRet]; * Bad Descriptor, Carry_ 1 * DiskBootSoft (cont'd) * Read the label of the first page, since certain things (e.g., file type) * are not known in advance. T_ (Store_ T)+1, DBuf_ 1C; * count _ 1 BTemp0_ (Store_ T)+1, DBuf_ 260C; * command _ [check, read, none] * IOCB.diskAddress _ Descriptor.bootingInfo[bootFileType].diskAddress T_ (BTemp2)+(DFID.da); BTemp1_ T, Cnt_ 1S, Call[BootBlt]; * Want to move 2 words, actually do 3 SCall[BootTransfer]; * Read the label PD_ T-T, Branch[DiskSBootRet]; * Failed, Carry_ 1 * Now set up to read the entire boot file into memory T_ (IOCB)+(IOCB.pageCount); T_ (Store_ T)+1, DBuf_ 77777C; * Transfer as many pages as exist BTemp0_ 100000C; * incrementDataPtr _ TRUE BTemp0_ (BTemp0) OR (254C); * command _ [check, check, read] BTemp0_ (Store_ T)+1, DBuf_ BTemp0; * IOCB.diskAddress _ Descriptor.bootingInfo[bootFileType].diskAddress * (must do this again because the address was incremented by the microcode). T_ (BTemp2)+(DFID.da); BTemp1_ T, Cnt_ 1S, Call[BootBlt]; * Want to move 2 words, actually do 3 * IOCB.dataPtr _ BootDataPtr T_ (IOCB)+(IOCB.dataPtr); Store_ T, DBuf_ BootDataPtr; * IOCB.diskLabel.fileID _ Descriptor.bootingInfo[bootFileType].fID; * IOCB.diskLabel.filePageLo _ Descriptor.bootingInfo[bootFileType].firstPage; BTemp0_ T+(Sub[IOCB.diskLabel!, IOCB.dataPtr!]C); T_ (BTemp2)+(DFID.fID); BTemp1_ T, Cnt_ 4S, Call[BootBlt]; * Move 6 words * IOCB.diskLabel.bootChainLink _ 0; T_ (IOCB)+(Add[IOCB.diskLabel!, Lab.bootChainLink!]C); T_ (Store_ T)+1, DBuf_ 0C; Store_ T, DBuf_ 0C; SCall[BootTransfer]; * Transfer the boot file PD_ T-T, Branch[DiskSBootRet]; * Failed, Carry_ 1 T_ (IOCB)+(IOCB.dataPtr); PD_ Fetch_ T; * Get updated dataPtr; Carry_ 0 * Carry=0 if completed successfully, 1 if unsuccessfully. DiskSBootRet: Link_ DMBLink, T_ MD; Subroutine; BootDataPtr_ T, Return[Carry']; * This clobbers BootDataPtr on fail return *----------------------------------------------------------- BootBlt: * Copy memory to and fro * Enter: BTemp0 = first destination address * BTemp1 = first source address * Cnt = (# words to transfer)-2 * Exit: BTemp0 and BTemp1 advanced by number of words transferred * Clobbers T *----------------------------------------------------------- Subroutine; BTemp1_ (Fetch_ BTemp1)+1; BTemp1_ (Fetch_ BTemp1)+1, T_ MD; BTemp0_ (Store_ BTemp0)+1, DBuf_ T, Branch[.-1, Cnt#0&-1]; BTemp0_ (Store_ BTemp0)+1, DBuf_ MD, Return;