! Disq IO procedures for Fred-Machine Filestore ! Version for M2294N drive - 1024*16*32*512 !This version logs interrupts per transfer %option "-nocheck-noline-nostack-nodiag-low" %include "inc:util.imp" %externalroutinespec pdate ! Configuration parameters %constinteger lbps = 9; ! log(bytes per sector) %constinteger bps = 1< ! Unit Status ! SEL | SEN | WPR | AMF | RDY | ONC | SER | FLT ! Controller Commands %constinteger clear done = 8 %constinteger mute srq = 4 %constinteger clear fifo = 2 %constinteger reset = 1 %constinteger specify = 16_20 %constinteger sense int = 16_10 %constinteger sense unit = 16_30 %constinteger detect error = 16_40 %constinteger recalibrate = 16_50 %constinteger seek = 16_60 %constinteger format = 16_70 %constinteger verify format = 16_80 %constinteger read format = 16_90 !constinteger read bad data = 16_a0 %constinteger read data = 16_b0 %constinteger write data = 16_f0 %constinteger verify data = 16_e0 !constinteger check data = 16_c0 !constinteger scan data = 16_d0 %routine parameter(%integer x) nec data = x %end %integerfn result %result = nec data %end %routinespec intwait %routine wait(%integer mask,target) %cycle ipt = ipt+1 intwait %returnif nec csr&mask=target nec csr = clear done %repeat %end %routine controller wait(%integer bc) bcr = bc board control = bc wait(128,0) board control = normal bcr = normal %end %integerfn drive wait(%integer drive) %integer i %cycle bcr = intenable board control = intenable wait(16,16) nec csr = sense int controller wait(intenable) i = result %repeatuntil i&7=drive %result=i %end %integerfn unit status(%integer drive) nec csr = sense unit+drive controller wait(intenable) %result = result<<8 %end %routine initialise controller %integer i,dtl=16_8000+bps bcr = board reset board control = board reset %for i=1,1,10000 %cycle; %repeat bcr = normal board control = normal %for i=1,1,10000 %cycle; %repeat parameter(16_40); !Mode parameter(dtl>>8); !DTLH parameter(dtl); !DTLL parameter(tpc-1); !ETN parameter(spt-1); !ESN parameter(16); !GPL2 parameter(10); !MGPL1 nec csr = specify controller wait(intenable) i = drive wait(7) %end %owninteger ec=0,fec=0; ! Error count, Fatal error count %ownintegerarray curcyl(0:maxdrive) = -1(*) %owninteger curdrive = -1 %owninteger drive,cylinder,track,sector,disqaddress,errorcode %routine restore %integer x nec csr = recalibrate+drive x = drive wait(drive) %end %routine position head %integer x parameter(cylinder>>8) parameter(cylinder) nec csr = seek+drive x = drive wait(drive) %end %routine fail(%integername lives,%integer code,operation) %owninteger e=0,f=0 ec = ec+1; e = e+1 pdate; printstring("*** Disk error "); printsymbol(operation) write(disqaddress>>lbps,6); printsymbol('b') write(cylinder,3); printsymbol('c') write(track,2); printsymbol('t') write(sector,2); printstring("s ") %unless code=-1 %start code = unit status(code&7)+code phex(code) printstring(" cb") %if code&16_80000000#0 printstring(" rrq") %if code&16_08000000#0 printstring(" ier") %if code&16_04000000#0 printstring(" nci") %if code&16_02000000#0 printstring(" drq") %if code&16_01000000#0 printstring(" enc") %if code&16_00800000#0 printstring(" ovr") %if code&16_00400000#0 printstring(" der") %if code&16_00200000#0 printstring(" eqc") %if code&16_00100000#0 printstring(" nr") %if code&16_00080000#0 printstring(" nd") %if code&16_00040000#0 printstring(" nwr") %if code&16_00020000#0 printstring(" mdm") %if code&16_00010000#0 printstring(" sel") %if code&16_00008000#0 printstring(" sen") %if code&16_00004000#0 printstring(" wpr") %if code&16_00002000#0 printstring(" rdy") %if code&16_00000800#0 printstring(" onc") %if code&16_00000400#0 printstring(" ser") %if code&16_00000200#0 printstring(" flt") %if code&16_00000100#0 printstring(" sen") %if code&16_00000080#0 printstring(" rc") %if code&16_00000040#0 printstring(" ser") %if code&16_00000020#0 printstring(" eqc") %if code&16_00000010#0 printstring(" nr") %if code&16_00000008#0 %finish errorcode = code lives = lives-1 initialise controller; restore; position head newline %andreturnunless lives<=0 fec = fec+1 printstring(" - fatal"); newline %signal 9 %if lives=0 %end %routine bulk move (%integer bytes,from,to) !Assume bytes is multiple of 4 and not more than 256k bytes = bytes>>1-1 {was bytes>>2-1} *move.l from,a0 *move.l to,a1 *move.l bytes,d0 loop: *move.w (a0)+,(a1)+ {was move.l} *dbra d0,loop %end %routine copy from(%integer userbuffer,bytes) bulkmove(bytes,userbuffer,disqbuffer) %unless userbuffer=disqbuffer %end %routine copy to(%integer userbuffer,bytes) bulkmove(bytes,disqbuffer,userbuffer) %unless userbuffer=disqbuffer %end %routine do(%integer op,bytes,da,ub) %integer target,sectors,max,size,lives=3 %integer st,h,f,c,t,s,n %cycle sectors = bytes>>lbps disqaddress = da sector = da>>lbps track = sector//spt cylinder = track//tpc drive = cylinder//cpd sector = rem(sector,spt) track = rem(track,tpc) cylinder = rem(cylinder,cpd) max = spt-sector; !Disallow head crossing max = 4096>>lbps %if max>4096>>lbps; !(Disk buffer size restriction) sectors = max %if sectors>max size = sectors<>8); !LCNH parameter(cylinder); !LCNL parameter(track); !LHN parameter(sector); !LSN parameter(sectors); !NSEC neccsr = op+drive %if op=readdata %start controllerwait(dmain+intenable) %else controllerwait(dmaout+intenable) %finish st = neccsr; st = result<<16+st<<24 h = result; f = result; c = result; c = result+c<<8 t = result; s = result; n = result copyto(ub,size) %if op=readdata target = rem(track+(sector+sectors)//spt,tpc) target = (target!!t)!(track!!h)!f!n target = target!(rem(sector+sectors,spt)!!s) target = target!((cylinder+(track+(sector+sectors)//spt)//tpc)!!c) %if target#0 %or st&16_efff0000#16_40000000 %start ! %if op=writedata %then printsymbol('W') %c ! %elseif op=readdata %then printsymbol('R') %c ! %elseif op=verifydata %then printsymbol('V') %c ! %else printsymbol('?'); space ! fail(lives,st,'T') %if op = read data %then fail(lives, st, 'R') %c %else %if op = write data %then fail(lives, st, 'W') %c %else %if op = verify data %then fail(lives, st, 'V') %c %else fail(lives, st, '?') %if target#0 %start printstring("H="); write(h,0); printstring(" F="); write(f,0) printstring(" C="); write(c,0); printstring(" T="); write(t,0) printstring(" S="); write(sector,0); printstring(" N="); write(n,0) newline %finish %continue %finish ub = ub+size; da = da+size; bytes = bytes-size %repeatuntil bytes=0 %end %constinteger dwrite=1,dread=2,dverify=4 %integerfn xtransfer(%integer func,bytes,disqaddr,%integername buf) %constinteger signbit = \((-1)>>1) %integer lives=0 %onevent 9 %start lives = lives-1 %result = signbit!errorcode %finish fail(lives,-1,'A') %andresult = -1 %unless disqaddr&(1<maxipt minipt = ipt %if ipt