// CopyDisk.bcpl // Copyright Xerox Corporation 1979, 1980 // Last modified November 27, 1980 1:27 PM by Boggs get "CopyDisk.decl" get "BcplFiles.d" get "AltoDefs.d" get "SysDefs.d" external [ // outgoing procedures SysErr // incoming procedures BeforeJuntaInit; Junta; AfterJuntaInit CallContextList; AddToZone MoveBlock; Zero; StartIO; DisableInterrupts BfsTryDisk; EtherBoot; OsFinish // outgoing static versionText // incoming statics ctxQ; sysZone; bootFlag; ramFlag lvUserFinishProc; lvAbortFlag ] static [ savedUserFinishProc; endCode; versionText ] //---------------------------------------------------------------------------- let CopyDisk(blv, upe, nil) be //---------------------------------------------------------------------------- [ versionText = "CopyDisk of 29 Sept 82" endCode = blv>>BLV.endCode BeforeJuntaInit(blv, upe, nil) Junta((ramFlag? levBuffer, levBcpl), AfterJunta) ] //---------------------------------------------------------------------------- and AfterJunta() be //---------------------------------------------------------------------------- [ savedUserFinishProc = @lvUserFinishProc @lvUserFinishProc = CopyDiskFinishProc AfterJuntaInit() AddToZone(sysZone, BeforeJuntaInit, endCode-BeforeJuntaInit) @lvAbortFlag = @lvAbortFlag +1 [ CallContextList(ctxQ!0) //Shift-Swat is handled manually because aborting OutLds the // environment onto Swatee which may not be there since the disk // may not be ready! if kbdAd!2 eq 177677B & kbdAd!3 eq 177773B then OsFinish(fcAbort) ] repeat ] //---------------------------------------------------------------------------- and CopyDiskFinishProc() be //---------------------------------------------------------------------------- [ @displayListHead = 0; for i = 0 to 32000 loop //turn off display if ramFlag then [ (table [ 61010B; 1401B ])(177776B, 22B) //JMPRAM 22: SetBLV(177776B) StartIO(100000B) //Silent boot back into ROM0. ] @lvUserFinishProc = savedUserFinishProc unless BfsTryDisk(0, 0, 0, 0) do EtherBoot(10b) //NetExec unless bootFlag return // manual disk boot: structure KCB: [ link word status word command word headerAddress word labelAddress word dataAddress word normalWakeups word errorWakeups word header word diskAddress word ] manifest lenKCB = size KCB/16 DisableInterrupts() StartIO(3) //reset ethernet let kcb, data, label = vec lenKCB, vec 256, vec 8 [ Zero(kcb, lenKCB) kcb>>KCB.command = 44100b // check header, read label, read data kcb>>KCB.headerAddress = lv kcb>>KCB.header kcb>>KCB.labelAddress = label kcb>>KCB.dataAddress = data kcb>>KCB.diskAddress = kbdAd!0 xor -1 until @diskCommand eq 0 loop @diskCommand = kcb //spin the disk while (kcb>>KCB.status & 7400b) eq 0 loop //wait for it to stop if (kcb>>KCB.status & 7667b) eq 7400b break //good ] repeat MoveBlock(402b, label, 8) //402-411 ← label MoveBlock(1, data, 256) //1-400 ← data @2 = kcb>>KCB.status //2 ← status goto 1 //jump into bootloader ] //---------------------------------------------------------------------------- and SysErr(p1, errNo, p2, p3, p4, p5) be //---------------------------------------------------------------------------- [ let t = p1; p1 = errNo; errNo = t (table [ 77403b; 1401b ])("Sys.Errors", lv p1) ]