// DiExRun.bcpl
// Last modified October 26, 1977 9:43 AM
get "DiEx.defs"
static [ pass; totalPasses; WritePass; ErrRes=3 ]
static [ @RandomAddr = #123456; @nPages ] //local statics
structure BIT[ b ↑ 0,256*16 bit ]
let RunDisk() be
[
Msg(" Testing .....")
let saveY,saveX = @mouseY,@mouseX
let repeats = T>>P.Repeats
let listConstant = true
PattCnt = 1
if (@diskStatus & DSTerrorBits) ne 0 then ResetDisk(true)
let cleanUp = (T>>P.TestData % T>>P.ListPage)? cleanUpRoutine,0
let PagesPerCylinder = nHeads*nSectors
let mouseXinc,mouseXposn = (500/repeats),0
Zero(DAs,100)
if T>>P.StopDisplay then [ rv DAstart = 0; Wait(50) ]
saveMsgS = MsgS; if not T>>P.MsgEnable then MsgS = 0
let LastPage = nil
nPages=makeDAtable(0) //initialize nPages to selected heads times selected sectors
pass = 0
let dummy = vec 1
let cylindersRead = 0
[passLoop
for dr = FirstDr to LastDr do
[driveLoop
mouseXposn = mouseXinc * (pass+1)
rv mouseX = mouseXposn
DiskSel = dr
SetParameters()
if (T>>P.Waction.header ne diskSkip) & WriteEnable then
[ WritePass = true
SetCursor($W)
makePattern(wbuff,1000)
for cylinder = T>>P.FirstCyl to T>>P.LastCyl do
[
rv mouseY = cylinder*2
rv mouseX = mouseXposn
makeDAtable(cylinder)
LastPage = 0
for i=0 to nPages do CAs!i = WhereIsWbuff(i)
DoWrite:
test T>>P.Chain
ifso LastPage = ActOnPages(CAs, DAs, 0, LastPage+1, nPages, T>>P.Waction)
ifnot for p = 1 to nPages do
[
LastPage = ActOnPages(CAs, DAs, 0, p, p, T>>P.Waction)
//if LastPage ne p then break
if SkipOperation() then goto exit
]
if SkipOperation() then goto exit
if LastPage ls nPages then goto DoWrite
cylinder = cylinder + T>>P.CylInc-1
]
]
WritePass = false
cylindersRead = 0
for i=1 to PagesPerCylinder by blks do
for n = 0 to blks-1 do CAs!(i+n) = rbuff + (n*300)
if (T>>P.Raction.header ne diskSkip) then
[
SetCursor($R)
for cylinder = T>>P.FirstCyl to T>>P.LastCyl do
[
rv mouseY = cylinder*2
rv mouseX = mouseXposn
makeDAtable(cylinder)
LastPage = 0
DoRead:
test T>>P.Chain
ifso LastPage=ActOnPages(CAs, DAs, 0, LastPage+1, nPages, T>>P.Raction, 0, 0, 0, cleanUp)
ifnot for p = 1 to nPages do
[ LastPage = ActOnPages(CAs,DAs, 0, p, p, T>>P.Raction, 0, 0, 0, cleanUp)
//if LastPage ne p then break
if SkipOperation() then goto exit
]
if SkipOperation() then goto exit
if LastPage ls nPages then goto DoRead
cylindersRead = cylindersRead+1
cylinder = cylinder + T>>P.CylInc-1
]
]
let CylRange = ((T>>P.LastCyl - T>>P.FirstCyl)/T>>P.CylInc)+1
if T>>P.nRandom then
[
SetCursor($R)
for i = 1 to T>>P.nRandom do
[
RandomAddr = MakeRandom(wbuff,2,RandomAddr)
let nextCyl = T>>P.FirstCyl + ((wbuff!0ṡ) rem CylRange)*T>>P.CylInc
rv mouseY = nextCyl*2
rv mouseX = mouseXposn
makeDAtable(nextCyl)
let p = 1+(((wbuff!1)±) rem nPages)
let Cmmd = 0; Cmmd<<ACTx.header = diskCheck
ActOnPages(CAs,DAs, 0, p, p, Cmmd)
if SkipOperation() then goto exit
]
]
if cylindersRead then
[
FAD(dr,FML(FLDI(30,nPages),FLDI(31,cylindersRead))); cylindersRead = 0
FAD(dr,FLDI(31,T>>P.nRandom))
]
if SkipOperation() then goto exit
]driveLoop
totalPasses = totalPasses + 1; pass = pass+1
if pass ge 500 then pass = 0
if pass eq repeats then break
if listConstant eq true then
listConstant = ((cylindersRead*(FirstDr+1 - LastDr)*(T>>P.LastHd+1 - T>>P.FirstHd))/41)
if listConstant then if totalPasses rem (1000/listConstant) eq 0 then ListET(true)
]passLoop repeat
exit:
@mouseX = saveX; @mouseY = saveY
FAD(DiskSel,FML(FLDI(30,nPages),FLDI(31,cylindersRead)))
rv DAstart = displayCB; MsgS = saveMsgS
ListET(true)
Msg(" Done*n*n>>")
]
and cleanUpRoutine(cb,doneOK) =valof
[ let res = false
if (T>>P.TestData eq 1)%((T>>P.TestData eq 2) & not doneOK) then res=CheckData(cb,true)
if (T>>P.ListPage eq 1)%((T>>P.ListPage eq 2) & not doneOK) then PrintContents(cb)
resultis res
]
and makeDAtable(Cylinder) = valof
[
let nPage = 0
let DA = 0
for head = T>>P.FirstHd to T>>P.LastHd do
for sector = T>>P.FirstSec to T>>P.LastSec do
[ nPage=nPage+1
DA<<DA.track = Cylinder; DA<<DA.head = head; DA<<DA.sector = sector
DAs!nPage = DA
]
resultis nPage
]
and SkipOperation(stream) = valof
[
unless CheckInput() then resultis 0
MsgS = saveMsgS
rv DAstart = displayCB
PrintBits()
Msg(" ... Continue?"); GetChar(); char = GetChar()
let result = (char eq $N) % (char eq Middle)
Msg(" $S",result? "No ... ","Yes")
unless result then RestartDiex()
resultis result
]
and CheckData(cb,QuickCk) = valof
[
let buffw = WhereIsWbuff(cb>>CB.truePageNumber)
let buffr = cb>>CB.dataAddress
manifest errlines = 20
//buffr!10 = 50 //~~~~~~~~~~~~~USED TO TEST THIS CODE
let cnt = quickCheck(buffw,buffr,wordsPerPage)
if not cnt then resultis 0
//[ Zero(buffr,wordsPerPage); resultis 0 ]
if QuickCk then resultis cnt
if cnt gr thisErr>>ET.burstBits then thisErr>>ET.burstBits = cnt
if CheckInput() then resultis 0
MsgS = saveMsgS
if cnt then Msg("*n$4D errors found by checking memory after read!",cnt)
cnt = 0
let lasterror,ErBurst = wordsPerPage,0
for i = wordsPerPage-1 to 0 by -1 do if buffw!i ne buffr!i then
[
test i eq lasterror - 1
ifso ErBurst = ErBurst + 1
ifnot
[
if ErBurst gr errlines then Msg("*n ETC. for $D consecutive errors.",ErBurst)
ErBurst = 0
]
lasterror = i
if ErBurst le errlines then
[
if i & (ErBurst eq 0) then Msg("*n OK Word $4D was $6F0UO.", i+1, buffr!(i+1))
Msg("*n Word $4D: wrote $6F0UO, but read $6F0UO; error = $6F0UO.", i, buffw!i, buffr!i, buffw!i xor buffr!i)
]
cnt = cnt+1
]
if ErBurst gr errlines then Msg("*n ETC. for $D consecutive errors.",ErBurst)
//Bug("undetected errs",cb,cnt)
if cb>>CB.command.dataAction eq diskCheck then Zero(buffr,wordsPerPage)
RestartDiex()
resultis cnt
]
and RestartDiex() be
[ if T>>P.StopDisplay then rv DAstart = 0; Wait(50)
if not T>>P.MsgEnable then MsgS = 0
]
and quickCheck(wrote,read,cnt) = valof
[ external CompairASM
let buff = vec 2
buff!0 = wrote
buff!1 = read
buff!2 = cnt
resultis CompairASM(buff)
]
and SetParameters() be
[
ErrRes = T>>P.ErrRes
maxEC = T>>P.maxEC
//if TriexHandeling then
//[ SetBlock(HeaderBuff,3,32)
//LabelBuff!0 = #100000%DriveSel; for i = 1 to 31 do LabelBuff!i = i
//]
]
and ErrorLength(wrote,cb) = valof
[
let buffw = WhereIsWbuff(cb>>CB.truePageNumber)
let buffr = cb>>CB.dataAddress
let Fw,Fb,Lw,Lb = 0,0,0,0
for w = 255 to 0 by -1 do for b = 0 to 15 do
[ let wb = w+b
if buffw>>BIT.b↑wb ne buffr>>BIT.b↑wb then [ Fw=w; Fb=b; break ]
]
for w = 0 to Fw do for b = 15 to 0 by -1 do
[ let wb = w+b
if buffw>>BIT.b↑wb ne buffr>>BIT.b↑wb then [ Lw=w; Lb=b; break ]
]
let length = (Lw-Fw)*16 + Lb-Fb + 1
resultis length
]
// from page number figure out where Wbuff must be
and WhereIsWbuff(pageNumber) =valof
[
test PattCnt eq 2
ifso resultis wbuff+((wbuff!pageNumber) & #377)
ifnot resultis wbuff
]