|
|
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◀