|
|
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: 235008 (0x39600)
Types: TextFile
Names: »mdisc «
└─⟦9ccaf6601⟧ Bits:30008165 Bånd med SW8000 kildetekst/release værktøjer
└─⟦2ba378e4a⟧
└─⟦this⟧ »mdisc «
\f
m. mondisc - disc driver 17.0 beta
;--------------------------------------------------------------------------
; REVISION HISTORY
;--------------------------------------------------------------------------
; DATE TIME OR DESCRIPTION
; RELEASE
;--------------------------------------------------------------------------
;88.03.24 14.1A HSI start of description
; regret csp-att mess when ifp is reset
; connect csp-terminals and -printers: set kind
; ifp-mess disconnect: dont disconnect the mainprocess
; ifp-mess setmask: dont send operation to ifp
; ifp-mess copy: check that w1 is a legal address
; ifp-interrupt disconnect csp-terminal: send att-mess to user of remoter
; ifp-interrupt csp-attention: if terminal reserved then ignore
;
; ----- " -------- " --------: if att-receiver is unknown
; then send 6<12+1 operation to adp
;
;88.04.19 15.0 TSH mainprocess driver/interrupt rewritten for RC9000.
;88.05.04 10.0 KAK power interrupt at ifpmain cause return at once to
; driverproc's wait event
;88.05.16 13.21 kak reset ifp/ida re-inserted with a few modification
;88.06.20 10.15 TSH sspmain included
;88 06 24 20.06 hsi max transfer in ifp devices set to 32000
;88 08 08 14.17 kak sense operation to ifpmain inserted
;88 08 16 14.43 hsi timeout on main operations
;88 09 05 12.47 hsi ifp mess: connect: start search for free linkproc
; from the highest devicenumber
; csp-term: set base on link when created.
;88 09 14 14.19 hsi monitor must send a hard reset not a soft
;88 09 15 15.14 IFP/ADP: change default timeout to 60 sec.
;88 11 24 13.31 kak - timeout value inserted in sense message.mess_3
;89 01 30 07.51 kak tape state inserted after answer create link
;89 03 08 09.33 kak at interrupt received, the queue of waiting operation are checked
; before return to driverproc.wait_event
; if the interrupt is delivered from a IOC/LAN controller
;89 03 15 15.28 kak decrease no_of_outstanding at commen end in driverprocs nterrupt procedure
; two new testpoint inserted in timeout and power interrup;89 03 17 11.20 kak no_of_outstanding is set to one after reset, it will be decreased at commen end
;89 03 26 10 21 kak when driverproc receive an attention message from a controller, it is checked that
; driverproc.bufferclaim > 5 before the message is sent to the receiver,
; otherwise only the answer to the controller is sent
;--------------------------------------------------------------------------
; START OF RELEASE 16.0
;89 04 11 13.38 hsi unlink logical disk not allowed if part of logical vol.
;89 04 26 12.12 hsi check name in createlink from lan (correction from 15.1)
;89 05 02 14.48 hsi insert procfunc as user of new terminal link (15.1)
;--------------------------------------------------------------------------
;90 05 30 11.40 kak START OF RELEASE 17.0
;90 05 30 11.40 kak prepare dump excluded
;90 08 09 13.12 kak the two attention events testbuffer full and error correction performed included as legal events
;90 10 12 1.14 kak when excluding preparedump set timeout(ida/ifp) was excluded too this is corrected
b.i30 w.
i0=90 08 09
i1=13 14 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 = 500 ; 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 : zl w0 x2+m1 ; action 7:
ls w0 -3 ; get mess.mode
ea w0 x1+p14 ;
al. w3 c4. ; startaddr:= 1st sense.channel pg;
se w0 0 ; if initdisc.curr receiver <> 0 or mess.mode = 8
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: ; error: c. w1 = curr receiver;
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
i35: 2. 1 1 1 0 1 1 1 1 1 1 1 1 <12+2. 1 1 1 1 0 0 1 1 , i36: n2
2. 1 1 1 1 0 0 <12+2. 1 1 1 1 1 1 1 1 1 1 , 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 2: set initdisc
; tr.state: all, except sense
; err.kind: all, except overrrun, write prot, and data err
n2 : al w0 1 ; initdisc.curr receiver:= 1;
hs w0 x1+p14 ;
jl. j130. ; goto central action;
; 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. j98. ;
jl. j98. ;
jl. j98. ; if tries <= 3 then goto start
jl. j55. ; else goto deliver error;
j98: rl w1 b19 ;
al w0 0 ; if more than 3 timeouts then
rs w0 x1+p12 ; then execute initdisc before next operation
jl. j96. ; (possible kitshift in progress)
; 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
b. p22, m50, n114 w. ; block including ioc and dlc main process.
; -------------------------------------------------------------------------
;
; I O C M A I N P R O C E S S D R I V E R
;
; D L C M A I N P R O C E S S D R I V E R
;
; -------------------------------------------------------------------------
;
;
; the main processes supports the following operations:
;
; IOC DLC
; -------------------------- -----------------------------
;
; - dump (*)
; - prepare dump (*)
; - create link (*) - create link (*)
; - extract statistics - extract statistics
; - remove link (*) - remove link (*)
; - set mask - set mask
; - link logical disc
; - unlink logical disc
; - test (*)
; - initialize controller (*) - initialize controller (*)
;
; RC8000-IDA/IFP
; --------------------------
;
; - input
; - output
; - position
;
; driverproc messages
; -----------------------------
; - answer create link
; - answer remove link request
; - answer attention
; - stop normal communication (only rc8000)
;
; (*) the (possible re-formattet) message is transmitted to the controller
;
;
; execution of messages:
; ----------------------
;
; when a message is received by the mainprocess, it is claimed
; (receiver is negated).
; only one message is executed by (the 1st part of) the driver at a
; time. when the message is executed in this part of the driver it is
; in no queue. if the message isn't going to be transmitted to the
; controller (those operation which are not marked '(*)' above) the
; answer to the message is returned before the next message is received
; (i.e. the message will never be in the event queue of the main
; process).
; if the message is going to be transfered to the controller (all
; operations marked '(*)') the message will be delivered to the 2ed
; part of the main driver, where it will be linked either to the
; waiting queue of the main process or to the event queue of the
; receiver. at this time the 1st part of the driver will never see
; the message/answer again (except for the create/remove link
; operations where it receives an interrupt-operation).
; the 1st part of the driver need not to worry about regret of messages
; as it will never receive a regretted message. the second part (setup
; part) of the driver will take a proper action on a regretted message
; if it is regretted while it is under execution (either in the rc8000
; or in the controller).
;
\f
; use of names:
; -------------
; m main routines (one for each operation)
;
; n sub-routines
;
; p names of operations
;
;
; definition of operations
;
p2 = 2 ; prepare dump
p6 = 6 ; create link
p9 = 9 ; extract statistics
p10 = 10 ; remove link
p12 = 12 ; set mask
p14 = 14 ; dump
p16 = 16 ; link logical disc
p18 = 18 ; unlink logical disc
p20 = 20 ; test
p22 = 22 ; initialize controller
p3 = 3 ; ida/ifp input
p5 = 5 ; ida/ifp output
p8 = 8 ; ida/ifp position
; ***** stepping stones *****
jl. (+2), d150 , d150 = k - 4
jl. (+2), d151 , d151 = k - 4
jl. (+2), d156 , d156 = k - 4
\f
;
; M E S S A G E R E C E I V E D B Y M A I N P R O C E S S .
; ---------------------------------------------------------------
;
; Control is transfered to this part when driverproc receives a
; message sent to an IOC or DLC main process.
;
; From driverproc the following messages can be received:
; stop normal communication - 4
; answer attention - 3
; answer remove link request - 2
; answer create link - 1
; remove link 10
;
; At entry the registers contains:
;
; w0 -
; w1 sender
; w2 message
; w3 main process
;
b. i10, j10 w.
h20: ; message received
h26: ;
rs. w1 i1. ; begin
rl w3 b21 ;
zl w0 x3+a19 ; <* claim the buffer - driverproc will have claims
bs. w0 1 ; enough as it received the message in wait event
hs w0 x3+a19 ; and unclaimed it 'by hand' when it received it *>
ac w3 (x2+a141) ;
rs w3 x2+a141 ;
;
sn w1 (b21) ; if message.sender = driverproc then
jl. j3. ; goto branch; <* skip all checks *>
;
rl w1 b19 ; <* select the proper operation/mode mask
al w0 2.0111 ; depending on main state and main kind *>
la w0 x1+a78 ;
al w3 8 ; if main.connect_state = connected then
sn w0 l38 ; index := connect_mask
al w3 0 ; else index := free_mask;
rl w0 x1+a10 ;
se w0 q20 ; if main.kind = ifp_main then
al w3 x3+4 ; index := index or ifp_mask
al. w3 x3+i2. ; else index := index or ida_mask;
dl w1 x3+0 ;
jl w3 g16 ; check operation(operation mask, mode mask, message);
;
rl. w1 i1. ;
zl w3 x2+a150 ; if message.operation needs reservation then
rl. w0 i3. ;
ls w0 x3 ; check reserver(sender, message)
sh w0 -1 ; else
am g15-g14; check user(sender, message);
jl w3 g14 ;
;
zl w0 x2+a138+1 ;
so w0 2.1 ; if message.state.io then
jl. j3. ; begin
jl w3 g34 ; if message.regretted or
sz ; message.sender.state = stopped then
jl. j2. ; begin
rl w3 b20 ; no operation;
jl g26 ; goto driverproc.wait event;
; end;
;
j2: jl w3 g31 ; increase stopcount(message.sender);
sn w0 p9 ; if message.operation <> extract statistics then
jl. j3. ; begin
;
rl w3 x2+a152 ; message.no of bytes :=
al w0 x3+2 ; (last address - first address + 2)/2 * 3;
ws w0 x2+a151 ;
ls w0 -1 ;
wm w0 g48 ;
rs w0 x2+a152 ;
;
rl w0 x2+a151 ; message.first address :=
wa w0 x1+a182 ; message.first address + sender.base;
rs w0 x2+a151 ; <* physical address *>
; end;
; end;
;
j3: el w3 x2+a150+0 ; branch:
ls w3 +1 ;
jl. (x3+i5.) ; goto case message.operation of
;
m34 ; -4 : stop normal communication
m33 ; -3 : answer attention
m32 ; -2 : answer remove link request
m31 ; -1 : answer create link
i5: m0 ; 0 : sense
-1 ; 1 : -
m1 ; 2 : prepare dump / set tiomout (ida/ifp)
m3 ; 3 : ida/ifp input
m4 ; 4 : ida/ifp reset
m5 ; 5 : ida/ifp output
m6 ; 6 : create link
-1 ; 7 : -
m8 ; 8 : ida/ifp position
m9 ; 9 : extract statistics
m10 ; 10 : remove link
-1 ; 11 : -
m12 ; 12 : set mask
-1 ; 13 : -
m14 ; 14 : dump
-1 ; 15 : -
m16 ; 16 : link logical disc
-1 ; 17 : -
m18 ; 18 : unlink logical disc
-1 ; 19 : -
m20 ; 20 : test
-1 ; 21 : -
m22 ; 22 : initialize controller
i1: 0 ; saved w1 (sender)
;
; format of the operation/mode mask table:
; -2 : ida/ioc, connected, operations
;i2: 0 : ida/ioc, connected, modes
; 2 : ifp/dlc, connected, operations
; 4 : ifp/dlc, connected, modes
; 6 : ida/ioc, not connected, operations
; 8 : ida/ioc, not connected, modes
; 10 : ifp/dlc, not connected, operations
; 12 : ifp/dlc, not connected, modes
a0>3+a0>4+a0>5+a0>6+a0>8+a0>9+a0>10+a0>12+a0>16+a0>18+a0>22
i2: a0>0 + a0>1 + a0>2 + a0>3 + a0>4 + a0>5
a0>0+a0>2+a0>3+a0>4+a0>5 + a0>6 +a0>8 + a0>9 + a0>10 + a0>12 + a0>22
a0>0 + a0>1 + a0>2 + a0>3 + a0>4 + a0>5 + a0>6
a0>4+a0>5+a0>9+a0>12+a0>22
a0>0+a0>1+a0>2
a0>2+a0>3+a0>4+a0>5+a0>9+a0>12+a0>22
a0>0+a0>1+a0>2+a0>3+a0>4+a0>5+a0>6
; the following operations needs reservation:
i3: a0>4
e. ; end *** message received ***;
\f
; sense
;----------------------------------------------------------------------------
; message (sender format) message (when delivered to part 2)
; --------------------------- ----------------------------------
;
; + 0: 0 < 12 + 0 0 < 12 + 0
; + 6: timeout value (0.1 msec)
;
;
; at entry:
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
m0: ; sense:
rl w1 b19 ;
rl w3 x1+a87 ;
rs w3 x2+a153 ; mess_3:=timeout value;
al w0 0 ; force := no;
jl. (n100.) ; start_controller(force);
\f
; set timeout (ifp)
;----------------------------------------------------------------------------
;
; The timevalue is set in the mainprocess. If the value exceeds 800 sec.
; timeout will be set to 800 sec.
; If timeout is set to 0, the timeout supervision is disabled.
; NOTE: the procedure is called from m2.
; The operation does not involve the ifp.
;
; message (sender format)
; +0 2<12 +0
; +2 timeout value (in sec.)
;
;
; at entry:
; w0 -
; w1 sender
; w2 message
; w3 -
b. i1 w.
m1: rl w0 x2+a151 ; if mess.timeout < 0 then deliver result(3)
sh w0 -1 ;
jl g5 ; ;
sl w0 800 ; if mess.timeout > 800 sec then
al w0 800 ; main.timeout := 800 sec
wm. w0 i1. ;
rl w1 b19 ;
rs w0 x1+a87 ; else main.timeout := mess.timeout
al w0 0 ;
rs w0 g20 ; deliver result(1)
jl g7 ;
i1: 10000 ; timeout in 0.1 msec
e.
\f
c.-(:a399>23a.1:)
m2=-1
z.
c.(:a399>23a.1:)-1
; prepare_dump (ioc)
; -----------------------------------------------------------------------------
;
; the area specifed in the message is reserved for dump of the two specified
; core areas.
; the core areas will be changed if necessary to be a multiplum of the
; segment size by first decrementing (if possible) the first_address and then
; (if necessary) increment the last_address.
; the area process must be reserved by the sender when the message is received
; by the main process.
;
; message (sender format) message (when delivered to part 2)
; --------------------------- ----------------------------------
;
; + 0: 2 < 12 + 0 2 < 12 + 0
; + 2: first address (low core) first address (low core)
; + 4: last address (low core) 0 (no of bytes)
; + 6: first address (high core) first segment (disk: phys, area: 0)
; + 8: last address (high core) no of segments
; +10: dump_device 0 (next logical segment if area)
; +12: first segment (if dump dev=disk) first address (high core)
; +14: - no of segments (in high core)
;
; the format of the message when delivered to part 2 is close to the i/o
; format of a message to an area process.
;
; at entry:
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
b. i10, j20 w.
m2: ; prepare dump/set timeout
am b19 ;
rl w0 +a10 ; if main.kind = ifp then goto set timeout
se w0 q20 ; else
jl. m1. ;
ds. w2 i2. ; begin
; ------- check specified dump device -------
rl w1 x2+a155 ;
rl w3 (b6) ; proc := message.dump_device;
rl w0 (b4) ;
sl w1 (0) ; if not proc within area or external then
sl w1 x3 ; deliver_result(3);
jl g5 ;
;
rl w3 x1+a11 ; if proc.name = 0 or
rl w0 x1+a10 ; proc.kind <> area and
sn w3 0 ; proc.kind <> disk then
jl g5 ; deliver_result(3);
se w0 q4 ;
sn w0 q6 ;
sz ;
jl g5 ;
al w3 x1 ; p := proc;
sz ;
j1: rl w3 x3+a50 ; while p.kind <> ioc_main
rl w0 x3+a10 ; begin
se w0 q20 ; p := proc.main;
jl. j1. ; end;
;
se w3 (b19) ; if p <> this main then
jl g5 ; deliver_result(3);
;
rl w0 x1+a10 ; size :=
se w0 q4 ; if dump_device.kind = area then
jl. j0. ; area.number_of_segments
rl w0 x1+a61 ; else
sz ; disk.number_of_segments;
j0: rl w0 x1+a74 ;
rs. w0 i4. ;
;
rl w3 x3+a200 ;
se w3 0 ; if this main.pending_prepare_dump <> 0 then
jl g5 ; deliver_result(3);
;
al w2 x1 ;
rl. w1 i1. ;
jl w3 d113 ; check_reserver(internal, proc);
jl g6 ;+0: other: deliver_result(2);
sz ;+2: internal: ok;
jl g6 ;+4: none: deliver_result(2);
;
; -------- check addresses --------
al w0 2 ;
rs. w0 i6. ; check high core addresses first
;
rl w2 b18 ;
j9: am. (i6.) ;check_addresses:
dl w1 x2+a152 ;
la w0 g50 ; first := message.first & -2; <* even *>
la w1 g50 ; last := message.last & -2; <* even *>
am. (i6.) ; message.first := first;
rs w0 x2+a151 ;
;
sl w0 0 ; if first > 8Mhw or
sh w1 -1 ; last > 8Mhw or
jl g5 ; last > core_size then
sl w1 (b12) ; deliver_result(3);
jl g5 ;
;
al w1 x1+2 ;
ws w1 0 ; dump_size := last - first + 2;
sh w1 -1 ; if dump_size < 0 then
jl g5 ; deliver_result(3);
;
al w0 0 ; no_of_segm,rest := dump_size / 512;
wd w1 b221 ;
sn w0 0 ; if rest <> 0 then
jl. j11. ; begin
am. (i6.) ;
rl w3 x2+a151 ; if message.first <> 0 then
sn w3 0 ; begin
jl. j10. ;
ws w3 0 ;
sh w3 0 ; first := message.first - rest;
al w3 0 ; if first < 0 then first := 0;
la w3 g50 ; first := first & -2; <* even *>
am. (i6.) ;
rs w3 x2+a151 ; message.first := first;
jl. j9. ; goto check_addresses;
; end
j10: ; else
am. (i6.) ; begin
rl w3 x2+a152 ;
wa w3 0 ; last := message.last + rest & -2; <* even *>
la w3 g50 ;
am. (i6.) ;
rs w3 x2+a152 ;
jl. j9. ; goto check_addresses;
; end;
; end;
j11: ;
sl. w1 (i4.) ; if no_of_segm > size then
rl. w1 i4. ; no_of_segm := size;
am. (i6.) ;
rs w1 x2+a152 ; message.no_of_segments := no_of_segm;
rl. w0 i4. ;
ws w0 2 ; size := size - no_of_segm;
rs. w0 i4. ;
;
al w0 0 ; if address_pair = last then
rx. w0 i6. ; begin
se w0 0 ; address_pair := first;
jl. j9. ; goto check_addresses;
; end;
rl w0 x2+a152 ;
wa w0 x2+a154 ; if message.no_of_segments = 0 then
sn w0 0 ; deliver_result(3);
jl g5 ;
;
dl w0 x2+a154 ; <* save high core addr in mess_6 - mess_7 *>
ds w0 x2+a157 ;
ds w0 b28 ; <* save high core addr in monitor for post mortem *>
dl w0 x2+a152 ;
ds w0 b27 ; <* save low core addr in monitor for post mortem *>
;
rs w0 x2+a154 ; <* transform the format to resemble the
al w0 0 ; area i/o format *>
rs w0 x2+a152 ;
rs w0 x2+a153 ;
;
rl w3 b19 ;
rs w2 x3+a200 ; main.pending_prepare_dump := message;
al w1 0 ; main.dump_device := message.dump_device;
rx w1 x2+a155 ; message.dump_device := 0; <* area: next logical segment *>
rs w1 x3+a201 ;
rl w0 x1+a10 ; if dump_device.kind = area then
se w0 q4 ; begin
jl. j12. ;
al w2 x1 ; insert_reserver(driverproc, area);
rl w1 b21 ;
jl w3 d125 ;
jl. j13. ; end
j12: ; else
rl w0 x2+a155 ; begin
wa w0 x1+a73 ; message.first_segment :=
rs w0 x2+a153 ; message.first_logical_segment +
; disk.first_segment;
j13: ; end;
;
al w0 0 ; force := no;
jl. (n100.) ; start_controller(force);
;
i1: 0 ; save w1
i2: 0 ; save w2
i4: 0 ; size
i6: 0 ; address pair: 0 a151 - a152
; 2 a153 - a154
;
e. ; end;
z.
\f
;
; reset (ida & ifp)
; -------------------------------------------------------------------------
;
; message (sender format) answer
; ----------------------- ------
; + 0: 4<12 + mode 0
; + 2: ifp_type (if soft_reset)
;
; the controller will be reset. for ida it will always be a hard reset
; (where the comm. area is not used); for ifp it will be a hard reset if
; mode <> 2 otherwise it will be a soft reset involving a reset operation
; to be sent to the controller - in this case an answer is returned when
; the ifp controller is ready. In this case cleanup is performed when the
; answer arrives.
; the process complex in rc8000 concerning this controller is cleaned up
; i.e. all pending messages are returned with result 4, and all physical
; disc, mt processes or gsd processes are removed.
;
; at entry:
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
b. i10, j10 w.
m4: ; reset
rl w1 b4 ; begin
j0: rl w3 x1 ; for proc := first external, next until last external do
rl w0 x3+a10 ; begin
se w0 q6 ;
jl. j1. ; if proc.kind = disc and
rl w0 x3+a50 ;
se w0 (b19) ; proc.main = this main and
jl. j1. ;
rl w0 x3+a70 ; proc.next logical disc <> 0 then
se w0 0 ;
jl g5 ; deliver result(3);
;
j1: al w1 x1+2 ;
se w1 (b5) ;
jl. j0. ; end;
;
rl w1 b19 ;
al w0 2.100000 ; main.state := not_ok;
lo w0 x1+a78 ;
hs w0 x1+a78+1 ;
rs w1 x1+a77 ; main.proc_id := main; <* just to initialize it *>
; al w0 0 ;
; rs w0 x1+a76 ; main.device_id := 0; <* - " - *>
;
rl w0 x1+a10 ; if main.kind = ifp_main and
am (b18) ; message.mode = soft_reset then
zl w3 +a150+1 ; begin
se w0 q20 ;
se w3 2 ;
jl. j2. ;
al w0 2 ; force := strong; <* ignore state of main *>
jl. (n100.) ; start_controller(force);
; <* never reached *>
j2: ; end
; else
rl w3 x1+a235 ; begin
sn w0 q26 ;
rs w3 b58 ; <* place ifp device addr in monitor table *>
al w2 0 ;
se w0 q26 ; if main.kind = ifpmain then
am 2.01<1 ; reset(har_ifp_reset)
do w2 x3+0 ; else reset(normal);
la w3 b212 ;
wa w3 b65 ; <* clear any pending interrupt from contrller *>
rl w0 x3+a313 ;
gp w0 b95 ;
;
jl. w3 (n109.) ; cleanup;
;
rl w1 b19 ; <* give the main process a few free
al w0 3 ; buffers to play with *>
ls w0 12 ;
rs w0 x1+a78+0 ; proc.free_buffers := 3; proc.state:=free;
al w0 0 ; status := 0;
rs w0 x1+a86 ;
rs w0 g20 ;
al w2 x1+a242 ;
se w2 (x2) ; if in timeout queue then
jl w3 d5 ; remove (main, timeout_queue)
jl g7 ; deliver_result(1);
; end;
;
e. ; end;
\f
; create link (ioc & dlc)
; -------------------------------------------------------------------------
;
; if the specified rc8000 device number is -1 a free subprocess is
; selected (and the device no will be placed in word +6 of the message).
; the subprocess is (partly) initialized and the state of the subprocess
; is set to 'during connect'.
; the rest of the process is initialized when the maindriver receives
; a create link answer operation from the controller.
;
; IOC: message (sender/setup format) answer (*)
; ----------------------------- ----------
; + 0: 6<12 + mode status
; + 2: control module/formatter RC8000 device number
; + 4: slave device/station no controller device index
; + 6: RC8000 device no/-1 (**) device kind
; + 8: device kind, device type device capacity
;
;
; mode: 0: include sender as user of connection
; 1: include users of main as users of connection
;
; device kind:
; 6: disk
; 18: tape
;
; device type: none is defined
;
; DLC: message (sender/setup format) answer
; ----------------------------- ----------
; + 0: 6<12 + mode status
; + 2: device type (0-9) RC8000 device number
; + 4: controller index/255
; + 6: RC8000 device no/-1 (**)
; + 8: name in controller
; +10: - " -
; +12: - " -
; +14: - " -
;
; mode: as for IOC
;
; device type: see device type table (i0:)
;
; (*) the answer is created by the controller.
; (**) RC8000 process address inserted instead of device no in part 1.
;
; at entry
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
b. i10, j20 w.
m6: ; create link
rl w1 x2+a153 ; begin
se w1 -1 ;
jl. j3. ; if message.rc8000_device_no = -1 then
; begin
rl w1 b5 ; for proc := last external, next until first external do
al w1 x1-2 ;
j1: rl w3 x1 ; begin
rl w0 x3+a10 ;
sn w0 q68 ; if proc.kind = free subprocess then
jl. j4. ; goto out;
; end;
j2: al w1 x1-2 ;
sl w1 (b4) ;
jl. j1. ; goto no_resources;
jl. j20. ; end
; else
j3: ls w1 +1 ; begin
wa w1 b4 ;
sl w1 (b4) ; if not message.rc8000_device_no within external then
sl w1 (b5) ; deliver_result(3);
jl g5 ;
rl w3 x1 ; proc := nametable(rc8000 device no);
rl w0 x3+a10 ; if proc.kind <> free subprocess then
se w0 q68 ; goto no_resources;
jl. j20. ;
; end;
j4: am (b19) ;out:
rl w0 +a10 ; <* w3: proc *>
se w0 q20 ; if this main.kind = ioc_main then
jl. j5. ; begin
;
zl w0 x2+a154 ; kind := message.device_kind;
se w0 q6 ; if kind <> disk and tape then
sn w0 q18 ; deliver_result(3);
sz ;
jl g5 ; <* w0: kind *>
jl. j7. ; end
j5: ; else <* main = dlc *>
rl w1 x2+a151 ; begin
sl w1 1 ; if message.device_type < 1 or
sl w1 10 ; message.device_type > 9 then
jl g5 ; deliver_result(3);
;
zl. w0 x1+i0. ; kind := device_kind_table(message.device_type);
; jl. j7. ; end;
;
j7: ;
rl w1 x2+a142 ; if message.regrettet then
sh w1 0 ; deliver_result(dummy);
jl g7 ;
zl w1 x2+a150+1 ; if message.mode <> 0 or 1 then
sz w1 -2 ; deliver_result(3);
jl g5 ;
;
; <* init process *>
rs w0 x3+a10 ; proc.kind := kind;
;
dl w2 x2+a152 ; proc.module,facility :=
ds w2 x3+a68 ; message.module,facility;
ld w2 -48 ; <* module,fac. irr. for dlc - don't matter *>
ds w2 x3+a71 ; <* clear proc a70 - a87 *>
ds w2 x3+a73 ;
ds w2 x3+a75 ;
ds w2 x3+a87 ;
;
rl w2 b19 ; proc.main := this main;
rs w2 x3+a50 ;
al w1 2.000001; proc.state := during_connect;
hs w1 x3+a78+1 ;
rs w3 x3+a77 ; proc.proc_id := proc;
am (b18) ;
rs w3 +a153 ; message.8000_process := proc;
;
al w2 x3 ;
am (b18) ; if message.mode = 0 then
zl w0 +a150+1 ; include_user(message.sender, proc)
se w0 0 ; else
jl. j10. ; include_all_users(main, proc);
am (b18) ;
rl w1 +a142 ;
sh w1 0 ;
ac w1 x1 ;
jl w3 d126 ;
al w0 0 ; force := no;
jl. (n100.) ;
j10: ;
rl w1 b19 ;
jl. w3 (n103.);
al w0 0 ; force := no;
jl. (n100.) ; start_controller(force);
; <* never reached *>
;
j20: ; no_resources:
al w0 8.1400 ; status := no_resources;
rs w0 g20 ;
jl g7 ; deliver_result(1);
;
h. ; device_kind_table(0:9)
i0: -1 ; 0 : -
8 ; 1 : terminal
28 ; 2 : IMC port handler
28 ; 3 : mailbox
28 ; 4 : 3270 input
28 ; 5 : 3270 output
28 ; 6 : lanstat (test device)
28 ; 7 : floppy
14 ; 8 : printer
18 ; 9 : streamer
w. ;
e. ; end;
\f
; extract statistics (ioc & dlc)
; -------------------------------------------------------------------------
;
; the statistical information collected in the main process is copied
; to the sender.
;
; message (sender format) answer
; ----------------------- ------
; + 0: 9<12 + mode status
; + 2: first storage address no of halfwords
; + 4: last storage address no of characters
;
; mode: clear statistics<0: 0 = statistics remain unchanged
; 1 = statistics are cleared
;
; at entry
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
b. i10, j10 w.
m9: ; extract statistics
rl w3 b19 ; begin
al w0 x3+a216 ; param.first address := this main.statistics.first
al w1 x3+a218 ; param.last address := this main.statistics.last
ds. w1 i3. ;
al. w1 i1. ;
jd 1<11+84 ; general_copy(buffer, param);
;
sn w0 0 ; if result = 3 then
jl. j1. ; decrease stopcount and deliver result_3(message)
se w0 2 ; else if result = 2 then
jl. (n104.); begin
jl w3 d132 ; decrease_stopcount(message);
rl w3 b20 ;
jl g26 ; goto_no_operation;
; end;
j1: rs w1 g21 ;
ls w1 -1 ; message.no_of_halfwords := halfwords;
wm w1 g48 ; message.no_of_characters:= halfwords*2/3;
rs w1 g22 ;
al w0 0 ;
rs w0 g20 ; message.status := 0;
;
zl w1 x2+a150+1 ; if not clear_statistics then
so w1 2.1 ; decrease stopcount and deliver result_1(message)
jl. (n105.); else
ld w1 -100 ; begin
ds w1 x3+a216+2 ; clear all statistics in this mainprocess
ds w1 x3+a218 ;
jl. (n105.); decrease stopcount and deliver result_1(message);
; end;
;
; param:
i1: 2<1 + 1 ; function := 1st address pair, core to buffer
0 ; first address
i3: 0 ; last address
0 ; relative start
;
e. ; end;
\f
;
; remove link (ioc & dlc)
; ------------------------------------------------------------------------
;
; removes the connection between a rc8000 external process representing an
; device and the corresponding device.
;
; message (sender format) answer (*)
; ----------------------- ----------
; + 0: 10<12 + 0 0
; + 2: rc8000 device number
; (+ 4: rc8000 proc addr when sent
; from driverproc)
;
; message (setup format)
; ----------------------
; + 0: 10<12 + 0
; + 2: rc8000 process address
; + 4: controller_index
;
; (*) the answer is created by the controller.
;
; at entry
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
b. i10, j10 w.
m10: ; remove link
; begin
se w1 (b21) ; if sender = driverproc then
jl. j0. ; begin
rl w2 x2+a152 ; proc := message.mess_2;
;
al w0 2.000111; if proc.state = free or
la w0 x2+a78 ; proc.state = during disconnect then
se w0 l36 ; deliver_result(3);
sn w0 l39 ; <* a remove link message has been received
jl g5 ; after driverproc sent this message *>
jl. j2. ; goto proc_ok;
j0: ; end;
rl w3 x2+a151 ;
ls w3 +1 ;
wa w3 b4 ;
sl w3 (b4) ; if not message.device number within external processes then
sl w3 (b5) ; deliver result(3);
jl g5 ;
rl w2 x3 ; proc := nametable(message.device number);
;
rl w3 x2+a50 ;
sn w2 (b19) ; if proc = this main or
jl g5 ; proc.main <> this main then
se w3 (b19) ; deliver_result(3);
jl g5 ; <* test of main will catch disconnect of logical
; disks and return result 3 *>
al w0 2.000111;
la w0 x2+a78 ;
se w0 l36 ; if proc.state= free or
sn w0 l39 ; proc.state= during disconnect
jl g5 ; then deliver_result(3);
rl w0 x2+a10 ;
se w0 q6 ; if proc.kind = disk then
jl. j1. ; begin
rl w0 x2+a70 ;
rl w3 b19 ; if proc.next_logical_disk <> 0 or
se w0 0 ; proc = this main.dump_device then
jl g5 ; deliver_result(3);
sn w2 (x3+a201) ;
jl g5 ; end;
;
j1: jl w3 d76 ; test user and reserver(sender, proc);
sz w3 2.1000 ; if other reserver or
jl g6 ; (sender not user and other users) then
so w3 2.0001 ; deliver_result(2);
so w3 2.0100 ;
sz ;
jl g6 ;
j2: ; proc_ok:
rl w1 b18 ;
rl w3 x2+a76 ; message.mess_1 := proc;
ds w3 x1+a152 ; message.mess_2 := proc.controller_index;
;
ac w0 2.000111+1;
la w0 x2+a78 ;
al w3 l39 ;
lo w0 6 ;
hs w0 x2+a78+1 ; proc.state := during disconnect;
; <* prevents create peripheral process *>
rl w0 x2+a10 ;
se w0 q8 ; if proc.kind = terminal then
jl. j3. ; begin
al w0 1<1 ; type := disconnected;
rl w1 b19 ;
jl. w3 (n112.) ; check_remoter(type, main, proc);
rs w3 x2+a74 ; proc.att_receiver := internal_supervisor;
se w3 0 ; if internal_supervisor then
jl. w3 n114. ; send_remoter_att(type, main, proc);
; end;
j3: ;
jl. w3 n2. ; clear_process(proc);
;
al w0 0 ; force := no;
jl. (n100.) ; start controller(force);
; <* the rest of the process will be cleared when
; answer disconnect is received *>
e. ; end;
\f
;
; set mask (ioc & dlc)
; ------------------------------------------------------------------------
;
; sets the test mask in the rc8000 driver.
;
; message (sender/setup format) answer
; ----------------------------- ----------
; + 0: 12<12 + mode status
; + 2: rc8000 mask (point 0 - 23)
; + 4: rc8000 mask (point 24 - 47)
;
; at entry
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
m12: ; set mask
; begin
rl w3 b19 ; <* set mask for rc8000 device drivers *>
dl w1 x2+a152 ;
ds w1 x3+a75 ;
al w0 0 ; answer.status := ok;
rs w0 g20 ;
jl g7 ; deliver_result(1);
; end;
\f
; dump (ioc)
; -----------------------------------------------------------------------------
;
; the previously sent 'prepare dump' operation will be executed.
;
; message (sender & setup format)
; -------------------------------
; + 0: 14 < 12 + 0
; + 2: 0
; + 4: 0
;
;
; at entry:
;
; w0: -
; w1: sender
; w2: message
; w3: -
;
b. i10, j10 w.
m14: ; dump
rl w3 b19 ; begin
rl w0 x3+a200 ;
sn w0 0 ; if main.pending_prepare_dump = 0 then
jl g5 ; deliver_result(3);
rl w0 x2+a151 ;
lo w0 x2+a152 ;
se w0 0 ; if message.mess_1<>0 or message.mess_2<>0 then
jl g5 ; deliver_result(3);
al w0 1 ; force := weak;
jl. (n100.) ; start_controller(force);
;
e. ; end;
\f
;
; link logical disk (ioc)
; ------------------------------------------------------------------------
;
; creates a logical disc process and initialize it. if the specified
; device number of the logical disc is -1 a free subprocess is selec-
; ted.
;
; message (sender format) answer
; ----------------------- ------
; + 0: 16<12 + mode status
; + 2: device no of logical disc/-1 device no of logical disc
; + 4: device no of physical disc device no of physical disc
; + 6: first segment first segment
; + 8: no of segments no of segments
;
; mode: 0: sender is included as user of logical disc.
; 1: all users of main are included as users of the logical disc.
;
; at entry
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
b. i10, j15 w.
m16: ; link logical disc
zl w0 x2+a150+1 ; begin
sz w0 -2 ; if not message.mode = 0 or 1 then
jl g5 ; deliver result(3);
rl w3 x2+a152 ;
ls w3 +1 ;
wa w3 b4 ; if not external processes then
sl w3 (b4) ;
sl w3 (b5) ; deliver result(3);
jl g5 ;
;
rl w3 x3 ; proc := nametable(devno);
rl w0 x3+a10 ; if proc.kind <> disc or
rl w2 x3+a50 ; proc.main <> this mainprocess then
sn w0 q6 ; deliver result(3);
se w2 (b19) ;
jl g5 ;
al w0 2.000111;
la w0 x3+a78 ; if proc.state <> connected then
se w0 l38 ; deliver result(3);
jl g5 ;
;
al w2 x3 ;
jl w3 d113 ; check reserver(sender, proc);
jl g6 ; +0: if other reserver then deliver result(2);
jl. j0. ; +2:
jl w3 d102 ; +4: if no reserver then check user(sender, proc);
jl g6 ; +0: if not user then deliver result(2);
; +2:
j0: al w3 x2 ;
rs. w1 i1. ;
rl w1 b18 ; logical := proc.first logical disc;
rl w2 x3+a70 ;
j1: sn w2 0 ; while logical <> 0 do
jl. j4. ; begin
;
rl w0 x2+a73 ; if logical.first segment < message.first segment then
sl w0 (x1+a153) ; begin
jl. j2. ; if logical.first segment+logical.no of segments >=
wa w0 x2+a74 ; message.first segment then
sh w0 (x1+a153) ; deliver result(3);
jl. j3. ;
jl g5 ;
; end else
j2: rl w0 x1+a153 ; begin
wa w0 x1+a154 ; if message.first segment+message.no of segments >=
sh w0 (x2+a73) ; logical.first segment then
sz ; deliver result(3);
jl g5 ;
; end;
j3: rl w2 x2+a70 ; logical := logical.next logical disc;
jl. j1. ; end;
;
j4: rl w2 x1+a153 ; if message.first segment <
al w0 x2-1 ; proc.first segment or
wa w0 x1+a154 ; message.first segment + message.no of segments >
sl w2 (x3+a73) ; proc.no of segments or
sl w0 (x3+a74) ;
jl g5 ;
sl w0 x2 ; message.no of segments <= 0 then
sz ;
jl g5 ; deliver result(3);
;
rl w1 x1+a151 ; if message.logical devno = -1 then
se w1 -1 ; begin
jl. j7. ;
rl w1 b4 ; for ext := first external, next until last external do
j5: rl w2 x1 ; begin
rl w0 x2+a10 ;
se w0 q68 ; if ext.kind = free subprocess then
jl. j6. ; begin
rl w1 x2+a59 ; message.logical devno := ext.device_no;
am (b18) ;
rs w1 +a151 ; goto out;
jl. j7. ; end;
;
j6: al w1 x1+2 ;
se w1 (b5) ;
jl. j5. ; end;
jl. j10. ; deliver status('no free subprocesses');
;out:
; end;
j7: ls w1 +1 ;
wa w1 b4 ;
sl w1 (b4) ; if not ext within external processes then
sl w1 (b5) ; deliver result(3);
jl g5 ;
rl w2 x1 ; ext := nametable(logical devno);
rl w0 x2+a10 ; if ext.kind <> free subprocess then
se w0 q68 ; deliver status('no free subprocesses');
jl. j10. ;
;
ld w1 -100 ; ext.chaintable := 0;
ds w1 x2+a72 ; ext.slicelength := 0;
al w1 x2+a81 ;
al w0 x1 ; <* init process queues *>
ds w1 x2+a81+2 ;
al w1 x2+a54 ;
al w0 x1 ;
ds w1 x2+a55 ;
;
rs w3 x2+a50 ; ext.main := physical disc;
al w0 q6 ; ext.kind := disc kind;
rs w0 x2+a10 ;
al w0 2.1 ;
hs w0 x2+a57 ; ext.type := logical type;
am (b18) ;
dl w1 +a154 ; ext.first segment := message.first segment;
ds w1 x2+a74 ; ext.no of segments:= message.no of segments;
dl w1 x3+a87 ; ext.max_transfer_size := physical_disk.max_transfer_size;
ds w1 x2+a87 ; ext.max_buffer_size := physical_disk.max_buffer_size;
rl w1 x3+a75 ; ext.bytes_pr_track := physical_disk.bytes_pr_track;
rs w1 x2+a75 ;
dl w1 x3+a77 ; ext.controller_index:=physical_disc.controller_index;
ds w1 x2+a77 ; ext.rc8000process:= physical disc.rc8000process;
dl w1 x3+a68 ; ext.cm := physical disc.cm;
ds w1 x2+a68 ; ext.unit:= physical disc.unit;
;
al w0 0 ;
j8: sn w0 (x3+a70) ; while proc.next logical disc <> 0 do
jl. j9. ; proc := proc.next logical disc;
rl w3 x3+a70 ;
jl. j8. ;
;
j9: rs w2 x3+a70 ; proc.next logical disc := ext;
rs w0 x2+a70 ; ext.next logical disc := 0;
;
am (b18) ;
zl w0 +a150+1 ; if message.mode = 0 then
se w0 0 ; include user(message.sender, ext)
jl. j11. ; else
rl. w1 i1. ; include all users(physical disc, ext);
jl w3 d126 ;
jl. j12. ;
j11: ;
rl w1 x2+a50 ;
jl. w3 (n103.) ;
j12: ;
al w0 l38 ;
hs w0 x2+a78+1 ; ext.state := connected;
;
rl w3 b18 ;
al w0 0 ;
rs w0 g20 ; status := ok;
dl w1 x3+a152 ; rc8000 device no of logical disc
ds w1 g22 ; rc8000 device no of physical disc
dl w1 x3+a154 ; first segment
ds w1 g24 ; no of segments
jl g7 ; deliver result(1);
;
;
j10: ; no_resources:
al w0 8.1400 ; status := no_resources;
rs w0 g20 ;
jl g7 ; deliver result(1);
;
i1: 0 ; saved sender
;
e. ; end;
\f
;
; unlink logical disc (ioc)
; ------------------------------------------------------------------------
;
; removes the logical disc process in rc8000 and the connection to the
; physical disc process.
;
; message (sender format) answer
; ----------------------- ------
; + 0: 18<12 + 0 0
; + 2: rc8000 device number
;
; at entry
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
b. i10, j10 w.
m18: ; unlink logical disc
rl w3 x2+a151 ; begin
ls w3 +1 ;
wa w3 b4 ;
sl w3 (b4) ; if not message.device number within external processes then
sl w3 (b5) ; deliver result(3);
jl g5 ;
;
rl w2 x3 ; proc := nametable(message.device number);
rl w0 x2+a10 ; if proc.kind <> disc or
zl w3 x2+a57 ; proc.type <> logical disc then
sn w0 q6 ; deliver result(3);
so w3 2.1 ;
jl g5 ;
sz w3 2.1100000; if proc.type = logical volume then
jl g5 ; deliver result(3);
;
rl w3 x2+a50 ; if proc.main.main <> this mainprocess or
rl w3 x3+a50 ; proc.chaintable <> 0 then
rl w0 x2+a71 ; deliver result(3);
sn w0 0 ;
se w3 (b19) ;
jl g5 ;
;
sn w2 (x3+a201) ; if mainprocess.dump_device = proc then
jl g5 ; deliver_result(3);
;
jl w3 d76 ; test user and reserver(sender, proc);
sz w3 2.1000 ; if other reserver or
jl g6 ; (sender not user and other users) then
so w3 2.0001 ; deliver result(2);
so w3 2.0100 ;
sz ;
jl g6 ;
;
rl w1 x2+a50 ; p := proc.main; <* physical disc *>
j1: sn w2 (x1+a70) ; while p.next logical disc <> proc do
jl. j2. ; p := p.next logical disc;
rl w1 x1+a70 ;
jl. j1. ;
;
j2: rl w0 x2+a70 ; p.next logical disc := proc.next logical disc;
rs w0 x1+a70 ;
al w0 0 ; proc.next logical disc := 0;
rs w0 x2+a70 ;
;
jl. w3 n2. ; clear_process(proc);
;
jl. w3 n8. ; free_process(proc);
;
al w0 0 ; status := 0;
rs w0 g20 ;
jl g7 ; deliver result(1);
;
e. ; end;
\f
m20: ; test:
al w0 0 ; force := no;
jl. (n100.) ; start_controller(force);
\f
;
; initialize controller
; -----------------------------------------------------------------------------
;
; the mainprocess is connected to the supervisor process in the controller.
; credits for outstanding messages are exchanged between the two parties.
;
; message (sender/setup format) answer format
; + 0 22 < 12 + 0 0
; + 2 controller credit monitor credit
;
; at entry
; w0 -
; w1 sender
; w2 message
; w3 -
b. i10, j10 w.
m22: ; initialize controller
rl w1 b19 ; begin
al w0 8.07 ;
la w0 x1+a78+1 ; if main.state <> free then
se w0 0 ; deliver_result(3);
jl g5 ;
;
am (b21) ; if driverproc.buffer_claim <=
zl w0 +a19 ; message.controller_credit then
sh w0 (x2+a151) ; deliver_result(3);
jl g5 ;
;
rl w0 x2+a142 ; if regretted(message) then
sh w0 0 ; deliver_result(dummy);
jl g7 ;
;
al w0 2.000001; main.state := during_connect;
lo w0 x1+a78 ;
hs w0 x1+a78+1 ; <* give the main process a few free
al w0 4 ; buffers to play with *>
hs w0 x1+a78+0 ; proc.free_buffers := 4;
;
rs w1 x1+a50 ; main.main := main;
rs w1 x1+a77 ; main.proc_id := main;
al w0 0 ; main.device_id := 0;
rs w0 x1+a76 ;
al w3 0 ;
ds w0 x1+a216+2 ; <* clear statistics *>
ds w0 x1+a218 ;
ds w0 x1+a201 ; <* clear prepare dump variables *>
;
rx w1 4 ;
rl w1 x1+a142 ;
jl w3 d126 ; include_user(message.sender, proc);
;
al w0 1 ; force := weak;
jl. (n100.) ; start_controller(force);
;
e. ; end;
\f
;
; answer create link (internal driverproc message)
; -----------------------------------------------------------------------------
;
; sent from driverproc to mainprocess (driverproc) when 'answer create link'
; is sent to then controller.
; format of the message: see o20 in the interrupt procedure c36.
;
; at entry
; w0 -
; w1 (sender)
; w2 message
; w3 -
;
b. i5, j5 w.
i1: 0 ; reserver, result
i2: 0 ; terminal_process
m31: ; answer create link
rl w0 x2+a151 ; begin
rs. w0 i1. ; <* save reserved, result *>
rl w0 x2+a153 ;
rs. w0 i2. ; <* save terminal process *>
;
al w0 0 ; force := no;
am (b19) ;
rl w1 +a59 ;
jd 1<11+128 ; start_controller(force, this main.devno, message);
se w0 0 ; if result <> ok then
jl g4 ; deliver_result(4);
;
hl. w0 i1.+0 ;
hl. w1 i1.+1 ; if save_result <> ok or
sn w1 1 ; save_reserved = 0 then
se w0 1 ; goto driverproc.wait_event;
jl (b20) ;
;
; al w0 1<0 ; type := connected;
rl w1 b19 ;
rl. w2 i2. ;
jl. w3 n14. ; send_remoter_att(type, main, terminal);
;
jl (b20) ; goto driverproc.wait_event;
;
;
e. ; end;
\f
; answer remove link request
; answer attention
m32:
m33:
al w0 0 ; force := no;
jl. (n100.) ; start_controller(force);
; stop normal communication
m34: al w0 2 ; force := strong
jl. (n100.); start_controller(force)
\f
;
; input (ida ifp) only RC8000
; -----------------------------------------------------------------------------
;
; this operation must have been preceeded by a 'position' operation in which
; the input area was defined.
;
; message (sender format) answer (*)
; ----------------------- ----------
; + 0: 3<12 + 0 status
; + 2: first storage address no of halfwords transfered
; + 4: last storage address no of chareacters transfered
;
; message (setup format)
; ----------------------
; + 0: 3<12 + 0
; + 2: first storage address
; + 4: no of bytes
;
; (*) the answer is created by the controller.
;
; at entry:
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
b. i5, j5 w.
m3: ; input
; begin
al w3 0 ; message.no of bytes :=
rl w0 x2+a152 ; (message.no of bytes//768) * 768;
wd w0 b222 ;
wm w0 b222 ; < let no of bytes be a multiplum of the
rs w0 x2+a152 ; segmentsize >
al w0 0 ; force := no;
jl. (n100.) ; start_controller(force);
;
e. ; end;
\f
;
; take autoload block (ida & ifp) only RC8000
; -------------------------------------------------------------------------
;
; the specified autoload block is transmitted to the controller.
;
; message (sender format) answer (*)
; ----------------------- ----------
; + 0: 5<12 + 0 status
; + 2: first storage address number of halfwords transfered
; + 4: last storage address number of characters transfered
;
; message (setup format)
; ----------------------
; + 0: 5<12 + 0
; + 2: first storage address
; + 4: no of bytes
;
; (*) the answer is created by the controller.
;
; at entry
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
b. i10, j10 w.
m5: ; take autoload block
; begin
al w0 0 ; force := no;
jl. (n100.) ; start_controller(force);
;
e. ; end;
\f
;
; position (ida ifp) only RC8000
; -----------------------------------------------------------------------------
;
; this operation defines the (logical) filenumber from where the succeding
; input operations will receive data.
;
; message (sender/setup format) answer (*)
; ----------------------------- ----------
; + 0: 8<12 + 0 status
; + 2: 0
; + 4: 0
; + 6: (logical) filenumber
;
; (*) the answer is created by the controller.
;
; at entry:
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
m8: ; position
; begin
al w0 0 ; force := no;
jl. (n100.) ; start_controller(force);
; end;
\f
;
; M E S S A G E R E C E I V E D B Y S S P M A I N P R O C E S S .
; ----------------------------------------------------------------------
;
; Control is transfered to this part when driverproc receives a
; message sent to the SSP main process.
;
; From driverproc the following messages can be received:
; answer attention - 3
;
; The ioc/dlc code for the following operations are used by the
; ssp main-driver:
; - extract_statistics ( m9)
; - set_mask (m12)
; - initialize_controller (m22)
;
; At entry the registers contains:
;
; w0 -
; w1 sender
; w2 message
; w3 main process
;
b. i10, j10 w.
h24: ; message received
rs. w1 i1. ; begin
rl w3 b21 ;
zl w0 x3+a19 ; <* claim the buffer - driverproc will have claims
bs. w0 1 ; enough as it received the message in wait event
hs w0 x3+a19 ; and unclaimed it 'by hand' when it received it *>
ac w3 (x2+a141) ;
rs w3 x2+a141 ;
;
sn w1 (b21) ; if message.sender = driverproc then
jl. j3. ; goto branch; <* skip all checks *>
;
zl w0 x2+a150+0 ; if message.operation < 24 then
sl w0 24 ; begin
jl. j1. ;
dl. w1 i2. ; check_operation(operation_mask, mode_mask, message);
jl w3 g16 ;
rl. w1 i1. ;
jl w3 g14 ; check_user(sender, message);
jl. j2. ; end
j1: ; else <* no io operation with oper. code > 23 as *>
se w0 24 ; begin <* check_operation must be called for those *>
sn w0 25 ; if message.operation <> 24 and
sz ; message.operation <> 26 then
jl g5 ; deliver_result(3);
rl. w1 i1. ;
jl w3 g15 ; check_reserver(sender, message);
j2: ; end;
;
zl w0 x2+a138+1 ;
so w0 2.1 ; if message.state.io then
jl. j4. ; begin
jl w3 g34 ; if message.regretted or
sz ; message.sender.state = stopped then
jl. j3. ; begin
rl w3 b20 ; no operation;
jl g26 ; goto driverproc.wait event;
; end;
;
j3: jl w3 g31 ; increase stopcount(message.sender);
;
rl w3 x2+a152 ; message.no of bytes :=
al w0 x3+2 ; (last address - first address + 2)/2 * 3;
ws w0 x2+a151 ;
ls w0 -1 ;
wm w0 g48 ;
rs w0 x2+a152 ;
;
rl w0 x2+a151 ; message.first address :=
wa w0 x1+a182 ; message.first address + sender.base;
rs w0 x2+a151 ; <* physical address *>
; end;
;
j4: ; branch:
zl w0 x2+a150+0 ; oper := message.operation;
sn w0 5 ; if oper = operator_output then
jl. m41. ; goto operator_output else
sn w0 6 ; if oper = create_link then
jl. m42. ; goto create_link else
sn w0 9 ; if oper = extract_statistics then
jl. m9. ; goto extract_statistics else
sn w0 12 ; if oper = set_mask then
jl. m12. ; goto set_mask else
sn w0 22 ; if oper = initialize_controller then
jl. m22. ; goto initialize_controller else
sn w0 24 ; if oper = close_system then
jl. m43. ; goto close_system else
sn w0 26 ; if oper = reload_system then
jl. m44. ; goto reload_system
jl. m45. ; else goto answer_attention;
;
;
i1: 0 ; save w1 (sender)
;
; ssp legal operation mask (only operations < 24)
; ssp legal mode mask (only operations < 24)
a0>5 + a0>6 + a0>9 + a0>12 + a0>22
i2: a0>0 + a0>1
e. ; end *** message received ***;
\f
; operator_output
; ---------------------------------------------------------------------------
;
; message:
;
; + 0: 5<12 + 0
; + 2: first address
; + 4: last address (byte count when sent to controller)
;
m41: ; operator_output:
; begin
al w0 0 ; force := no;
jl. n0. ; start_controller(force);
; end;
; close_system
; reload_system
; ---------------------------------------------------------------------------
; nothing to check - nothing to do here!
m43: ; close_system:
m44: ; reload_system:
; begin
al w0 1 ; force := yes; <* just do it quickly *>
jl. n0. ; start_controller)force);
; end;
; answer_attention
; -------------------------------------------------------------------------
; nothing to check - nothing to do here!
m45: ; answer_attention:
; begin
al w0 0 ; force := no;
jl. n0. ; start_controller(force);
; end;
\f
; create link (SSP)
; -------------------------------------------------------------------------
;
; if the specified rc8000 device number is -1 a free subprocess is
; selected (and the device no will be placed in word +6 of the message).
; the subprocess is (partly) initialized and the state of the subprocess
; is set to 'during connect'.
; the rest of the process is initialized when the maindriver receives
; a create link answer operation from the controller.
;
; message (sender/setup format) answer
; ----------------------------- ----------
; + 0: 6<12 + mode status
; + 2: device type (1 or 7) RC8000 device number
; + 4: -
; + 6: RC8000 device no/-1 (**)
;
; mode: 0: include sender as user of link
; 1: include users of main as users of link
;
; device type: 1 : console
; 7 : floppy disk
;
; (**) RC8000 process address inserted instead of device no in part 1.
;
; at entry
;
; w0 -
; w1 sender
; w2 message
; w3 -
;
b. i10, j20 w.
m42: ; create link
rl w1 x2+a153 ; begin
se w1 -1 ;
jl. j3. ; if message.rc8000_device_no = -1 then
; begin
rl w1 b4 ; for proc := first external, next until last external do
j1: rl w3 x1 ; begin
rl w0 x3+a10 ;
sn w0 q68 ; if proc.kind = free subprocess then
jl. j4. ; goto out;
; end;
j2: al w1 x1+2 ;
se w1 (b5) ;
jl. j1. ; goto no_resources;
jl. j20. ; end
; else
j3: ls w1 +1 ; begin
wa w1 b4 ;
sl w1 (b4) ; if not message.rc8000_device_no within external then
sl w1 (b5) ; deliver_result(3);
jl g5 ;
rl w3 x1 ; proc := nametable(rc8000 device no);
rl w0 x3+a10 ; if proc.kind <> free subprocess then
se w0 q68 ; goto no_resources;
jl. j20. ;
; end;
j4: ; out:
rl w1 x2+a151 ;
se w1 1 ; if message.device_type <> 1 and
sn w1 10 ; message.device_type <> 9 then
sz ; deliver_result(3);
jl g5 ;
;
al w0 9 ; kind := if message.device_type = terminal then 9
se w1 1 ; else 28;
al w0 28 ;
;
rl w1 x2+a142 ; if message.regrettet then
sh w1 0 ; deliver_result(dummy);
jl g7 ;
zl w1 x2+a150+1 ; if message.mode <> 0 or 1 then
sz w1 -2 ; deliver_result(3);
jl g5 ;
;
; <* init process *>
rs w0 x3+a10 ; proc.kind := kind;
ld w2 -48 ;
ds w2 x3+a71 ; <* clear proc a70 - a87 *>
ds w2 x3+a73 ;
ds w2 x3+a75 ;
ds w2 x3+a87 ;
;
rl w2 b19 ; proc.main := this main;
rs w2 x3+a50 ;
al w1 2.000001; proc.state := during_connect;
hs w1 x3+a78+1 ;
rs w3 x3+a77 ; proc.proc_id := proc;
am (b18) ;
rs w3 +a153 ; message.8000_process := proc;
;
al w2 x3 ;
am (b18) ; if message.mode = 0 then
zl w0 +a150+1 ; include_user(message.sender, proc)
se w0 0 ; else
jl. j10. ; include_all_users(main, proc);
am (b18) ;
rl w1 +a142 ;
sh w1 0 ;
ac w1 x1 ;
jl w3 d126 ;
al w0 0 ; force := no;
jl. n0. ;
j10: ;
rl w1 b19 ;
jl. w3 n3. ;
al w0 0 ; force := no;
jl. n0. ; start_controller(force);
; <* never reached *>
;
j20: ; no_resources:
al w0 8.1400 ; status := no_resources;
rs w0 g20 ;
jl g7 ; deliver_result(1);
;
e. ; end;
; ***** stepping stones *****
n100: n0 ;
n103: n3 ;
n104: n4 ;
n105: n5 ;
n109: n9 ;
n112: n12 ;
n114: n14
jl. (+2), d156 , d156 = k - 4
\f
; I N T E R R U P T R E C E I V E D F R O M C O N T R O L L E R .
; ---------------------------------------------------------------------
;
; all interrupts except 'answer device operation' are delivered
; as interrupts to the mainprocess in question.
; when an interrupt is received the communication area from the controller
; to rc8000 has not been released yet.
b. i10, j10, o121 w.
c36: ; interrupt received
rl w1 b19 ; begin
rl w2 x1+a501 ;
rs w2 b18 ; <* w1 = main, w2 = message (if any) *>
rl w0 x1+a244 ;
sn w0 3 ; if timeout_interrupt then goto timeout
jl. o3. ;
se w0 0 ; if NOT ok_interrupt then
jl. o2. ; goto power_interrupt;
; else begin <*normal io result*>
rl w3 b218 ; <* left 8 bits *>
la w3 x1+a500 ;
ls w3 -3-12 ;
sl w3 13*2*2 ; if main.function >12 then
jl -1 ; panic;
jl. (x3+j0.) ; goto case main.function of
;
; <* w1: main, w2: message (if any) *>
; func, answ
; - - - - - -
j0: -1 ; 0 0 : panic
-1 ; 0 1 : panic
-1 ; 1 0 : panic
-1 ; 1 1 : panic, answer device operation, catched
o20 ; 2 0 : create link
o21 ; 2 1 : answer create link
-1 ; 3 0 : panic
o31 ; 3 1 : answer remove link
o40 ; 4 0 : attention
-1 ; 4 1 : panic
-1 ; 5 0 : panic
o1 ; 5 1 : answer regret: start controller
-1 ; 6 0 : panic
o1 ; 6 1 : answer reserve device: start controller
-1 ; 7 0 : panic
o1 ; 7 1 : answer release device: start controller
o80 ; 8 0 : remove link request
-1 ; 8 1 : panic
-1 ; 9 0 : panic
o91 ; 9 1 : answer initialize controller
-1 ; 10 0 : panic
-1 ; 10 1 : panic
-1 ; 11 0 : panic
o111 ; 11 1 : answer reset
-1 ; 12 0 : panic
o121 ; 12 1 : answer stop normal communication
\f
b. i10, j10 w. ; - - - data - - -
i0: -1 < 12 + 0 ; mess_0: operation (= answer_create_link)
i1: 0 ; +2: reserved, result
i2: 0 ; +4: device_id
i3: 0 ; +6: proc_id
i4: 0, 0, 0, 0 ; +8-+14: name of reserver (if any)
i8: 32000 ; max transfer size
o20: ; create link
; --------------------
; begin
rl w0 x1+a502 ;
rs. w0 i2. ; mess_2 := main.device_id;
al w2 x1+a514 ;
jl w3 d11 ; check_name,(driverproc,name_address);
sz ; not found goto search free sub process
jl. j0. ; found goto set result 9;
rl w3 b5 ; proc := last_external;
j1: al w3 x3-2 ; while proc.kind <> free and
rl w2 x3 ; proc <> first_external
rl w0 x2+a10 ; begin
sn w0 q68 ; proc := nametable(prev);
jl. j2. ;
se w3 (b4) ;
jl. j1. ; end;
;
;
am 8-9 ; if proc = first_external
j0: al w0 9 ; or name already exist then
rs. w0 i1. ; begin
jl. j9. ; result := no_resources/already exist;
; goto answer_controller;
; end;
j2: ;
al w0 1 ;
rs. w0 i1. ; reserved := 0; result := ok;
rs. w2 i3. ; mess_3 := proc;
ld w0 -48 ;
ds w0 x2+a71 ; <* clear proc a70 - a87 *>
ds w0 x2+a73 ;
ds w0 x2+a75 ;
ds w0 x2+a87 ;
al w3 x2+a81 ; <* init process queues *>
al w0 x3 ;
ds w0 x2+a81+2 ;
al w3 x2+a54 ;
al w0 x3 ;
ds w0 x2+a54+2 ;
rs w1 x2+a50 ; proc.main := this main;
rl w1 (b6) ;
jl w3 d126 ; insert_user(proc,proc_func);
rl w1 x2+a50 ;
al w0 l37 ;
rs w0 x2+a78 ; proc.state := during_connect;
al w0 q8 ;
rs w0 x2+a10 ; proc.kind := terminal;
rl w0 x1+a502 ;
rs w0 x2+a76 ; proc.device_index := main.device_id;
rs w2 x2+a77 ; proc.process_address := proc;
rl. w3 i8.;x1+a513;
rs w3 x2+a87 ; proc.buffer_size := main.mess_3;
al w3 x3+1 ;
rs w3 x2+a86 ; proc.max_transfer := buffer_size + 1;
dl w0 x1+a514+2 ;
ds w0 x2+a11+2 ; proc.name := main.mess_4 - mess_7;
dl w0 x1+a514+6 ;
ds w0 x2+a11+6 ;
am (b21) ; proc.name_base := driverproc.base (i.e. max)
dl w0 +a49 ;
ds w0 x2+a49 ;
al w0 1<0 ; type := connected;
jl. w3 (n112.) ; check_remoter(type, main, proc);
; <* w3 retur: 0 or internal_supervisor *>
sn w3 0 ; if internal_supervisor then
jl. j4. ; begin
al w2 x3 ;
dl w0 x2+a11+2 ;
ds. w0 i4.+2 ; mess_4 - mess_7 := internal_supervisor.name;
dl w0 x2+a11+6 ;
ds. w0 i4.+6 ;
am. (i3.) ;
rs w2 +a74 ; proc.att_receiver := internal_supervisor;
al w2 1 ; mess_1.reserver := 1;
hs. w2 i1.+0 ; end;
j4: ;
j9: ; answer_controller:
al. w2 i0. ;
jl. w3 n13. ; send_main_message(main, message);
;
jl. o1. ; goto common_end;
;
e. ; end <* ----- end create link ----- *>
\f
b. i10, j20 w. ; - - - data - - -
i0: 32000 ; default ifp buffersize
i2: 0 ; saved message
i4: ; result : comment
; ccccccccddssssss........ ; c=connect_result, d=description, s=dev_status
2.000000000000010000000000 ; 8 : no resources
2.000000000000010100000000 ; 9 : link already exist
2.100000000000000100000000 ; 10 : ill kind (should not come ?)
2.001000000000000100000000 ; 11 : controller unknown
2.100000000000000100000000 ; 12 : device unknown
2.000100000000000100000000 ; 13 : controller fault
2.000100000000000100000000 ; 14 : device fault
;
o21: ; answer create link
; --------------------
; begin
al w0 8.377 ; if main.result = ok then
la w0 x1+a500 ; begin
se w0 1 ;
jl. j8. ;
;
rl w3 x1+a503 ; proc := main.proc_id;
rl w0 x3+a10 ;
se w0 q6 ; if proc.kind = disk then
jl. j2. ; begin
;
rl w0 x1+a520+a154 ; proc.no_of_segments :=
rs w0 x3+a74 ; message.device_capacity :=
rs w0 x2+a154 ; main.mess_4;
;
sn w0 0 ; if proc.no_of_segments > 0 then
jl. j1. ; begin
rs. w2 i2. ;
al w2 x3 ;
al w3 0 ; proc.segments_pr_track :=
rl w0 x1+a520+a156 ; main.mess_6 / bytes_pr_segment;
wd w0 b222 ;
rs w0 x2+a75 ;
;
al w3 0 ; proc.buffer_size :=
rl w0 x1+a520+a155 ; main.mess_5 / bytes_pr_segment;
wd w0 b222 ;
rs w0 x2+a87 ;
; <* make max transfer a multiple
al w3 0 ; of track size *>
wd w0 x2+a75 ; proc.max_transfer :=
wm w0 x2+a75 ; proc.buffer_size / proc.segments_pr_track *
; proc.segments_pr_track;
sn w0 0 ; if proc.max_transfer = 0 then
rl w0 x2+a87 ; proc.max_transfer := proc.buffer_size;
rs w0 x2+a86 ; <* in case where buffersize < tracksize *>
;
al w3 x2 ;
jl. j6. ; end
j1: ; else
; begin
; <* drive has not been formated *>
; <* io requests will be rejected due to
; disk.no_of_segments *>
; end;
jl. j6. ; end
j2: ; else
se w0 q18 ; if proc.kind = tape then
jl. j3. ; begin
;
rl w0 x1+a520+a155 ; proc.buffer_size := main.mess_5;
rs w0 x3+a87 ; proc.max_transfer := main.mess_5 + 1;
ba. w0 1 ;
rs w0 x3+a86 ;
;
rl w0 (b3) ; proc.remoter_process :=
rs w0 x3+a75 ; nametabel(1);
;
al w0 3 ; proc.document_state :=
la w0 x1+a520+a157 ;
rs w0 x3+a70 ; returned_state;
jl. j6. ; end
j3: ; else
sn w0 q28 ; if proc.kind = gsd or
jl. j4. ; proc.kind = printer or
sn w0 q14 ; proc.kind = terminal or
jl. j4. ; proc.kind = ssp terminal then
sn w0 q8 ;
jl. j4. ;
se w0 q9 ;
jl -1 ; begin
j4: ;
rl. w0 i0. ; proc.buffer_size := standard size
rs w0 x3+a87 ;
ba. w0 1 ; proc.max_transfer := standard size;
rs w0 x3+a86 ;
; jl. j6. ; end
; else panic;
j6: ;
rl w0 x1+a502 ; proc.device_id :=
rs w0 x3+a76 ; main.device_id;
ac w0 2.000111+1;
la w0 x3+a78 ;
al w2 l38 ; proc.state :=
lo w0 4 ; proc.state or connected;
hs w0 x3+a78+1 ;
; <* prepare answer *>
al w0 0 ;
rs w0 g20 ; answer_0 := ok; <* status *>
rl w0 x3+a59 ;
rs w0 g21 ; answer_1 := proc.devno;
rl w0 x1+a502 ;
rs w0 g22 ; answer_2 := main.device_id;
am (b18) ;
rl w0 +a154 ; answer_3 := message.device_kind,device_modif;
rs w0 g23 ;
rl w0 x1+a514 ; answer_4 := main.mess_4; <*device capacity *>
rs w0 g24 ;
al. w3 o1. ;
jl g18 ; deliver_result(1);
; goto common_end;
; end
j8: ; else
rl w2 x1+a503 ; begin
jl. w3 n2. ; clear_process(main.proc_id);
jl. w3 n8. ; free_process(main.proc_id);
;
al. w3 o1. ; if main.result < 5 then
sh w0 5 ; begin
jl g19 ; deliver_result(main.result);
; goto common_end;
; end;
rl w2 0 ;
al w2 x2-8 ;
ls w2 1 ;
rl. w0 x2+i4. ;
rs w0 g20 ; answer_0 := status_table(main.result);
jl g18 ; deliver_result(1);
; goto common_end;
; end;
e. ; end;
\f
b. i10, j10 w. ;
o31: ; answer remove link
; --------------------
; begin
al w0 8.377 ; if main.result <> ok then
la w0 x1+a500 ; panic;
se w0 1 ;
jl -1 ;
;
rl w2 x1+a503 ; proc := main.proc_id;
rl w0 x2+a10 ;
sn w0 q8 ; if proc.kind = terminal then
jl. w3 n7. ; remove_attention_buffer(proc);
;
jl. w3 n8. ; free_process(proc);
;
al w2 x2+a54 ; clear_queue(normal, proc.event_q);
al w0 0 ;
jl. w3 n1. ;
;
rs w0 g20 ; answer_0 := 0; <* status *>
jl w3 g18 ; deliver_result(1);
;
jl. o1. ; goto common_end;
;
e. ; end;
\f
b. i10, j25 w. ; - - - data - - -
; ------ message ------
i0: -3<12 + 0 ; + 0: operation (= answer attention)
i1: 0 ; + 2: att_result, result
i2: 0 ; + 4: device_id
i3: 0 ; + 6: proc_id
i5: 0 ; internal receiver of att_message
i6: 0 ; remoter event_q
i7: 0 ; remoter message
;
o40: ; attention
; --------------------
; begin
; <* prepare answer attention message *>
dl w3 x1+a503 ; mess_2 := main.device_id;
ds. w3 i3. ; mess_3 := main.proc_id;
al w0 1 ; mess_1.att_result := ok; mess_1.result := ok;
rs. w0 i1. ; <* initialized to ok; might be changed later on *>
;
al w2 x3 ; proc := main.proc_id;
rl w0 x2+a10 ; if proc.kind = disk then
se w0 q6 ; begin
jl. j5. ;
;
al w0 8.377 ;
la w0 x1+a511 ; event := main.mess_1;
se w0 1 ; if event = intervention then
jl. j4. ; begin
;
al w0 l40 ; proc := proc.next_logical_disk;
j2: rl w2 x2+a70 ; while proc <> 0 do
sn w2 0 ; begin
jl. j3. ; proc.state := intervention;
hs w0 x2+a78+1 ; proc := proc.next_logical_disk;
jl. j2. ; end;
j3: jl. j20. ;
j4: sl w0 1 ; end else
sl w0 4 ; if envent <> test buffer full and event <> data correction performed then
jl -1 ; panic
jl. j20. ; end
j5: ; else
se w0 q18 ; if proc.kind = tape then
jl. j15. ; begin
;
al w0 8.377 ;
la w0 x1+a511 ; event := main.mess_1;
se w0 0 ; if event = online then
jl. j10. ; begin
;
al w0 l46 ; proc.document_state :=
rs w0 x2+a70 ; unidentified_document_mounted;
al w0 0 ; proc.name := 0;
rs w0 x2+a11 ;
rs w0 x2+a52 ; proc.reserver := 0;
;
rl w3 x2+a75 ; if proc.remoter<>0 then
sn w3 0 ; begin
jl. j9. ;
al w1 x3+a54 ; message:=proc.remoter.eventq.first;
rl w3 x1 ;
rs. w1 i6. ;
rs. w3 i7. ;
j6: sn. w3 (i6.) ; while message<>none do
jl. j9. ; begin
rl w0 x3+a140 ;
rs. w0 i7. ; if message.operation=wait for online and
zl w0 x3+a150 ; ((message.mode=specific main and
se w0 0 ; message.main=this main) or
jl. j8. ; message.mode=all main) then
zl w0 x3+a150+1 ; begin
so w0 2.1 ;
jl. j7. ;
rl w0 x3+a151 ;
se w0 (b19) ;
jl. j8. ;
j7: rs w3 b18 ; message.status:=0;
al w0 0 ; message.mt-addr:=proc;
rs w0 g20 ;
rs w2 g21 ;
jl w3 g18 ; deliver_result(1);
j8: rl. w2 i2. ; end;
rl. w3 i7. ; message:=message.next;
jl. j6. ; end ;
j9: ; end;
jl. j11. ; end
; else
j10: se w0 1 ; if event = offline then
jl -1 ; begin
al w0 l45 ; proc.document state := no document mounted;
rs w0 x2+a70 ;
al w0 0 ; proc.name := 0 ;
rs w0 x2+a11 ;
rs w0 x2+a52 ; proc.reserver := 0;
; end
; else panic; <* not defined *>;
j11: ;
jl. j20. ; end
j15: ; else
se w0 q8 ; if proc.kind = terminal or
sn w0 q9 ; proc.kind = ssp terminal then
sz ;
jl. j21. ; begin
;
rl w0 x2+a52 ; if terminal.reserver <> 0 then
sn w0 0 ; begin
jl. j16. ;
rl w0 x2+a71 ; if terminal.attention_buffer_address <> 0 then
se w0 0 ; goto skip_att_message; <* att already sent to
jl. j19. ; reserving internal *>
rl w2 x2+a74 ; att_receiver := terminal.att_receiver;
jl. j18. ; end
j16: ; else
al w2 x1+a514 ; begin
rl. w1 i3. ;
dl w1 x1+a49 ;
jl w3 d71 ; i := search_name(main.mess_4, terminal.name_base);
rl w2 x3 ; att_receiver := name_table(i);
rl w0 x2+a10 ; if i = name_table_end or
se w3 (b7) ; att_receiver.kind <> internal and
sz w0 -1-64 ; att_receiver.kind <> pseudo_process then
sz ; begin
jl. j18. ;
al w0 1 ; mess_1.att_result := unknown;
hs. w0 i1.+0 ; goto skip_att_message;
jl. j19. ;
; end;
; end;
j18: ;
rs. w2 i5. ; <* save att_receiver *>
rl. w1 i3. ;
al w2 0 ; if terminal.attention_buffer <> 0 then
rx w2 x1+a71 ; regret_message(terminal.attention_buffer);
se w2 0 ;
jl w3 d75 ;
am (b21) ;
zl w0 +a19 ;
sh w0 5 ; if bufferclaim.driverproc < 6 then
jl. j19. ; no message to receiver
rl. w1 i5. ;
rl w0 x1+a10 ; if att_receiver.kind = pseudo_process then
se w0 0 ; att_receiver := att_receiver.main;
rl w1 x1+a50 ;
rl. w2 i3. ;
jl w3 d126 ; insert_user(att_receiver, terminal);
rl w1 b19 ;
rl w0 x1+a511 ;
rs w0 g21 ; att_mess_1 := main.event; <*returned messages *>
;
ld w0 -48 ; <* clear att message *>
rs w0 g20 ;
ds w0 g23 ;
al w1 g20 ;
rl. w3 i5. ;
jd 1<11+17 ; send_att_message(message, terminal, att_receiver);
rl. w1 i3. ;
rs w2 x1+a71 ; terminal.attention_buffer := message_buffer;
;
j19: ; skip_att_message:
;
jl. j20. ; end
; else panic;
j21: se w0 q24 ; if proc_kind = ssp main then
jl -1 ; begin
rl w0 x1+a511 ;
se w0 1 ; if event<>temperatur_too_high and
sn w0 2 ; event<>power_warning then
jl -1 ; panic;
jl. j20. ; <* do nothing yet *>
; end;
;
j20: ;
rl w1 b19 ;
al. w2 i0. ;
jl. w3 n13. ; send_main_message(main, message);
jl. o1. ; goto common_end;
;
e. ; end;
\f
b. i10, j10 w. ; - - - data - - -
; --------- message ---------
; answer_remove_link_request remove_link
i4: 0 ; + 0: -2 < 12 + 0 10 < 12 + 0
i5: 0 ; + 2: result proc.devno
i6: 0 ; + 4: device_id proc address
i7: 0 ; + 6: proc_id (address)
;
o80: ; remove link request:
; --------------------
; begin
dl w3 x1+a503 ; mess_2 := main.device_id;
ds. w3 i7. ; mess_3 := proc := main.proc_id;
al w0 2.000111 ;
la w0 x3+a78 ;
sn w1 (x3+a50) ; mess_1 := <* result *>
se w0 l38 ; if proc.main <> main or
am 2 ; proc.state <> connected then
al w0 1 ; 3 else 1;
rs. w0 i5. ;
al w0 -2 ; mess_0.operations := -2;
hs. w0 i4.+0 ; <* answer remove link request *>
;
al. w2 i4. ;
jl. w3 n13. ; send_main_message(main, message);
;
rl. w0 i5. ; if message.result = ok <* mess_1 *>
se w0 1 ; begin
jl. j1. ;
;
rl w1 b19 ; <* main *>
rl w3 x1+a503 ; mess_1 := proc.device_no;
rl w2 x3+a59 ; mess_2 := proc;
ds. w3 i6. ;
al w0 10 ; mess_0.operation := remove_link;
hs. w0 i4.+0 ;
al. w2 i4. ;
jl. w3 n13. ; send_main_message(main, message);
; end;
j1: ;
jl. o1. ; goto common_end;
;
e. ; end <* ----- remove link request ----- *>
;
;
b. i10, j10 w.
o91: ; answer initialize controller;
al w0 8.377 ; begin
la w0 x1+a500 ;
se w0 1 ; if main.result <> ok then
jl -1 ; panic;
rl w0 x1+a511 ; main.free_buffers:=
hs w0 x1+a78+0 ; main.mess_1;
rl w0 x1+a78 ;
ea. w0 1 ; main.state:=connected;
hs w0 x1+a78+1 ; <* a bit diry - is was in state during connect *>
rl w0 x1+a502 ; main.supervisor_id:=
rs w0 x1+a76 ; main.device_id;
al w0 0 ;
rs w0 g20 ; answer_0:=0; <* status *>
jl w3 g18 ; deleiver_result(1);
jl. o1. ; goto common end;
e. ; end;
\f
b. i10, j10 w.
i2: 0 ; saved message to answer
o111: ; answer reset and answer stop
o121: ; ---------------------
al w0 8.377 ; begin
la w0 x1+a500 ;
se w0 1 ; if main.result <> ok then
jl -1 ; panic;
;
jl w3 d5 ; unlink(message);
rs. w2 i2. ; <* unlink and save message to prevent it from
; being returned with result 4 *>
jl. w3 n9. ; cleanup;
rl w1 b19 ;
al w0 3 ; main.free_buffers := 3;
hs w0 x1+a78+0 ; <* give it a few buffers to play with *>
al w0 0 ; main.controller_stat := ok and not busy;
hs w0 x1+a78+1 ; main.connect_state := free;
rs w0 g20 ; answer.status := 0;
al w0 1 ;
rs w0 x1+a86 ; main.no_of_outstanding := 1 <* it will be decreased at commen end *>
al w2 x1+a242 ;
se w2 (x2) ; if in timeout queue then
jl w3 d5 ; unlink (main, timeout_queue)
rl w0 x1+a511 ;
rs w0 g21 ; answer.mess_1 := main.mess_1;
rl. w0 i2. ;
rs w0 b18 ;
jl w3 g18 ; deliver_result(1);
jl. o1. ; goto common_end;
;
e. ; end;
\f
; timeout_interrupt ;
b. i4 w. ; <*** begin io result <> 0 ***>
i1: -4<12 + 0 ; stop
i2: 4<12 + 1 ; reset hard
o3:
c.l53 b. f4 w. ; ****** test 44 ******
rs. w3 f1. ;
rs. w1 f0. ;
jl. w3 (f3.) ;
44 ;
f0: 0 ; main
f1: 0 ;
jl. f2. ;
al w0 x1+a86 ; dump main.communication area
al w1 x1+a81+2 ;
jl. w3 (f4.) ;
jl. f2. ;
f3: d150 ;
f4: d151 ;
f2: ;
e.z. ; ****** end test 44 ******
al w0 0 ; clear interrupt
rs w0 x1+a244 ;
zl w0 x1+a78+1 ; if main.state = connected then
se w0 l38 ; message := stop communication
am i2-i1 ; else
al. w2 i1. ; message := reset hard
la w0 8.40 ; state := not ok
hs w0 x1+a78+1 ;
jl. w3 n13. ;
jl. o0. ; return
o2: ; power_interrupt:
c.l53 b. f4 w. ; ****** test 43 ******
rs. w3 f1. ;
rs. w1 f0. ;
jl. w3 (f3.) ;
43 ;
f0: 0 ; main
f1: 0 ;
jl. f2. ;
al w0 x1+a86 ; dump main.communication area
al w1 x1+a81+2 ;
jl. w3 (f4.) ;
jl. f2. ;
f3: d150 ;
f4: d151 ;
f2: ;
e.z. ; ****** end test 43 ******
al w3 0 ;
rs w3 x1+a244 ; clear interrupt
rs w3 x1+a78 ; main.free_buffers := 0; main.stat := free;
rl w2 x1+a10 ; insert timeout depending of kind
ws. w2 i3. ;
rl. w0 x2+i0. ; main.timeout := default
ds w0 x1+a87 ; main.no_of_outstanding := 0
jl. o0. ; return;
i0: 0 ; default timeout: 20 ida
0 ; - - - - - - - : 22 not used
0 ; - - - - - - - : 24 (not invented yet)
600000 ; - - - - - - - : 26 ifp
i3: 20
o1: ; common_end:
; --------------------
am (b19) ;
rl w1 +a59 ;
al w2 -1 ;
jd 1<11+128 ; start_controller(this main.device_no, answer_device);
rl w1 b19 ;
rl w0 b218 ;
la w0 x1+a500 ;
ls w0 -15 ;
jl. w3 d156. ; decrease no_of_outstanding(main,function);
rl w2 x1+a81 ; element := main.waiting_q.first;
sn w2 x1+a81 ; if element = none then
jl. o0. ; return;
al w0 0 ; force :=
sl w2 (b8+4) ;
sl w2 (b8+6) ; if element <> message then no
jl. i4. ;
al w0 2.1000000 ; else message.state.force;
la w0 x2+a138 ;
ls w0 -6
i4: ;
rl w1 x1+a59 ;
jd 1<11+128 ; start_controller(this main.device_no, message);
; end;
o0: jl (b20) ; goto driverproc.wait_event;
e. ; end <*** io result <> 0 **>
e. ; end <*** interrupt received ***>
\f
m. commen procedures
;
; ========================================================================
;
; common procedures used by main processes
;
; ========================================================================
;
;
; procedure start controller(force)
; ------------------------------------------------------------------------
;
; the controller supervised by current receiver (b19) will be started
; with current message (b18).
; controll will be returned to 'wait event' in driverproc.
; the parameter force will be passed to the procedure test_ready_and_setup.
;
; call
;
; w0 force
; w1 -
; w2 -
; w3 -
;
n0: ; procedure start controller;
rl w1 b19 ; begin
rl w1 x1+a59 ;
rl w2 b18 ; start_controller(force, this main.devno, message);
jd 1<11+128 ;
;
se w0 0 ; if result <> ok then
jl g4 ; deliver result(4)
jl (b20) ; else goto wait event;
; end;
\f
;
; procedure clear queue(io result,queue head);
; ------------------------------------------------------------------------
;
; all messages in the specified queue are returned with result 4.
; for each message the receiver is tested. if the receiver is a monitor
; driven driver then the receiver is changed to the driverprocess of the
; mainprocess. this will make it possible for driverproc to send the answer.
;
; call return
;
; w0 io result io result
; w1 - unchanged
; w2 queue head queue head
; w3 link destroyed
;
b. i10, j10 w.
n1: ; procedure clear queue(io result, queue head);
sn w2 (x2+0) ; begin
jl x3 ;
ds. w3 i3. ;
ds. w1 i1. ;
dl w1 b19 ;
ds. w1 i5. ;
; while not queue head.empty do
j1: rl w2 x2+0 ; begin
rs w2 b18 ; cur buf := queue head.first;
jl w3 g32 ; decrease stopcount(cur buf);
rl w2 b18 ;
ac w3 (x2+a141) ;
rl w0 x3+a10 ; if message.receiver.kind <> main_kinds then
se w0 q20 ; begin <* monitor driven driver *>
sn w0 q26 ; message.receiver := driverproc;
jl. j2. ; <* simulate that the message hasn't been claimed
rl w1 b21 ; this will force 'deliver result' to decrease
rs w1 x2+a141 ; bufferclaime of driverproc before sending the
; answer *>
; end;
j2: rl. w0 i0. ; message.io result := io result;
rs w0 g23 ;
al w0 4 ;
jl w3 g19 ; deliver result(4);
rl. w2 i2. ;
se w2 (x2+0) ;
jl. j1. ; end;
;
dl. w1 i5. ;
ds w1 b19 ;
dl. w1 i1. ;
jl. (i3.) ;
;
i0: 0 ; saved w0
i1: 0 ; saved w1
i2: 0 ; saved w2
i3: 0 ; saved w3
0 ; saved current buffer
i5: 0 ; saved current receiver
;
e. ; end;
\f
;
; procedure clear process(proc);
; ------------------------------------------------------------------------
;
; the specified process is cleared, i.e. name, users and reserver
; are zeroized.
;
; call return
;
; w0 - unchanged
; w1 - unchanged
; w2 proc proc
; w3 link link
;
b. i10, j10 w.
n2: ; procedure clear process(proc);
ds. w1 i1. ; begin
ld w1 -100 ;
ds w1 x2+a11+2 ; proc.name := 0;
rs w1 x2+a52 ; proc.reserver := 0;
;
j0: am x1 ; users := 0;
rs w0 x2+a402 ;
al w1 x1+2 ;
sh w1 a403-2 ;
jl. j0. ;
dl. w1 i1. ;
jl x3 ;
;
0 ; saved w0
i1: 0 ; saved w1
;
e. ; end;
;
\f
;
; procedure include all users(main, proc);
; -----------------------------------------------------------------------------
;
; all users of the main process are included as users of the specified process.
;
; call return
; w0 - destroyed
; w1 main main
; w2 proc proc
; w3 link destroyed
;
b. i10, j10 w.
n3: ; include all users
rs. w3 i3. ; begin
al w3 a401 ;
al w1 x1+a402 ; for i:=1 step 1 until no of words do
al w2 x2+a402 ; proc.userbittable(i) :=
j1: rl w0 x1 ; main.userbittable(i);
rs w0 x2 ;
al w1 x1+2 ;
al w2 x2+2 ;
al w3 x3-1 ;
se w3 0 ;
jl. j1. ;
al w1 x1-a48 ;
al w2 x2-a48 ;
jl. (i3.) ;
;
i3: 0 ; saved return;
e. ; end;
\f
;
; procedure decrease stopcount and deliver result_3(message);
; procedure decrease stopcount and deliver result_1(message);
; ------------------------------------------------------------------------------
;
; the stopcount of the sender of the message is decreased and the message is
; answered with result 3 or 1.
;
; call
; w0 -
; w1 -
; w2 message
; w3 -
;
b. i5, j5 w.
n4: ; decrease stopcount and deliver result 3:
am 1 ;
n5: al w0 0 ; decrease stopcount and deliver result 1:
rs. w0 i0. ; begin
jl w3 d132 ; decrease stopcount(message);
rl. w0 i0. ;
se w0 1 ; goto deliver result (3 or 1);
am g7-g5 ;
jl g5 ;
;
i0: 0 ;
e. ; end;
\f
; procedure remove_attention_buffer(proc)
; -----------------------------------------------------------------------------
;
; regretted message is called if an attention buffer exist
;
; call return
; w0 - unchanged
; w1 - unchanged
; w2 terminal unchanged
; w3 return address unchanged
;
b. i5, j5 w.
n7: ds. w3 i3. ; procedure remove_attention_buffer
al w3 x2 ; begin
al w2 0 ;
rx w2 x3+a71 ;
se w2 0 ; if proc.attention_buffer <> 0 then
jl w3 d75 ; regretted_message(proc.attention_buffer);
dl. w3 i3. ;
jl x3 ;
;
i2: 0 ;
i3: 0 ;
e. ; end;
\f
;
; procedure free_process(proc);
; -----------------------------------------------------------------------------
;
; the specified process is set free i.e. kind is set to free process and
; state is set to 'free'.
;
; call return
;
; w0 - unchanged
; w1 - unchanged
; w2 proc proc
; w3 link destroyed
;
b. i5, j5 w.
n8: ; free_process
rs. w0 i0. ; begin
al w0 q68 ;
rs w0 x2+a10 ; proc.kind := free;
ac w0 2.0111+1 ;
la w0 x2+a78 ;
lo. w0 i1. ;
hs w0 x2+a78+1 ; proc.state := free;
rl. w0 i0. ;
jl x3 ;
;
i0: 0 ; save w0
i1: l36 ; proc state free
;
e. ; end;
\f
;
; procedure cleanup
; -----------------------------------------------------------------------------
;
; The process complex in rc8000 concerning the controller supervised by the
; mainprocess in b19, is cleaned up, i.e. all pending messages are returned
; with result 4 and all processes for devices on the controller are removed.
;
; call return
; w0 - destroyed
; w1 - destroyed
; w2 - destroyed
; w3 link destroyed
b. i10, j10 w.
n9: ; begin
;
rs. w3 i3. ;
rl w1 b4 ;for proc := first external, next until last external do
j2: rl w2 x1 ; begin
rl w0 x2+a10 ;
rl w3 x2+a50 ;
se w3 (b19) ; if proc.main = this main and
jl. j3. ; proc.kind <> mainkind then
se w0 q20 ; begin
sn w0 q26 ; <* disc, mt or ifpgsd *>
jl. j3. ;
;
al w2 x2+a54 ;
rl w0 x2+a10 ; if proc.kind = terminal then
sn w0 q8 ; remove_attention_buffer(proc);
jl. w3 n7. ;
al w0 0 ;
jl. w3 n1. ; clear_queue(normal, proc.event_queue);
al w2 x2-a54 ;
jl. w3 n2. ; clear_process(proc);
jl. w3 n8. ; free_process();
jl. j4. ; end
; else
j3: se w2 (b19) ; if proc = this main then
jl. j4. ; begin
al w0 0 ;
al w2 x2+a54 ;
jl. w3 n1. ; clear queue(normal,this main.event queue);
al w2 x2-a54+a81;
jl. w3 n1. ; clear queue(normal,this main.waiting queue);
al w2 x2-a81 ;
al w3 0 ; this main.statistics := 0;
ds w0 x2+a216+2 ;
ds w0 x2+a218 ; end;
;
j4: al w1 x1+2 ;
se w1 (b5) ;
jl. j2. ; end;
jl. (i3.) ;
i3: 0 ; saved link
;
e. ; end;
\f
; procedure check_remoter(type, main, terminal)
; -----------------------------------------------------------------------------
;
; the message queue of the remoter is searched for an terminal supervisor
; message (operation = 2).
; if such a message is found the terminal is reserved and the internal is
; returned.
;
; call return
; w0 att type undefined
; w1 main main
; w2 terminal terminal
; w3 link internal_supervisor (reserver) or 0
;
b. i10, j10 w.
n12: ds. w3 i3. ; begin
ds. w1 i1. ;
al w0 0 ;
rs. w0 i4. ; internal_supervisor := 0;
rl w3 (b3) ;
al w0 x3+a54 ; message:= remoter.eventq.first;
rl w3 x3+a54 ; while message <> none do
rs. w0 i6. ; begin
j3: sn. w3 (i6.) ;
jl. j6. ;
rs. w3 i5. ;
zl w0 x3+a150+0 ; if message.operation = wait for connect then
se w0 2 ; begin
jl. j5. ;
zl w0 x3+a150+1 ; if (message.mode = all connections) or
so w0 2.1 ; (message.mode = specific main and
jl. j4. ; message.mainaddress = this main) then
rl w0 x3+a151 ; begin
se. w0 (i1.) ;
jl. j5. ;
j4: rl w1 x3+a142 ; sender:= message.sender;
rl w0 x1+a10 ; if sender.kind<>internal then
se w0 0 ; sender:=sender.main; <*pseudo proc*>
rl w1 x1+a50 ;
rl. w0 i0. ;
se w0 1<0 ; if type = connected then
jl. j6. ; begin
rs. w1 i4. ; internal_supervisor := sender;
jl w3 d125 ; include_reserver(sender, proc);
; end;
; end;
; end;
j5: rl. w3 i5. ;
rl w3 x3+a140 ; message:=message.next;
jl. j3. ; end;
j6: ; done:
dl. w2 i2. ; <* restore and return *>
rl. w0 i0. ;
rl. w3 i4. ; <* return reserving process *>
jl. (i3.) ;
;
i0: 0 ; save w0 att_type
i1: 0 ; w1 main
i2: 0 ; w2 terminal
i3: 0 ; w3 link
i4: 0 ; internal_supervisor or 0
i5: 0 ; remoter message
i6: 0 ; remoter queue
e. ; end;
\f
; procedure send_main_message(receiver, message);
; ----------------------------------------------------------------------------
;
; send the specified message to the receiver.
;
; call return
; w0 - destroyed
; w1 receiver destroyed
; w2 message destroyed
; w3 link destroyed
;
b. i5, j5 w.
i3: 0 ; saved return
i4: 0,0,0,0,0 ; namearea and nta
n13: ; send_main_message
rs. w3 i3. ; begin
dl w0 x1+a11+2 ; namearea := receiver.name;
ds. w0 i4.+2 ;
dl w0 x1+a11+6 ;
ds. w0 i4.+6 ;
al. w3 i4. ;
al w1 x2 ;
jd 1<11+16; send message(message, receiver.name);
jl. (i3.) ;
e. ; end;
\f
; procedure send_remoter_att(type, main, terminal)
; -----------------------------------------------------------------------------
;
; an attention message is sent to the internal process which has reserved the
; terminal process.
; the attention message has the following format:
;
; sender: terminal or main
; receiver: sender of message to remoter
; + 0 0 (attention)
; + 2 state (1<0: terminal connected, 1<1: terminal disconnected)
; + 4 terminal address
; + 6- +12 terminal name
;
; if state = disconnected mainproc is inserted as sender of att message
;
; call return
; w0 att type att type
; w1 main main
; w2 terminal terminal
; w3 link undefined
;
b. i10, j10 w.
n14: ds. w3 i3. ; begin
ds. w1 i1. ;
al w3 0 ; att_mess.mess_0 := 0;
ds w0 g21 ; att-mess.status := type;
rs w2 g22 ; att-mess.terminal := terminal
dl w0 x2+a11+2 ; att-mess.name := terminal.name
ds w0 g23+2 ;
dl w0 x2+a11+6 ;
ds w0 g23+6 ;
rl w3 x2+a74 ; receiver := terminal.att_receiver;
rl. w2 i2. ; if type = disconnect then
rl. w1 i0. ; sender := this main
sn w1 1<1 ; else
rl. w2 i1. ; sender := terminal;
al w1 g20 ;
jd 1<11+17; send_att_message(message, sender, receiver);
am. (i2.) ;
rs w2 +a71 ; terminal.att_buffer := buffer;
rl. w0 i0. ;
dl. w2 i2. ; <* restore and return *>
jl. (i3.) ;
;
i0: 0 ; save w0 att_type
i1: 0 ; w1 main
i2: 0 ; w2 terminal
i3: 0 ; w3 link
e. ; end;
e. ; end of main driver