*----------------------------------------------------------- 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;