|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 121344 (0x1da00) Types: TextFile Names: »mondisc«
└─⟦621cfb9a2⟧ Bits:30002817 RC8000 Dump tape fra HCØ. Detaljer om "HC8000" projekt. └─⟦0364f57e3⟧ └─⟦87223b8a0⟧ »kkrcmonfil« └─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ. └─⟦b2ec5d50f⟧ └─⟦87223b8a0⟧ »kkrcmonfil« └─⟦this⟧
\f m. mondisc - disc driver b.i30 w. i0=80 12 10, i1=14 00 00 ; if newtime (i0,i1) > oldtime (a133,a134) then oldtime:=newtime; c.i0-a133 c.i0-a133-1, a133=i0, a134=i1, z. c.i1-a134-1, a134=i1, z. z. i10=i0, i20=i1 i15=i10/100000 , i10=i10-i15*100000 , i25=i20/100000 , i20=i20-i25*100000 i14=i10/10000 , i10=i10-i14*10000 , i24=i20/10000 , i20=i20-i24*10000 i13=i10/1000 , i10=i10-i13*1000 , i23=i20/1000 , i20=i20-i23*1000 i12=i10/100 , i10=i10-i12*100 , i22=i20/100 , i20=i20-i22*100 i11=i10/10 , i10=i10-i11*10 , i21=i20/10 , i20=i20-i21*10 i2: <: date :> (:i15+48:)<16+(:i14+48:)<8+46 (:i13+48:)<16+(:i12+48:)<8+46 (:i11+48:)<16+(:i10+48:)<8+32 (:i25+48:)<16+(:i24+48:)<8+46 (:i23+48:)<16+(:i22+48:)<8+46 (:i21+48:)<16+(:i20+48:)<8+ 0 i3: al. w0 i2. ; write date: rs w0 x2+0 ; first free:=start(text); al w2 0 ; jl x3 ; return to slang(status ok); jl. i3. ; e. j. ; --------------------------------------------------------------- ; d i s c d r i v e r c o d e ; (dsc 801) ; ; a r e a p r o c e s s c o d e ; --------------------------------------------------------------- ; this section contains the code executed by driverproc for pro- ; cessing messages to an area process or a disc driver. ; ; messages have the following format: ; ; sense 0<12 + mode initialize 2<12 ; irrel no of heads ; irrel disp. on odd cyl. ; irrel disctype ; ; clean track 6<12 + mode position 8<12 + mode ; irrel irrel ; irrel irrel ; segment no segment no ; ; read 3<12 + mode write 5<12 + mode ; first address first address ; last address last address ; first segment no first segment no ; ; get statistics 9<12 ; first address ; last address ; irrel ; ; set regretted 10<12 continue 12<12 ; (used by testprograms) ; irrel irrel ; irrel irrel ; irrel irrel ; mode consists of a sum of one or more of following values: ; ; transput mode 0 transput of data ; 1 transput of address marks ; error recovery 0 repeat at error ; 2 do not repeat at error ; requeue 4 answer message after best repetitions ; 0 requeue message after best repetitions ; and try later again ; read after write 0 no read after write ; 8 read after write mode ; ; disctype 0 = dsm801, disctype 1 = dsm802 with variable offset. ; ; the answer to a message has the following format: ; ; statusword ; 0 or number of bytes transferred ; 0 or number of chars transferred ; i/o result, from start i/o ; current status from controller ; event status from controller ; technical status from controller ; ; the following bits may be set in a statusword: ; ; bit 0 intervention, no disc driver at area process message ; bit 1 parity , event status bit 1 or 4 (data-, hard err.) ; bit 2 sync.error , event status bit 5 (position error) ; bit 3 data overrun, event status bit 3 (data overrun) ; bit 4 blocklength , buffer too small at get statistics ; bit 5 end medium , 1st segm outside or curr stat b5 (seek err) ; bit 11 discerror , requeue mode = 4 and repetitions < max ; ; the message may be sent to an area process, a logical disc ; driver (one physical disc may be split into more logical devi- ; ces) or to a physical disc driver. in either case the message is ; linked to the physical driver unless it concerns an area on a ; remote disc, in which case the code for processing such messages ; is entered. ; ; initialize, clean track, and write addr mark can only be sent to ; a reserved physical disc driver. get statistics can only be sent ; to a disc driver. ; ; segment numbers in message correspond to absolute segments ; when sent to a physical driver, to segmentno relative to start ; of logical disc when sent to a logical driver, and relative ; to areastart when sent to an area process. ; ; before linking the message to the physical disc driver it is ; reformatted and will contain sufficient information for exe- ; cuting the first part of the transfer corresponding to the ; largest number of consecutive segments starting at first seg- ; ment wanted. the buffer is updated at each portion of conse- ; cutive segments transferred until the entire number of segments ; have been transferred. ; ; when the message is linked to the physical driver it is not ; possible to see if it was sent to an area process or directly ; to a driver. however, when sent to a driver, all segments ; wanted can be processed in the first transfer, whereas an ; area process message may be processed in more transfers as ; the slices of an area need not be consecutive. ; ; the driver will automatically examine the number of heads on ; the disc, the displacement of sector zero on odd cylinders, ; and the disctype (dsm801-2) when the first message (after ; intervention) is received unless this first message is the ; initialize message. \f ; pej 04.10.77 disc driver, contents ; c o n t e n t s ; --------------------------------------------------------------- ; definitions ; ----------- ; ; constant definitions ; format of transformed message ; process description format ; ; main routines ( in sequential order) ; ------------- ; ; message received by area process ; message received by disc driver ; link message to disc driver ; message not accepted ; ; process next message ; start device ; ; interrupt received ; successful transfer ; deliver answer routines ; ; error routine ; ; procedures (in alphabetical order) ; ---------- ; ; check area process ; check message ; clean ; compound status ; copy statistics ; correct data ; initialize disc ; prepare consecutive segments ; setup channel program and start ; set errorkind ; set result and status ; transform first segment ; update buf ; update buf on error ; update on corrected error ; update retryinformation b. j170, m10, p50, q70 ; disc driver and area process \f ; pej 30.09.77 disc driver, constant definitions ; c o n s t a n t d e f i n i t i o n s ; --------------------------------------------------------------- ; operation codes, control = even, transput = odd codes. if the ; codes are changed, also a table in proc setup channel program ; and start must be changed as well as error segment table ; updating in action 7a of error actions and proc. update buf. q30 = 0 ; sense q31 = 2 ; initialize q32 = 3 ; read q33 = 5 ; write q34 = 6 ; clean track q35 = 8 ; position q36 = 9 ; get statistics q39 = 10 ; set regretted q38 = 12 ; continue ; mode codes q40 = 1 ; transput mode, = addr mark mode q41 = 1 < 1 ; error recovery, = no repetition q42 = 1 < 2 ; requeue, = do not reque q43 = 1 < 3 ; read after write, = true ; segment units q50 = 8 ; no of bytes per addr mark q51 = 12 ; - - chars - - - q52 = 512 ; - - bytes - data segment q53 = 768 ; - - chars - - - ; process kinds q60 = 84 ; subproc q61 = 62 ; disc driver ; power restart parameters (time units: 0.1 msec) q10 = 1 * 1000 * 10 ; time between sense in power rest. loop q11 = 40 * 1000 * 10 ; maxtime to become ready at power rest. q12 = q10 ; - - - - - - down q13 = q11 / q10 + 1 ; no of times to sense at power restart q14 = q12 / q10 + 1 ; no of times to sense at power down q15 = 10 ; no of times to repeat at data overrun ; no of times to repeat at error ; repeats = 3 ; not defined as a constant due to imple- ; mentation details. to change strategy, ; correct proc update retryinformation ; and action 8a and 10 in error routine. ; assembly options q0 = (:a80>1a.1:)-1 ; disc driver included, 0=yes, -1=no q1 = (:a82>1a.1:)-1 ; statistics included, 0=yes, -1=no q2 = 10 ; no of entries in error segment table \f ; pej 04.10.77 disc driver, format of transformed message ; f o r m a t o f t r a n s f o r m e d m e s s a g e ; --------------------------------------------------------------- ; format of messagebuffer when linked to driver (after checking) m0 = a145, m1 = m0+1 ; operation , mode m2 = m1+1, ; first address m3 = m2+2 ; last address m4 = m3+2 ; first segment m5 = m4+2, m6 = m5+1 ; no of segments , retryinformation m7 = m6+1 ; next segment m8 = m7+2, m9 = m8+1 ; segments wanted, remaining segments m10 = m9+1 ; device ; operation : not changed ; mode : not changed ; firstaddr : in curr transfer ; lastaddr : not changed, used by start i/o for checking ; first segm : in curr transfer, rel. to start of disc ; no of segms: in curr transfer ; retryinf : at read data, read addr mark: ; modeindex<8 + offsetindex<3 + tries ; modeindex : index to modetable ; offsetindex: index to offset table ; tries : no of tries at given modeindex ; and offset index ; at read after write: ; writetries<3 + readtries ; writetries: no of times write has been tried ; readtries : no of times read has been tried ; after a write ; at other operations: ; no of times the transfer has been tried ; next segm : will be first segment in next transfer ; segms want : total no of segments wanted by sender ; rem segms : no of segments remaining to be transferred ; device : addr of disc driver containing sliceinformation ; and physical segment no of first segment \f ; pej 04.10.77 disc driver, proc descr format ; p r o c e s s d e s c r i p t i o n f o r m a t ; --------------------------------------------------------------- ; variables required for physical and logical disc. ; a250 ; driver descr addr ; a48 ; interval ; a49 ; - ; a10 ; kind ; a11 ; name p2 = a50 ; mainproc, phys.=0, log.=addr of physical ; a52 ; reserver ; a53 ; users ; a54 ; next message ; a55 ; last message ; a56 ; regretted, often called interrupt address ; a70 ; not used p0 = a71 ; chaintable p1 = a72 ; slicelength p3 = p1+2 ; first segment, phys.=0, log.= segm no of log. 0 p4 = p3+2 ; no of segments, phys.=on disc, log.=on log. disc ; disc characteristics (only required for physical disc). p6 = p4+2 ; no of segments per track p7 = p6+2 ; flags, used in address marks p8 = p7+2 ; no of segments per cylinder (set by driver) p10 = p8 ; cylinder, used during define disc p9 = p8+2 ; displ. of sector 0 on odd cyl. (set by driver) p11 = p9 ; head, used during define disc p5 = p9+2 ; disctype, 0=dsm801, 1=dsm802 (var.offset) ; variables concerning state of disc (only physical disc). p12 = p5+2 ;state, 0=after intervention, 1=defining disc, ; 2=ready p13 = p12+2 ; transfer state, kind of transfer in progress ; bit 0 = idle (initial state) ; 1 = define disc ; 2 = power restart ; 3 = sense ; 4 = position ; 5 = clean track ; 6 = read data ; 7 = read addr mark ; 8 = write data ; 9 = write addr mark ; 10 = read after write data ; 11 = read after write addr mark p14 = p13+2 ; initdisc, 1=init at next start, 0=no p15 = p14+1 ; retryinformation, used at driver initiated ; transfers; see m6 of message buffer ; areas used by channelprograms (only physical disc). p16 = p15+1 ; statusarea1, statusarea for first sense ; +0 : channel program counter ; +2 : remaining bytecount ; +4 : current status ; +6 : event status ; +8 : last read addr mark (4 words) ; +16: ecc, error correction information (2 words) ; +20: technical status p18 = p16+22 ; statusarea2, statusarea for second sense, for- ; matted as statusarea1 p22 = p18+8 ; addr mark, input area at define disc (4 words) p36 = p18+16 ; actionkey, used in error actions p37 = p18+18 ; actionindex, used in error actions p38 = p18+20 ; write ok, used at read after write error p20 = p18+22 ; seek parameter ; +0: cylinder<8 + head ; +2: sector<16 + flags p21 = p20+4 ; setmode parameter, bit16-17:strobe, ; bit18-19:offset, bit20-23:offset magnitude ; (set to zero if strobe-offset not used) ; other variables (only physical disc). p31 = p21+2 ; +0: curr status (sum of all statusareas) ; +2: event status (- - - - ) p33 = p31+4 ; technical status (- - - - ) p34 = p33+2 ; compound status, formed from p31,p32,i/o result p35 = p34+2 ; segment unit in curr transfer: ; +0: bytes per segment ; +2: chars per segment ; statistical information (only physical disc). p40 = p35+4 ; no of transfers p41 = p40+2 ; no of transfers not successful in first attempt ; (intervention, power restart, power down, ; write protect are not counted) p42 = p41+2 ; no of errors corrected by ecc without repetition p43 = p42+2 ; no of errors corrected within 3 retries ; strobe offset table, no of errors corrected by: p44 = p43+2 ; strobe 0 & offset n , strobe 0 & offset p ; , strobe l & offset 0 ; strobe l & offset n , strobe l & offset p ; , strobe e & offset 0 ; strobe e & offset n , strobe e & offset p ; (e=early, l=late, p=positive, n=negative) p45 = p44+10 ; no of errors corrected by offset magnitude -, 1 ; 2, 3 ; 4, 5 ; . . ; . . ; 14, 15 ; (first byte not used, magnitude 0 unexistent) p47 = p45+16 ; counters for compound status bit 0, 1 ; 2, 3 ; . . ; . . ; 22,23 p48 = p47+24 ; counters for technic. status bit 0, 1 ; 2, 3 ; . . ; . . ; 22,23 p46 = p48+24 ; table of error segments, an entry contains ; +0: segment no. (physical) ; +2: no of reads ok +3: no of reads with rep. ; +4: no of writes ok +5: no of writes with rep. p50=p46+q2*6-p40; size of statistics in bytes ; ***** please note that: ; - declarations of p10 and p8 are equal. ; - declarations of p11 and p9 are equal. ; - p22, p36, p37, and p38 are declared inside p18. ; conflicts in use will not occur as overlapping locations ; are not used simultanously. \f ; pej 21.09.77 area process, message received ; m e s s a g e r e c e i v e d b y a r e a p r o c e s s ; --------------------------------------------------------------- m. area process ; this routine is entered when driverproc receives a message for ; an area process. curr receiver (b19) = area process descr. b. i10 w. ; block containing area proc driver ; check if sender ok and if specified operation legal. h5 : bz w0 x2+m0 ; area process: c. w2 = curr buf; sn w0 q33 ; if operation.curr buf = output am g15-g14; then check reservation jl w3 g14 ; else check user; dl. w1 i0. ; jl w3 g16 ; check operation(oper mask,mode mask); ; check the area process. jl. w3 j1. ; check area process; jl. j37. ; if area segms < 0 then goto outside; jl. j35. ; if no doc then goto doc not found; ; now curr receiver = disc driver (physical or logical). check ; if the disc is a remote disc or that disc driver included. rs w1 x2+m7 ; save area process addr in curr buf; rl w0 x3+a10 ; la w0 g50 ; se w0 q60 ; if kind.curr receiver = subproc then jl. i10. ; begin c. remote disc; rs w1 x3+a56 ; interrupt addr.curr rec:= area proc; jl. (2), h84; goto subproc driver; i10 : ; end; c. -q0-1 ; if disc driver not included jl g3 ; then goto result 5; c. unknown; z. ; c. q0 ; ; check contents of the message rl w0 x1+a61 ; top:= no of segments.area proc; al w1 q52 ; bytes:= no of bytes in data segments; jl. w3 j2. ; check message(top,bytes); jl. j37. ; if outside then goto outside; ; convert first segment into a segment no relative to discstart ; and prepare first portion of consecutive segments bz w0 x2+m0 ; sn w0 q30 ; if operation.curr buf <> sense then jl. j30. ; begin rl w1 x2+m7 ; area proc:= saved area proc; jl. w3 j3. ; transform first segm(area proc); bz w0 x2+m0 ; se w0 q35 ; if operation.curr buf <> position jl. w3 j4. ; then prepare consec segms(curr rec); ; end; jl. j30. ; goto link message; z. ; ; legal mode combinations: ; read after write ; requeue ; error recovery i1 = a0>(: q41:) i2 = a0>(: q42 :) i3 = a0>(: q42+q41:) i4 = a0>(:q43 :) i5 = a0>(:q43 +q41:) i6 = a0>(:q43+q42 :) i7 = a0>(:q43+q42 :) ; oper and mode masks for area process message a0>q30+a0>q32+a0>q33+a0>q35 ; oper mask: sense, read, write, pos. i0 : a0>0+i1+i2+i3+i4+i5+i6+i7 ; mode mask: no addr mark transput e. ; end of area process driver \f ; pej 21.09.77 disc driver, message received ; m e s s a g e r e c e i v e d b y d i s c d r i v e r ; --------------------------------------------------------------- b. i50 w. ; block including disc driver h6 : ; ; c. q0 ; m. dsc 801 ; this routine is entered when driverproc receives a message for ; a disc driver. curr receiver (b19) = (logical or physical) disc ; driver process description. ; check if sender ok and if specified operation legal bz w0 x2+m0 ; disc driver: c. w2 = curr buf; sn w0 q33 ; if operation.curr buf = output jl. j20. ; se w0 q31 ; or operation.curr buf = initialize sn w0 q34 ; or operation.curr buf = clean track j20 : am g15-g14; then check reservation jl w3 g14 ; else check user; dl. w1 i0. ; use oper/mode mask for phys. driver; am (b19) ; rl w3 p2 ; sn w3 0 ; if mainproc.curr receiver <> 0 then jl. j25. ; begin c. logical disc driver; rl. w0 i1. ; use oper mask for logical driver; bz w3 x2+m0 ; if operation.curr buf = output sn w3 q33 ; then use mode mask for output; rl. w1 i2. ; end; j25 : jl w3 g16 ; check operation(oper mask,mode mask); ; check if message is continnue. ; such a message should not be linked up to the physical driver. ; if regretted is set by the command "set regretted " the message ; is answered ok and the physical disc is started in rutine process ; next message. otherwise the message is answered with result 3 and ; and no action is performed. bz w3 x2+m0 ; if operation.curr buf = continue then se w3 q38 ; begin jl. j28. ; if regretted not set by "set regret" am (b19) ; ( regretted.curr receiver=3) rl w1 +a56 ; then deliver result 3 else se w1 3 ; deliver result 1 and continue with jl g5 ; process next message jl. j101. ; end ; check contents of the message j28 : bz w0 x2+m1 ; al w1 q52 ; if transput mode.curr buf = 0 sz w0 q40 ; then bytes:= bytes in data segments al w1 q50 ; else bytes:= bytes in addr marks; am (b19) ; rl w0 p4 ; top:= no of segments.curr receiver; jl. w3 j2. ; check message(top,bytes); jl. j37. ; if outside then goto outside; jl. j30. ; goto link message; ; legal mode combinations: ; read after write ; requeue ; error recovery ; transput of addr marks i3 = a0>(: q40:) i4 = a0>(: q41 :) i5 = a0>(: q41+q40:) i6 = a0>(: q42 :) i7 = a0>(: q42 +q40:) i8 = a0>(: q42+q41 :) i9 = a0>(: q42+q41+q40:) i10 = a0>(:q43 :) i11 = a0>(:q43 +q40:) i12 = a0>(:q43 +q41 :) i13 = a0>(:q43 +q41+q40:) i14 = a0>(:q43+q42 :) i15 = a0>(:q43+q42 +q40:) i16 = a0>(:q43+q42+q41 :) i17 = a0>(:q43+q42+q41+q40:) ; get statistics operation only allowed if statistics wanted c. q1 ; i18 = a0>q36 ; statistics wanted z. ; c. -q1-1 ; i18 = 0 ; statistics not wanted z. ; ; oper and mode masks for disc driver message ; op: sense init. read write clean pos. stat. regr. cont. i1 : a0>q30 +a0>q32+a0>q33 +a0>q35+i18; logical a0>q30+a0>q31+a0>q32+a0>q33+a0>q34+a0>q35+i18+a0>q39+a0>q38; physical ; physical driver modes (all): i0 : a0>0+i3+i4+i5+i6+i7+i8+i9+i10+i11+i12+i13+i14+i15+i16+i17 ; logical driver modes at output (all except addrmarks): i2 : a0>0 +i4 +i6 +i8 +i10 +i12 +i14 +i16 \f \f ; pej 22.09.77 disc driver, link message ; l i n k m e s s a g e t o d i s c d r i v e r ; --------------------------------------------------------------- ; this routine is entered when a message received by an area ; process or a disc driver has been checked. the message is ; linked to the physical disc driver and curr receiver will ; be changed accordingly. ; ; please note that the buffer is not claimed by the driver during ; the processing. the claiming takes place when the answer is re- ; turned, see procedure deliver result. ; change curr receiver into physical driver. j30 : rl w1 b19 ; link message: c. w2 = curr buf; rs w1 x2+m10 ; device.curr buf:= curr receiver; rl w1 x1+p2 ; if mainproc.curr receiver <> 0 then sn w1 0 ; begin c. curr rec = logical driver; jl. j32. ; curr receiver:= mainproc.curr rec; rs w1 b19 ; end; ; link the message by calling procedure link operation which ; will continue in case the driver is idle or otherwise will ; jump to waitnext in driver proc. j32 : jl w3 g17 ; link operation(curr buf); jl. j50. ; goto process next message; z. ; \f ; pej 22.09.77 disc driver, message not accepted ; m e s s a g e n o t a c c e p t e d ; --------------------------------------------------------------- ; the routines are entered when a message received by an area ; process or a disc driver can not be accepted. the message ; is answered and continuation takes place at waitnext in driver ; proc. j35 : rl w0 g49 ; document not found: jl. j41. ; status:= bit 0; c. intervention; j37 : rl w0 g62 ; outside: ; status:= bit 5; c. end medium; j41 : rs w0 g20 ; status.i/o answer:= status; c. w0; ld w1 -100 ; bytes.i/o answer:= ds w1 g22 ; chars.i/o answer:= 0; jl g7 ; goto result 1; c. cont. at waitnext; \f ; pej 20.09.77 disc driver, check area process ; procedure check area process ; --------------------------------------------------------------- ; ; the procedure performs: ; - checks if no of segments.curr receiver (= area proc) >= 0. ; - searches for document.curr receiver if device addr.curr ; receiver = 0 and initializes device addr.curr receiver. ; - changes curr receiver to device addr.curr receiver . ; (i.e. to disc driver). ; ; registers: call exit ; w0 destroyed ; w1 area proc (= curr receiver at call) ; w2 curr buf ; w3 link curr receiver ; ; entry : j1 ; ; return : link+0: no of segments.area proc < 0 ; link+2: document not found ; link+4: normal return b. i2 w. j1 : rs. w3 i0. ; check area proc: save link; rl w1 b19 ; rl w3 x1+a61 ; sh w3 -1 ; if no of segms.curr receiver < 0 jl. (i0.) ; then outside return; c. link; rl w3 x1+a50 ; se w3 0 ; if device addr.curr receiver = 0 then jl. i1. ; begin al w2 x1+a62 ; name:= document.curr receiver; dl w1 d72 ; base:= max interval; jl w3 d71 ; search name(name,entry,base); rl w1 b19 ; sn w3 (b7) ; if entry = nametable end jl. i2. ; then goto doc not found return; rl w3 x3+0 ; device addr.curr receiver:= rs w3 x1+a50 ; core(entry); i1 : rl w2 b18 ; end; rs w3 b19 ; curr receiver:=device addr.curr receiver; am. (i0.) ; jl 4 ; normal return; c. link+4; i2 : am. (i0.) ; doc not found return; jl 2 ; goto link+2; ; variables i0 : 0 ; saved link e. c. q0 ; \f ; pej 21.09.77 disc driver, check message ; procedure check message(top segment,bytes per segment) ; --------------------------------------------------------------- ; top segment : highest allowed segment no + 1. ; bytes per segment: no of bytes to be transferred per segment. ; ; the procedure performs: ; - zeroizes retryinformation.curr buf. ; - checks that 0 <= first segment.curr buf < top segment (not ; for sense, initialize, get statistics). ; - sets segms wanted.curr buf and remaining segms.curr buf ; and no of segments.curr buf to: ; (lastaddr.curr buf + 2 - firstaddr.curr buf)/bytes per segm. ; (undefined for sense, initialize, get statistics). ; ; registers: call exit ; w0 top segment destroyed ; w1 bytes per segm. unchanged ; w2 curr buf unchanged ; w3 link destroyed ; ; entry : j2 ; ; return : link+0: first segment.curr buf outside limits ; link+2: normal return b. i2 w. j2 : rs. w3 i0. ; check message: save link; al w3 0 ; hs w3 x2+m6 ; retryinformation.curr buf:= 0; rl w3 x2+m4 ; sl w3 0 ; if first segment.curr buf >= 0 sl w3 (0) ; and first segm.curr buf < top segment jl. i2. ; then rl w3 x2+m3 ; begin al w3 x3+2 ; segments wanted:= ws w3 x2+m2 ; (lastaddr.curr buf + 2 al w2 0 ; - first addr.curr buf) wd w3 2 ; / bytes per segment; rl w2 b18 ; segments possible:= ws w0 x2+m4 ; top segment - first segm.curr buf; sh w0 x3+0 ; rl w3 0 ; s:= min(segms wanted,segms poss.); hs w3 x2+m5 ; no of segments.curr buf:= hs w3 x2+m8 ; segments wanted.curr buf:= hs w3 x2+m9 ; remaining segments.curr buf:= s; i1 : am. (i0.) ; normal: normal return; c. link+2; jl 2 ; end i2 : bz w3 x2+m0 ; else se w3 q39 ; if operation.curr = set regret or sn w3 q30 ; operation.curr buf = sense jl. i1. ; se w3 q31 ; or operation.curr buf = initialize sn w3 q36 ; or operation.curr buf = get statist. jl. i1. ; then goto normal jl. (i0.) ; else outside return; c. link+0; ; variables i0 : 0 ; e. \f ; pej 21.09.77 disc driver, transform first segment ; procedure transform first segment(area process) ; --------------------------------------------------------------- ; area process: addr of area proc which received curr buf. ; ; the procedure performs: ; - transforms first segment.buf from being a segment no relative ; to bs-area start into being a segment no relative to start ; of (physical or logical) disc. ; ; registers: call exit ; w0 destroyed ; w1 area process curr receiver ; w2 curr buf unchanged ; w3 link destroyed ; ; entry : j3 ; ; return : link+0 b. i0 w. j3 : rs. w3 i0. ; transform first segment: save link; al w3 0 ; rl w0 x2+m4 ; no of slices:= am (b19) ; first segment.curr buf wd w0 p1 ; / slicelength.curr receiver; rs w3 x2+m4 ; first segment.curr buf:= remainder; rl w2 x1+a60 ; index:= rl w1 b19 ; first slice.area proc wa w2 x1+p0 ; + chaintable.curr receiver; jl w3 d74 ; follow chain(noof slices,index,slice); ws w2 x1+p0 ; slice:= slice - chaintable.curr rec; al w0 x2+0 ; rl w2 b18 ; wm w0 x1+p1 ; first segment.curr buf:= wa w0 x2+m4 ; slice * slicelength.curr receiver rs w0 x2+m4 ; + first segment.curr buf; jl. (i0.) ; return; ; variables i0 : 0 ; saved link e. \f ; pej 21.09.77 disc driver, prepare consecutive segments ; procedure prepare consecutive segments(proc) ; --------------------------------------------------------------- ; proc: addr of disc proc descr containing sliceinformation. ; ; the procedure performs: ; - initializes no of segments.curr buf by the largest possible ; number of adjecent segments which can be transferred from ; first segment.curr buf and on. ; - sets next segment.curr buf to a value which may be used as ; first segment in the next call of this procedure. ; ; note: must only be called in connection with message origi- ; nating from an area process. ; ; registers: call exit ; w0 destroyed ; w1 proc unchanged ; w2 curr buf unchanged ; w3 link destroyed ; ; entry : j4 ; ; return : link+0 b. i3 w. j4 : rs. w3 i0. ; prepare consecutive segments: bz w3 x2+m9 ; save link; rs. w3 i1. ; remaining:= remaining segms.curr buf; rl w3 x2+m4 ; al w2 0 ; slice:= first segment.curr buf wd w3 x1+p1 ; / slicelength.proc wa w3 x1+p0 ; + chaintable.proc; ws w2 x1+p1 ; segments possible:= slicelength.proc ac w0 x2+0 ; - first segm.curr buf mod slicel.proc; i2 : bl w2 x3+0 ; while core(slice) = 1 sn w2 1 ; and segments possible < remaining do sl. w0 (i1.) ; begin jl. i3. ; slice:= slice + 1; al w3 x3+1 ; segments possible:= wa w0 x1+p1 ; segments possible+slicelength.proc; jl. i2. ; end; i3 : ba w3 x3+0 ; ws w3 x1+p0 ; next segment.curr buf:= wm w3 x1+p1 ; (slice + core(slice) - chaintab.proc) rl w2 b18 ; * slicelength.proc; rs w3 x2+m7 ; sl. w0 (i1.) ; if segments possible >= remaining rl. w0 i1. ; then segments possible:= remaining; hs w0 x2+m5 ; no of segms.curr buf:= segms possible; jl. (i0.) ; return; ; variables i0 : 0 ; saved link i1 : 0 ; remaining (from rem.segms.curr buf) e. \f ; pej 04.10.77 disc driver, proc copy statistics ; procedure copy statistics(result,words) ; --------------------------------------------------------------- ; result: see proc copy to buffer. ; words : no of words copied. ; ; the procedure performs: ; - copies the number of words specified in curr buf from ; statistics of curr receiver. ; - zeroizes the statistics area if copy ok. ; ; registers: call exit ; w0 result if result <> ok return ; w1 curr receiver destroyed ; w2 curr buf curr receiver if normal return ; w3 link words if normal return ; ; entry : j5 ; ; return : link+0: not enough room in buf for statistics ; link+2: result <> ok ; link+4: normal return c. q1 b. i8 w. j5 : al w0 2 ; copy statistics: wa w0 x2+m3 ; bytes:= 2 + lastaddr.curr buf ws w0 x2+m2 ; - firstaddr.curr buf; la w0 g50 ; make bytes even; sl w0 p50 ; if bytes < length of statistics jl. i2. ; jl x3+0 ; then no room return; i2 : al w3 x3+2 ; link:= link + 2; rs. w3 i0. ; save link; rs. w0 i1. ; save bytes; al w1 x1+p40 ; first:= addr of statistics.curr rec; rs. w1 i6. ; wa w1 0 ; al w1 x1-2 ; rs. w1 i7. ; al. w1 i5. ; jd 1<11+84 ; se w0 0 ; if result <> 0 jl. (i0.) ; then return; c. link + 2; rl w2 b19 ; al w1 x2+p40 ; i:= addr of statistics.curr rec; al w3 x1+p50 ; al w0 0 ; repeat i3 : rs w0 x1+0 ; curr receiver(i):= 0; al w1 x1+2 ; i:= i + 2 se w1 x3+0 ; jl. i3. ; until i = top of statistics; al w0 -1 ; entry:= 1st error segment.curr rec; al w3 x2+p46 ; repeat i4 : rs w0 x3+0 ; segment no.entry:= -1; al w3 x3+6 ; entry:= entry + 1 se w3 x2+p46+q2*6; jl. i4. ; until entry = top entry; rl. w3 i1. ; ls w3 -1 ; words:= bytes / 2; am. (i0.) ; jl 2 ; return; c. link + 4; ; variables i0 : 0 ; saved link i1 : 0 ; saved bytes i5: 2<1+1 ; function i6: 0 ; first i7: 0 ; last 0 ; relative e. z. \f ; pej 30.09.77 disc driver, initialize disc ; procedure initialize disc ; --------------------------------------------------------------- ; ; the procedure performs: ; - sets no of segments per cylinder and displacement of sector ; zero on odd cylinders and the disctype in the driver process ; description from information supplied in curr buf. ; - sets state.curr receiver to ready indicating that define disc ; should not be executed. ; - sets initdisc.curr receiver = 1. ; ; registers: call exit ; w0 destroyed ; w1 curr receiver unchanged ; w2 curr buf unchanged ; w3 link destroyed ; ; entry : j6 ; ; return : link+0 b. i0 w. j6 : rs. w3 i0. ; initialize disc: rl w0 x2+m2 ; wm w0 x1+p6 ; no of segments per cyl.curr rec:= rs w0 x1+p8 ; no of heads.curr buf rl w0 x2+m3 ; * no of segments per track.curr rec; rs w0 x1+p9 ; displacement.curr rec:= disp.curr buf; rl w0 x2+m4 ; disctype.curr receiver:= rs w0 x1+p5 ; disctype.curr buf; al w0 2 ; rs w0 x1+p12 ; state.curr receiver:= ready; al w0 1 ; hs w0 x1+p14 ; initdisc.curr receiver:= 1; jl. (i0.) ; return; ; variables i0 : 0 ; saved link e. \f ; pej 19.09.77 disc driver, setup channelprogram and start ; procedure setup channel program and start(kind,result); ; --------------------------------------------------------------- ; kind : 0 : setup channel pg according to curr buf. ; q39: define disc, setup read. (has no connection to ; q39+2: power rest., setup sense. the commands set regretted and continue ) ; result: result from procedure start i/o. ; ; the procedure performs: ; - sets up a channelprogram according to either the contents ; of curr buf, a channel program for reading addr mark at ; define disc or a channel program for sensing the disc at ; power restart. ; ; please note that if a channelprogram for reading or writing ; is set up according to curr buf, and no of segments.curr buf ; equals zero then firstaddr.curr buf is not used in the ; transfer command as procedure update buf on error may have ; incremented firstaddr.curr buf beyond lastaddr.curr buf. ; instead, to avoid result 3 from start i/o, the transfer ; command will contain a first address pointing into drivers ; process description. ; - calls procedure start i/o to start the transfer. the device ; is reset if initdisc.curr receiver <>0, and initdisc:= 0. ; - sets segment units.curr receiver at read or write to ; bytes-chars per segment. ; - zeroizes remaining bytes, curr status, event status, and ; technical status in the two statusareas. ; - zeroizes setmode param.curr receiver if setmode is not used ; (read, write, clean, position). ; - continues at waitnext in driver proc if the device is started ; or, if not, returns with a result (see proc start i/o). ; ; registers: call exit ; w0 result ; w1 kind channel pg start ; w2 0 or buf ; w3 link device address ; ; entry : j0 ; ; return : waitnext if ok ; link+0 if error b. c74, i110, l1, n10 w. \f ; pej 19.09.77 disc driver, setup channelprogram and start j0 : ; setup channel program and start: rs. w3 i0. ; save link; ; initialize according to most frequently used channel pg rl. w0 i4. ; command.mode.channel pg:= noop; rs. w0 c1. ; c. do not use strobe-offset; rl. w0 i5. ; command.first stop.channel pg:= stop; rs. w0 c5. ; c. not read after write; al. w0 c2. ; rs. w0 i1. ; startaddr:= first seek.channel pg; rl w2 b18 ; sn w1 0 ; if kind = 0 bz w1 x2+m0 ; then kind:= operation.curr buf; la w1 g50 ; wm w1 g48 ; i:= (kind >> 1) << 1 * 3; dl. w0 x1+l0. ; command.first transfer.channel pg:= rs. w3 c3. ; operation table(i); am (b19) ; transfer state.curr receiver:= rs w0 p13 ; operation table(i + 2); rl. w0 x1+l1. ; rs. w0 i2. ; actionaddr:= operation table(i + 4); ; enter next action with w1 = curr receiver, w2 = curr buf i20: rl w1 b19 ; central action: w1:= curr receiver; rl w2 b18 ; w2:= curr buf; am. (i2.) ; actionaddr:= actionaddr + 1; al w3 1 ; rs. w3 i2. ; ba w3 x3 ; jl x3 ; goto actiontable(actionaddr); ; actiontable h. ; 0 1 2 3 4 5 6 7 8 9 10 i101: n7., n9. ; sense i102: n0., n2., n5., n8., n10. ; read i103: n0., n2., n6., n8., n10. ; write i104: n0., n3., n8.,n9. ; clean i105: n0., n8.,n9. ; position i106: n1., n4., n8.,n9. ; define disc i107: n7., n9. ; power rest. w. \f ; pej 19.09.77 disc driver, setup channelprogram and start ; action 0, calculate seekinformation (read,write,clean,pos.). n0 : rl w0 x2+m4 ; action 0: am (x2+m10) ; s:= first segment.curr buf wa w0 p3 ; + first segment.device.curr buf; ld w3 -100 ; rs w3 x1+p21 ; setmode param.curr receiver:= 0; wd w0 x1+p8 ; cyl:= s / segments per cyl.curr rec; ; r:= s mod segments per cyl.curr rec; wd w3 x1+p6 ; head:= r / segms per track.curr rec; ; sect:= r mod segms per track.curr r; sz w0 2.1 ; if cyl odd wa w2 x1+p9 ; then sect:= sl w2 (x1+p6) ; (sect + displacement.curr receiver) ws w2 x1+p6 ; mod segments per track.curr receiver; i25: ls w0 8 ; insert seekinformation: wa w3 0 ; c. w0=cyl,w1=curr,w2=sect,w3=head; rs w3 x1+p20 ; seek param(0).curr receiver:= ls w2 16 ; cyl << 8 + head; wa w2 x1+p7 ; seek param(2).curr receiver:= rs w2 x1+p20+2 ; sect < 16 + flags.curr receiver; jl. i20. ; goto central action; ; action 1, calculate transfer - and seekinformation (define disc) n1 : al w3 p22 ; action 1: al w0 q51 ; first addr.1st transfer.channel pg:= ds. w0 c34. ; addr mark.curr receiver; rl w0 x1+p10 ; charcount.1st transfer.ch pg:=chars; rl w3 x1+p11 ; cyl:= define disc cyl.curr receiver; rl w2 x1+p6 ; head:= define disc head.curr rec; al w2 x2-1 ; sect:= segms per track.curr rec - 1; jl. i25. ; goto insert seekinformation; ; action 2, calculate transferinformation (read,write). n2 : dl. w0 i10. ; action 2: ds w0 x1+p35+2 ; segment units.curr receiver:= bz w0 x2+m1 ; chars-bytes per data segment; so w0 q40 ; if transput mode.curr buf = 1 then jl. i30. ; begin c. addr mark mode; rl. w0 c3. ; lo. w0 i8. ; command.1st transfer.channel pg:= rs. w0 c3. ; command.1st transfer.channel pg rl w0 x1+p13 ; +modif; ls w0 -1 ; transfer state.curr receiver:= rs w0 x1+p13 ; transfer state.curr receiver >> 1; dl. w0 i9. ; segment units.curr receiver:= ds w0 x1+p35+2 ; chars-bytes per addr mark; ; end; i30 : bz w0 x2+m5 ; wm w0 x1+p35+2 ; charcount.1st transfer.channel pg:= rs. w0 c34. ; chars * no of segments.curr buf; rl w1 x2+m2 ; firstaddr.1st transfer.channel pg:= rs. w1 c32. ; firstaddr.curr buf; se w0 0 ; if charcount.1st transfer.ch pg=0 then jl. i20. ; begin c. see procedure description; rl. w0 c3. ; lo. w0 i11. ; addrcode.1st transfer.channel pg:= rs. w0 c3. ; drivers process; al w0 p20 ; firstaddr.1st transfer.channel pg:= rs. w0 c32. ; rel of seek param; jl. i20. ; end; ; goto central action; ; action 3, insert dummy transfer information (clean track). n3 : dl. w1 c24. ; action 3: ds. w1 c34. ; parameters.1st transfer.channel pg:= ; parameters.1st seek.channel pg; ; c. because of checking in start i-o; jl. i20. ; goto central action; ; action 4, test if strobe-offset used (define disc). n4 : bz w3 x1+p15 ; action 4: ; retryinf:= retryinf.curr receiver; jl. i35. ; goto test mode; ; action 5, test if strobe-offset used (read). n5 : bz w3 x2+m6 ; action 5: retryinf:= retryinf.curr buf; ; test mode: c. ac3 = retryinf; i35 : sh w3 2.111 ; if retryinf(0:20) = 0 jl. i20. ; then goto central action; rl. w0 i6. ; rs. w0 c1. ; command.mode.channel pg:= setmode; ls w3 -3 ; rl. w2 i3. ; la w2 6 ; i:= modeindex.retryinf; ls w3 -5 ; i1:= offset index.retryinf; al w3 x3-1 ; bz. w0 x3+q20. ; ba. w0 x2+q21. ; setmode param.curr receiver:= rs w0 x1+p21 ; modetable(i-1)+ offsettable(i1); jl. i20. ; goto central action; ; action 6, test if read after write (write). n6 : bz w3 x2+m1 ; action 6: so w3 q43 ; if -, read after write.mode.curr buf jl. i20. ; then goto central action; rl w0 x1+p13 ; ls w0 -2 ; transfer state.curr receiver:= rs w0 x1+p13 ; transfer state.curr receiver >> 2; rl. w0 i4. ; rs. w0 c5. ; command.1st stop.channel pg:= noop; rl. w0 i7. ; command:= read with no transfer; sz w3 q40 ; if transput mode.curr buf = 1 rl. w0 i7. ;* then command:= command + modif; rs. w0 c7. ; command.2nd transfer.channel pg:= ; command; dl. w0 c34. ; parameters.2nd transfer.channel pg:= ds. w0 c74. ; parameters.1st transfer.channel pg; se w0 0 ; if charcount.2nd transfer.ch pg=0 then jl. j37. ; rl. w0 c7. ; addrcode.2nd transfer.channel pg:= lo. w0 i11. ; drivers process; rs. w0 c7. ; c. see action 2; i37 : bz w0 x2+m6 ; al w3 0 ; c. test if write is to be skipped; sz w0 2.111 ; if readtries.retryinf.curr buf <> 0 rs. w3 c34. ; then charcount.1st transfer.channel pg jl. i20. ; := 0; ; goto central action; ; action 7, determine startaddress (sense,power restart). n7 : bz w0 x1+p14 ; action 7: al. w3 c4. ; startaddr:= 1st sense.channel pg; se w0 0 ; if initdisc.curr receiver <> 0 al. w3 c3. ; then startaddr := rs. w3 i1. ; 1st transfer.channel pg; c. init; jl. i20. ; goto central action; ; action 8, determine startaddr (read,write,clean,pos,define). n8 : bz w0 x1+p14 ; action 8: al. w3 c0. ; se w0 0 ; if initdisc.curr receiver <> 0 rs. w3 i1. ; then startaddr:= init.channel pg; jl. i20. ; goto central action; ; action 9, perform start with buf = 0 (all except read,write) n9 : al w2 0 ; action 9: buf:= 0; jl. i40. ; goto start; ; action 10, perform start with buf = curr buf: n10 : ; action 10: c. buf = curr buf; ; call start i/o to start the transfer. w1,w2 = curr rec.,buf. i40 : ld w0 -100 ; start: ds w0 x1+p16+4 ; zeroize rembytes, curr status, rs w0 x1+p16+6 ; event status, technical status rs w0 x1+p16+20 ; in statusarea1.curr receiver ds w0 x1+p18+4 ; and statusarea2.curr receiver; rs w0 x1+p18+6 ; rs w0 x1+p18+20 ; hs w0 x1+p14 ; initdisc.curr receiver:= 0; al w0 1<2+1 ; + std exit + start channel pg; rl w3 x1+a235 ; device addr:= device addr.curr rec; rl. w1 i1. ; jd 1<11+100; start i/o(func,startad,buf,devicead); jl. (i0.) ; return; ; pej 19.09.77 disc driver, setup channelprogram and start ; variables i0 : 0 ; saved link i1 : 0 ; start addr, in channel pg i2 : 0 ; action addr, index to actiontable i3 : 2.11111 ; for masking out offsetindex.retryinf i4 : 4095 ; channel pg command = noop i5 : 15<8 ; = stop i6 : 4<12+2<8+1 ; = setmode i7 : 4095 ;* = read, no transfer i8 : 1 ; modifier for addr mark (read,write) q50 ; bytes per addr mark i9 : q51 ; segment unit: +0: chars per addr mark q52 ; bytes per data segm i10 : q53 ; segment unit: +0: chars per data segm i11 : 4<12 ; addrcode = drivers process ; operation table. ; the table contains: +0: command for 1st transfer.channel pg ; +2: transfer state ; +4: action table base ; a row in the table is indexed by: (operation>1)<1*3 ; addrcode+command+modif, state, actionbase i100: 0<12 + 6<8 + 0,l0:1<20,l1:i101-1 ; + 0: sense 0<12 + 1<8 + 0 , 1<17 , i102-1 ; + 6: read 0<12 + 3<8 + 0 , 1<15 , i103-1 ; +12: write 4<12 + 3<8 + 3 , 1<18 , i104-1 ; +18: clean track 4095 , 1<19 , i105-1 ; +24: position 4<12 + 1<8 + 1 , 1<22 , i106-1 ; +30: define disc 0<12 + 6<8 + 0 , 1<21 , i107-1 ; +36: power restart ; 1 read ; 0 data ; 1 addr mark ; 3 write ; 0 data ; 1 addr mark ; 3 clean ; 6 init ; 0 data area in senders process ; 4 data area in drivers process descr \f ; pej 19.09.77 disc driver, channel program ; c h a n n e l p r o g r a m ; addrcode command params ; init after error c0 : 6<8 ; init irrel init 0 ; irrel 0 ; irrel ; normal starting point c2 : 4<12+ 2<8 ; 1st seek device seek c22 : p20 ; paramaddr c24 : 6 ; charcount c1 : 4<12+ 2<8+1 ; mode device setmode p21 ; paramaddr 3 ; charcount c3 : 0 ; 1st transfer c32 : 0 ; c34 : 0 ; c4 : 4<12+ 0<8 ; 1st sense device sense p16 ; statusarea1 33 ; max charcount ; stop unless read after write c5 : 15<8 ; 1st stop irrel stop 0 ; irrel 40000 ; timer, 0.1 ms ; checkread c6 : 4<12+ 2<8 ; 2nd seek device seek p20 ; paramaddr 6 ; charcount c7 : 0 ; 2nd transfer c72 : 0 ; c74 : 0 ; c8 : 4<12+ 0<8 ; 2nd sense device sense p18 ; statusarea2 33 ; max charcount ; stop c9 : 15<8 ; 2nd stop irrel stop 0 ; irrel 40000 ; timer, 0.1 ms e. \f ; pej 22.09.77 disc driver, process next message ; p r o c e s s n e x t m e s s a g e ; --------------------------------------------------------------- ; this routine is entered when the next message is to be proces- ; sed by the disc driver. the routine is entered either from link ; message routine (driver able to process a received message ; immediately) or when an answer to a processed message has been ; delivered and more messages are queued to the driver. curr buf ; contains addr of buffer to be processed. ; check if message is get statistics message ; process next message: j50 : al w0 0 ; c. w1 = curr receiver, w2 = curr buf; hs w0 x1+p15 ; retryinf.curr receiver:= 0; bz w0 x2+m0 ; c. q1 ; if statistics wanted se w0 q36 ; and operation.curr buf = get stat then jl. j52. ; begin jl. w3 j5. ; copy statistics(result,words); jl. j90. ; if no room then goto deliv. blockl; jl. j102. ; if -, ok then goto status/segms 0; jl. j94. ; goto deliver words wanted; z. ; end; ; check if message is initialize message j52 : se w0 q31 ; if operation.curr buf = init then jl. j53. ; begin jl. w3 j6. ; initialize disc; jl. j101. ; goto deliver size zero; ; end; ; check if message is set regretted j53 : se w0 q39 ; if operation.curr buf = set regretted then jl. j55. ; begin al w0 3 ; set regretted.curr receiver = 3 rs w0 x1+a56 ; deliver result 1 al w0 0 ; rs w0 g20 ; deliver status 0 jl g7 ; end \f ; pej 22.09.77 disc driver, start device ; s t a r t d e v i c e ; --------------------------------------------------------------- ; this routine is executed to start the device and is entered ; from process next message routine or when an operation is to ; be repeated. the disc is started according to the contents of ; curr buffer. ; ; if the disc is not yet defined (state.curr receiver <> ready) ; then a special transfer is activated to check number of heads ; and displacement of sector zero on odd cylinders. curr buf is ; left in the head of the queue and will be processed when the ; disc has been defined. regretted.curr receiver will be odd ; during define disc so as to avoid a start (this might happen if ; curr buf is regretted and the queue turns empty). ; ; continuation takes place at waitnext in driverproc. ; set up channel program for contents of curr buf j55 : rl w1 b19 ; start: rl w0 x1+p12 ; se w0 2 ; if state.curr receiver = ready then jl. j57. ; begin c. q1 ; if statistics wanted am (x1+p40) ; al w0 1 ; then no of transfers.curr rec:= rs w0 x1+p40 ; no of transfers.curr rec + 1; z. ; al w1 0 ; kind:= 0; c. use curr buf; jl. w3 j0. ; setup channel pg and start(kind); se w0 3 ; if result <> 3 jl. j101. ; then goto deliver size zero jl. j99. ; else goto deliver unintilligible; ; end; ; setup channel program for define disc j57 : se w0 0 ; if state.curr rec = after interv then jl. j59. ; begin rs w0 x1+p10 ; define disc cyl.curr receiver:= 0; rs w0 x1+p11 ; define disc head.curr receiver:= 0; hs w0 x1+p15 ; retryinformation.curr receiver:= 0; al w0 1 ; state.curr receiver:= defining disc; rs w0 x1+p12 ; regretted.curr receiver:= 1; rs w0 x1+a56 ; disctype.curr receiver:= 1; rs w0 x1+p5 ; initdisc.curr receiver:= 1; hs w0 x1+p14 ; end; j59 : al w1 q39 ; jl. w3 j0. ; setup channel pg and start(kind); \f ; pej 26.09.77 disc driver, interrupt received ; i n t e r r u p t r e c e i v e d ; --------------------------------------------------------------- ; ; this routine is entered when driver proc receives an interrupt ; operation for a disc driver. the i/o result stored in the ; device description indicates the event leading to generation of ; the interrupt operation: ; ; i/o result 0: normal termination, interrupt from device. ; 1: bus reject, busy , device not started. ; 2: bustimeout, discon, - - - ; 3: software timeout , software generated. ; 4: abnormal terminat., interrupt from device. ; 5: wait pg. terminat., - - - ; 6: power restart , software generated. ; form the compoundstatus from i/o result and all statuswords ; (curr status, event status) generated by the device. c34 : rl w3 b19 ; interrupt received: rl w0 x3+a230 ; if channel pg count.std status = 0 sn w0 0 ; then am p16+6-a233; curr-event:= curr-event.statusarea1 dl w1 x3+a233 ; else curr-event:=curr-event.stdstatus; lo w0 x3+p16+4 ; curr:= curr or curr.statusarea1; lo w1 x3+p16+6 ; event:= event or event.statusarea1; rl w2 x3+p16+20 ; tech:= techn status.statusarea1; lo w0 x3+p18+4 ; curr:= curr or curr.statusarea2; lo w1 x3+p18+6 ; event:= event or event.statusarea2; lo w2 x3+p18+20 ; tech:= tech or tech.statusarea2; ds w1 x3+p31+2 ; curr-event.curr rec:= curr-event; rs w2 x3+p33 ; technical status.curr rec:= tech; jl. w3 j8. ; compoundstatus(curr,event,compound); rs w0 x1+p34 ; compound status.curr rec:= compound; ; check if compound status is ok with respect to actual transfer. rl w3 x1+p13 ; ls w3 -1 ; i:= transfer state.curr rec >> 1; ns. w3 3 ; sh:= no of shifts to normalize i; ac w3 ; -sh ; ls w3 2 ; sh:= sh * 4; rl w2 b18 ; c. w1 = curr rec, w2 = curr buf; sz. w0 (x3+i20.) ; if compound and table(sh) <> 0 jl. j125. ; then goto error jl. (x3+i21.) ; else goto table(sh+2); ; table to determine if transfer was successful. an entry corre- ; sponds to a transfer state and contains: ; +0: mask which anded to compound status must give zero. ; +2: addr where to continue. ; mask addr transfer state i20 : -1 , i21 : j125 ; bit 0, idle (will always go to error) i23 , j85 ; 1, define disc i25 , j87 ; 2, power restart i23 , j75 ; 3, sense i23 , j75 ; 4, position i24 , j75 ; 5, clean track i23 , j77 ; 6, read data i23 , j77 ; 7, read addr mark i24 , j77 ; 8, write data i24 , j77 ; 9, write addr mark i24 , j77 ; 10, read after write data i24 , j77 ; 11, read after write addr mark ; masks, normal term (bit 19) not checked. must be 1. i23 = 8.77617757 ; input ok, bits not checked: 8,9,10 ; (write protect, high density, mode) i24 = 8.77737757 ; output ok, bits not checked: 9 ; (high density) i25 = 8.37617757 ; power ok, bits not checked: 0,8,9,10 ; (intervention, write protect, high ; density, mode) \f ; pej 26.09.77 disc driver, successful transfer ; s u c c e s s f u l t r a n s f e r ; --------------------------------------------------------------- ; these routines are entered when a transfer is regarded success- ; ful. w1 = curr receiver, w2 = curr buf. ; c o n t r o l s u c c e s s f u l j75 : rl w0 x1+a56 ; control ok: se w0 0 ; if regretted.curr receiver jl. j110. ; then goto examine queue; c. q1 ; if statistics wanted bz w0 x2+m6 ; se w0 0 ; and retryinf.curr buf <> 0 jl. w3 j17. ; then update on corrected error; z. ; jl. j101. ; goto deliver size zero; ; t r a n s p u t s u c c e s s f u l j77 : al w0 0 ; transput ok: sn w0 (x1+p16+2) ; if rembytes.statusarea1.curr rec <> 0 se w0 (x1+p18+2) ; or rembytes.statusarea2.curr rec <> 0 jl. j125. ; then goto error; al w3 1 ; rl w0 x1+p21 ; if setmode param.curr receiver <> 0 se w0 0 ; then initdisc.curr receiver:= 1; hs w3 x1+p14 ; c. force heads back to nominal pos; c. q1 ; if statistics wanted bz w0 x2+m6 ; se w0 0 ; and retryinf.curr buf <> 0 jl. w3 j16. ; then update on corrected error; z. ; bz w0 x2+m5 ; segments:= no of segments.curr buf; jl. w3 j11. ; update buf(segments,bytes); ; check if more segments are to be transferred at transput j80 : bz w0 x2+m9 ; sn w0 0 ; if remaining segms.curr buf = 0 jl. j103. ; then goto deliver wanted; al w0 0 ; c. jumps always at direct disc msg; hs w0 x2+m6 ; retryinformation.curr buf:= 0; rl w0 x2+m7 ; first segment.curr buf:= rs w0 x2+m4 ; next segment.curr buf; rl w1 x2+m10 ; proc:= device.curr buf; jl. w3 j4. ; prepare consecutive segms(proc); jl. j55. ; goto start; ; d e f i n e d i s c s u c c e s s f u l j85 : rl w0 x1+p16+2 ; define disc ok: se w0 0 ; if rembytes.statusarea1.curr rec <> 0 jl. j125. ; then goto error; rl w0 x1+p34 ; type:= ls w0 -14 ; hi dens.compound status.curr rec; la w0 g3 ; c. 0=dsm801, 1=dsm802; rs w0 x1+p5 ; disctype.curr receiver:= type; al w0 1 ; initdisc.curr receiver:= 1; hs w0 x1+p14 ; c. ensures nominal head position; wa w0 x1+p11 ; define disc head.curr receiver:= rs w0 x1+p11 ; define disc head.curr receiver + 1; al w3 8.377 ; c. test if last addr mark on cylind.; sz w3 (x1+p22+4) ; if nexthead.addrmark.curr rec <> 0 jl. j55. ; then goto start; wm w0 x1+p6 ; segments per cyl.curr receiver:= rs w0 x1+p8 ; define disc head.curr receiver rl w0 x1+p22+6 ; * segments per track.curr receiver; ls w0 -16 ; displacement.curr receiver:= rs w0 x1+p9 ; next sector.addrmark.curr receiver; al w0 2 ; c. sector 0 on odd cylinders; rs w0 x1+p12 ; state.curr receiver:= ready; jl. j110. ; goto examine queue; ; p o w e r r e s t a r t s u c c e s s f u l j87 : rl w0 x1+p12 ; power restart ok: sn w0 1 ; if state.curr rec = defining disc al w0 0 ; then state.curr rec:= after interven; rs w0 x1+p12 ; c. resume define disc from beginning; jl. j110. ; goto examine queue; \f ; pej 26.09.77 disc driver, deliver answer ; d e l i v e r a n s w e r r o u t i n e ; --------------------------------------------------------------- ; these routines are entered to deliver the answer to a processed ; message. upon delivering the answer it is examined if more ; messages are queued to the driver. if so, next message is pro- ; cessed, and if not, idle state is entered and a wait program ; is started. p35+0 and p35+2 contains bytes/chars per segment. ; result 1, status blocklength, bytes 0. j90 : dl. w1 i27. ; deliver blocklength: al w3 0 ; result:= 1; status:= bit4; jl. j106. ; segments:= 0; goto deliver; ; result 1, status discerror, bytes = what was transferred. j92 : dl. w1 i28. ; deliver discerror: result:= 1; rl w2 b18 ; status:= bit11; jl. j97. ; goto deliver transferred; ; result 1, status 0, words contained in ac3 j94 : al w0 2 ; deliver words wanted: c. w2=curr rec; al w1 3 ; bytes:= 2; chars:= 3; ds w1 x2+p35+2 ; c. w3 = words == segments; jl. j104. ; goto deliver ok; ; result 4, status 0, bytes=what was transferred j95 : al w0 4 ; deliver spurious: al w1 0 ; result:= 4; status:= 0; rl w2 b18 ; w2:= curr buf; jl. j97. ; goto deliver transferred; ; result, status corresp. to compound, bytes=what was transferred j96 : ; deliver error: jl. w3 j10. ; set result and status(result,status); j97 : bz w3 x2+m8 ; deliver transferred: c. w2 = curr buf; bs w3 x2+m9 ; segments:= segments wanted.curr buf bz w2 x2+m0 ; - remaining segments.curr buf; so w2 2.1 ; if operation.curr buf = control al w3 0 ; then segments:= 0; jl. j106. ; goto deliver; ; result 1, 2, 3, status 0, bytes 0. j99 : am 3-2 ; deliver unintelligible: j100: am 2-1 ; deliver rejected : j101: al w0 1 ; deliver size zero : j102: al w1 0 ; deliver status and segms zero: al w3 0 ; status:= 0; segments:= 0; jl. j106. ; goto deliver; ; result 1, status 0, bytes = what was wanted. j103: ; deliver wanted; c. w2 = curr buf; bz w3 x2+m8 ; segment:= segments wanted.curr buf; j104: dl. w1 i29. ; deliver ok: result:= 1; status:= 0; ; deliver the answer, w0=result, w1=status, w3=segments. j106: rs w1 g20 ; deliver: rl w1 b19 ; status.i/o answer:= status; rs w3 g21 ; wm w3 x1+p35 ; rx w3 g21 ; bytes.i/o answer:= segments * bytes; wm w3 x1+p35+2 ; rs w3 g22 ; chars.i/o answer:= segments * chars; rl w2 x1+a244 ; file.i/o answer:= i/o result.curr rec; rl w3 x1+p31 ; block.i/o answer:= ds w3 g24 ; curr status.curr receiver; rl w2 x1+p31+2 ; curr buf(18:19):= event stat.curr rec; rl w3 x1+p33 ; curr buf(20:21):= techn stat.curr rec; am (b18) ; ds w3 m8 ; rs w0 x1+p35 ; save result; ; w0= result; b18 =buffer rl w2 b18 ; w2:=buffer rl w1 x2+a141 ; w1:= receiver.buf sh w1 0 ; ac w1 x1 ; w1:= absolute value of receiver sh w1 6 ; jl. j107. ; rl w3 x1+a10 ; w3:= kind(rec); se w3 4 ; if area process then jl. j107. ; begin rl w3 g22 ; sn w0 1 ; if bytes<>0 then sn w3 0 ; begin jl. j107. ; bz w3 x2+8 ; if operation = write then se w3 q33 ; nooftiw:=nooftiw+1 am a412-a411 ; else al w3 x1+a411 ; nooftir:=nooftir+1; rl w2 x3 ; al w2 x2+1 ; rs w2 x3 ; j107: jl w3 g19 ; deliver result(result); ; clean the driver in case of abnormal result. rl w0 x1+p35 ; sl w0 4 ; if result > 3 jl. w3 j14. ; then clean(result); ; examine if more messages are queued. j110: al w0 0 ; examine queue: c. w1=curr receiver; rs w0 x1+a56 ; regretted.curr receiver:= 0; jl w3 g64 ; examine queue(queue empty); jl. j112. ; if not queue empty jl. j50. ; then goto process next message; ; queue is empty, start a wait program. continue at waitnext. j112: rl w0 g49 ; start wait: c. w1 = curr receiver; rs w0 x1+p13 ; transfer state.curr receiver:= idle; rl w3 x1+a235 ; dev:= device descr.curr rec; al w0 3<2+1 ; start control + std exit; ld w2 -100 ; buf:= 0; timeout:= eternal; jd 1<11+100 ; start i/o(func,timeout,buf,dev); \f ; pej 28.09.77 disc driver, error routine ; e r r o r r o u t i n e ; --------------------------------------------------------------- ; this routine is entered when an interrupt not corresponding to ; a successful transfer has been received. the treatment of the ; error takes place by running through a number of actions, each ; action being executed as a function of the kind of error and ; the transfer state of the driver. ; ; if possible, the transfer is repeated. if the routine is entered ; due to power restart (or disc power down = possible power break ; in progress) a loop is entered to check if power comes up again, ; leaving a possible message being currently processed in the head ; of the queue. ; determine the kind of error j125: al w0 1 ; error: c. w1 = curr receiver; hs w0 x1+p14 ; initdisc.curr receiver:= 1; jl w2 (b31) ; call errorlog jl. w3 j9. ; set errorkind(kind); wa w0 x1+p13 ; actionkey:= rs w0 x1+p36 ; errorkind + transfer state.curr rec; al w0 -4 ; rs w0 x1+p37 ; actionindex:= -4; ; determine if next action is to be executed j130: rl w1 b19 ; central action: w1:= curr receiver; j132: am (x1+p37) ; skip: al w3 4 ; rs w3 x1+p37 ; action index:= actionindex + 4; rl w0 x1+p36 ; la. w0 x3+i35. ; i:= table(actionindex) and actionkey; bz w2 1 ; sz w0 (g51) ; if i(0:11) = 0 sn w2 0 ; or i(12:23) = 0 jl. j132. ; then goto skip; rl w2 b18 ; goto table(actionindex + 2); jl. (x3+i36.) ; c. with w1 = curr rec, w2 = curr buf; b. n25, o16 w. ; block containing error actions ; table guiding the execution of actions. each entry contains: ; +0: transfer states < 12 + errorkinds ; the action is executed if the actionkey (see above) anded ; to this word gives nonzero in both bytes. ; +2: action address. ; --------------------------------------------------------------- ; ----transfer states---- --error kinds-- actions ; read ; write d a i p p t w d a o ; read aft. f n o o i r a d t ; i d p s p c d a d a d a o t t w w m t d h ; d e o e o l a d a d a d v e e e e p a r e ; l f w n s e t d t d t d e d r r r o r r ; e i e s a a r a r a r r v u o e e ; n r e n r o r d t t r r ; --------------------------------------------------------------- ; action 1 vacant ; action 2 vacant i35: 2. 1 1 1 1 0 0 <12+2. 1 1 1 1 1 1 1 1 1 1 , i36: n3 2. 1 1 <12+2. 1 1 1 1 1 1 1 1 1 1 , n4 2. 1 1 1 0 0 0 0 0 0 <12+2. 1 0 1 1 1 , n5 2. 1 1 1 1 1 1 1 1 1 <12+2. 1 0 1 1 1 , n6 2. 1 0 0 0 0 0 <12+2. 1 0 0 , n7 c. q1 2. 1 1 1 1 1 1 <12+2. 1 0 1 1 1 , o7 z. 2. 1 1 0 0 0 0 <12+2. 1 1 0 , n8 2. 1 1 0 0 0 0 <12+2. 1 0 0 0 0 , o8 2. 1 1 1 1 1 1 1 0 0 <12+2. 1 0 1 1 1 , n9 2. 1 1 <12+2. 1 0 1 1 1 , n10 2. 1 1 0 1 1 1 1 1 1 1 1 1 <12+2. 1 0 0 0 0 0 , n11 2. 1 1 1 1 1 1 1 1 1 1 1 1 <12+2. 1 0 0 0 0 0 0 , n12 2. 1 0 0 0 0 0 0 0 0 0 <12+2. 1 0 0 0 0 , n13 2. 1 0 0 0 0 0 0 0 0 0 <12+2. 1 1 1 1 1 1 1 1 1 1 , n14 2. 1 1 1 1 1 1 1 1 1 1 1 1 <12+2. 1 0 0 0 0 0 0 0 , n17 2. 1 0 0 1 1 1 1 <12+2. 1 0 0 0 , n16 2. 1 1 0 1 1 0 0 0 0 <12+2. 1 0 0 0 , o16 2. 1 0 0 0 0 0 0 0 0 0 0 0 <12+2. 1 1 1 1 1 1 1 1 1 1 , n17 2. 1 0 0 0 0 0 0 0 0 0 0 <12+2. 1 0 , n18 2. 1 0 0 0 0 0 0 0 0 0 0 <12+2. 1 1 1 1 1 1 1 1 1 1 , n19 2. 1 1 1 1 1 1 1 1 1 1 1 1 <12+2. 1 0 0 0 0 0 0 0 0 , n20 2. 1 1 1 1 1 1 1 1 1 1 1 1 <12+2. 1 0 0 0 0 0 0 0 0 0 , n21 2. 1 1 1 1 1 1 1 1 1 1 1 1 <12+2. 1 1 1 1 1 1 1 1 1 1 , n22 \f ; pej 28.09.77 disc driver, error routine ; action 3: update buf at error at read or simple write. ; tr.state: read data, read addr m, write data, write addr m ; err.kind: any n3 : al w2 x1+p16 ; area:= statusarea1.curr receiver; al. w3 j130. ; update buf on err(area,bytes,chars); jl. j12. ; goto central action; ; action 4: update buf at read after write error. ; tr.state: read after write data, read after write addr m. ; err.kind: any n4 : al w0 0 ; c. test if first transfer (write) ok; rs w0 x1+p38 ; write ok:= 0; c. see action 10; se w0 (x1+p16) ; if chan pg count.status1.curr rec = 0 se w0 (x1+p16+2) ; or rembytes.statusarea1.curr rec <> 0 jl. j130. ; then goto central action; c. not ok; dl w1 x1+p16+6 ; jl. w3 j8. ; compoundstatus(curr,event,compound); sz. w0 (i40.) ; if compound and output ok <> 0 jl. j130. ; then goto central action; c. not ok; rs w1 x1+p38 ; write ok:= <> 0; c. see action 10; al w2 x1+p18 ; area:= statusarea2.curr receiver; al. w3 j130. ; update buf on err(area,bytes,chars); jl. j12. ; goto central action; ; action 5: repeatable error, test if control message regretted. ; tr.state: sense, position, clean track ; err.kind: timeout, data error, addr mark error, other error n5 : al w0 0 ; sn w0 (x1+a56) ; if regretted.curr receiver = 0 jl. j130. ; then goto central action jl. j110. ; else goto examine queue; ; action 6: repeatable error, test if transfer may be repeated. ; tr.state: any, except idle, define disc, power restart ; err.kind: timeout, data error, addr mark error, other error n6 : ; c. q1 ; if statistics wanted then am (x1+p41) ; begin al w3 1 ; count:= not successful.curr rec + 1; bz w0 x2+m6 ; sn w0 0 ; if retryinf.curr buf = 0 then rs w3 x1+p41 ; not successful.curr rec:= count; z. ; end; bz w0 x2+m1 ; sz w0 q41 ; if -, error recovery.mode.curr buf jl. j96. ; then goto deliver error jl. j130. ; else goto central action; ; action 7: data error at read, try to repair by ecc. ; tr.state: read data ; err.kind: data error n7 : jl. w3 j15. ; correct data; jl. j130. ; if not corrected then goto cent act.; al w0 1 ; segments:= 1; rl w1 b19 ; c. one segment, the last, corrected; rl w2 b18 ; jl. w3 j11. ; update buf(segments,bytes); c. q1 ; if statistics wanted then am (x1+p42) ; begin al w3 1 ; count:= ecc corrected.curr rec + 1; bz w0 x2+m6 ; sn w0 0 ; if retryinf.curr buf = 0 rs w3 x1+p42 ; then ecc corrected.curr rec:= count se w0 0 ; jl. w3 j16. ; else update on corrected error; z. ; end; al w0 0 ; if setmode param.curr rec = 0 sn w0 (x1+p21) ; then initdisc.curr rec:= 0; hs w0 x1+p14 ; c. init not necessary; hs w0 x2+m6 ; retryinf.curr buf:= 0; bz w0 x2+m5 ; c. check if entire transfer now ok; sn w0 0 ; if no of segments.curr buf = 0 jl. j80. ; then goto check if more jl. j55. ; else goto start; ; action 7a, update table of error segments ; tr.state : read data, read addr m, write data, write addr m, ; read after write data, read after write addr m ; err.kind : timeout, data error, addr mark error, other error o7 : c. q1 ; if statistics wanted then bz w0 x2+m6 ; begin se w0 0 ; if retryinf.curr buf <> 0 jl. j130. ; then goto central action; rl w3 x2+m4 ; c. already registrated; am (x2+m10) ; segment:= first segment.curr buf wa w3 p3 ; + first segment.device.curr buf; al w2 x1+p46 ; entry:= 1st error segm.curr rec; j141: sl w2 x1+p46+q2*6; while entry <> top entry do jl. j130. ; begin sh w0 (x2+0) ; if segment no.entry < 0 sn w3 (x2+0) ; or segment no.entry = segment jl. j143. ; then goto found; increase entry; al w2 x2+6 ; end; jl. j141. ; goto central action; c. table full; j143: rs w3 x2+0 ; found: am (b18) ; segment no.entry:= segment; ba w2 m0 ; i:= operation.curr buf; bz w1 x2+0 ; al w1 x1+1 ; entry(i):= entry(i) + 1; hs w1 x2+0 ; jl. j130. ; end; z. ; goto central action; ; action 8, data error or addr m error at read, use strobe-offset ; tr.state: read data, read addr mark ; err.kind: data error, addr mark error n8 : al w1 x2+m6 ; retryinf:= retryinf.curr buf; jl. w3 j13. ; update retryinformation(retryinf); jl. j96. ; if no more tries goto deliver error; jl. j147. ; jl. j145. ; if next offset magnitude used then jl. j147. ; begin c. may buf be requeued; j145: rl w2 b18 ; bz w0 x2+m1 ; sz w0 q42 ; if requeue.curr buf = no requeue jl. j92. ; then goto deliver discerror; jl w3 d5 ; c. remove and link the buf to q end; am (b19) ; remove(curr buf); al w1 a54 ; jl w3 d6 ; link(mess queue.curr rec,curr buf); rl w1 b19 ; goto examine queue; jl. j110. ; end; j147: al w0 2.10 ; c. initdisc may be skipped if data rl w1 b19 ; error as the correct segment was la w0 x1+p36 ; read; sn w0 0 ; if actionkey and -, addr mark error hs w0 x1+p14 ; then initdisc.curr rec:= 0; jl. j55. ; goto start; ; action 8a: timeout at read, simulate address mark error if ; timeout is possibly caused by use of strobe - ; offset (synchronization chars out of reach). ; tr.state : read data, read addr m ; err.kind : timeout o8: bz w3 x2+m6 ; sh w3 2.111 ; if retryinf.curr buf <> strobe.offset jl. j130. ; used then goto central action; la. w3 i45. ; c. force next offset magnitude; wa. w3 i44. ; retryinf.curr buf:= last modeindex < 8 hs w3 x2+m6 ; +offset.retryinf.curr buf + maxtries; rl w3 x1+p36 ; c. simulate addr mark error; al w3 x3-2.10000; action key.cur rec:= al w3 x3+2.10 ; action key.curr rec rs w3 x1+p36 ; -timeout + addr m error; rl. w3 i43. ; compound status.curr rec:= rs w3 x1+p34 ; data err + hard err + abnorm term; jl. n8. ; goto action 8; ; action 9: error at control, read, simple write. repeat transfer ; tr.state: sense, position, clean track, ; read data, read addr m, write data, write addr m ; err.kind: timeout, data error, addr mark error, other error n9 : al w1 x2+m6 ; retryinf:= retryinf.curr buf; jl. w3 j13. ; update retryinformation(retryinf); jl. j96. ; jl. j96. ; jl. j96. ; if tries <= 3 then goto start jl. j55. ; else goto deliver error; ; action 10: error at read after write, repeat transfer. ; tr.state : read after write data, read after write addr mark ; err.kind : timeout, data error, addr mark error, other error n10 : rl w0 x1+p38 ; c. see action 4 re. write ok; bz w3 x2+m6 ; r:= retryinformation.curr buf; c. w3; sn w0 0 ; if write ok then jl. j150. ; begin c. repeat 2nd transfer (read); al w3 x3+1 ; readtries.r:= readtries.r + 1; so w3 2.100 ; if readtries.r <= 3 then goto rep; jl. j151. ; end; j150: la. w3 i41. ; c. repeat 1st transfer (write); al w3 x3+2.1000 ; readtries.r:= 0; incr writetries.r; sz w3 2.100<3; if writetries.r > 3 jl. j96. ; then goto deliver error; j151: hs w3 x2+m6 ; rep: retryinformation.curr buf:= r; jl. j55. ; goto start; ; action 11: disc power down, enter power restart loop. ; tr.state : any, except power restart ; err.kind : power down n11 : am q14-q13; power down: n:= no of times to sense disc; ; action 12: power restart, enter power restart loop. ; tr.state : any ; err.kind : power restart n12 : al w3 q13 ; n:= no of times to sense disc; al w0 0 ; sn w0 (x1+p12) ; if state.curr rec = after intervent. jl. n15. ; then goto intervention; al w0 1 ; regretted.curr receiver:= 1; rs w0 x1+a56 ; c. to prevent start if buf arrives; jl. j154. ; goto power sense; ; action 13: sense disc in power restart loop. ; tr.state : power restart ; err.kind : timeout n13 : bz w3 x1+p15 ; n:= retryinformation.curr receiver; al w3 x3-1 ; n:= n - 1; sh w3 -1 ; if n < 0 then goto intervention; jl. n15. ; power sense: c. w3 = n; j154: hs w3 x1+p15 ; retryinformation.curr receiver:= n; al w1 q39+2 ; kind:= power restart; jl. w3 j0. ; setup channelprogram and start(kind); ; c. cont. at waitnext in driverproc; ; action 14: delay before next sense in power restart loop. ; tr.state : power restart ; err.kind : any n14 : rl w3 x1+a235 ; dev:= device descr.curr rec; al w0 2<2+1 ; function:= start wait, std exit; rl. w1 i42. ; timer:= time between sense in loop; al w2 0 ; buf:= 0; jd 1<11+100 ; start i/o(function,timer,buf,dev); ; c. cont. at waitnext in driverproc; ; action 15: intervention. ; tr.state : any ; err.kind : intervention n15 : al w0 5 ; intervention: result:= 5; c. unknown; jl. w3 j14. ; clean(result); jl (b20) ; goto waitnext; c. in driver proc; ; action 16: write protect at output. ; tr.state : clean track, all write states ; err.kind : write protect n16 : jl. j100. ; goto deliver rejected; ; action 16a: write protect at control, read. repeat transfer. ; tr.state : sense, position, read data, read a m ; err.kind : write protect o16 : al w1 x2+m6 ; retryinf:= retryinf.curr buf; jl. w3 j13. ; update retryinformation(retryinf); jl. j95. ; jl. j95. ; jl. j95. ; if tries <= 3 then goto start jl. j55. ; else goto deliver spurious; ; action 17: wait program terminated not because of intervention. ; tr.state : idle ; err.kind : any n17: jl. n11. ; goto power down; ; action 18: addr mark error at define disc, use stobe-offset. ; tr.state : define disc ; err.kind : addr mark error n18 : al w1 x1+p15 ; retryinf:= retryinf.curr receiver; jl. w3 j13. ; update retryinformation(retryinf); jl. j160. ; if no more tries possible then jl. j55. ; jl. j55. ; jl. j55. ; begin c. try next even cylinder j160: rl w1 b19 ; am (x1+p10) ; al w0 2 ; define disc cyl.curr rec:= rs w0 x1+p10 ; define disc cyl.curr rec + 2; al w0 0 ; define disc head.curr rec:= 0; rs w0 x1+p11 ; retryinformation.curr rec:= 0; hs w0 x1+p15 ; end; jl. j55. ; goto start; ; action 19: error at define disc. repeat transfer. ; tr.state : define disc ; err.kind : any n19 : al w1 x1+p15 ; retryinf:= retryinf.curr receiver; jl. w3 j13. ; jl. j162. ; jl. j162. ; jl. j162. ; jl. j55. ; if tries <= 3 then goto start; j162: al w0 4 ; result:= 4; c. malfunction; jl. w3 j14. ; clean(result); al w0 0 ; rs w0 x1+p12 ; state.curr rec:= after intervention; jl (b20) ; goto waitnext; c. in driverproc; ; action 20: repeat transfer in data overrun loop ; tr.state : any ; err.kind : after data overrun n20 : al w0 0 ; rs w0 x1+a56 ; regretted.curr receiver:= 0; bz w3 x1+p15 ; n:= retryinf.curr receiver; al w3 x3+1 ; n:= n+1; sl w3 q15 ; if n > max no of retries jl. j96. ; then goto deliver error hs w3 x1+p15 ; else begin jl. j55. ; retryinf.curr receiver:= n; ; goto start; ; end; ; action 21: start wait in data overrun loop ; tr.state : any ; err.kind : data overrun n21 : bz w0 x2+m1 ; sz w0 q41 ; if -,error recovery.mode.curr buf jl. j96. ; then goto deliver error; al w0 1 ; regretted.curr receiver:= 1; rs w0 x1+a56 ; c. to prevent start if buf arrives rl w3 x1+a235 ; dev:= device descr.curr receiver; al w1 x3 ; timer:= (dev >> 5) << 9; ls w1 -5 ; c. (controller io no)*512; ls w1 9 ; c. to ensure diff. waiting periods for diff. devices al w0 2<2+1 ; function:= start wait, std exit; al w2 0 ; buf:= 0; jd 1<11+100 ; start io(function,timer,buf,dev); ; action 22: final action, acts as a stopper. ; tr.state : any ; err.kind : any n22 : al w0 4 ; result:= 4; c. malfunction; jl. w3 j14. ; clean(result); jl. j112. ; goto start wait; e. ; end of block containing error actions \f ; pej 04.10.77 disc driver, variables ; m o d e t a b l e ; each entry contains strobe and offset information corre- ; sponding to bit 16-19 in a setmode parameter. modeindex in ; retryinformation - 1 is an index to the table. q23 = 3 ; first mode index in next round q24 = 8 ; last modeindex h. ; strobe offset q20 : 2.0100<4 ; +0: late 2.1000<4 ; +1: early 2.0001<4 ; +2: negative 2.0010<4 ; +3: positive 2.0101<4 ; +4: late negative 2.0110<4 ; +5: late positive 2.1001<4 ; +6: early negative 2.1010<4 ; +7: early positive -1 ; +8: top of table ; o f f s e t t a b l e ; each entry contains offset magnitude corresponding to bit 20-23 ; in a setmode parameter. offset index in retryinformation is ; an index to the table. q21 : 8,15,1,3,6,10,13,2,4,5,7,9,11,12,14 ; +0 - +14 -1 ; +15: top entry w. ; variables 1 ; -2: result (1) i27 : 8.02000000 ; blocklength error: +0: status (bit 4) 1 ; -2: result (1) i28 : 8.00010000 ; discerror: +0: status (bit 11) 1 ; -2: result (1) i29 : 0 ; ok: +0: status(0) i40 : i24 ; mask for zeroes in compound at output i41 : 2.11111000 ; mask for zeroizing readtries.retryinf i42 : q10 ; time between sense in power rest. loop i43: 1<22+1<19+1<8 ; compound status: data or hard err,abnorm term i44: q24<8+3 ; last modeindex<8+maxtries(retry inf) i45: 2.000011111000 ; mask for zeroize modeindex or tries (retryinf) \f ; pej 26.09.77 disc driver, compound status ; procedure compoundstatus(curr status,event status,compound) ; --------------------------------------------------------------- ; ; the procedure performs: ; - creates a compound status word from curr status and event ; status and i/o result from device descr, so that: ; ; bit 0 intervention event status bit 0 ; 1 data error - - - 1 ; 2 (unused, = 0) ; 3 data overrun - - - 3 ; 4 hard error - - - 4 ; 5 position error - - - 5 ; 6 power low curr - - 0 ; 7 local - - - 1 ; 8 write protect - - - 8 ; 9 high density - - - 9 ; 10 mode - - - 10 ; 11 seek error - - - 5 ; 12 (unused, = 0) ; 13 power restart i/o result 6 ; 14 wait pg. terminated - - 5 ; 15 abnormal termination - - 4 ; 16 software timeout - - 3 ; 17 bustimeout, disconn. - - 2 ; 18 bus reject, busy - - 1 ; 19 normal termination - - 0 ; 20 bus com, error event status bit 20 ; 21 interrupt error - - - 21 ; 22 bustimeout - - - 22 ; 23 bus parity error - - - 23 ; ; registers: call exit ; wo curr status compound status ; w1 event status curr receiver ; w2 destroyed ; w3 link unchanged ; ; entry : j8 ; ; return : link+0 b. i1 w. j8 : ; compound status: rl w2 0 ; i:= curr status >> 6; ls w2 -6 ; c. bit(6:7):= bit(0:1), bit11:= bit5; lo w2 0 ; i:= i or curr status; la. w2 i0. ; i:= i and bit 6,7,8,9,10,11; la. w1 i1. ; mask out unused event status bits; lo w1 4 ; compound:= event status or i; c. w1; al w0 2.10000; i:= bit 19; am (b19) ; rl w2 a244 ; sh:= i-o result.curr receiver; ls w0 x2+0 ; i:= i shift sh; c. w0; lo w0 2 ; compound:= compound or i; c. w0; rl w1 b19 ; jl x3+0 ; ; variables i0 : 8.00770000 ; bit 6,7,8,9,10,11 i1 : 8.67000017 ; bit 0,1,3,4,5,20,21,22,23 e. \f ; pej 27.09.77 disc driver, set errorkind ; procedure set errorkind(errorkind) ; -------------------------------------------------------------- ; errorkind: bit 14: data overrun ; 15: after data overrun ; 16: intervention ; 17: power restart ; 18: power down (disc power) ; 19: time out ; 20: write protect ; 21: data error ; 22: addr mark error ; 23: other error ; ; the procedure performs: ; - updates tables of compound status and technical statusbits ; if statistics wanted. ; - sets the errorkind as a function of bits in compound status ; and bits in statuswords stored by controller. ; ; registers: call exit ; w0 errorkind ; w1 curr receiver unchanged ; w2 compound status ; w3 link destroyed ; ; entry : j9 ; ; return : link+0 b. i30 w. j9 : rs. w3 i10. ; set errorkind: save link; c. q1 ; if statistics wanted then rl w0 x1+p34 ; begin rl w2 x1+p33 ; i:= 0; al w3 x1+p47 ; repeat i26 : sl w0 0 ; if compound(i).curr rec = 1 jl. i27. ; al w1 1 ; then ba w1 x3+0 ; compound table(i).curr rec:= hs w1 x3+0 ; compound table(i).curr rec + 1; i27 : sl w2 0 ; if technical(i).curr rec = 1 jl. i28. ; al w1 1 ; then ba w1 x3+p48-p47; technical table(i).curr rec:= hs w1 x3+p48-p47; technical table(i).curr rec + 1; i28 : al w3 x3+1 ; ls w0 1 ; ls w2 1 ; i:= i + 1 sn w0 0 ; until compound(i+1:23) = 0 and se w2 0 ; technical(i+1:23) = 0; jl. i26. ; rl w1 b19 ; z. ; end; rl w2 x1+p34 ; ac2:= compound status.curr rec; so. w2 (i6.) ; if data overrun then jl. i29. ; begin sz w2 8.200 ; if timeout jl. i15. ; then goto after data overrun jl. i14. ; else goto data overrun; i29 : ; end; rl w3 x1+p16+6 ; event:= event.statusarea 1.curr rec; sz. w2 (i0.) ; if compound and mask1 = 0 jl. i24. ; so. w3 (i1.) ; and dataerr.event and harderr.event jl. i24. ; then goto data error; jl. i21. ; i24 : rl w0 x1+a233 ; event:= event.std status.curr rec; sz. w2 (i2.) ; if compound and mask2 = 0 jl. i25. ; rl w3 x1+a230 ; se w3 0 ; and chan pg count.std status.curr rec bz w3 x3-6+1 ; <> 0 ls w3 -8 ; and latest command executed = read sn w3 1 ; so. w0 (i3.) ; and harderr.event and pos err.event jl. i25. ; jl. i22. ; then goto addr mark error; i25 : sz w2 8.2000 ; if power restart.compound jl. i17. ; then goto power restart; sz. w2 (i4.) ; if powlow.compound or discon.compound jl. i18. ; then goto power low; sz w2 8.200 ; if timeout.compound jl. i19. ; then goto timeout; sz. w2 (i5.) ; if interv.compound or local.compound jl. i13. ; then goto check power up; sz. w2 (i7.) ; if write protect.compound jl. i20. ; then goto write protect jl. i23. ; else goto other error; i13: ; check power up: rl w0 b75 ; if power up not yet serviced se w0 0 ; by clockdriver jl. i18. ; then goto power down jl. i16. ; else goto intervention; i14 : am 512-256; data overrun : set kind bit 14 i15 : am 256-128; aft. data ov. : 15 i16 : am 128-64 ; intervention : 16 i17 : am 64-32 ; power restart : 17 i18 : am 32-16 ; power down : 18 i19 : am 16-8 ; time out : 19 i20 : am 8-4 ; write protect : 20 i21 : am 4-2 ; data error : 21 i22 : am 2-1 ; addr mark error: 22 i23 : al w0 1 ; other error : 23; jl. (i10.) ; return; ; variables i0 : 8.45613757 ; mask1, data error, mask for zeroes i1 : 8.22000000 ; bit 1,4 i2 : 8.44613377 ; mask2, addr mark err, mask for zeroes i3 : 8.03000000 ; bit 4,5 i4 : 8.00400100 ; bit 6,17 i5 : 8.40200000 ; bit 0, 7 i6 : 8.04000000 ; bit 3, data overrun i7 : 8.00100000 ; bit 8 i10 : 0 ; saved link e. \f ; pej 27.09.77 disc driver, set result and status ; procedure set result and status(result,status). ; -------------------------------------------------------------- ; result: 4 if bit 16 in compound status (software timeout) ; - - 18 - - - (bus reject, busy) ; - - 20 - - - (communication error) ; - - 21 - - - (interrupt error) ; - - 22 - - - (bustimeout) ; - - 23 - - - (bus parity error) ; if no bits are set in status. ; 1 if bits are set in status. ; status: bit 1 (parity) if bit1,4 in compound (data,hard) ; bit 2 (sync.err) - - 5 - - (pos.error) ; bit 3 (data overr.) - - 3 - - (data overr.) ; bit 5 (end med.) - - 11 - - (seek error) ; ; the procedure performs: ; - calculates result and status from compound status. ; ; registers: call exit ; w0 result ; w1 status ; w2 curr buf ; w3 link unchanged ; ; entry : j10 ; ; return : link+0 b. i4 w. j10 : am (b19) ; set result and status: rl w2 p34 ; sz. w2 (i0.) ; if compound and result 4 mask am 4-1 ; then result:= 4 al w0 1 ; else result:= 1; al w1 0 ; status:= 0; sz. w2 (i1.) ; if compound and seek error mask al w1 x1+1<6 ; then status:= status + end medium; sz. w2 (i2.) ; if compound and data/hard error mask al w1 x1+1<10 ; then status:= status + parity; sz. w2 (i3.) ; if compound and data overrun mask al w1 x1+1<8 ; then status:= status + data overrun; sz. w2 (i4.) ; if compound and position error mask al w1 x1+1<9 ; then status:= status + sync.error; sn w1 0 ; if status = 0 al w0 4 ; then result:= 4; ls w1 12 ; rl w2 b18 ; w2:= curr buf; jl x3+0 ; return; ; variables i0 : 8.00000257 ; result 4 mask, bit 16,18,20,21,22,23 i1 : 8.00010000 ; seek error mask, bit 11 i2 : 8.22000000 ; data/hard err mask, bit 1,4 i3 : 8.04000000 ; data overrun mask, bit 3 i4 : 8.01000000 ; pos.error mask, bit 5 e. \f ; pej 26.09.77 disc driver, update buf ; procedure update buf(segments,bytes) ; --------------------------------------------------------------- ; segments: no of segments transferred. ; bytes : no of bytes transferred per segment. must at calltime ; be stored in p35.curr receiver. ; ; the procedure performs: ; - updates curr buf by segments: ; first segment and firstaddr are incremented. ; no of segments and remaining segments are decremented. ; - updates table of error segments (successful transfer) if sta- ; tistics wanted and a segment in the table lies in the ; interval given by first segment.curr buf and segments. ; ; registers: call exit ; w0 segments destroyed ; w1 curr receiver unchanged ; w2 curr buf unchanged ; w3 link destroyed ; ; entry : j11 ; ; return : link+0 b. i4 w. j11 : rs. w3 i0. ; update buf: save link; rl w3 x2+m4 ; wa w3 0 ; first segment.curr buf:= rs w3 x2+m4 ; first segment.curr buf + segments; c. q1 ; if statistics wanted then rs. w0 i2. ; begin am (x2+m10) ; wa w3 p3 ; top:= first segment.curr buf rs. w3 i1. ; + first segment.device.curr buf; ws w3 0 ; first:= top - segments; al w2 x1+p46-6 ; entry:= 1st error segment.curr rec; i3 : al w2 x2+6 ; while segment no.entry >= 0 and rl w0 x2+0 ; entry <> top entry do sl w0 0 ; begin sl w2 x1+p46+q2*6; if segmentno.entry >= first jl. i4. ; and segmentno.entry < top sl w0 (6) ; then goto found; sl. w0 (i1.) ; entry:= entry + 1; jl. i3. ; end; goto not found; am (b18) ; found: ba w2 m0 ; i:= operation.curr buf; bz w3 x2-1 ; al w3 x3+1 ; entry(i-1):= entry(i-1) + 1; hs w3 x2-1 ; i4 : rl w2 b18 ; not found: rl. w0 i2. ; z. ; end; bz w3 x2+m5 ; ws w3 0 ; no of segments.curr buf:= hs w3 x2+m5 ; no of segments.curr buf - segments; bz w3 x2+m9 ; ws w3 0 ; remaining segments.curr buf:= hs w3 x2+m9 ; rem segments.curr buf - segments; wm w0 x1+p35 ; b:= segments * bytes; wa w0 x2+m2 ; first addr.curr buf:= rs w0 x2+m2 ; first addr.curr buf + b; jl. (i0.) ; return; ; variables i0 : 0 ; saved link i1 : 0 ; saved top (segment) i2 : 0 ; saved param segments e. \f ; pej 28.09.77 disc driver, update buf on error ; procedure update buf on error(statusarea,bytes,chars) ; --------------------------------------------------------------- ; statusarea: addr of statusarea containing information about ; a read or write operation. ; bytes : see proc update buf. ; chars : no of chars transferred per segment. must at call- ; time be stored in p35+2.curr receiver. ; ; the procedure performs: ; - updates curr buf by calling proc update buf with segments ; according to transferred segments using remaining bytes in ; statusarea or, if statusarea undefined, then remaining bytes ; in std statusarea provided it relates to a read or write ; operation. ; please note that, due to a controller error (never to be ; corrected), remaining bytecount must be transformed as ; follows: ; if rem mod chars_per_segm <> 0 ; then rem:= rem - if data transfer then 65536 else 256 ; - leaves curr buf unchanged if neither statusarea nor std sta- ; tus area may be used. ; please note that if the error was of such a kind that the ; transfer specified in the channelprogram was completed ; (statusinformation etc. ok), but the channel program was ; not terminated normally (f.x. error during storing of std ; status), then this procedure may increment firstaddr.curr buf ; to a value equal to lastaddr.curr buf + 2. ; ; registers: call exit ; w0 destroyed ; w1 curr receiver unchanged ; w2 statusarea destroyed ; w3 link destroyed ; ; entry : j12 ; ; return : link+0 b. i5 w. j12 : rs. w3 i0. ; update buf on error: save link; rl w0 x2+2 ; rem:= rem bytecount.statusarea; rl w3 x2+0 ; se w3 0 ; if chan pg count.status area = 0 then jl. i1. ; begin c. statusarea undefined; rl w3 x1+a230 ; se w3 0 ; if chan pg count.stdstatus.curr rec bz w3 x3-6+1 ; <> 0 ls w3 -8 ; se w3 1 ; (and last command executed = read sn w3 3 ; or last command executed = write) jl. i2. ; then rem:= rembytes.stdstatus.curr jl. (i0.) ; else return; i2 : rl w0 x1+a231 ; i1 : rs. w0 i3. ; end; al w3 0 ; saved rem:= rem; wd w0 x1+p35+2 ; rem:= rem // chars; sn w3 0 ; if saved rem mod chars <> 0 then jl. i5. ; begin rl. w0 i3. ; rl w2 x1+p35+2 ; se w2 q53 ; rem:= saved rem - am 2 ; if chars = chars per data segm ws. w0 i4. ; then 65536 else 256; sh w0 -1 ; if rem < 0 jl. (i0.) ; then return; c. should be impossib; al w3 0 ; rem:= rem // chars; wd w0 4 ; end; i5 : ac w0 (0) ; rl w2 b18 ; segments:= ba w0 x2+m5 ; no of segments.curr buf - rem; rl. w3 i0. ; update buf(segments,bytes); jl. j11. ; c.return from there; ;variables i0 : 0 ; saved link i3 : 0 ; for saving rem i4 : 65536 ; constant for correcting rem, +0: data 256 ; +2: addr m e. \f ; pej 28.09.77 disc driver, update retryinformation ; procedure update retryinformation(retryinformation) ; --------------------------------------------------------------- ; retryinformation: addr of the byte containing retryinformation. ; bit 0- 3: modeindex ; bit 4- 8: offsetindex ; bit 9-11: tries ; ; the procedure performs: ; - increments tries. ; - increments modeindex if tries flows over and sets tries to 1. ; - increments offsetindex if modeindex flows over and sets mode- ; index to first value and tries to 1. not performed if ; variable offset impossible. ; ; registers: call exit ; w0 destroyed ; w1 retryinformation destroyed ; w2 destroyed ; w3 link unchanged ; ; entry : j13 ; ; return : link+0: no more tries possible ; link+2: next stobe-offset combination ; link+4: next offset magnitude ; link+6: tries <= 3 (mode/offset index unchanged) b. i4 w. j13 : rs. w1 i4. ; update retryinformation: bz w1 x1+0 ; r:= core(retryinformation) al w1 x1+1 ; tries.r:= tries.r + 1; hs. w1 (i4.) ; core(retryinformation):= r; so w1 2.100 ; if tries.r <= 3 jl x3+6 ; then return; c. link+6; la. w1 i0. ; tries.r:= 1; al w1 x1+i1 ; modeindex.r:= modeindex.r + 1; hs. w1 (i4.) ; core(retryinformation):= r; al w2 x1+0 ; ls w2 -8 ; bl. w0 x2+q20.-1 ; se w0 -1 ; if modetable(modeindex.r) <> -1 jl x3+2 ; then return; c. link+2; la. w1 i2. ; ls w1 -3 ; al w1 x1+1 ; i:= offsetindex + 1; bl. w0 x1+q21. ; am (b19) ; rl w2 p5 ; se w2 0 ; if disctype.curr receiver = 0 sn w0 -1 ; or offset table(i) = -1 jl x3+0 ; then return; c. link+0; ls w1 3 ; r:= modeindex for next round << 8 al w1 x1+i3 ; + i << 3 + 1; hs. w1 (i4.) ; core(retryinformation):= r; jl x3+4 ; return; c. link + 4; ; variables i0 : 2.111111111000 ; mask for zeroizing tries i1 = 2.000100000001 ; mask for incrementing modeindex, tries i2 : 2.000011111000 ; mask for zeroizing modeindex, tries i3 = q23<8+1 ; modeindex for next round << 8 + tries i4 : 0 ; saved param retryinformation e. \f ; pej 30.09.77 disc driver, clean ; procedure clean(result) ; --------------------------------------------------------------- ; result: result to be used as parameter to deliver result. ; ; the procedure performs: ; - returns all messages queued to the driver with above ; mentioned result. ; - zeroizes regretted.curr receiver. ; - sets transfer state.curr receiver idle. ; - if result = 5 (unknown) then state.curr receiver is set to ; after intervention, the name of curr receiver is zeroized ; and so is device address in all areaprocesses referring ; to curr receiver. the same is performed on eventual logical ; disc drivers referring to current receiver. ; ; registers: call exit ; w0 result destroyed ; w1 curr receiver ; w2 destroyed ; w3 link destroyed ; ; entry : j14 ; ; return : link+0 b. i7 w. j14 : ds. w0 i1. ; clean: save link, result; rl w1 b19 ; rl w2 g49 ; rs w2 x1+p13 ; transfer state.curr rec:= idle; al w2 0 ; rs w2 x1+a56 ; regretted.curr rec:= 0; rs w2 g20 ; status.i/o answer:= 0; rs w2 g21 ; bytes.i/o answer:= 0; rs w2 g22 ; chars.i/o answer:= 0; i2 : rl w2 x1+a54 ; while next message.curr rec <> sn w2 x1+a54 ; addr of next message.curr rec do jl. i3. ; begin rs w2 b18 ; curr buf:= next message.curr rec; jl w3 g19 ; deliver result(result); rl. w0 i1. ; jl. i2. ; end; i3 : se w0 5 ; if result <> 5 jl. (i0.) ; then return; al w0 0 ; rs w0 x1+p12 ; state.curr rec:= after intervention; rl w1 b4 ; proci:= addr of 1st device.nametable; i4 : rs. w1 i1. ; repeat rl w1 x1+0 ; proc:= nametable(proci); rl w3 x1+a10 ; rl w0 x1+p2 ; sn w0 (b19) ; if (mainproc.proc = curr receiver se w3 q61 ; and kind.proc = disc) sn w1 (b19) ; or proc = curr receiver then jl. i5. ; begin jl. i7. ; i5 : al w0 0 ; rs w0 x1+a11 ; name(0).proc:= 0; rs w0 x1+a52 ; reserver.proc:= 0; rl w3 b5 ; areai:= first areaproc.nametable; i6 : rl w2 x3+0 ; repeat area:= nametable(areai); sn w1 (x2+a50) ; if device addr.area:= proc rs w0 x2+a50 ; then device addr.area:= 0; al w3 x3+2 ; areai:= areai + 2 se w3 (b6) ; jl. i6. ; until areai = first internal; i7 : am. (i1.) ; end; al w1 2 ; proci:= proci + 2 se w1 (b5) ; jl. i4. ; until proci = first area proc; rl w1 b19 ; jl. (i0.) ; ; variables i0 : 0 ; saved link i1 : 0 ; saved result, proci in loop e. \f ; pej 04.10.77 disc driver, procedure correct data ; procedure correct data ; --------------------------------------------------------------- ; ; the procedure performs: ; - checks if the error correction information stored in status- ; area1 of curr receiver may be used for correcting the data ; segment pointed to by first addr.curr buf. ; - performs the correction by copying the bad word(s) ; from the buffer and back again after having corrected them. ; the copying is performed by calling a monitor procedure. ; two words are copied unless the errorburst starts in the ; base word or last word of the segment. ; ; registers: call exit ; w0 destroyed ; w1 curr receiver destroyed ; w2 curr buf if corrected ; w3 link destroyed ; ; entry : j15 ; ; return : link+0: data not corrected ; link+2: data corrected b. i25 w. j15 : rs. w3 i0. ; correct data: save link; al w2 x1+p16+16 ; addr:= ld w1 -100 ; addr of ecc inf.statusarea1.curr rec; ds. w1 i2. ; sum:= 0; jl. w3 i16. ; sum:= sum 21 ; + (21 - char0.addr) 452387 ; * 452387; jl. w3 i16. ; sum:= sum 88 ; + (88 - char1.addr) 72358 ; * 72358; jl. w3 i16. ; sum:= sum 12 ; + (12 - char2.addr) 315238 ; * 315238; al w2 x2+2 ; c. now eccinf(0) = 0; addr:= addr + 2; jl. w3 i16. ; sum:= sum 22 ; + (22 - char0.addr) 330902 ; * 330902; wd. w1 i3. ; c. now eccinf(2) = err pattern << 8; al w1 x1+1 ; bitdisp:= wm. w1 i3. ; (sum // 585442 + 1) * 585442 ws. w1 i2. ; - sum - 56 + 16; al w0 x1-56+16 ; c. is now base for error pattern; sl. w0 (i5.) ; if bitdisp outside segment jl. (i0.) ; then not corrected return; c. link+0; sh w0 0 ; if bitdisp <= 0 jl. i15. ; then goto corrected; rl w2 0 ; c. error entirely in checkcharacters; al w2 x2+11 ; al w1 0 ; bytedisp:= wd. w2 i6. ; (bitdisp + 11) / 12; c. w2; al w3 0 ; wd. w0 i8. ; al w3 x3-24 ; sh:= -24 + (bitdisp mod 24); sn w3 -24 ; if sh = - 24 al w3 0 ; then sh:= 0; rs. w3 i9. ; save sh; al w0 q52 ; ws w0 4 ; relative:= la w0 g50 ; even (segment size - bytedisp); c.w0; al. w1 i10. ; c. relative to firstaddr.curr buf; al. w3 i11. ; first:= first bad; last:= second bad; se w0 -2 ; if relative = -2 then jl. i17. ; begin c. only one word; al w0 0 ; relative:= 0; first:= last; al w1 x3+0 ; end; i17 : sn w0 q52-2 ; if relative = segmentsize - 2 al w3 x1+0 ; then last:= first; c. only 1 word; rl w2 b18 ; buf:= curr buf; rs. w1 i21. ; save first rl. w1 i25. ; store mode.call rs. w1 i20. ; ds. w0 i23. ; save relative,last al. w1 i20. ; w1:= parameter address jd 1<11+84; general copy(params,buf) se w0 0 ; if result <> 0 jl. (i0.) ; then not corrected return; c. link+0; am (b19) ; c. align the err pattern to error; rl w3 p16+18 ; w3:= eccinf(2).statusarea1.curr rec; al w0 0 ; w0:= 0; ld. w0 (i9.) ; w3w0:= w3w0 shift sh; lx. w3 i10. ; first bad:= first bad xor w3; lx. w0 i11. ; second bad:= second bad xor w0; ds. w0 i11. ; rl. w1 i24. ; change function in parameter list(from=curr,to=buf) rs. w1 i20. ; al. w1 i20. ; w1:= parameter address jd 1<11+84; general copy(params,buf) se w0 0 ; if result <> 0 jl. (i0.) ; then not corrected return; c. link+0; i15 : am. (i0.) ; corrected: jl 2 ; return; c. link + 2; ; routine for updating sum. the routine performs: ; sum:= sum + (k - (core(addr) shift (-16)) * m ; core(addr):= core(addr) shift 8 ; registers: call w2=addr, w3=link ; exit w0w1=sum (also stored in i1i2), w2,w3=unch ; call : jl. w3 i16. ; k link+0 ; m link+2 ; returnpoint link+4 i16 : rl w1 x2+0 ; update sum: al w0 0 ; w1:= core(addr); w0:= 0; ld w1 8 ; w0w1:= w0w1 shift 8; rs w1 x2+0 ; core(addr):= w1; sz w0 8.200 ; if char in w0 negative jl. (i0.) ; then not corrected return; rl w1 x3+0 ; ws w1 0 ; w1:= k - w0; wm w1 x3+2 ; w0w1:= w1 * m; aa. w1 i2. ; w0w1:= sum:= sum + w0w1; ds. w1 i2. ; jl x3+4 ; return; ; variables i0 : 0 ; saved link i1 : 0 ; double word for sum i2 : 0 ; - - i3 : 585442 ; constant used in calculations i6 : 12 ; - - - - i8 : 24 ; - - - - i5 : q53*8+16 ; largest bitdisplacement + 1 + 16 i9 : 0 ; saved sh (shifts to align err pattern) i10 : 0 ; to receive first bad word i11 : 0 ; - - 2nd - - ; parameters for general copy: i20 : 2<1+0 ; function(pair<1+mode),init: from=buf,to=curr i21 : 0 ; first i22 : 0 ; last i23 : 0 ; relative i24 : 2<1+1 ; function(from=curr,to=buf) i25 : 2<1+0 ; function(from=buf,to=curr) e. \f ; pej 17.11.77 disc driver, update on corrected error ; procedure update on corrected error ; --------------------------------------------------------------- ; ; the procedure performs: ; - updates statistics concerning an error which has been ; corrected either by incrementing the counter for errors ; corrected within 3 retries (setmode param.curr receiver = 0) ; or by incrementing a counter in the tables for errors ; corrected by strobe-offset. ; ; registers: call exit ; w0 destroyed ; w1 curr receiver unchanged ; w2 unchanged ; w3 link destroyed ; ; entry : j16 - used at transput ; j17 - used at control ; return : link + 0 c. q1 b. i3 w. j16 : rl w0 x1+p21 ; update on corrected transput error: se w0 0 ; if setmode param.curr rec = 0 then jl. i1. ; begin j17 : am (x1+p43) ; update on corrected control error: al w0 1 ; corrected in 3 tries.curr rec:= rs w0 x1+p43 ; corrected in 3 tries.curr rec + 1; jl x3+0 ; end else i1 : rs. w3 i0. ; begin c. strobe-offset used; ls w0 -4 ; i:= setmode param(16:19).curr rec; am (0) ; c. strobe and offset; bz w3 x1+p44-1 ; al w3 x3+1 ; strobe offset table(i-1).curr rec:= am (0) ; strobe offset table(i-1).curr rec+1; hs w3 x1+p44-1 ; c. i-1 as value 1 is counted in rl w0 x1+p21 ; byte o; sz w0 2.11<4 ; if setmode param(18:19).curr rec =0 jl. i2. ; then jl. (i0.) ; begin i2 : la. w0 i3. ; i:= setmode param(20:23).curr rec; am (0) ; c. offset magnitude; bz w3 x1+p45 ; al w3 x3+1 ; offset magn. table(i).curr rec:= am (0) ; offset magn. table(i).curr rec + 1; ; end; hs w3 x1+p45 ; end; jl. (i0.) ; return; ; variables i0 : 0 ; saved link i3 : 2.1111 ; for masking out offset magnitude e. z. \f ; pej 04.10.77 disc driver, end of code z.e. ; end disc driver block e. ; end area process-disc driver block \f ▶EOF◀