//PrintDisk31.bcpl - handle queued I/O for model 31 disk

// last modified by Butterfield, April 17, 1980  1:29 PM
// - ReadBuffer31, use FileVDA to get vda's - 4/17/80

get "PressInternals.df"
get "PressParams.df"
get "altofilesys.d"
get "disks.d"
get "bfs.d"

//outgoing procedures
external
	[
	ReadBuffer31
	PrintBuffer31
	InitBuffers31
	]

//incoming procedures
external FileVDA;

//incoming statics
external
	[
	FontTable
	nextBogusChar
	nDCBs
	sysDisk
	BitsFile
	]

//ReadBuffer31 pushes new dcbs onto KBLK for 4096 word read
let ReadBuffer31(page,adr,dcb) be 
    [  let realDA=sysDisk!7
	page=page*4
	let vDA=vec 16;
	for i=0 to 15 do vDA!i = FileVDA(BitsFile, page + 1 + i);

	let mydcb=dcb
	for i=0 to 15 do
	 [ mydcb>>KCB.dataAddress=adr+i*256
	   realDA(sysDisk,vDA!i,lv mydcb>>KCB.diskAddress)
	   mydcb>>KCB.status=0
	   mydcb=mydcb+lKCB
	 ]
	mydcb!-lKCB=0 //end of the line
//QueueDiskCommand
	let np=#521
	until @np eq 0 do np=@np
	@np=dcb
    ]

//PrintBuffer31 waits until the requested buffer is filled from the disk,
//and relocates the font pointers appropriately
and PrintBuffer31(dcb,doneFlaglv) = valof
 [ let inPtr=0
   let adr=dcb>>KCB.dataAddress
   let mydcb=dcb
   for i=0 to 15 do
    [ if (mydcb>>KCB.status&DSTdoneBits) eq 0 then resultis false
      mydcb=mydcb+lKCB
    ]
   until inPtr ge 4096 do //fix up bogus characters
    [ let n=-(adr!inPtr)
      if n eq 0 then @doneFlaglv=true
      if n le 0 then break //this page done
      FontTable!nextBogusChar=adr+inPtr
      nextBogusChar=nextBogusChar+1
      inPtr=inPtr+2+n
    ]
   resultis true
 ]

and InitBuffers31(DCBs,firstBuff,nBuffs,headerBuff,labelBuff,pagelv)=valof
 [ //get the disk set up to fill initial buffs
  let page=@pagelv
  let doneFlag=false
  let command=readHLD
  if BitsFile>>F.Device eq DISK31B then command=command+1
  for d=0 to nDCBs-1 do
   [ let dcb=DCBs!d
     for blk=0 to (4096/256)-1 do
	[
	dcb>>KCB.link=dcb+lKCB
	//dcb>>KCB.status=0 assigned in ReadBuffer31
	dcb>>KCB.command=command
	dcb>>KCB.headerAddress=headerBuff
	dcb>>KCB.labelAddress=labelBuff
	//dcb>>KCB.dataAddress assigned in ReadBuffer31
	dcb>>KCB.normalWakeups=0
	dcb>>KCB.errorWakeups=0
	//dcb>>KCB.DA assigned in ReadBuffer31
	dcb=dcb+lKCB
	]
      dcb!-lKCB=0	//end of the line
   ]
 
   for bf=0 to nBuffs-1 do
	[
	if doneFlag then break
	let adr=firstBuff+4096*bf
	ReadBuffer31(page,adr,DCBs!0)
	page=page+4096/1024
	until PrintBuffer31(DCBs!0,lv doneFlag) do [ ]
	] 

   @pagelv=page
   resultis doneFlag
 ]