//PrintDisk.bcpl - Queued disk I/O for printing phases

// errors 2300

// Layout of buffers:
//		buff!-2:	buffer status (0=checked, 1=being filled from disk)
//		buff!-1:	pointer to next buffer (word D)
// D:				first "data" word of buffer
//					If Orbit is in use, first 2 data words are:
//						-height
//						width-1
//	D+dataOfset:			image data
// D+dcbOffset:	dcb chain for disk to read this buffer

// If there are nBands in a page image, there will be nBands buffers
// total to be read.

// Statics record certain things for device-specific disk routines to use:
//		dcbOffset:	add to buffer pointer to find dcb chain for buffer
//		nDCBPerBuffer:	number of DCB's associated with each buffer
//		dataOffset:	0 for Slot, 2 for Orbit: place to start read
//		lenDCB:		size allocated for a DCB
//		nextReadPage:	number of next page to read
//		nBufsToRead:	number of buffers still to be read
//		nextReadBuf:	pointer to next buffer to read
//		nBufsToCheck:	number of buffers still to be checked
//		nextCheckBuf:	pointer to next buffer to check

get "PDInternals.d"

//outgoing procedures
external
	[
	PrintDiskInit
	PrintDiskRead
	PrintDiskCheck
	PrintDiskStop
	]

//outgoing statics
external
	[
	dcbOffset
	nDCBPerBuffer
	dataOffset
	lenDCB
	nextReadPage
	nBufsToRead
	nextReadBuf
	nBufsToCheck
	nextCheckBuf
	]
static
	[
	dcbOffset
	nDCBPerBuffer
	dataOffset
	lenDCB=28
	nextReadPage
	nBufsToRead
	nextReadBuf
	nBufsToCheck
	nextCheckBuf
	]

//incoming procedures
external
	[
// PrintDisk31
	PrintInit31
	PrintRead31
	PrintCheck31
	PrintStop31
// PrintDiskTrident
	PrintInitTrident
	PrintReadTrident
	PrintCheckTrident
	PrintStopTrident
// PDPRINT
	PDError
	]

//incoming statics
external
	[
	BitsFile
	printerDevice
	]

// PrintDiskInit builds buffer lists, etc.
//	pg:	PageG structure for this page
//	firstAddr, lastAddr: region of memory for buffers
//	@lvFirstBuffer:	returns pointer to first buffer
//	returns:	number of buffers

let PrintDiskInit(pg, firstAddr, lastAddr, lvFirstBuff) = valof
[
	let disk=BitsFile>>F.Device
	nextReadPage=pg>>PageG.BitPage
	let sectorSize=BitsFile>>F.Pagesize
	test disk ls DISKT80 then
	[
		PrintDiskRead=PrintRead31
		PrintDiskCheck=PrintCheck31
		PrintDiskStop=PrintStop31
//**** omit next 2 lines after disk routine rationalization ****
		sectorSize=256
		nextReadPage=nextReadPage*4
	] or [
		PrintDiskRead=PrintReadTrident
		PrintDiskCheck=PrintCheckTrident
		PrintDiskStop=PrintStopTrident
	]

	nDCBPerBuffer=(pg>>PageG.BandWidth*pg>>PageG.BitWc+sectorSize-1)/sectorSize
	let dataSize=nDCBPerBuffer*sectorSize	//round up to sector bdy
	dcbOffset=dataSize+2

	dataOffset=(printerDevice le printerOrbitLast)? 2,0

	let totlen=(4+dataSize+lenDCB*nDCBPerBuffer+1)&(-2)
	let nBuffers=0
	let firstBuff=(firstAddr+3)&(-2)	//Make it even
	@lvFirstBuff=firstBuff
	let buff=firstBuff
	[
		let nb=buff+totlen
		if nb ugr lastAddr then break
		buff!-2=0		//checked
		buff!-1=nb
		buff!0=-(pg>>PageG.BitWc*16)
		buff!1=pg>>PageG.BandWidth-1
		test disk ls DISKT80 then PrintInit31(buff) or PrintInitTrident(buff)
		nBuffers=nBuffers+1
		buff=nb
	] repeat
	if nBuffers ls 2 then PDError(2300)
	buff!(-totlen-1)=firstBuff

	let nBands=pg>>PageG.LastBand-pg>>PageG.FirstBand+1
	nBufsToRead=nBands
	nBufsToCheck=nBands
	nextReadBuf=firstBuff
	nextCheckBuf=firstBuff

	resultis nBuffers
]

// Call PrintDiskRead to read the next buffer. Returns the number
// of buffers remaining to be read, i.e., 0 when all done

and PrintDiskRead() = PDError(2301)

// Call PrintDiskCheck to check the next buffer. Returns the number
// of buffers remaining to be checked, i.e., 0 when all done

and PrintDiskCheck() = PDError(2301)

and PrintDiskStop() = PDError(2301)