// DiExMSG.bcpl


get "DiEx.defs"

static [ saveMsgS=0; thisErr=0 ]

let saveErr(lvDA,status,ec) be
	[ unless T>>P.MsgEnable do return
	rv DAstart = displayCB; MsgS = saveMsgS
	status = status & #7777
	let xstatus = status & #777
	test ec eq 1
		ifso 
			[
			Msg("*n*nError on $S pass $UD",WritePass? "Write","Read",pass)
			Msg(" of Drive #$D: ",DiskSel)
			Msg("Track $3D, Head $D,Sector $D had ",  lvDA>>DA.track, lvDA>>DA.head, lvDA>>DA.sector)
			]
		ifnot Msg("*n   again ")
	Msg("Status of $6UF0O.", xstatus)
	if (ec eq 1) % (not thisErr) then thisErr = errTable + DiskSel*maxEntries*lET
	status = status % #7000
	if ec eq 1 then
		[
		let block = 0
			[
			if rv lvDA eq thisErr>>ET.Addr & status eq thisErr>>ET.status then break
			if block eq maxEntries-1 then [ thisErr>>ET.Addr = thisErr>>ET.Addr + 1; break ]
			if thisErr>>ET.status eq 0 then
				[ thisErr>>ET.Addr = rv lvDA; break ]
			thisErr = thisErr + lET
			block = block + 1
			] repeat
		thisErr>>ET.softErr = thisErr>>ET.softErr+1
		]
	thisErr>>ET.status = thisErr>>ET.status % status 
	if ec eq maxEC then 
		[
		thisErr>>ET.softErr = thisErr>>ET.softErr-1
		thisErr>>ET.hardErr = thisErr>>ET.hardErr+1
		]
	Wait(300); RestartDiex()
	]


and ListET(drive) be
	[ let disko = false
	let LF(wide) be [ Msg("*n");if wide then Msg("*n") ]
	//let diskoTemp = disko
	let MsgStemp = MsgS
	let bitmask = 1b15
	let FromDr = drive
	let ToDr = drive
	if drive eq true then return
		//[ 
		//disko = OpenFile("PACKERR",ksTypeWriteOnly,charItem); MsgS=0
		//FromDr = FirstDr; ToDr=LastDr
		//]
	for dr = FromDr to ToDr do
	[driveLoop
	thisErr = errTable + dr*maxEntries*lET
	let errors, CheckErr, noResponse = 0,0,0
	let Final1, Final2, Final3 = 0,0,0
	Msg(" Summary of errors found while running Drive #$D with Pack Serial Number #............",dr)
	LF(disko)
	PrintBits(dr)
	if not thisErr>>ET.status then [ Msg("  No errors found."); goto exit ]
	LF(disko)
	Msg("DA > Cyl, Head, Sector:  Status** SoftErs HardErs *n")
	for block = 1 to maxEntries do
		[
		let last1 = block eq maxEntries
		if not thisErr>>ET.status then break
		let status = thisErr>>ET.status & #777
		let burst = thisErr>>ET.burstBits
		let burstSize = 0
		while burst do [ burst = burst rshift 1; burstSize=burstSize+1 ]
		if last1 then Msg("*n. . . etc.*n# of remaining errors")
		Msg("*n      $3F0D     $2F0D       $2F0D     $6F0UO", thisErr>>ET.track% last1,thisErr>>ET.head% last1,thisErr>>ET.sector% last1,status)
		Msg("  $5F0UD   $5F0UD        ", thisErr>>ET.softErr, thisErr>>ET.hardErr )
		//if thisErr>>ET.status eq 7 then Msg("$2D words", thisErr>>ET.burstBits)
		if thisErr>>ET.finalStatus eq 1 then Final1 = true
		if thisErr>>ET.finalStatus eq 2 then Final2 = true
		if thisErr>>ET.finalStatus eq 3 then Final3 = true
		errors = errors % status
		//if status eq 1 then CheckErr = true
		if not status then noResponse = true
		thisErr = thisErr + lET
		]
	LF(disko)
	Msg("*n--------")
	LF(disko)
	Msg("** Status bits indicate the following:*n      ")
	while bitmask ne 2 do
		[
		if (bitmask & errors) ne 0 then
			[ Msg("$6F0UO  =  ",bitmask); TypeErrors(bitmask) ]
		bitmask = bitmask rshift 1
		]
	//if CheckErr then [ Msg("000001  =  "); TypeErrors(7) ]
	if noResponse then [ Msg("000000  =  "); TypeErrors(-1) ]
	if Final1 then [ Msg("000001  =  "); TypeErrors(1) ]
	if Final2 then [ Msg("000002  =  "); TypeErrors(2) ]
	if Final3 then [ Msg("000003  =  "); TypeErrors(3) ]
	exit:
	LF(disko)
	]driveLoop
	if drive eq true then if disko then Closes(disko)
	//disko = diskoTemp
	Msg("*n*n>>")
	MsgS = MsgStemp
	]

and PrintBits(drive; numargs nargs) be
	[
	if nargs eq 0 then drive = 0
	FLD(29,drive)
	FML(29,FLDI(31,2+8+256))
	FML(29,FLDI(31,16))
	Msg("*nTotal bits Read = "); PrintFP(29)
	Msg(" during $UD *"test$S*" of the disk.",totalPasses,totalPasses eq 1? "","s")
	]

and PrintFP(ac) be
	[
	if FCM(ac,FLDI(31,1000)) ls 0 then [ Msg("$D",FTR(ac)); return ]
	let power = 3
	FLDI(30,10)
	FLDI(31,10000)
	while FCM(ac,31) ge 0 do [ FDV(ac,30); power = power+1 ]
	let num = FTR(ac)
	Msg("$D.$3F0D**10↑$D",num/1000,num rem 1000,power)
	]

and initCounters() be
	[ totalPasses = 0; for dr = 0 to 7 do FLDI(dr,0); Zero(errTable,ETsize) ]

and PrintContents(cb, doneOK) be
	[
	MsgS = saveMsgS
	if CheckInput() then return
	let printBlk(type, blk, com) =valof
		[ let str = nil; let done = nil
		switchon type into
			[
			case 0: str = "*nHeader - "; done = 2; endcase
			case 1: str = "*nLabel - "; done = 8; endcase
			case 2: str = "*nData - "; done = 256; endcase
			]
		Msg(str)
		test com eq diskRead
			ifso Msg("read:") 
			ifnot Msg("checked against:") 
		let cnt = 0
		for L = 1 to 32 do
			[
			Msg("*n$4O: ",cnt)
			for i = 0 to 7 do
				[ Msg(" $6F0UO",blk!cnt); cnt=cnt+1; if cnt eq done then resultis false ]
			if CheckInput() then resultis true
			]
		resultis false
		]

let rDA = cb>>CB.diskAddress
let vDA = VirtualDA(lv rDA)
	if doneOK then Msg("*n*nData read from virtual disk address = $UD ($3D,$D,$D); ",vDA, rDA<<DA.track, rDA<<DA.head, rDA<<DA.sector)

	if printBlk(0, cb>>CB.headerAddress, cb>>CB.command.headerAction) then return
	if printBlk(1, cb>>CB.labelAddress, cb>>CB.command.labelAction) then return
	if printBlk(2, cb>>CB.dataAddress, cb>>CB.command.dataAction) then return 

	let Exit = 6000; Msg("    ... Continue?")
	[ if CheckInput() % (Exit eq true) then break; Exit = Exit-1; Wait(100) ] repeat  
	if Exit ne true then GetChar()  //read out the continue character
	]