Consolidate license copies
[its.git] / system / mtape.196
1 ;;; Copyright (c) 1999 Massachusetts Institute of Technology
2 ;;;
3 ;;; This program is free software; you can redistribute it and/or
4 ;;; modify it under the terms of the GNU General Public License as
5 ;;; published by the Free Software Foundation; either version 3 of the
6 ;;; License, or (at your option) any later version.
7 ;;;
8 ;;; This program is distributed in the hope that it will be useful,
9 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 ;;; General Public License for more details.
12 ;;;
13 ;;; You should have received a copy of the GNU General Public License
14 ;;; along with this program; if not, write to the Free Software
15 ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
17 ;********************************
18 ;**
19 ;** TO BE DONE:
20 ;**
21 ;** RECORDS LONGER THAN 1K
22 ;** AUTOMTAIC DETERMINATION OF DENSITY AND RECORD LENGTH WHEN READING
23 ;** ALLOW CLOSE WHEN TAPE HAS BEEN TAKEN OFF
24 ;** BE MORE FORGIVING OF CONTROLLER LOSSAGE
25 ;** PASS .MTAPE TO JOB DEVICE
26 ;** HAVE AN IGNORE ERRORS SWITCH
27 ;** THIS HORRIBLE BLETCHEROUS IOT CODE SHOULD BE REDESIGNED
28 ;**
29 ;********************************
30
31
32 IFN TM10A,TM10B==0
33 IFE TM10A,TM10B==1
34 IFN TM10A,INFORM IO BUSS MAG TAPE,1
35 IFN TM10B,INFORM DATA CHANNEL MAG TAPE,1
36 MSCBL==8        ; COMMAND BUFFER LENGTH
37 MGQDLL==6       ; INTERUPT LEVEL PDL
38 IF2 IFN MNUMB-140600, .ERR IMPLICIT DEPENDENCY ON MNUMB
39 MSEOFP==210100  ;HIGH BIT OF MNUMB IN MEMBLT IS EOF FLAG
40 MSCHN==140500   ;OTHER 5 BITS OF MNUMB IN MEMBLT IS DRIVE NUMBER
41
42 MTXP==410300,,  ;XPORT NUMBER
43 MUNITF==170300  ; UNIT FIELD IN MTC CONI
44 MNOPIN==10000
45 MWRITE==4000
46 MW3IN==14000
47 MSPRR==7000
48 MREAD==2000
49 MSPFR==6000
50 MSPFF==16000
51 MSPRF==17000
52 MREWND==1000
53 MRWNDD==11000
54 MWEOF==5000
55 MGNRTY==10.     ;NUMBER OF READ RETRIES
56 \f
57 SUBTTL MAG TAPE OPEN ROUTINE
58
59 ;       C/      MODE,,DEV
60 ;       D/      MODE (ROT 1) 4.9=1=>OUTPUT
61 ;       I/      DEVICE NUMBER
62 ;       R/      IOCHNM WORD POINTER
63
64 MAGTO:  SKIPL W,I       ; GET DEVICE
65          CAIL W,NMTCS   ; TO BIG?
66           JRST OPNL1    ; NO SUCH DEVICE
67         MOVSI T,%MAREW
68         TDNE T,MSRAC(W) ; REWINDING
69          PUSHJ P,UFLS   ; YES, THEN WAIT
70         CONO PI,CLKOFF  ; DON'T WANT STATUS CHANGED FROM UNDER ME
71         SKIPGE MTUSE(W) ; CHECK FOR FIRST USER
72          JRST MAGTU1    ; FIRST
73         CAME U,MTUSR(W) ;SAME USER
74          JRST OPNL10    ; DIFFERENT USER IS ERROR
75         MOVE B,D
76         EQV B,MSCRW(W)
77         SKIPL B         ; CHECK FOR SECOND OPEN IN SAME DIRECTION
78          JRST OPNL2     ; WRONG DIRECTION
79 MAGTU:  MOVEM U,MTUSR(W)        ; STORE USER
80         SETZM MSCRW(W)  ; INDICATE READ UNTIL FOUND TO BE OTHERWISE
81         TLNE C,1        ; READ OR WRITE
82          SETOM MSCRW(W) ;INDICATE WRITE
83         AOS MTUSE(W)    ;INDICATE 1 MORE USER
84         PUSHJ P,SOSSET
85             MTUSE(W)    ; SOS IF PCLSRED
86         CONO PI,CLKON   ; LET UM GET ME
87         PUSHJ P,MTSTAT  ; GET CONIS OF 340 AND 344 IN I AND J
88         MOVE A,MSRAC(W)
89         TLNE A,%MAERR   ; PI ERROR MEANS DEVICE NOT THERE
90          JRST MTOL1
91         TRNN J,200040
92          JRST OPNL7     ; DEVICE NOT ONLINE
93         SKIPN MSCRW(W)  ;WRITING?
94          JRST MTOW1
95         TRNE J,10       ; AND WRITE LOCKED
96          JRST OPNL26    ; DEVICE WRITELOCKED
97         SKIPE MSRAC(W)  ; WRITING
98          TRNN J,4000    ;EOT?
99           JRST MTOW1    ; NO
100         MOVSI A,%MAETW+%MAERR   ; IF WRITE AND EOT,MAKE .IOT GIVE IOC ERROR BUT LET OPEN WIN
101         IORM A,MSRAC(W)
102 MTOW1:  TRNN J,400000   ; XPORT HUNG
103          JRST MTOW2     ; OK
104         TRNN J,20000    ; OK IF REWINDING
105          JRST OPNL7     ;DEVICE NOT WORKING
106 MTOW2:  TLNN C,400      ; GET CORE DUMP MODE
107          JRST MTOW3
108         TLNN C,300
109          JRST MTOW3
110         TLC C,300
111         TLCE C,300      ; IBM AND DENSITY 800 BPI OK
112          JRST OPNL12    ; MODE NOT AVAILABLE
113 MTOW3:  ;BY THIS POINT OPEN WILL WIN
114         PUSHJ P,LSWDEL  ; RELEASE MTUSE SWITCH
115         MOVEI A,MTCCHN_3        ;SET UP MAG TAPE CONO
116 IFN TM10A,      TRO A,1 ; DATA PI CHANNEL
117         LDB B,[300200,,C]       ; GET DENSITY FROM OPEN
118         SKIPN B
119          MOVEI B,3
120         SUBI B,1        ; CONVERT TO PROPER PARITY
121         DPB B,[060200,,A]
122         TLNN C,400      ; CORE DUMP
123          TRO A,20000    ; YES
124         TLNN C,40       ; PARITY CHECK
125          TRO A,40000    ; SET ODD PARITY
126         DPB W,[170300,,A]       ; SET UNIT NUMBER
127         MOVEM A,MTCONO(W)       ; STORE IT
128         LDB B,[330300,,C]       ; GET WORDS PER BLOCK
129         TRC B,7
130         MOVEI A,10
131         LSH A,(B)       ;NUMBER OF WORDS PER RECORD
132         MOVEM A,MTBLKS(W)       ;BLOCKSIZE
133         LDB A,[230200,,C]       ; GET MODE (BUT NOT READ/WRITE BIT)
134         HLR C,MTOPTB(A) ; GET INPUT DISPATCH
135         TLNE D,400000   ; OPEN FOR OUTPUT?
136          HRR C,MTOPTB(A);CHANGE TO OUTPUT IF SO
137         MOVEM C,(R)     ;STORE IN IOCHNM
138         DPB W,[MTXP(R)] ; STORE XPORT NUMBER
139         JRST POPJ1      ; SKIP RETURN
140
141 MTOPTB: MTUAIX,,MTUAOX
142         MTBIX,,MTBOX
143         MTUIIX,,MTUIOX
144         MTBIX,,MTBOX
145
146 MAGTU1: SETZM MSBUFP(W) ; INDICATE NO BUFFERS ON CHAIN
147         SETZM MSNBOL(W) ; ANOTHER WAY OF SAYING ABOVE
148         SETZM MSMPRC(W) ; BUFFER WORDS REMAINING
149         SETZM MSMPRP(W) ; POINTER TO BUFFERS
150         SETOM MTMDN(W)  ;NO BUFFER AT MP
151         SETOM MGCABN(W) ;NONE AT PI
152         SETZM MSRAC(W)
153         MOVEI A,2
154         MOVEM A,MTCEFW(W)       ; NUMBER OF EOF'S WRITTEN
155         MOVSI A,%MANWT
156         IORM A,MSRAC(W) ; INDICATE NOTHING WRITTEN ON TAPE
157         JRST MAGTU
158
159 MTOL1:  SETZM MSRAC(W)
160         JRST OPNL1
161 \f
162 SUBTTL MAG TAPE INPUT .IOT ROUTINES
163
164         SKIPA B,[SIOKT]
165 MTUAI:   MOVEI B,CHRKTI ;UNIT ASCII INPUT
166         MOVE E,[440700,,5]
167         JRST MTREAD
168
169         SKIPA B,[SIOKT]
170 MTUII:   MOVEI B,CHRKTI ;UNIT IMAGE
171         MOVE E,[444400,,1]
172         JRST MTREAD
173
174 MTBI:   MOVE E,[444400,,1]      ;BLOCK INPUT
175         MOVEI B,BLKT
176 MTREAD: LDB W,[MTXP(R)] ; W <= XPT #
177         PUSHJ P,MTIECK
178         MOVEM P,MTPSAV(W)       ; SAVE P FOR EOF RETURN
179         JSP B,(B)       ;BLKT,CHRKT,SIOKT
180             MSMPRP(W)   ;LOC OF NEXT WORD
181             MSMPRC(W)   ;COUNT REMAINING
182             SETZ MTRBG  ; GET NEW BUFFER (SETZ FOR CHRKT RETURN ON EOF)
183             MTRBD       ; DISCARD BUFFER
184             JRST 4,.
185             PUSHJ P,MTRBFW      ; FLUSH INSTRUCTION WAIT FOR BUFFERS TO COME FROM PI
186
187 ;MAG TAPE READ BUFFER GET ROUTINE
188 ; BUFFER ASSUMED TO HAVE COME IN FROM PI LEVEL.  (I.E. MTRBFW WAS CALLED)
189
190 MTRBG:  SKIPG MSNBOL(W)         ;ANY BUFFER AVAILABLE?
191          JRST MTRBG3            ;NO, MUST BE ERROR OR EOF
192         CONO PI,UTCOFF
193         HLRZ A,MSBUFP(W)        ; GET IN POINTER
194         HRRZ TT,MSBUFP(W)       ; GET OUT POINTER
195         MOVEM TT,MTMDN(W)       ; STORE BUFFER ACTIVE AT MP
196         CAMN A,TT               ;IN = OUT?
197          JRST MTRBG1            ; YES
198         LDB T,[MLO,,MEMBLT(TT)] ; BACK POINTER TO NEXT BLOCK
199         HRRM T,MSBUFP(W)        ;STORE NEW OUT POINTER
200         JRST MTRBG2
201
202 MTRBG1: SETZM MSBUFP(W) ;EMPTY BUFFER LIST
203 MTRBG2: SOS MSNBOL(W)           ; ONE LESS BUFFER ON LIST
204         CONO PI,UTCON
205         LDB J,[MWC,,MEMBLT(TT)] ;WORD COUNT OF BLOCK
206         MOVEM J,MTBLKS(W)       ;SAVE FOR MTAPE 13
207         LSH TT,10.              ;MAKE BLOCK NUMBER AN ADDRESS
208         MOVEM TT,MSMPRP(W)
209         JRST SIOBGX
210
211 MTRBG3: SKIPGE MSRAC(W) .SEE %MAEOF
212          JRST [ MOVSI T,%MAEFA  ;THE EOF IS NOW NO LONGER READ-AHEAD
213                 ANDCAM T,MSRAC(W)       ;TELL THE USER ABOUT IT
214                 JRST POPJ2 ]
215         PUSHJ P,MTIECK
216         JRST 4,.                ;BULLSHIT, WHY DID MTRBFW SKIP?
217 \f
218 ;MAG TAPE READ BUFFER DISCARD ROUTINE
219 MTRBD:  SKIPGE A,MTMDN(W)       ; ANY BUFFERS
220          JRST MOVTWJ    ;SET UP T FOR BUFFER WAIT,RETURN
221         CONO PI,UTCOFF  ; SHUT UP WORLD
222         SETOM MTMDN(W)  ; NO BUFFER ACTIVE AT M.P.
223         SETZM MSMPRC(W)
224         LDB TT,[MSEOFP,,MEMBLT(A)]      ;GET EOF FLAG FROM PI
225         PUSHJ P,MGMEMR  ;RETURN MEM, TURN UTCON
226         JUMPN TT,MTRBD2 ;EOF?
227 MOVTWJ: MOVE T,W        ; T NEEDS CHANNEL NUMBER FOR BUFFER WAIT UFLUSH
228         POPJ P,         ;ALSO MTRBG, MTRBFW RELY ON THIS SETTING T
229
230 MTRBD2: MOVSI A,%MAEOF  ; SET EOF
231         IORM A,MSRAC(W)
232         JRST MOVTWJ
233
234 ;MAG TAPE READ WAIT FOR DATA ROUTINE
235 MTRBFW: SKIPG MSNBOL(T) ; ANY FREE BUFFERS ON LIST?
236          SKIPGE MSRAC(T) .SEE %MAEOF
237           JRST POPJ1    ;INPUT AVAILABLE, OR AT EOF, UNHANG
238         MOVE TT,MSRAC(T)
239         TLNE TT,%MAERR  ; CHECK FOR ERRORS
240          JRST POPJ1     ;WAKE UP SO YOU CAN GET YOUR IOC ERROR
241         TLNE TT,%MARAC  ; IF NOT ALREADY DONE SO, SEND OUT A CALL FOR TAPE READ
242          POPJ P,
243         PUSH P,W        ;THIS BEING DONE UNDER A UFLS. ONLY T GOOD
244         PUSH P,B
245         MOVE W,T
246         MOVEI B,MGREAD  ;WHERE TO GO AT PI LEVEL
247         MOVEI T,MSCBL   ;MAKE SURE THAT THERE IS ROOM IN THE RING BUFFER
248         CAMG T,MSCMDC(W)
249          JRST MTRBW2    ; NO ROOM, GO AWAY
250         MOVSI TT,%MARAC
251         IORM TT,MSRAC(W)        ;READ IS ACTIVE NOW, OR WILL BE SHORTLY
252         PUSHJ P,MTCMD1
253 MTRBW2: MOVE T,W
254         POP P,B
255         POP P,W
256         POPJ P,
257 \f
258 SUBTTL MAG TAPE OUTPUT .IOT ROUTINES
259
260         SKIPA B,[SIOKT]
261 MTUAO:   MOVEI B,CHRKT  ;UNIT ASCII OUTPUT
262         MOVE E,[440700,,5]
263         JRST MTWRIT
264
265         SKIPA B,[SIOKT]
266 MTUIO:   MOVEI B,CHRKT  ;UNIT IMAGE OUTPUT
267         MOVE E,[444400,,1]
268         JRST MTWRIT
269
270 MTBO:   MOVE E,[444400,,1]      ; BLOCK OUT
271         MOVEI B,BLKT
272 MTWRIT: LDB W,[MTXP(R)] ; GET XPORT NUMBER
273         PUSHJ P,MTIECK
274         HRLZI A,%MAETW  ; END OF TAPE CHECK
275         TDNE A,MSRAC(W)
276          JRST IOCER9
277         JSP B,(B)
278             SETZ MSMPRP(W)      ;LOC OF WORD
279             MSMPRC(W)   ; COUNT
280             SETZ MTWBFG ; GET NEW BUFFER
281             MTWBFD      ; WRITE OUT BUFFERS
282             JRST 4,.
283             TRNA        ;NO WAIT FOR BUFFER
284 \f
285 ;MAG TAPE WRITE BUFFER GET ROUTINE
286
287 MTWBFG: PUSHJ P,MTIECK
288         PUSHJ P,TCALL           ; TURN OFF UTC
289             JRST IOMQ
290          POPJ P,                ;GO BACK NO SKIP IF NO CORE
291         MOVEM A,MTMDN(W)        ; STORE ACTIVE BUFFER NUMBER
292         MOVEI T,MUMGB
293         DPB T,[MUR,,MEMBLT(A)]  ; TELL WORLD THAT IT IS A MAG TAPE BUFFER
294         DPB W,[MSCHN,,MEMBLT(A)]        ; CHANNEL NUMBER
295         SETZM TT
296         DPB A,[121000,,TT]      ;CONVERT BLOCK NUMBER TO ADDRESS IN TT
297         MOVE J,MTBLKS(W)        ;GET WRITE BLOCK SIZE
298         JRST SIOBGX
299
300 ;MAG TAPE WRITE BUFFER DISCARD ROUTINE
301
302 MTWBFD: PUSHJ P,MTIECK
303         SKIPGE A,MTMDN(W)
304          POPJ P,
305         MOVEI T,MSCBL
306         CAMG T,MSCMDC(W)
307          PUSHJ P,UFLS   ; MAKE SURE ROOM IN COMMAND BUFFER EXISTS IN CASE OF PCLSRING
308         MOVE T,MTBLKS(W)        ; DISCARD BUFFER. FIRST SEE HOW BIG IT IS
309         SUB T,MSMPRC(W)
310         CONO PI,UTCOFF  ;CAN'T TOLERATE ANY HANKY PANKY
311         SETOM MTMDN(W)  ;CLEAR IT
312         SETZM MSMPRC(W) ; CLEAR COUNT
313         JUMPE T,MEMR    ; DON'T DO ANYTHING BUT RETURN BLOCK IF NO WORDS
314         DPB T,[MWC,,MEMBLT(A)]  ; STORE WORD COUNT
315         SKIPG MSNBOL(W) ; LIST STARTED YET?
316          JRST MTWBD1    ;NO
317         HLRZ TT,MSBUFP(W)       ; GET OLD IN POINTER
318         DPB A,[MLO,,MEMBLT(TT)] ;CHAIN BACK
319         SKIPA
320 MTWBD1:  HRRM A,MSBUFP(W)       ; START NEW LIST
321         HRLM A,MSBUFP(W)        ; IN = OUT = (A)
322 MTWBD2: SETZM TT
323         DPB TT,[MLO,,MEMBLT(A)] ; INDICATE END OF LIST
324         AOS MSNBOL(W)   ; ONE MORE BUFFER ON LIST
325         CONO PI,UTCON
326         PUSH P,B
327         MOVEI B,MGWRIT
328         PUSHJ P,MTCMD   
329         MOVSI B,%MANWT
330         ANDCAM B,MSRAC(W)
331         SETZM MTCEFW(W) ; INDICATE SOMETHING WRITTEN
332         JRST POPBJ      ; RETURN
333 \f
334 SUBTTL MTCMD - GIVE COMMAND TO PI LEVEL
335
336 ;PUSHJ P,MTCMD
337         ;RH(W) HAS XPORT NUMBER
338         ;RH(B) HAS ADDR OF INTERUPT ROUTINE
339
340 MTCMD:  MOVEI T,MSCBL   ; COMAND BUFFER LENGTH
341         CAMG T,MSCMDC(W)        ;COMAND COUNT
342          PUSHJ P,UFLS   ; WAIT FOR ROOM
343 MTCMD1: MOVE T,MTCMBP(W)        ; GET POINTER TO RING BUFFER
344         AOBJN T,.+2
345          SUB T,[MSCBL,,MSCBL]   ; REACHED END OF BUFFER, RING IT
346         MOVEM B,(T)     ; STORE COMMAND
347         MOVEM T,MTCMBP(W)       ; STORE NEW POINTER
348         CONO PI,UTCOFF
349         AOS MSCMDC(W)   ; INDICATE ONE MORE COMMAND
350         JRST MSTRTR     ; START UP PI ROUTINE
351
352 SUBTTL MTIECK - CHECK FOR IOC ERROR
353
354 MTIECK: PUSH P,A        ; CHECK FOR IOTERR
355         MOVE A,MSRAC(W)
356         TLNN A,%MAERR   ; ERROR AT PI?
357          JRST POPAJ
358         SKIPLE MSCMDC(W)
359          PUSHJ P,UFLS   ; LET PI CLEAR BEFORE MUNGING BUFFERS
360         SKIPL A,MTMDN(W)
361          PUSHJ P,MEMR
362         SETOM MTMDN(W)
363         SETZM MSMPRP(W)
364         SETZM MSMPRP(W)
365         PUSHJ P,MTCBFF  ; FREE CHAIN
366         POP P,A
367         MOVE T,MGCMTS(W)        ; GET CONI MTS,
368         TRNE T,440000   ; XPT HUNG,ILLOP
369          JRST IOCER1
370         TRNE T,23600    ; PAR ERROR,R/C, RLI,DL,BT
371          JRST IOCER3    ; IRRECORVERABLE DATA ERROR
372         TRNE T,4000     ; EOT
373          JRST IOCER9    ; EOT, DEV FULL
374         MOVE A,MGEOFR(W)        ; LOGICAL EOT
375         CAIL A,2
376          JRST IOCER9
377         JRST IOCER3     ; UNKNOWN, GIVE IRR DATA
378 \f
379 SUBTTL MAG TAPE .STATUS ROUTINE
380
381 STAMTC: LDB W,[MTXP(R)] ; LOAD W
382         DPB A,[60300,,D]        ; OPEN MODE
383         PUSHJ P,MTSTAT
384         LDB A,[.BP %MAETW_22,MSRAC(W)]  ; EOT ON WRITE
385         LDB B,[.BP %MAETR_22,MSRAC(W)]  ; EOT ON READ
386         IOR A,B
387         DPB B,[140100,,D]       ;EOT
388         LDB A,[20100,,J]
389         TRC A,1
390         DPB A,[150100,,D]       ; 7 OR 9
391         LDB A,[160100,,MTCONO(W)]
392         TRC A,1
393         DPB A,[200100,,D]       ;PARITY
394         LDB A,[60200,,MTCONO(W)]        ; DENSITY
395         ADDI A,1
396         CAIN A,3
397          SETZM A        ; 800 IS 00
398         DPB A,[160200,,D]
399         LDB A,[.BP %MARCE_22,MSRAC(W)]  ; READ COMPARE ERROR
400         DPB A,[130100,,D]
401         MOVE A,MTCONO(W)
402         TRNN J,4        ; 7 TRACK
403          TRNE A,20000   ; OR CORE DUMP
404           POPJ P,       ; THEN DONE
405         TRO D,140000    ; IBM, 9 TRACK AND 800 BPI
406         POPJ P,
407
408
409 ;RCHST ROUTINE FOR MAG TAPE
410
411 RCHMGT: HLRZ E,(R)      ;OPEN-MODE IS KEPT IN LH OF IOCHNM WORD - HOW CONVENIENT!
412         LDB J,[MTXP(R)] ;GET THE MAG TAPE DRIVE NUMBER
413         MOVSI J,'MT0(J) ;RETURN THAT DRIVE'S DEVICE NAME.
414         TRZ E,(.BM MTXP) ;CLEAR THE PLACE IN THE OPEN-MODE THAT HAS THE DRIVE #.
415         JRST POPJ1      ;SKIP SO THAT J OVERRIDES BUILT-IN DEVICE NAME.
416
417 \fEBLK
418
419 SUBTTL MAG TAPE STORAGE AREA
420
421 MGVTC:  0       ; 1 SCRATCH WORD FOR VIRGIN TAPE CHECK
422 MGRWCD: BLOCK NMTCS     ; REWIND COMMAND
423 MGEOTT: BLOCK NMTCS     ; TIMEOUT FOR VIRGIN TAPE
424 MGJDTI: 0       ; WAIT FOR JOB DONE TIME OUT
425 MGEOFR: BLOCK NMTCS     ; NUMBER OF EOFS SINCE LAST READ
426 MGNWRD: 0       ; NUMBER OF WORDS READ IN A PI LEVEL READ
427 MTPSAV: BLOCK NMTCS     ; STORAGE TO RESTORE P ON EOF
428 MSRAC:  BLOCK NMTCS     ; MAG TAPE GENERAL GARBAGE
429  %MA==1,,525252
430  %MAEOF==400000         ; 4.9 EOF ON READ
431  %MAETR==200000         ; 4.8 EOT ON INTERNAL READ
432  %MAETW==100000         ; 4.7 EOT ON WRITE
433  %MAERR==040000         ; 4.6 PI ERROR
434  %MARCE==020000         ; 4.5 READ COMPARE ERROR
435  %MACTH==014000         ; 4.4 CORE ALLOCATOR SAYS STOP
436                         ; 4.3 "  (WHY 2 BITS?)
437  %MASTP==002000         ; 4.2 STOP READ AHEAD
438  %MANWT==001000         ; 4.1 NOTHING WRITTEN ON TAPE YET
439  %MAEFA==000400         ; 3.9 EOF SEEN ON READ-AHEAD, USER HASN'T SEEN YET
440  %MAESO==000200         ; 3.8 EOF READ SINCE OPEN
441  %MAMSO==000100         ; 3.7 TAPE MOVED SINCE FIRST OPEN
442  %MAREW==000040         ; 3.6 REWINDING FLAG
443  %MARAC==000020         ; 3.5 READ ACTIVE FLAG
444 MGTBZY: -1              ; FLAG TO GET INTURPT STARTED
445 MTCONO: REPEAT NMTCS,\.RPCNT_17+20      ; MAIN CONO STORAGE
446 MGUNIT: -1              ; UNIT EXPECTING INTERUPT
447 MGCMTS: BLOCK NMTCS     ; PI CONI MTS STORAGE
448 MGCMTC: BLOCK NMTCS     ; PI MTC STORAGE
449 MGWCW:  0               ; WAIT FOR CONTROL WORD WRITTEN FLAG
450 LMIOWD: 0               ; LAST MIOWD
451 MGERRC: BLOCK NMTCS     ; ERROR COUNT
452 MTMFNC: BLOCK NMTCS     ; .MTAPE FUNCTION STORAGE
453 MTMCNT: BLOCK NMTCS     ; .MTAPE COUNT
454 MTMTAP: BLOCK NMTCS     ; MTAPE CALL WORD
455 MTCEFW: BLOCK NMTCS     ; NUMBER OF EOF'S WRITTEN AT CLOSE
456 MSCMDC: REPEAT NMTCS,0  ; NUMBER OF COMMANDS
457 MSBUFP: REPEAT NMTCS,0  ; MAG TAPE BUFFER POINTER  IN,,OUT
458 MSCRW:  BLOCK NMTCS     ; -1=>OUTPUT 0=>INPUT
459 MSMPRC: BLOCK NMTCS     ; WORDS LEFT IN BUFFER
460 MSMPRP: BLOCK NMTCS     ;NEXT WORD IN BUFFER
461 MTMDN:  REPEAT NMTCS,-1 ; BLOCK ACTIVE AT MP
462 MTUSE:  REPEAT NMTCS,-1 ; NUMBER OF CHANNELS OPEN ON THIS MTAPE
463 MTUSR:  REPEAT NMTCS,-1 ; USER INDEX OF XPORT
464 MSNBOL: BLOCK NMTCS     ; NUMBER OF BUFFERS ON LIST
465 MGCABN: REPEAT NMTCS,-1 ; BUFFER ACTIVE AT PI LEVEL
466 MTBLKS: BLOCK NMTCS     ; WRITE, BUFFER SIZE
467                         ; READ, SIZE OF LAST RECORD READ
468 MGQDLP: REPEAT NMTCS,-MGQDLL,,CONC MGQD,\.RPCNT,-1      ;QDL POINTER
469 REPEAT NMTCS,[
470         CONC MSCB,\.RPCNT,:     BLOCK MSCBL     ; COMMAND BUFFER
471                                 MGRCV   ; TO RING BUFFER
472
473                                 MGNCMD  ; GET NEW COMMAND
474         CONC MGQD,\.RPCNT,:     BLOCK MGQDLL
475         IFE .RPCNT,MSLCTB==.-MSCB0      ; LENGTH OF EACH TABLE
476 ]
477 MTCMBP: REPEAT NMTCS,-MSCBL-1,,CONC MSCB,\.RPCNT,-1     ; INPUT TO COMMAND TABLE
478 MGCMBP: REPEAT NMTCS,4400,,CONC MSCB,\.RPCNT,-1 ; OUTPUT FROM COMAND TABLE
479 IFE KL10P,MIOWD: BLOCK 2        ; CHANNEL PROGRAM
480 IFN TM10A,[
481 MGDBRK: 0
482         CONO MTS,1
483         JRST 12,@MGDBRK
484 ];TM10A
485 MGEMTC: 0       ;CONI MTC, AT LAST ERROR
486 MGEMTS: 0       ;CONI MTS, AT LAST ERROR
487 BBLK
488 \f
489 SUBTTL MAG TAPE PI LEVEL
490
491 ;ROUTINES TO GET INTERUPT ROUTINES STARTED
492 MGXGO:  MOVE Q,MGQDLP(W)        ;GET QDLPOINTER
493         PUSHJ P,QPOPJ   ;CALL ROUTINE . SHOULD FINISH WITH POPJ P,OR PUSHJ Q,CPOPJ
494                         ;PUSHJ Q,CPOPJ IF ROUTINE WANTS TO RETURN
495                         ;POPJ P, IF AT END OF COMAND. AND NEW IS TO BE GOTTEN
496         MOVEM Q,MGQDLP(W)       ; STORE NEW QDL
497         POPJ P,
498
499 MGRCV:  MOVNI A,MSCBL+1 ;AT END OF COMAND LIST,RING IT
500         ADDM A,MGCMBP(W)        ;RING THE BUFFER
501 MGNCM1: ILDB B,MGCMBP(W)        ; GET NEW COMMAND
502         JRST (B)
503
504 MGNCMD: AOBJN Q,MGNCM1  ; AT BOTTOM OF QDL, SIMULATE PUSHJ AND GET NEW COMMAND
505         JRST 4,.        ;QDL POINTER CLOBBERED
506
507 QPOPJ1: AOS (Q)
508 QPOPJ:  POPJ Q,
509
510 MSTRTR: CONO PI,UTCOFF  ; GET MAGTAPE INTURPT STARTED
511         SETZM MGTBZY
512         CONO PI,MTCRQ
513         CONO PI,UTCON
514         POPJ P,
515
516 ;HERE FOR MAG TAPE FLAG CHANNEL INTERUPT
517 MGHBRK: SKIPGE W,MGUNIT ; LOAD UNIT
518          JRST MGUBRK    ;NO ONE WANTS IT
519         LDB B,[MUNITF,,A]
520         CAME W,B        ; UNITS AGREE
521          JRST 4,.       ; WE MUST NOT MIX UNITS
522         MOVE J,C
523         PUSH P,[DSKEX]
524 IFN TM10B,[
525         TLNE C,160
526          JRST MGERR
527 ];TM10B
528         TRNE C,40000
529          JRST MGERR
530         JRST MGXGO
531
532 MGSBRK: SETOM MGTBZY    ;HERE FOR ANY RANDOM MP PI STARTUP
533         MOVEI B,NMTCS-1
534         SKIPG MSCMDC(B) ;ANY COMMANDS IN BUFFER
535 MGSBK1:  SOJGE B,.-1
536         SKIPGE B        ;LAST UNIT?
537          JRST DSKEX     ; THEN GOTO DSKEX
538         MOVE W,B
539         PUSH P,B
540         MOVSI B,%MACTH
541         TDNN B,MSRAC(W) ; CORE ALLOCATOR SAYING GO AWAY
542          PUSHJ P,MGXGO  ; START UP THAT ROUTINE
543         POP P,B
544         JRST MGSBK1     ; ANY MORE?
545
546 MGUBRK: LDB W,[MUNITF,,A]       ; WHO CAUSED INTERUPT?
547         MOVE B,MTCONO(W)
548         CONO MTC,(B)
549         CONO MTS,31     ; CLEAR INTERUPT
550         JRST DSKEX
551 \f
552 ;       ROUTINE TO WAIT FOR JOB DONE TO SET
553 MGWTJD: CONI MTS,J
554         TRNE J,440000   ;SKIP IF STARTED SUCCESSFULLY
555          JRST MGERR     ;JOB-DONE ISN'T EVER GOING TO SET
556 MGWJD1: CONI MTS,J
557         SKIPN MGJDTI    ; TIME OUT?
558          JRST MGWJD2
559         MOVE T,TIME
560         CAML T,MGJDTI
561          JRST MGERR
562 MGWJD2: TRNN J,100      ; JOB DONE?
563          JRST MGOVER    ; NOT SET
564         CONI MTS,J
565         CONI MTC,I      ; GET CONI MTC
566         MOVEM J,MGCMTS(W)
567         MOVEM I,MGCMTC(W)
568         SKIPE MGWCW     ; SHOULD I WAIT FOR CONTROL WORD WRITTEN
569          PUSHJ Q,MGWCWC ; CHECK TO SEE IF IT IS WRITTEN
570         SETZM MGWCW     ;CLEAR FLAG
571         CONO MTS,30     ; CLEAR CHANNEL CONDITIONS
572         MOVE B,MTCONO(W)
573         CONO MTC,(B)    ; RELESE MTC, CLEAR JOB DONE
574 IFN TM10B,[
575         TLNE J,160
576          POPJ Q,        ;CHANNEL ERROR
577 ]
578         TRNE J,463600
579          POPJ Q,        ; RANDOM OTHER NON PERFECTIONS, NOT NECESSARILY ERRORS
580         JRST QPOPJ1     ; SUCCESS
581
582 ;       GET XPORT
583 MGGXPT: CONSO MTS,2     ; LOAD NEXT UNIT SET?
584          JRST MGOVER    ; NO, WAIT FOR IT
585         MOVEM W,MGUNIT
586         MOVE T,TIME
587         ADDI T,10.*30.  ; TIME OUT IN 10. SECONDS
588         MOVEM T,MGJDTI
589         MOVE B,MTCONO(W)
590         CONO MTC,MNOPIN(B)      ; SELECT DRIVE
591         PUSHJ Q,MGWJD1
592          JFCL           ; WAIT FOR JOB DONE, BUT ALLOW ANY ERRORS
593         SETZM MGJDTI
594         POPJ Q,
595
596 MGOVER: CONSZ MTS,440020        ; ANY PROBLEMS?
597          JRST MGERR     ;TAPE HUNG, ILL FUNCTION, CHANNEL ERROR
598         SOS (Q)
599         POPJ P,
600
601 ;ERROR
602 MGERR:  CONI MTS,MGEMTS
603         CONI MTC,MGEMTC
604         MOVSI T,%MARAC  ;READ NOT ACTIVE, FOR SURE
605         ANDCAM T,MSRAC(W)
606         SETZM MSCMDC(W) ; NO COMMANDS
607         SETOM MGUNIT    ; CLEAR UNIT WAIT FLAG
608         SETZM MGJDTI
609 IFN TM10B,[
610         TLNE J,160      ; CHANNEL ERROR?
611          BUG PAUSE,[MTAPE: CHANNEL ERROR, STATUS=],OCT,J,[MICWA+1=],OCT,MICWA+1,[MIOWD=],OCT,MIOWD
612 ];TM10B
613         SKIPL A,MGCABN(W)       ; ANY PI BUFFERS?
614          PUSHJ P,IMEMR
615         SETOM MGCABN(W)
616         HRLZI B,%MAERR  ; PI ERROR
617         IORM B,MSRAC(W) ; STORE IN STATUS WORD
618         MOVE Q,[-MGQDLL,,MGQD0-1]
619         MOVE T,MSLCTB
620         IMUL T,W
621         ADD Q,T         ; RESTORE Q
622         PUSH P,Q
623         MOVE Q,[-MSCBL-1,,MSCB0-1]
624         ADD Q,T
625         MOVEM Q,MTCMBP(W)       ; INITIALIZE MP AND PI COMMND POINTERS
626         MOVE Q,[4400,,MSCB0-1]
627         ADD Q,T
628         MOVEM Q,MGCMBP(W)
629         MOVSI B,%MAREW
630         ANDCAM B,MSRAC(W)       ; CLEAR REWINDING
631         SKIPN MSCRW(W)  ; DONE IF READING
632          JRST POPQJ
633         SKIPN MSNBOL(W) ; ANY BUFFERS ON LIST?
634          JRST POPQJ
635 MGERR1: HRRZ A,MSBUFP(W)
636         PUSHJ P,MTICL1
637         PUSHJ P,IMEMR
638         SOSLE MSNBOL(W) ; ANY MORE
639          JRST MGERR1
640         SETZM MSBUFP(W) ;EMPTY LIST
641         JRST POPQJ
642
643 MGWCWC:
644 IFN TM10B,[
645         SKIPE MICWA+1   ; CONTROL WORD WRITTEN?
646          POPJ Q,
647         CONO MTS,4      ; TELL IT TO WRITE IT
648 MGWCW1: SKIPE MICWA+1
649          JRST MGWCW2    ; DONE
650         PUSHJ Q,CPOPJ   ; WAIT
651         JRST MGWCW1
652
653 MGWCW2: MOVE I,MGCMTC(W)
654         MOVE J,MGCMTS(W)        ;RESTORE STATUS
655         TLO J,10        ;SET CONTROL WORD WRITTEN
656 ]               ;END OF IFN TM10B
657         POPJ Q,
658
659 IFN TM10A,[
660 MGDCSI: SKIPA A,[BLKI MTC,MIOWD]
661 MGDCSO:  MOVE A,[BLKO MTC,MIOWD]
662         MOVEM A,MAGLOC
663         MOVE A,[JSR MGDBRK]
664         MOVEM A,MAGLOC+1
665         POPJ Q,
666 ]               ;END OF IFN TM10A
667 \f
668 SUBTTL MAG TAPE PI LEVEL WRITE
669
670 MGWRIT: PUSHJ Q,MGGXPT  ; GET XPORT
671         TRNE J,600010   ; WRITE LOCKED,HUNG OR REWINDING
672          JRST MGERR
673         MOVEM W,MGUNIT  ; SET UNIT
674         MOVSI A,%MACTH  ; CORE ALLOC WANT QUIT TEMPORARLY
675         TDNE A,MSRAC(W)
676          JRST MGWRT4
677         HRRZ A,MSBUFP(W)        ; GET BUFFER POINTER
678         HLRZ B,MSBUFP(W)        ; IN POINTER
679         SOS MSNBOL(W)   ; ONE LESS BUFFER
680         MOVEM A,MGCABN(W)       ; BUFFER ACTIVE AT PI
681         SKIPN MSCRW(W)  ; WRITING
682          JRST 4,.
683         CAME A,B        ; IN = OUT
684          JRST MGWRT1
685         SETZM MSBUFP(W) ; EMPTY BUFFER LIST
686         JRST MGWRT2
687
688 MGWRT1: LDB B,[MLO,,MEMBLT(A)]  ; BACK POINTER
689         HRRM B,MSBUFP(W)        ; NEW OUT POINTER
690 MGWRT2: LDB B,[MWC,,MEMBLT(A)]  ; WORD COUNT
691         MOVNS B         ; NEGATE
692         HRLZS B         ; FORM COUNT
693 IFN KL10P, LSH B,4      ; SHIFT IF KL10 DATA CHANNEL
694 IFN KL10P, MOVE R,A     ; SAVE CORE PAGE NUMBER FOR CACHE SWEEP
695         LSH A,10.       ; FORM WORD POINTER
696         SUBI A,1
697         HRRM A,B        ; CHANNEL POINTER IN B
698 IFN TM10B,      DATAO MTS,[MICWA]       ; SET TO GO TO MAG TAPE
699 IFN TM10A,      PUSHJ Q,MGDCSO
700         MOVEM B,MIOWD
701         MOVEM B,LMIOWD  ; LAST MIOWD
702         SETZM MIOWD+1   ; TELL CHANNEL TO STOP
703 IFN KL10P,[
704         PUSHJ P,CSHSWP  ; UNLOAD BUFFER FROM CACHE INTO CORE
705           CAI
706 ]
707         MOVE B,MTCONO(W)
708         CONO MTC,MWRITE(B)      ; DO IT
709         PUSHJ Q,MGWTJD  ; WAIT FOR JOB DONE
710          JRST MGWBT     ; WRITE BLANK TAPE AND TRY AGAIN
711 MGWRT3: MOVE A,MGCABN(W)        ; GET BUFFER NUMBER
712         HRLZI B,%MAETW+%MAERR   ; END OF TAPE CHECK
713         TRNE J,4000     ; END POINT
714          IORM B,MSRAC(W)        ; TELL MP
715         LDB T,[MUR,,MEMBLT(A)]
716         CAIE T,MUMGB    ; DO I OWN BLOCK
717          JRST 4,.
718         SETOM MGCABN(W) ; NO BUFFER ACTIVE AT PI
719         PUSHJ P,IMEMR   ; GIVE BACK BUFFER
720         MOVSI A,%MAMSO
721         IORM A,MSRAC(W) ; TAPE MOVEMENT
722         JRST MGCMDR
723
724 MGWBT:
725 IFN TM10B,      SETZM MIOWD     ; WRITE BLANK TAPE OVER POSSIBLE BAD SPOT
726 IFN TM10A,[
727         MOVE A,[-1,,MGVTC-1]
728         MOVEM A,MIOWD   ; ONE RECORD
729 ]
730         TRNE J,644010   ; BAD TYPES OF ERRORS
731          JRST MGERR
732         MOVE B,MTCONO(W)
733         CONO MTC,MSPRR(B)       ; REVERSE 1 RECORD
734         PUSHJ Q,MGWTJD  ; WAIT FOR JOB DONE
735          JRST MGERR     ; ERROR
736         MOVE B,LMIOWD
737         MOVEM B,MIOWD   ; RESTORE MIOWD
738         MOVE B,MTCONO(W)
739         CONO MTC,14000(B)       ; WRITE WITH EXTENDED EOR
740         PUSHJ Q,MGWTJD  ; WAIT
741          JRST MGWBT     ; INFINITE RETRIES ;    JRST MGERR      ; ERRORS
742         JRST MGWRT3
743
744 MGWRT4: PUSHJ Q,CPOPJ   ; WAIT A WHILE
745         JRST MGWRIT
746 \f
747 SUBTTL MAG TAPE PI LEVEL READ
748
749 MGREAD: PUSHJ Q,MGGXPT  ; GET XPORT
750 MGRD0:  TRNE J,600000   ; UNIT HUNG OR REWINDING OR EOT
751          JRST MGERR
752         MOVE B,MGEOFR(W)        ; EOF'S READ
753         CAIL B,2
754          JRST MGERR
755         MOVEM W,MGUNIT  ; STORE UNIT NUMBER
756         SKIPE MSCRW(W)  ; MAKE SURE READING
757          JRST 4,.
758         MOVSI B,%MACTH  ; CORE ALLOCATOR WANT OUT
759         TDNN B,MSRAC(W)
760          PUSHJ P,IOMQ
761           JRST MGROVR   ; WAIT FOR IT
762         MOVEM A,MGCABN(W)       ; STORE ACTIVE BUFFER AT PI LEVEL
763         MOVEI B,MUMGB
764         DPB B,[MUR,,MEMBLT(A)]  ; CLAIM BLOCK
765         HRREI B,-MGNRTY ; NUMBER OF RETRIES
766         MOVEM B,MGERRC(W)       ; STORE ERROR COUNT
767 IFN KL10P, MOVE R,A
768         LSH A,10.       ; FORM ADDRESS
769         SUBI A,1
770 IFE KL10P,      HRLI B,-2000
771 IFN KL10P,      HRLI B,-2000_4
772         HRR B,A
773         MOVEM B,LMIOWD  ; STORE LAST IOWD FOR RETRY
774 IFN TM10B,      DATAO MTS,[MICWA]       ; SET CHANNEL STARTING ADDRESS
775 IFN TM10A,      PUSHJ Q,MGDCSI
776 IFN TM10B,      SETZM MICWA+1
777         SETZM MIOWD+1
778 MGRD1:  MOVEM B,MIOWD   ; CHANNEL COMMAND
779         MOVEI B,2000
780         MOVEM B,MGNWRD  ; ASSUME AT FIRST THAT THE RECORD TO BE READ HAS 2000 WORDS
781 IFN KL10P,[
782         PUSHJ P,CSHSWP  ; ENSURE NO RESIDUE OF THIS PAGE IN CACHE
783             CAIA
784 ]
785         MOVE B,MTCONO(W)
786         CONO MTC,MREAD(B)       ; DO IT
787 IFN TM10B,      SETOM MGWCW     ; TELL IT TO WAIT FOR CONTROL WORD WRITTEN
788         PUSHJ Q,MGWTJD  ; WAIT FOR JOB DONE
789          JRST MGRERR
790 MGRD2:  SKIPG A,MGCABN(W)
791          BUG                    ;BUFFER SHOULDN'T BE -1, WOULD SCREW UP MEMBLT
792         SETOM MGCABN(W)         ; NO BUFFER ACTIVE AT PI
793         HLRZ T,MSBUFP(W)        ;LAST BUFFER IN
794         SETZM B
795         DPB B,[MLO,,MEMBLT(A)]  ;  BACK POINTER IS 0
796         SKIPG MSNBOL(W)
797          HRRM A,MSBUFP(W)       ; ONE BUFFER MEANS IN = OUT
798         HRLM A,MSBUFP(W)        ; NEW IN POINTER
799         SKIPLE MSNBOL(W)
800          DPB A,[MLO,,MEMBLT(T)] ; CHAIN BACK BUFFERS
801         AOS C,MSNBOL(W)         ; ONE MORE BUFFER ON LIST (COUNT TO C)
802         MOVE B,MGNWRD
803         DPB B,[MWC,,MEMBLT(A)]  ; NUMBER OF WORDS IN BUFFER
804         TRNE J,10000            ;EOF?
805          JRST [ MOVSI B,%MAESO+%MAEFA   ;YES
806                 IORM B,MSRAC(W)
807                 SETO B,
808                 DPB B,[MSEOFP,,MEMBLT(A)]
809                 AOS A,MGEOFR(W)
810                 CAIL A,2
811                  JRST MGRD4     ; LOGICAL EOT, SPACE BACK OVER IT
812                 JRST .+2 ]
813           SETZM MGEOFR(W)       ; NO EOF
814         MOVSI A,%MAMSO
815         IORB A,MSRAC(W) ; TAPE MOVEMENT
816         TRNE J,4000     ; EOT?
817          JRST MGRD3
818         TRNN J,10000            ;IF NO EOF, NOT 6 BUFFERS YET,
819          CAIL C,6
820           JRST MGRD5
821         TLNN A,%MASTP
822          JRST MGRD0             ; AND NO REQUEST TO STOP, KEEP READING
823 MGRD5:  MOVSI A,%MASTP+%MARAC   ;GIVE UP FOR NOW, CLEAR READ ACTIVE
824         ANDCAM A,MSRAC(W)
825         JRST MGCMDR             ;MP LEVEL WILL SEND NEW READ COMMAND WHEN READY
826 \f
827 MGRD3:  DPB B,[MSEOFP,,MEMBLT(A)]       ;PHYSICAL EOT
828         DPB B,[420100,,MSRAC(W)] .SEE %MAETR    ; INDICATE EOT ON READ
829         JRST MGRD5      ; RETURN
830
831 MGRD4:  MOVSI A,%MAESO+%MARAC+%MASTP    ;SECOND EOF, LOGICAL EOT
832         ANDCAM A,MSRAC(W)
833         JRST MGSPRF
834
835 MGRERR:
836 IFN TM10B,[
837         TLNE J,160
838          JRST MGERR     ; CHANNEL ERROR
839 ]
840         TRNE J,642000
841          JRST MGERR
842         TRNE J,20600
843          JRST MGMRT     ; DATA TYPE OF ERROR OR OVERRUN, MAYBE TRY AGAIN
844 ;RECORD LENGTH ERROR, ADJUST MGNWRD
845 IFN TM10B,      HRRZ A,MICWA+1
846 IFN TM10A,      HRRZ A,MIOWD
847         HRRZ B,LMIOWD
848         SUB A,B
849 IFN TM10B,      SOS A   ; CHANNEL FUNNYNESS
850         CAIN A,1        ; POS EOF IS ALL
851          JRST MGRER2
852 MGRER1: MOVEM A,MGNWRD
853         JRST MGRD2
854
855 MGRER2: TRNE J,14000    ; 1 WORD, EOF? EOT?
856          SETZM A        ; YES, THIS RECORD HAS ZERO LENGTH, IT JUST CARRIES MSEOFP
857         JRST MGRER1
858
859 MGMRT:  AOSL MGERRC(W)
860          JRST MGERR     ; TOO MANY ERRORS
861 IFN TM10B,      SETZM MIOWD
862 IFN TM10A,[
863         MOVE A,[-1,,MGVTC-1]
864         MOVEM A,MIOWD   ; ONE RECORD
865         PUSHJ Q,MGDCSO
866 ]
867         MOVE B,MTCONO(W)
868         CONO MTC,MSPRR(B)       ; REVERSE RECORD
869         PUSHJ Q,MGWTJD
870          JRST MGERR     ; NO ERRORS ALLOWED
871 IFN TM10A,      PUSHJ Q,MGDCSI  ; PUT BACK PI 1 BLKI
872         MOVE B,LMIOWD
873         JRST MGRD1      ; TRY AGAIN
874
875 MGROVR: PUSHJ Q,CPOPJ
876         JRST MGREAD
877 \f
878 SUBTTL MAG TAPE PI LEVEL SPACE
879
880 MGSPCF: PUSHJ Q,MGGXPT  ; GET XPORT SPACE FORWARD
881         TRNE J,600000
882          JRST MGERR
883 MGSPC:  MOVEM W,MGUNIT
884         MOVE B,MGRWCD(W)        ; GET COMMAND
885         ADD B,MTCONO(W)
886 IFN TM10B,[
887         SETZM MIOWD
888         DATAO MTS,[MICWA]
889 ]
890 IFN TM10A,[
891         MOVE A,[-1,,MGVTC-1]
892         MOVEM A,MIOWD
893         PUSHJ Q,MGDCSO
894 ]
895         CONO MTC,(B)    ; DO IT
896         PUSHJ Q,MGWTJD
897          JRST MGERR     ; NO RETRIES
898         TRNN J,10000    ; EOF
899          SETZB B,MGEOFR(W)
900         TRNE J,10000
901          AOS B,MGEOFR(W)
902         CAIL B,2        ;TOO MANY EOF'S
903          JRST MGSPRF
904 MGCMDR: SOS MSCMDC(W)   ; GENERAL EXIT ROUTINE
905         SETOM MGUNIT
906         SKIPG MSCMDC(W)
907          POPJ P,        ; NO MORE
908         MOVE B,MTCONO(W)
909         CONO MTC,MNOPIN(B)      ; INTERUPT WHEN UNIT READY
910         MOVEM W,MGUNIT  ; RESTORE UNIT NUMBER
911         PUSHJ Q,MGWTJD
912          JRST MGERR
913         SETOM MGUNIT
914         POPJ Q,         ; MORE
915
916 MGSPFR: MOVEI B,MSPFR   ; SPACE FOR RECORD
917         MOVEM B,MGRWCD(W)
918         MOVSI B,%MAMSO
919         IORM B,MSRAC(W) ; TAPE MOVEMENT
920         JRST MGSPCF
921
922 MGSPFF: MOVSI B,%MAESO
923         TDZE B,MSRAC(W)
924          JRST MGCMDR    ; EOF ALREADY READ DURING THE READ
925         AOS MSCMDC(W)   ;SO IT WILL RETURN
926         MOVEI B,MSPFR
927         MOVEM B,MGRWCD(W)
928         PUSHJ Q,MGSPCF
929         SKIPE MGEOFR(W)
930          JRST MGCMDR    ; EOF READ ON SPACE RECORD. DONE
931         MOVEI B,MSPFF
932         MOVEM B,MGRWCD(W)
933         JRST MGSPCF
934
935 MGSPRR: MOVEI B,MSPRR
936         MOVEM B,MGRWCD(W)
937         MOVSI B,%MAMSO
938         IORM B,MSRAC(W)
939         JRST MGSPCR
940 \f
941 MGSPCR: PUSHJ Q,MGGXPT  ; SPACE REVERSE
942         TRNE J,600000   ; ERR
943          JRST MGERR
944         TRNE J,100000   ; BOT
945          JRST MGCMDR    ; THEN DO NOTHING
946         MOVEM W,MGUNIT
947         MOVE B,MGRWCD(W)
948         ADD B,MTCONO(W)
949 IFN TM10B,[
950         SETZM MIOWD
951         DATAO MTS,[MICWA]
952 ]
953 IFN TM10A,[
954         MOVE A,[-1,,MGVTC-1]
955         MOVEM A,MIOWD
956         PUSHJ Q,MGDCSO
957 ]
958         CONO MTC,(B)
959         PUSHJ Q,MGWTJD
960          JRST MGERR
961         TRNE J,10000
962          SOSGE MGEOFR(W)        ; ONE LESS EOF
963           SETZM MGEOFR(W)
964         JRST MGCMDR
965
966 MGSPRF: MOVEI B,MSPRF   ; REVERSE FILE
967         MOVEM B,MGRWCD(W)
968         MOVSI A,%MAESO  ; EOF READ IN FORWARD DIRECTION
969         TDNN A,MSRAC(W)
970          JRST MGSPCR
971         AOS MSCMDC(W)   ; YES DO IT TWICE
972         PUSHJ Q,MGSPCR
973         MOVSI B,%MAESO
974         ANDCAM B,MSRAC(W)       ; TURN OFF FLAG
975         JRST MGSPCR     ; SECOND TIME
976
977 MGRWD1: PUSHJ Q,MGGXPT  ; REWIND
978         MOVEM W,MGUNIT
979         MOVE B,MGRWCD(W)        ; GET COMMAND
980         ADD B,MTCONO(W)
981         CONO MTC,(B)
982         PUSHJ Q,MGWTJD  ; WAIT
983          JRST MGERR
984         SETZM MGEOFR(W)
985         MOVSI A,%MAMSO
986         ANDCAM A,MSRAC(W)       ;CLEAR TAPE MOTION
987 MGRWD2: TRNN J,200000   ; STILL REWINDING?
988          JRST MGRWD3    ; NO
989         PUSHJ Q,CPOPJ   ; WAIT
990         CONI MTS,J
991         MOVEM J,MGCMTS(W)
992         JRST MGRWD2
993
994 MGRWD3: MOVE T,TIME     ;WAIT 1 SECOND MORE
995         ADDI T,30.      ;THIS IS AN ATTEMPT TO FIX A HARDWARE BUG
996         MOVEM T,MGJDTI
997 MGRWD4: MOVE T,TIME
998         CAML T,MGJDTI
999          JRST [ SETZM MGJDTI
1000                 POPJ Q, ]
1001         PUSHJ Q,CPOPJ
1002         JRST MGRWD4
1003
1004 MGRWND: MOVEI B,MREWND  ; NORMAL REWIND
1005         CAIA
1006 MGRWDM:  MOVEI B,MRWNDD ; REWIND AND DISMOUNT
1007         MOVEM B,MGRWCD(W)
1008         PUSHJ Q,MGRWD1
1009         MOVSI A,%MAMSO+%MAREW
1010         ANDCAM A,MSRAC(W)
1011         JRST MGCMDR
1012 \f
1013 MGSEOT: PUSHJ Q,MGGXPT  ; SKIP TO LOGICAL EOT
1014         TRNE J,600000
1015          JRST MGERR
1016         MOVEM W,MGUNIT
1017         TRNE J,100000   ; BOT?
1018          JRST MGVTCK    ; VIRGIN TAPE CHECK
1019 MGNVT:  MOVE B,MTCONO(W)
1020 IFN TM10A,[
1021         PUSHJ Q,MGDCSO
1022         MOVE A,[-1,,MGVTC-1]
1023         MOVEM A,MIOWD   ; ONE RECORD
1024 ]
1025 IFN TM10B,      SETZM MIOWD
1026         CONO MTC,MSPRR(B)       ; SPACE REVERSE FIRST
1027         PUSHJ Q,MGWTJD  ; WAIT
1028          JRST MGERR
1029         SETZM MGEOFR(W)
1030         AOS MGEOFR(W)
1031 MGEOT2: MOVE B,MTCONO(W)
1032         CONO MTC,MSPFF(B)       ; SKIP FORWARD FILE
1033         PUSHJ Q,MGWTJD
1034          JRST MGERR
1035         MOVSI B,%MAETR  ; EOT CHECK
1036         TRNE J,4000
1037          IORM B,MSRAC(W)        ; TELL MP
1038         MOVE B,MTCONO(W)
1039 IFN TM10A,[
1040         MOVE A,[-1,,MGVTC-1]
1041         MOVEM A,MIOWD   ; ONE RECORD
1042 ]
1043 IFN TM10B,      SETZM MIOWD
1044         CONO MTC,MSPFR(B)       ; SPACE FORWARD RECORD
1045         PUSHJ Q,MGWTJD
1046          JRST MGERR
1047         MOVSI B,%MAETR  ; EOT AGAIN
1048         TRNE J,4000
1049          IORM B,MSRAC(W)        ; TELL MP
1050         TRNN J,10000    ; EOF ALSO?
1051          JRST MGEOT2    ; NO, TRY AGAIN
1052         MOVE B,MTCONO(W)        ; YES, NOW GO BACK OVER LAST
1053         CONO MTC,MSPRF(B)
1054         PUSHJ Q,MGWTJD
1055          JRST MGERR
1056         MOVSI B,%MAEOF+%MAETR   ; TELL MP,EOF
1057         IORM B,MSRAC(W)
1058         JRST MGCMDR
1059 \f
1060 MGVTCK: MOVE T,TIME
1061         ADDI T,60.      ; TWO SECOND TIME OUT
1062         MOVEM T,MGEOTT(W)       ; EOT TIME
1063 IFN TM10B,[
1064         SETZM MIOWD
1065         DATAO MTS,[MICWA]
1066 ]
1067 IFN TM10A,[
1068         MOVE A,[-1,,MGVTC-1]
1069         MOVEM A,MIOWD
1070         PUSHJ Q,MGDCSO
1071 ]
1072         MOVE B,MTCONO(W)
1073         CONO MTC,MREAD(B)       ; DO READ, WAIT EITHER FOR JOB DONE OR TIME OUT
1074 MGVTC1: CONI MTS,J
1075         MOVEM J,MGCMTS(W)
1076         TRNE J,100      ; J D?
1077          JRST MGNVT     ; NOT VIRGIN TAPE
1078         TRNE J,440000
1079          JRST MGERR     ; ERRORS?
1080         MOVE T,MGEOTT(W)
1081         CAMG T,TIME     ; TIME UP?
1082          JRST MGVT      ; YES
1083         PUSHJ Q,CPOPJ   ; WAIT
1084         JRST MGVTC1
1085
1086 MGVT:   MOVE B,MTCONO(W)
1087         CONO MTS,31
1088         CONO MTC,MNOPIN(B)      ; NO-OP WAIT FOR JOB DONE
1089         PUSHJ Q,MGWTJD
1090          JFCL           ; SEE IF I CARE IF THERE ARE ERRORS
1091         MOVEI B,MREWND
1092         MOVEM B,MGRWCD(W)
1093         PUSHJ Q,MGRWD1  ; REWIND
1094         SETZM MGEOFR(W)
1095         AOS MGEOFR(W)
1096         JRST MGCMDR     ; RETURN
1097
1098 MGMEOT: PUSHJ Q,MGGXPT
1099         TRNE J,600000
1100          JRST MGERR
1101         MOVEM W,MGUNIT
1102         SKIPE MTCEFW(W) ;HOW MANY EOF WRITTEN?
1103          JRST MGMET1
1104         AOS MSCMDC(W)   ; SO WILL RETURN
1105         AOS MTCEFW(W)
1106         PUSHJ Q,MGWEOF
1107 MGMET1: MOVE A,MTCEFW(W)
1108         SOSLE A
1109          JRST MGMET2
1110         AOS MSCMDC(W)
1111         AOS MTCEFW(W)
1112         PUSHJ Q,MGWEOF
1113 MGMET2: MOVE A,MSRAC(W)
1114         TLNE A,%MANWT   ; BACK OVER LAST?
1115          JRST MGMET3    ; NO
1116         AOS MSCMDC(W)   ; SO IT WILL RETURN
1117         PUSHJ Q,MGSPRF
1118 MGMET3: MOVSI A,%MANWT
1119         IORM A,MSRAC(W)
1120         JRST MGCMDR     ; DONE
1121 \f
1122 ; WRITE EOF
1123 MGWEOF: PUSHJ Q,MGGXPT
1124         TRNE J,600010
1125          JRST MGERR
1126         MOVEM W,MGUNIT
1127         MOVE B,MTCONO(W)
1128         CONO MTC,MWEOF(B)
1129         PUSHJ Q,MGWTJD
1130          JRST MGERR
1131         MOVSI A,%MAMSO
1132         IORM A,MSRAC(W) ; TAPE MOVEMENT
1133         JRST MGCMDR     ; RETURN
1134
1135 MGSTAT: PUSHJ Q,MGGXPT  ; GETS STATUS
1136         JRST MGCMDR
1137
1138 MGW3IN: PUSHJ Q,MGGXPT
1139         TRNE J,600010
1140          JRST MGERR
1141         MOVEM W,MGUNIT
1142 IFN TM10B,[
1143         SETZM MIOWD
1144         DATAO MTS,[MICWA]
1145 ]
1146 IFN TM10A,[
1147         MOVE A,[-1,,MGVTC-1]
1148         MOVEM A,MIOWD
1149         PUSHJ Q,MGDCSO
1150 ]
1151         MOVE B,MTCONO(W)
1152         CONO MTC,MW3IN(B)       ; WRITE THE RANDOM WORD PRECEEDED BY 3 INCHES OF BLANK TAPE
1153         PUSHJ Q,MGWTJD
1154          JFCL           ; ALLOW BAD TAPE ERROR
1155         JRST MGSPRR     ; NOW SPACE RECORD REVERSE OVER THE ONE WORD
1156 \f
1157 SUBTTL .MTAPE UUO 
1158
1159 ;.MTAPE AC,
1160 ;       AC/     CHNM,COMMAND
1161 ;               COMMAND/        COUNT,,FUNCTION
1162
1163 AMTAPE: XCTR XR,[HLRZ R,(J)]
1164         TRNE R,-NIOCHN
1165          JRST ILUUO
1166         HRRZM R,UUAC(U)         ; SO THAT ERRORS WILL BE REPORTED ON THE CORRECT CHANNEL
1167         ADDI R,IOCHNM(U)        ; FORM IOCHNM POINTER
1168         LDB W,[MTXP(R)] ; GET XPORT NUMBER
1169         CAME U,MTUSR(W) ; SAME USER
1170          POPJ P,        ; NO
1171         UMOVE J,(J)
1172         MOVEM J,MTMTAP(W)       ; SAVE J
1173         HRRZ A,MTMTAP(W)
1174         PUSHJ P,MTIECK
1175         UMOVE A,(A)
1176         HRRZM A,MTMFNC(W)       ;STORE FUNCTION
1177         HLREM A,MTMCNT(W)       ;AND COUNT
1178         SKIPN MTMCNT(W)         ;A COUNT OF ZERO ALWAYS MEANS ONE, FOR COMPATIBILITY
1179          AOS MTMCNT(W)          ; WITH THE OLD CODE.
1180         HRRZS A
1181         CAIL A,NMTAPC           ; LEGAL COMMAND
1182          POPJ P,        ; NO
1183         AOS (P)         ; SKIP RETURN
1184         JRST @MTAPDT(A)
1185
1186 MTAPDT: MTHANG  ;0 HANG TILL TAPE MOTION DONE
1187         MTRWND  ;1 REWIND
1188         MTRWDM  ;2 REWIND AND DISMOUNT
1189         MTWEOR  ;3 WRITE EOR IF APPROPRIATE
1190         MTW3IN  ;4 WRITE 3 INCHES OF BLANK TAPE
1191         MTWEOF  ;5 WRITE EOF
1192         MTSPR   ;6 SPACE RECORDS
1193         MTSPF   ;7 SPACE FILES
1194         MTSPEOT ;10 SPACE TO EOT
1195         MTSTOP  ;11 STOP ALL COMMAND ASSOCIATED WITH THIS COMMAND
1196         MTSBKS  ;12 SET BLOCK SIZE (TO COUNT)
1197         MTRBKS  ;13 READ BLOCK SIZE (TO AC)
1198 NMTAPC==.-MTAPDT
1199
1200 MTSBKS: MOVE A,MTMCNT(W)        ;DESIRED BLOCKSIZE
1201         CAIL A,4                ;CHECK REASONABLENESS
1202          CAILE A,2000
1203           SOSA (P)              ;FAIL IF TOO BIG OR TOO SMALL
1204            MOVEM A,MTBLKS(W)    ;OK, CHANGE WRITE-BUFFER SIZE
1205         POPJ P,
1206
1207 MTRBKS: MOVE A,MTBLKS(W)
1208         JRST APTUAJ
1209 \f
1210 MTHANG: SKIPLE MSCMDC(W)        ; HANG UNTILL ALL MOTION FINISHED
1211          PUSHJ P,UFLS
1212         JRST MTIECK
1213
1214 MTRWND: MOVEI B,MGRWND          ; REWIND
1215 MTRWD1: SKIPE MSCRW(W)
1216          JRST MTSOSP
1217         MOVSI A,%MAREW
1218         IORM A,MSRAC(W)
1219         JRST MTCMD
1220
1221 MTRWDM: MOVEI B,MGRWDM  ; REWIND AND DISMOUNT
1222         JRST MTRWD1
1223
1224 ;"WRITE END OF RECORD" - THIS IS REALLY THE FORCE SYSTEM CALL, OR SHOULD BE.
1225 MTWEOR: SKIPG MTMDN(W)  ; ANY BUFFERS STARTED
1226          POPJ P,        ; NO
1227         SKIPE MSCRW(W)  ; WRITING
1228          JRST MTWBFD    ; DISCARD BUFFER
1229 MTSOSP: SOS (P)         ; NOT WRITING, ERROR
1230         POPJ P,
1231
1232 MTWEOF: SKIPN MSCRW(W)  ; WRITING?
1233          JRST MTSOSP    ; NO
1234         PUSHJ P,MTWEOR
1235         MOVEI B,MGWEOF  ; WRITE EOF
1236         AOS MTCEFW(W)
1237         MOVSI TT,%MANWT
1238         ANDCAM TT,MSRAC(W)      ; SOMETHING WRITTEN
1239         JRST MTCMD
1240
1241 MTW3IN: SKIPN MSCRW(W)  ; WRITING?
1242          JRST MTSOSP
1243         MOVEI B,MGW3IN
1244         SETZM MTCEFW(W)
1245         MOVSI TT,%MANWT
1246         ANDCAM TT,MSRAC(W)
1247         JRST MTCMD
1248
1249 ;SPACE RECORDS, +=FORWARD, -=BACK
1250 MTSPR:  SKIPE MSCRW(W)  ; NOT ALLOWED IF WRITING
1251          JRST MTSOSP
1252         PUSHJ P,MTFLRA  ;FLUSH READ-AHEAD, FIND OUT HOW FAR OFF WE ARE
1253         ADD B,C         ;NUMBER OF RECORDS TAPE IS AHEAD OF USER (EOF=RECORD)
1254         MOVNS B         ;SUBTRACT THIS FROM USER'S REQUEST
1255         ADDB B,MTMCNT(W)
1256         JUMPE B,CPOPJ   ;IF COUNT IS NOW ZERO, WE ARE DONE
1257 MTSPR1: PUSHJ P,MTCNTR  ;UPDATE USER'S COPY IN CASE PCLSR
1258         JUMPG B,MTSPFR  ; SPACE FORWARD
1259         MOVEI B,MGSPRR  ; SPACE REVERSE
1260         PUSHJ P,MTCMD
1261         AOSGE B,MTMCNT(W)
1262          JRST MTSPR1    ;MORE
1263         POPJ P,
1264
1265 MTSPFR: MOVEI B,MGSPFR
1266         PUSHJ P,MTCMD
1267         SOSLE B,MTMCNT(W)
1268          JRST MTSPR1    ;MORE
1269         POPJ P,
1270
1271 ;THIS ROUTINE FLUSHES READAHEAD.  CALL BEFORE DOING A SPACING OPERATION
1272 ;THIS DOESN'T ACTUALLY UNDO THE EFFECT ON THE DRIVE
1273 ;OF THE READ-AHEAD.  IT DOES MAKE SURE THAT READ-AHEAD'S EFFECT CAN'T
1274 ;CHANGE, THEN RETURNS IN B THE NUMBER OF RECORDS AHEAD (NON-NEGATIVE)
1275 ;AND IN C THE NUMBER OF EOF'S AHEAD (0 OR 1).  IF CALLED TWICE IT WILL
1276 ;RETURN ZERO THE SECOND TIME.  BE SURE TO UPDATE YOUR PARAMETERS.
1277 MTFLRA: PUSHJ P,MTCNTR  ;FIRST, ENSURE WRITEABILITY, MUSTN'T PCLSR IN MTCNTR LATER
1278         MOVSI B,%MASTP
1279         MOVSI T,%MARAC
1280         IORM B,MSRAC(W) ;IF READ IS ACTIVE, TELL IT TO STOP
1281         TDNE T,MSRAC(W) ;AWAIT CESSATION OF READ
1282          PUSHJ P,UFLS   ;IF THIS PCLSR'S OUT WITH %MASTP SET, NO GREAT HARM DONE.
1283         ANDCAM B,MSRAC(W)       ;THEN TURN OFF %MASTP, THINGS ARE NOW QUIET
1284         SKIPLE MSCMDC(W)        ;BEFORE MESSING WITH BUFFERS, WAIT FOR PI TO QUIESCE
1285          PUSHJ P,UFLS
1286         MOVE B,MSNBOL(W)        ;NUMBER OF BUFFERS = NUMBER OF RECORDS
1287         LDB C,[.BP (%MAEFA),MSRAC(W)] ;1 IF PAST EOF WHICH THE USER DOESN'T KNOW ABOUT
1288         MOVSI T,%MAEFA          ;NOW GET RID OF THE READ-AHEAD
1289         ANDCAM T,MSRAC(W)
1290         JRST MTCBFF
1291 \f
1292 MTSPF:  SKIPE MSCRW(W)  ; NOT ALLOWED IF WRITING
1293          JRST MTSOSP
1294         PUSHJ P,MTFLRA  ;FLUSH READ-AHEAD
1295         MOVN B,C        ;NUMBER OF FILES TAPE IS AHEAD OF USER
1296         ADDB B,MTMCNT(W)
1297         JUMPE B,CPOPJ   ;DONE
1298 MTSPF1: PUSHJ P,MTCNTR  ;UPDATE USER'S COUNT IN CASE OF PCLSR
1299         JUMPG B,MTSPFF  ; SPACE FORWARD FILES
1300         MOVEI B,MGSPRF
1301         PUSHJ P,MTCMD
1302         AOSGE B,MTMCNT(W)
1303          JRST MTSPF1    ;MORE
1304         POPJ P,
1305
1306 MTSPFF: MOVEI B,MGSPFF
1307         PUSHJ P,MTCMD
1308         SOSLE B,MTMCNT(W)
1309          JRST MTSPF1    ;MORE
1310         POPJ P,
1311
1312 MTCNTR: HRRZ A,MTMTAP(W)
1313         MOVE T,MTMFNC(W)
1314         HRL T,MTMCNT(W)
1315         UMOVEM T,(A)
1316         POPJ P,
1317
1318 MTSTAT: SKIPLE MSCMDC(W)        ; WAIT TILL ALL COMMANDS DONE
1319          PUSHJ P,UFLS
1320         MOVEI B,MGSTAT  ; GET CONI'S
1321         PUSHJ P,MTCMD   ; GIVE TO PI
1322         SKIPLE MSCMDC(W)        ; WAIT TILL DONE
1323          PUSHJ P,UFLS
1324         MOVE I,MGCMTC(W)
1325         MOVE J,MGCMTS(W)
1326         POPJ P,
1327
1328 MTSPEOT:        MOVEI B,MGSEOT  ; SPACE TO LOGICAL EOT
1329         JRST MTCMD      ;NOTE THIS IS INDEPENDENT OF READ-AHEAD
1330
1331 MTSTOP: CONO PI,UTCOFF  ;THIS DOESN'T DEAL WITH READ-AHEAD, PROBABLY OK
1332         SETZM MSCMDC(W) ;NO MORE COMANDS
1333         MOVE Q,[-MGQDLL,,MGQD0-1]
1334         MOVE T,MSLCTB
1335         IMUL T,W
1336         ADD Q,T
1337         MOVEM Q,MGQDLP(W)       ; RESTORE Q
1338         MOVE Q,[-MSCBL-1,,MSCB0-1]
1339         ADD Q,T
1340         MOVEM Q,MTCMBP(W)       ; INITIALIZE MP AND PI COMAND POINTERS
1341         MOVE Q,[4400,,MSCB0-1]
1342         ADD Q,T
1343         MOVEM Q,MGCMBP(W)
1344         SKIPL A,MTMDN(W)
1345          PUSHJ P,IMEMR  ; RELEASE MP BUFFER
1346         SETOM MTMDN(W)
1347         SETZM MSMPRP(W)
1348         SETZM MSMPRC(W) ; SO BLKT WON'T GET UNHAPPY
1349         PUSHJ P,MTCBFF  ; FLUSH BUFFER LIST
1350         CAME W,MGUNIT   ; SAME UNIT?
1351          JRST UTCONJ
1352         SETOM MGUNIT    ; SO INTERUPT WILL GO AWAY
1353         CONI MTC,I      ; SEE WHAT DRIVE IS BEING TALKED TO
1354         LDB B,[MUNITF,,I]
1355         CAME W,B
1356          JRST UTCONJ    ; IF NOT SAME UNIT, DON'T DO ANYTHING
1357         MOVE B,MTCONO(W)
1358         CONO MTS,31     ; STOP THE TAPE
1359         CONO MTC,(B)    ; CLEAR INTERUPTS
1360         SKIPGE A,MGCABN(W)      ; ANY BUFFERS ACTIVE AT PI
1361          JRST UTCONJ    ; NO
1362         PUSHJ P,IMEMR   ; RETURN IT
1363         SETOM MGCABN(W)
1364         JRST UTCONJ
1365 \f
1366 SUBTTL MAG TAPE CLOSE ROUTINES
1367
1368 MTOCL:  LDB W,[MTXP(R)]
1369         SOSL MTUSE(W)
1370          POPJ P,        ; NOT ONLY CHANNEL OPEN
1371         AOS MTUSE(W)    ; INCASE PCLSRED
1372         MOVSI A,%MAERR  ;ERROR?
1373         TDNE A,MSRAC(W)
1374          PUSHJ P,MTOCL3
1375 ;       MOVEI T,MSCBL-4
1376 ;       CAMG T,MSCMDC(W)
1377 ;        PUSHJ P,UFLS   ; WAIT FOR ROOM FOR THREE COMMANDS
1378         SKIPL MTMDN(W)  ; MAG TAPE OUTPUT CLOSE
1379          PUSHJ P,MTWBFD ; WRITE OUT BUFFERS
1380 ;       MOVEI B,MGWEOF  ; WRITE OUT TWO EOF(S)
1381 ;       SKIPE MTCEFW(W)
1382 ;        JRST MTOCL2    ; MAY HAVE BEEN PCLSRED
1383 ;MTOCL1:        PUSHJ P,MTCMD
1384 ;       AOS MTCEFW(W)   ; ONE MORE CLOSE EOF WRITTEN
1385 ;MTOCL2:        MOVE A,MTCEFW(W)
1386 ;       SOSG A  ; DON'T WRITE EOF IF PCLSRED
1387 ;        PUSHJ P,MTCMD  ; DO IT TWICE
1388 ;       SKIPG A
1389 ;        AOS MTCEFW(W)
1390 ;       MOVEI B,MGSPRF
1391 ;       MOVE A,MSRAC(W)
1392 ;       TLNN A,1000
1393 ;        PUSHJ P,MTCMD  ; NOW BACK UP OVER ONE
1394 ;       MOVSI A,1000
1395 ;       IORM A,MSRAC(W)
1396         MOVEI B,MGMEOT  ; MAKE EOT
1397         PUSHJ P,MTCMD
1398         SKIPLE MSCMDC(W)        ; NOW WAIT TILL DONE
1399          PUSHJ P,UFLS
1400         MOVEI A,1
1401         MOVEM A,MGEOFR(W)
1402         SKIPL MTMDN(W)  ;ANY ACTIVE BUFFERS
1403          JRST 4,.
1404         SKIPL MGCABN(W)
1405          JRST 4,.
1406         SKIPE MSNBOL(W)
1407          JRST 4,.
1408         SETOM MTUSR(W)
1409         SETOM MTUSE(W)
1410         SETZM MSRAC(W)
1411         POPJ P,
1412
1413 MTOCL3: SKIPL A,MTMDN(W)
1414          PUSHJ P,MEMR   ; IF BUFFER AROUND,FLUSH IT
1415         SETOM MTMDN(W)
1416         SETZM MSMPRC(W)
1417         POPJ P,
1418 \f
1419 MTICL:  LDB W,[MTXP(R)]
1420         SOSL MTUSE(W)   ; LAST USER
1421          POPJ P,
1422         AOS MTUSE(W)
1423         MOVEI T,1
1424         CAMGE T,MSCMDC(W)       ; ALLOW ONE COMMAND IF REWINDING
1425          PUSHJ P,UFLS   ; ALL COMMANDS DONE
1426         MOVE T,MSRAC(W)
1427         TLNE T,%MAREW   ; REWINDING?
1428          JRST MTICL3    ; YES
1429         SKIPLE MSCMDC(W)        ; NO, WAIT TILL COMMAND DONE
1430          PUSHJ P,UFLS
1431 MTICL3: SKIPL MGCABN(W) ; ANY PI BUFFERS LEFT
1432          JRST 4,.
1433         PUSHJ P,MTRBD   ;GET RID OF M.P. BUF, IF ANY
1434         SETOM MTUSR(W)
1435         PUSHJ P,MTCBFF  ; FREE BUFFERS
1436         SOS MTUSE(W)
1437         MOVE T,MSRAC(W)
1438         TLNE T,%MAREW   ; DON'T HAVE TO SKIP TO EOF IF REWINDING
1439          JRST MTICL2
1440         MOVSI A,20
1441         TDNE A,(R)      ;CHECK TO SKIP TO EOF
1442          JRST MTICL2
1443         MOVSI A,%MAMSO
1444         TDNN A,MSRAC(W) ;TAPE MOVEMENT
1445          JRST MTICL2    ; NO
1446         SKIPE MGEOFR(W) ;NO TIMING CONFLECT HERE SINCE WE WAITED FOR PI TO CLEAR
1447          JRST MTICL2    ;NOTE THAT THIS DISPOSES OF A READ-AHEAD EOF.
1448         PUSHJ P,MTSTAT
1449         MOVE B,MGCMTS(W)
1450         TRNE B,100000
1451          JRST MTICL2
1452         MOVEI B,MGSPFF
1453         PUSHJ P,MTCMD
1454         SKIPLE MSCMDC(W)
1455          PUSHJ P,UFLS
1456 MTICL2: MOVSI T,%MAREW
1457         ANDM T,MSRAC(W) ;CLEAR ALL BUT REWINDING
1458         POPJ P,         ; NO, DONE
1459
1460 MTCBFF: SKIPN MSNBOL(W) ;ANY BUFFERS ON CHAIN?
1461          POPJ P,
1462         HRRZ A,MSBUFP(W)        ;YES, FREE ONE
1463         PUSHJ P,MTICL1  ; FIX CHAIN
1464         PUSHJ P,MEMR    ; RETURN BUFFER
1465         SOSLE MSNBOL(W) ;ANY MORE?
1466          JRST MTCBFF
1467         SETZM MSBUFP(W) ;EMPTY LIST
1468         POPJ P,
1469
1470 MTICL1: LDB T,[MLO,,MEMBLT(A)]  ; GET BACK POINTER
1471         HRRM T,MSBUFP(W)
1472         POPJ P,