// 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)
]