// SprucePrintRes -- resident Printer utilities, setup routines   
// errors 1000
//

get "Spruce.d"
get "Orbit.d"

// outgoing procedures
external
	[
	PrintSetParameters	// Send current values to adapter
	DoFunc		// Basic Orbit interface function
	ROSStatus		// Get one status word
	AdCommand		// Send Command to adapter
	DebugEnter		// Help trace Emulator behavior while running Orbit
	]

// incoming procedures
external
	[
	MoveBlock
	StartIO
	SpruceError
	]

// incoming statics
external			// values used to set adapter
	[
	AdapterScales
	BitClock
	MotorSpeed
	LineSyncDelay
	PageSyncDelay
	VideoGate

	Func
	// printerDevice
	Debug
	debugTrail

	CurRMR		// must indicate orbit microcode loaded and running
	]

// Structures and manifests.

manifest [
	debugTrailSize=10*3
	RTC = #430
	BeamOnDelay = 27/5	// Will leave beam on approx. 200 ms.
	]



// -----------------------------------------------------------
// PrintSetParameters		Set up adapter values
// -----------------------------------------------------------

// Ram must be loaded and Orbit task running

let PrintSetParameters() be
	[
	unless CurRMR eq OrbitRMR do SpruceError(1200)
	let v = vec 20
	Func = (v+1)&(-2)
	DoFunc(fControl, 1)	//Reset Orbit
	for i=0 to 15 do		//Set inkwell
		[
		DoFunc(fXY, i lshift 12)
		DoFunc(fInk, -1)
		]
	AdCommand(adBufferReset)
	AdCommand(AdapterScales+adCommandBeamOn)
	let sTim = @RTC				// Assure at least 200 ms. with beam on
	AdCommand(adBitClock+BitClock)
	AdCommand(adMotorSpeed+MotorSpeed)
	AdCommand(adLineSyncDelay+LineSyncDelay)
	AdCommand(adPageSyncDelay+PageSyncDelay)
	// if printerDevice ne printerDurango then
		AdCommand(adVideoGate+VideoGate)
	// ~~ Would rather use TimerHasExpired, etc., and verify this interval in Print()
	// ~~ Be sure beam has been forced on for at least 200 ms.
	while (@RTC-sTim) < BeamOnDelay loop
// ~~ For now, must turn off here, to avoid gritch
	AdCommand(AdapterScales) // ~~
	// Print() will return to normal beam modulation
	]


// -----------------------------------------------------------
// ROSStatus, AdCommand, DoFunc, DebugEnter -- basic Orbit functions
// -----------------------------------------------------------


and ROSStatus(w) be DoFunc(fROSStatus, w*(4*256))

and AdCommand(x) be DoFunc(fROSCommand, x)

// Static Func must be set up to an even address w/20 wds or so avail.

and DoFunc(function, arg1, arg2, arg3, arg4, arg5, nil,nil,nil,nil,nil) = valof
[
	compileif DebugSw&false then [ DebugEnter(function, arg1) ] // not currently set
	if Debug then resultis 0
	MoveBlock(Func, lv function, 11)
	if function eq fStatus then Func!0=fDBCWIDIn

	unless CurRMR eq OrbitRMR do SpruceError(1200)
// Give pointer to microcode stuff.
	@#720=Func
// Wake up microcode
	StartIO(#4)
// Wait for microcode to complete
	if function ne fSlot then while @#720 ne 0 do loop
	if function eq fStatus then resultis Func!9
	resultis Func!8
]

and DebugEnter(a, b) be
[	compileif DebugSw&false then // debugTrail currently not set by anyone
		[
		unless debugTrail return
		let m=debugTrail!0
		let dm=debugTrail+m
		dm!1=a; dm!2=b; dm!3=@RTC		//Time
		m=m+3; if m ge debugTrailSize-4 then m=0
		debugTrail!0=m
		]				]


// DCS, January 20, 1978  11:16 PM, derived from SprucePrint, SprucePrintInit
// April 17, 1978  5:06 PM, force beam on while setting scales -- Print will return to normal mod.
//January 29, 1980 4:57 PM, make sure orbit MCis in
//