//		A L T O   E X E C U T I V E
//	Internal Exec Commands - Partition.bcpl
// Copyright Xerox Corporation 1979

//	last edited by R. Johnsson, May 11, 1980  1:42 PM


get "AltoDefs.d"
get "AltoFileSys.d"
get "ComStruct.bcpl"

external
	[ Partition
	]


let Partition(ISTREAM, DSTREAM) be

	[
	let PN = vec 100
	let SWVEC = vec 20

	let AltoVersion = (table [ 61014b; 1401b ])()
	if AltoVersion rshift 12 ls 4 then
	   [
	   Wss(DSTREAM, "No partitions on this machine.*n")
	   return
	   ]

	SetupReadParam(PN, SWVEC, ISTREAM, SWVEC)

	let partition = ReadParam($D, -1)
	let ChangePartition = table [ 61037b; 1401b ]
	let oldPartition = ChangePartition(0)
	if partition eq -1 % Partition eq 0 then
	   [
	   Wss(DSTREAM, FORMATN("Current Partition is <D>.*n", oldPartition))
	   return
	   ]
	let result = ChangePartition(partition)
	if result eq 0 then
	   [
	   Wss(DSTREAM, FORMATN("Could not set Partition to <D>.*n", partition))
	   return
	   ]
	BootDP0()
	ChangePartition(oldPartition)
	Wss(DSTREAM, FORMATN("Could not boot Partition <D>.*n", partition))
	]


and BootDP0() be
[	// returns only if the boot fails
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

let saveDisplay = @displayListHead
@displayListHead = 0  //turn off display
(table [ 61000b; 1401b ])()  //disable interrupts

let kcb, data, label = vec lenKCB, vec 256, vec 8
for tries = 1 to 10 do
   [
   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
   @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 status
   if tries eq 10 then
      [
      (table [ 61001b; 1401b ])();
      @displayListHead = saveDisplay;
      return
      ]
   ]

MoveBlock(402b, label, 8)  //402-411 ← label
MoveBlock(1, data, 256)  // 1-400 ← data
@2 = kcb>>KCB.status  //2 ← status
goto 1  //jump to bootloader start address
]