*----------------------------------------------------------- Title[DiskBootTransfer.mc...August 27, 1985 11:53 AM...Willie-Sue]; * Simple disk driver for transfers between Pilot boot files and memory, * using the PilotDisk microcode. *----------------------------------------------------------- * Microcode and germ files are kept in Pilot boot files. * These are standard Pilot files, with the addition that wherever there * is a break in the run of pages, the bootChainLink of the last page * of the run points to the first page of the next run. Additionally, * the file ends with a bootChainLink of [-1, -1]. Set[XTask, IP[EMU]]; KnowRBase[AEmRegs]; *----------------------------------------------------------- BootTransfer: * Transfer page(s) to or from disk boot file * Enter: IOCB points to I/O command block, which must be at an odd address * and have the following fields already set up as desired: * drive, pageCount, command, diskAddress, dataPtr, diskLabel * The remainder of the IOCB must be zeroed. * Call by SCall[BootTransfer] * Returns +1: unrecoverable error occurred * +2: transfer completed successfully: * if IOCB.count = 0 then all pages have been transferred. * if #0, end-of-file was reached before the end of the transfer. * The command block is updated in the standard manner by the disk microcode; * specifically, the diskAddress and diskLabel.filePageLo are updated * to describe the first page not (successfully) transferred, as is * the dataPtr if incrementDataPtr was specified in the command. * If the label was checked, the diskLabel.bootChainLink contains the * corresponding data from the last label successfully checked. * Clobbers T, Q, BTemp0, BTemp1 *----------------------------------------------------------- Subroutine; T_ (IOCB)+(IOCB.headerPtr); BTemp0_ T-(Sub[IOCB.headerPtr!, IOCB.diskHeader!]C); Store_ T, DBuf_ BTemp0; * iocb.headerPtr _ @iocb.diskHeader T_ (IOCB)+(IOCB.labelPtr); BTemp0_ T+(Sub[IOCB.diskLabel!, IOCB.labelPtr!]C); Store_ T, DBuf_ BTemp0; * iocb.labelPtr _ @iocb.diskLabel BTemp1_ 17C; * Max number of retries NOP; * placement (wsh - 27 Aug 85) * BootTransfer (cont'd) BootTransferLp: T_ IOCB, RBase_ RBase[RTC430]; EventTemp1_ T_ (Store_ T)+1, DBuf_ 0C; * iocb.next _ 0 EventTemp0_ (Store_ T)-1, DBuf_ IOCBSealValue; * iocb.seal _ IOCBSealValue Fetch_ EventTemp1, T_ CSB.next; * MD_ 0 for first iteration of wait loop PD_ Store_ T, DBuf_ EventTemp0; * csb.next _ iocb -- start the command. * ALU<0 for first iteration of wait loop * Wait up to 2 seconds for the command to execute (sufficient time for transferring * ~3500 pages, minus time lost to seeks). T_ (RTC430)+1, FreezeBC; * Now + 65536 32-us ticks = ~ 2 seconds Fetch_ EventTemp1, PD_ MD, * Wait for iocb.seal to become zero Branch[BootTransferTimeout, ALU>=0]; PD_ (RTC430)-T-1, Branch[.-1, ALU#0]; RBase_ RBase[AEmRegs]; * Command finished. iocb.pageCount=0 means completed OK, #0 means an error occurred T_ (IOCB)+(IOCB.pageCount); T_ (Fetch_ T)+(Sub[IOCB.labelStatus!, IOCB.pageCount!]C); * Carry_ 0 Fetch_ T, PD_ MD; BTemp0_ A0, Branch[BootTransferDone, ALU=0]; * Error occurred. See if it was a label check error. T_ DPF[BTemp0, 2, 4, MD]; * Mask out readOnly and cylOffset from status PD_ T XOR (DS.checkErr); * Label check error and no others? T_ (IOCB)+(Add[IOCB.diskLabel!, Lab.bootChainLink!]C), Branch[BootOtherError, ALU#0]; * Label check error. If the bootChainLink of the last successfully-read label * is nonzero, it is the disk address of a new run of pages (-1 => end of file). T_ (Fetch_ T)+1; T_ (Fetch_ T)-1, BTemp0_ MD, Q_ MD; PD_ (BTemp0) OR MD; BTemp0_ (BTemp0)+1, Branch[BootLabelError, ALU=0]; * Start new run of pages; and zero the bootChainLink so that if it was wrong * the ensuing label check error won't cause us to come back here. * iocb.diskAddress _ iocb.diskLabel.bootChainLink; iocb.diskLabel.bootChainLink _ [0, 0] T_ (Store_ T)+1, DBuf_ 0C, Branch[BootEOF, ALU=0]; * Carry_ 0 Store_ T, DBuf_ 0C; T_ (IOCB)+(IOCB.diskAddress); T_ (Store_ T)+1, DBuf_ Q, BTemp0_ MD; Store_ T, DBuf_ BTemp0, Branch[BootTransferLp]; * Other error, retry. BootOtherError: PD_ (BTemp1) AND (7C), Branch[BootDiskError, R<0]; BTemp1_ (BTemp1)-1, Branch[BootTransferLp, ALU#0]; T_ CSB.cylinder; * Every 8 retries, do a restore Store_ T, DBuf_ -1C, Branch[BootTransferLp]; BootTransferTimeout: RBase_ RBase[AEmRegs]; * Timed out (disk probably not on-line) BootDiskError: BTemp0_ T-T, Branch[BootEOF]; * Too many retries; Carry_ 1 BootLabelError: BTemp0_ T-T, Branch[BootEOF]; * Label error not due to hitting end of run * On exit, failure is indicated by carry=1, success by carry=0. * BTemp0 = 0; T = @CSB.next (or pointer to some place that's harmless to store 0 into). BootEOF: T_ CSB.next; BootTransferDone: Store_ T, DBuf_ BTemp0, * Zap command chain Return[Carry']; * Return +1 if carry=1, +2 if carry=0