Consolidate license copies
[its.git] / system / mtape.197
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
1167                                 ;  CORRECT CHANNEL
1168         ADDI R,IOCHNM(U)        ; FORM IOCHNM POINTER
1169         HRRZ A,(R)              ; A: CLSTB/IOTTB index
1170         CAIL A,MTUAIX           ; Min index for tape
1171          CAILE A,MTBOX          ; Max
1172           POPJ P,               ; Laconic error reportage.
1173         LDB W,[MTXP(R)] ; GET XPORT NUMBER
1174         CAME U,MTUSR(W) ; SAME USER
1175          POPJ P,        ; NO
1176         UMOVE J,(J)
1177         MOVEM J,MTMTAP(W)       ; SAVE J
1178         HRRZ A,MTMTAP(W)
1179         PUSHJ P,MTIECK
1180         UMOVE A,(A)
1181         HRRZM A,MTMFNC(W)       ;STORE FUNCTION
1182         HLREM A,MTMCNT(W)       ;AND COUNT
1183         SKIPN MTMCNT(W)         ;A COUNT OF ZERO ALWAYS MEANS ONE, FOR COMPATIBILITY
1184          AOS MTMCNT(W)          ; WITH THE OLD CODE.
1185         HRRZS A
1186         CAIL A,NMTAPC           ; LEGAL COMMAND
1187          POPJ P,        ; NO
1188         AOS (P)         ; SKIP RETURN
1189         JRST @MTAPDT(A)
1190
1191 MTAPDT: MTHANG  ;0 HANG TILL TAPE MOTION DONE
1192         MTRWND  ;1 REWIND
1193         MTRWDM  ;2 REWIND AND DISMOUNT
1194         MTWEOR  ;3 WRITE EOR IF APPROPRIATE
1195         MTW3IN  ;4 WRITE 3 INCHES OF BLANK TAPE
1196         MTWEOF  ;5 WRITE EOF
1197         MTSPR   ;6 SPACE RECORDS
1198         MTSPF   ;7 SPACE FILES
1199         MTSPEOT ;10 SPACE TO EOT
1200         MTSTOP  ;11 STOP ALL COMMAND ASSOCIATED WITH THIS COMMAND
1201         MTSBKS  ;12 SET BLOCK SIZE (TO COUNT)
1202         MTRBKS  ;13 READ BLOCK SIZE (TO AC)
1203 NMTAPC==.-MTAPDT
1204
1205 MTSBKS: MOVE A,MTMCNT(W)        ;DESIRED BLOCKSIZE
1206         CAIL A,4                ;CHECK REASONABLENESS
1207          CAILE A,2000
1208           SOSA (P)              ;FAIL IF TOO BIG OR TOO SMALL
1209            MOVEM A,MTBLKS(W)    ;OK, CHANGE WRITE-BUFFER SIZE
1210         POPJ P,
1211
1212 MTRBKS: MOVE A,MTBLKS(W)
1213         JRST APTUAJ
1214 \f
1215 MTHANG: SKIPLE MSCMDC(W)        ; HANG UNTILL ALL MOTION FINISHED
1216          PUSHJ P,UFLS
1217         JRST MTIECK
1218
1219 MTRWND: MOVEI B,MGRWND          ; REWIND
1220 MTRWD1: SKIPE MSCRW(W)
1221          JRST MTSOSP
1222         MOVSI A,%MAREW
1223         IORM A,MSRAC(W)
1224         JRST MTCMD
1225
1226 MTRWDM: MOVEI B,MGRWDM  ; REWIND AND DISMOUNT
1227         JRST MTRWD1
1228
1229 ;"WRITE END OF RECORD" - THIS IS REALLY THE FORCE SYSTEM CALL, OR SHOULD BE.
1230 MTWEOR: SKIPG MTMDN(W)  ; ANY BUFFERS STARTED
1231          POPJ P,        ; NO
1232         SKIPE MSCRW(W)  ; WRITING
1233          JRST MTWBFD    ; DISCARD BUFFER
1234 MTSOSP: SOS (P)         ; NOT WRITING, ERROR
1235         POPJ P,
1236
1237 MTWEOF: SKIPN MSCRW(W)  ; WRITING?
1238          JRST MTSOSP    ; NO
1239         PUSHJ P,MTWEOR
1240         MOVEI B,MGWEOF  ; WRITE EOF
1241         AOS MTCEFW(W)
1242         MOVSI TT,%MANWT
1243         ANDCAM TT,MSRAC(W)      ; SOMETHING WRITTEN
1244         JRST MTCMD
1245
1246 MTW3IN: SKIPN MSCRW(W)  ; WRITING?
1247          JRST MTSOSP
1248         MOVEI B,MGW3IN
1249         SETZM MTCEFW(W)
1250         MOVSI TT,%MANWT
1251         ANDCAM TT,MSRAC(W)
1252         JRST MTCMD
1253
1254 ;SPACE RECORDS, +=FORWARD, -=BACK
1255 MTSPR:  SKIPE MSCRW(W)  ; NOT ALLOWED IF WRITING
1256          JRST MTSOSP
1257         PUSHJ P,MTFLRA  ;FLUSH READ-AHEAD, FIND OUT HOW FAR OFF WE ARE
1258         ADD B,C         ;NUMBER OF RECORDS TAPE IS AHEAD OF USER (EOF=RECORD)
1259         MOVNS B         ;SUBTRACT THIS FROM USER'S REQUEST
1260         ADDB B,MTMCNT(W)
1261         JUMPE B,CPOPJ   ;IF COUNT IS NOW ZERO, WE ARE DONE
1262 MTSPR1: PUSHJ P,MTCNTR  ;UPDATE USER'S COPY IN CASE PCLSR
1263         JUMPG B,MTSPFR  ; SPACE FORWARD
1264         MOVEI B,MGSPRR  ; SPACE REVERSE
1265         PUSHJ P,MTCMD
1266         AOSGE B,MTMCNT(W)
1267          JRST MTSPR1    ;MORE
1268         POPJ P,
1269
1270 MTSPFR: MOVEI B,MGSPFR
1271         PUSHJ P,MTCMD
1272         SOSLE B,MTMCNT(W)
1273          JRST MTSPR1    ;MORE
1274         POPJ P,
1275
1276 ;THIS ROUTINE FLUSHES READAHEAD.  CALL BEFORE DOING A SPACING OPERATION
1277 ;THIS DOESN'T ACTUALLY UNDO THE EFFECT ON THE DRIVE
1278 ;OF THE READ-AHEAD.  IT DOES MAKE SURE THAT READ-AHEAD'S EFFECT CAN'T
1279 ;CHANGE, THEN RETURNS IN B THE NUMBER OF RECORDS AHEAD (NON-NEGATIVE)
1280 ;AND IN C THE NUMBER OF EOF'S AHEAD (0 OR 1).  IF CALLED TWICE IT WILL
1281 ;RETURN ZERO THE SECOND TIME.  BE SURE TO UPDATE YOUR PARAMETERS.
1282 MTFLRA: PUSHJ P,MTCNTR  ;FIRST, ENSURE WRITEABILITY, MUSTN'T PCLSR IN MTCNTR LATER
1283         MOVSI B,%MASTP
1284         MOVSI T,%MARAC
1285         IORM B,MSRAC(W) ;IF READ IS ACTIVE, TELL IT TO STOP
1286         TDNE T,MSRAC(W) ;AWAIT CESSATION OF READ
1287          PUSHJ P,UFLS   ;IF THIS PCLSR'S OUT WITH %MASTP SET, NO GREAT HARM DONE.
1288         ANDCAM B,MSRAC(W)       ;THEN TURN OFF %MASTP, THINGS ARE NOW QUIET
1289         SKIPLE MSCMDC(W)        ;BEFORE MESSING WITH BUFFERS, WAIT FOR PI TO QUIESCE
1290          PUSHJ P,UFLS
1291         MOVE B,MSNBOL(W)        ;NUMBER OF BUFFERS = NUMBER OF RECORDS
1292         LDB C,[.BP (%MAEFA),MSRAC(W)] ;1 IF PAST EOF WHICH THE USER DOESN'T KNOW ABOUT
1293         MOVSI T,%MAEFA          ;NOW GET RID OF THE READ-AHEAD
1294         ANDCAM T,MSRAC(W)
1295         JRST MTCBFF
1296 \f
1297 MTSPF:  SKIPE MSCRW(W)  ; NOT ALLOWED IF WRITING
1298          JRST MTSOSP
1299         PUSHJ P,MTFLRA  ;FLUSH READ-AHEAD
1300         MOVN B,C        ;NUMBER OF FILES TAPE IS AHEAD OF USER
1301         ADDB B,MTMCNT(W)
1302         JUMPE B,CPOPJ   ;DONE
1303 MTSPF1: PUSHJ P,MTCNTR  ;UPDATE USER'S COUNT IN CASE OF PCLSR
1304         JUMPG B,MTSPFF  ; SPACE FORWARD FILES
1305         MOVEI B,MGSPRF
1306         PUSHJ P,MTCMD
1307         AOSGE B,MTMCNT(W)
1308          JRST MTSPF1    ;MORE
1309         POPJ P,
1310
1311 MTSPFF: MOVEI B,MGSPFF
1312         PUSHJ P,MTCMD
1313         SOSLE B,MTMCNT(W)
1314          JRST MTSPF1    ;MORE
1315         POPJ P,
1316
1317 MTCNTR: HRRZ A,MTMTAP(W)
1318         MOVE T,MTMFNC(W)
1319         HRL T,MTMCNT(W)
1320         UMOVEM T,(A)
1321         POPJ P,
1322
1323 MTSTAT: SKIPLE MSCMDC(W)        ; WAIT TILL ALL COMMANDS DONE
1324          PUSHJ P,UFLS
1325         MOVEI B,MGSTAT  ; GET CONI'S
1326         PUSHJ P,MTCMD   ; GIVE TO PI
1327         SKIPLE MSCMDC(W)        ; WAIT TILL DONE
1328          PUSHJ P,UFLS
1329         MOVE I,MGCMTC(W)
1330         MOVE J,MGCMTS(W)
1331         POPJ P,
1332
1333 MTSPEOT:        MOVEI B,MGSEOT  ; SPACE TO LOGICAL EOT
1334         JRST MTCMD      ;NOTE THIS IS INDEPENDENT OF READ-AHEAD
1335
1336 MTSTOP: CONO PI,UTCOFF  ;THIS DOESN'T DEAL WITH READ-AHEAD, PROBABLY OK
1337         SETZM MSCMDC(W) ;NO MORE COMANDS
1338         MOVE Q,[-MGQDLL,,MGQD0-1]
1339         MOVE T,MSLCTB
1340         IMUL T,W
1341         ADD Q,T
1342         MOVEM Q,MGQDLP(W)       ; RESTORE Q
1343         MOVE Q,[-MSCBL-1,,MSCB0-1]
1344         ADD Q,T
1345         MOVEM Q,MTCMBP(W)       ; INITIALIZE MP AND PI COMAND POINTERS
1346         MOVE Q,[4400,,MSCB0-1]
1347         ADD Q,T
1348         MOVEM Q,MGCMBP(W)
1349         SKIPL A,MTMDN(W)
1350          PUSHJ P,IMEMR  ; RELEASE MP BUFFER
1351         SETOM MTMDN(W)
1352         SETZM MSMPRP(W)
1353         SETZM MSMPRC(W) ; SO BLKT WON'T GET UNHAPPY
1354         PUSHJ P,MTCBFF  ; FLUSH BUFFER LIST
1355         CAME W,MGUNIT   ; SAME UNIT?
1356          JRST UTCONJ
1357         SETOM MGUNIT    ; SO INTERUPT WILL GO AWAY
1358         CONI MTC,I      ; SEE WHAT DRIVE IS BEING TALKED TO
1359         LDB B,[MUNITF,,I]
1360         CAME W,B
1361          JRST UTCONJ    ; IF NOT SAME UNIT, DON'T DO ANYTHING
1362         MOVE B,MTCONO(W)
1363         CONO MTS,31     ; STOP THE TAPE
1364         CONO MTC,(B)    ; CLEAR INTERUPTS
1365         SKIPGE A,MGCABN(W)      ; ANY BUFFERS ACTIVE AT PI
1366          JRST UTCONJ    ; NO
1367         PUSHJ P,IMEMR   ; RETURN IT
1368         SETOM MGCABN(W)
1369         JRST UTCONJ
1370 \f
1371 SUBTTL MAG TAPE CLOSE ROUTINES
1372
1373 MTOCL:  LDB W,[MTXP(R)]
1374         SOSL MTUSE(W)
1375          POPJ P,        ; NOT ONLY CHANNEL OPEN
1376         AOS MTUSE(W)    ; INCASE PCLSRED
1377         MOVSI A,%MAERR  ;ERROR?
1378         TDNE A,MSRAC(W)
1379          PUSHJ P,MTOCL3
1380 ;       MOVEI T,MSCBL-4
1381 ;       CAMG T,MSCMDC(W)
1382 ;        PUSHJ P,UFLS   ; WAIT FOR ROOM FOR THREE COMMANDS
1383         SKIPL MTMDN(W)  ; MAG TAPE OUTPUT CLOSE
1384          PUSHJ P,MTWBFD ; WRITE OUT BUFFERS
1385 ;       MOVEI B,MGWEOF  ; WRITE OUT TWO EOF(S)
1386 ;       SKIPE MTCEFW(W)
1387 ;        JRST MTOCL2    ; MAY HAVE BEEN PCLSRED
1388 ;MTOCL1:        PUSHJ P,MTCMD
1389 ;       AOS MTCEFW(W)   ; ONE MORE CLOSE EOF WRITTEN
1390 ;MTOCL2:        MOVE A,MTCEFW(W)
1391 ;       SOSG A  ; DON'T WRITE EOF IF PCLSRED
1392 ;        PUSHJ P,MTCMD  ; DO IT TWICE
1393 ;       SKIPG A
1394 ;        AOS MTCEFW(W)
1395 ;       MOVEI B,MGSPRF
1396 ;       MOVE A,MSRAC(W)
1397 ;       TLNN A,1000
1398 ;        PUSHJ P,MTCMD  ; NOW BACK UP OVER ONE
1399 ;       MOVSI A,1000
1400 ;       IORM A,MSRAC(W)
1401         MOVEI B,MGMEOT  ; MAKE EOT
1402         PUSHJ P,MTCMD
1403         SKIPLE MSCMDC(W)        ; NOW WAIT TILL DONE
1404          PUSHJ P,UFLS
1405         MOVEI A,1
1406         MOVEM A,MGEOFR(W)
1407         SKIPL MTMDN(W)  ;ANY ACTIVE BUFFERS
1408          JRST 4,.
1409         SKIPL MGCABN(W)
1410          JRST 4,.
1411         SKIPE MSNBOL(W)
1412          JRST 4,.
1413         SETOM MTUSR(W)
1414         SETOM MTUSE(W)
1415         SETZM MSRAC(W)
1416         POPJ P,
1417
1418 MTOCL3: SKIPL A,MTMDN(W)
1419          PUSHJ P,MEMR   ; IF BUFFER AROUND,FLUSH IT
1420         SETOM MTMDN(W)
1421         SETZM MSMPRC(W)
1422         POPJ P,
1423 \f
1424 MTICL:  LDB W,[MTXP(R)]
1425         SOSL MTUSE(W)   ; LAST USER
1426          POPJ P,
1427         AOS MTUSE(W)
1428         MOVEI T,1
1429         CAMGE T,MSCMDC(W)       ; ALLOW ONE COMMAND IF REWINDING
1430          PUSHJ P,UFLS   ; ALL COMMANDS DONE
1431         MOVE T,MSRAC(W)
1432         TLNE T,%MAREW   ; REWINDING?
1433          JRST MTICL3    ; YES
1434         SKIPLE MSCMDC(W)        ; NO, WAIT TILL COMMAND DONE
1435          PUSHJ P,UFLS
1436 MTICL3: SKIPL MGCABN(W) ; ANY PI BUFFERS LEFT
1437          JRST 4,.
1438         PUSHJ P,MTRBD   ;GET RID OF M.P. BUF, IF ANY
1439         SETOM MTUSR(W)
1440         PUSHJ P,MTCBFF  ; FREE BUFFERS
1441         SOS MTUSE(W)
1442         MOVE T,MSRAC(W)
1443         TLNE T,%MAREW   ; DON'T HAVE TO SKIP TO EOF IF REWINDING
1444          JRST MTICL2
1445         MOVSI A,20
1446         TDNE A,(R)      ;CHECK TO SKIP TO EOF
1447          JRST MTICL2
1448         MOVSI A,%MAMSO
1449         TDNN A,MSRAC(W) ;TAPE MOVEMENT
1450          JRST MTICL2    ; NO
1451         SKIPE MGEOFR(W) ;NO TIMING CONFLECT HERE SINCE WE WAITED FOR PI TO CLEAR
1452          JRST MTICL2    ;NOTE THAT THIS DISPOSES OF A READ-AHEAD EOF.
1453         PUSHJ P,MTSTAT
1454         MOVE B,MGCMTS(W)
1455         TRNE B,100000
1456          JRST MTICL2
1457         MOVEI B,MGSPFF
1458         PUSHJ P,MTCMD
1459         SKIPLE MSCMDC(W)
1460          PUSHJ P,UFLS
1461 MTICL2: MOVSI T,%MAREW
1462         ANDM T,MSRAC(W) ;CLEAR ALL BUT REWINDING
1463         POPJ P,         ; NO, DONE
1464
1465 MTCBFF: SKIPN MSNBOL(W) ;ANY BUFFERS ON CHAIN?
1466          POPJ P,
1467         HRRZ A,MSBUFP(W)        ;YES, FREE ONE
1468         PUSHJ P,MTICL1  ; FIX CHAIN
1469         PUSHJ P,MEMR    ; RETURN BUFFER
1470         SOSLE MSNBOL(W) ;ANY MORE?
1471          JRST MTCBFF
1472         SETZM MSBUFP(W) ;EMPTY LIST
1473         POPJ P,
1474
1475 MTICL1: LDB T,[MLO,,MEMBLT(A)]  ; GET BACK POINTER
1476         HRRM T,MSBUFP(W)
1477         POPJ P,