1 ; I T S DISK SERVICE ROUTINES AND FILE SYSTEM -*-MIDAS-*-
2 ;;; Copyright (c) 1999 Massachusetts Institute of Technology
4 ;;; This program is free software; you can redistribute it and/or
5 ;;; modify it under the terms of the GNU General Public License as
6 ;;; published by the Free Software Foundation; either version 2 of the
7 ;;; License, or (at your option) any later version.
9 ;;; This program is distributed in the hope that it will be useful,
10 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ;;; General Public License for more details.
14 ;;; You should have received a copy of the GNU General Public License
15 ;;; along with this program; if not, write to the Free Software
16 ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 IFN DC10P+RP10P+RH10P+RH11P-1, .ERR WRONG NUMBER OF DISK CONTROLLERS
22 ;GET DISK PHYSICAL PARAMETERS BY .INSRT'ING APPROPRIATE FILE
38 IFE KS10P, .ERR RH11 on something other than a KS10?
39 IFN RP06P+RM03P-1, .ERR WRONG NUMBER OF KINDS OF DISK DRIVE
48 ;GET FILE SYSTEM DEFINITIONS:
49 ; MFD MASTER FILE DIRECTORY
50 ; TUT TRACK (BLOCK) UTILIZATION TABLE
51 ; UFD USER FILE DIRECTORY
59 SUBTTL MISC FILE SYSTEM CALLS
61 ADMPCH: UMOVE A,(J) ;SET OR READ STATUS OF DUMP BIT OF FILE OPEN ON
63 MOVEI T,POPJ1 ;MAKE CHNDCD SKIP RETURN IF ALL OK.
64 PUSHJ P,CHNDCD ;DECODE RH(A) AS CHNL NUM.
65 JRST ILUUO ;NO SKIP IMPLIES BAD CHNL NUM.
67 JRST ILUUO ;NOT DISK CHANNEL.
68 PUSHJ P,QCHNLT ;DECODE THE CHNL FURTHER.
77 LDB A,[430100,,UNRNDM(C)]
81 NRFDATE: PUSHJ P,QCHNLT ;READ FILE CREATION DATE WORD
84 JRST POPJ1 ;STORE BACK IN USER MEM
86 NSRDATE: PUSHJ P,QCHNLT ; SET REFERENCE DATE
88 DPB B,[UNREFD+UNREF(C)]
91 NRESRDT: PUSHJ P,QCHNLT ; RESTORE REFERENCE DATE
92 HLRZ A,OLDRDT(R) ; WHOEVER CHOSE R IN QCHNLC SHOULD BE SHOT
93 DPB A,[UNREFD+UNREF(C)]
96 NSFDATE: PUSHJ P,QCHNLT ;SET FILE CREATION DATE WORD
104 NRDMPBT: PUSHJ P,QCHNLT ;READ FILE DUMPED BIT
105 LDB A,[430100,,UNRNDM(C)]
108 NSDMPBT: PUSHJ P,QCHNLT ;SET FILE DUMPED BIT
109 DPB B,[430100,,UNRNDM(C)]
113 PUSHJ P,QCHNLT ;RETURN NONZERO IF WE TRACED LINKS TO GET THIS FILE.
115 LDB A,[.BP (%QALOP),T]
118 NFILBLK:PUSHJ P,QCHNLT ;READ ALL 5 PARAMETERS OF NAME AREA
124 JRST NRDM1 ; UNLOCK DIR AND STORE ARGUMENTS
126 QCHNLT: TLNN R,%CLSQ ;IS CHNL A DISK CHNL?
127 JRST [SUB P,[1,,1] ? JRST OPNL34]
136 ASAUTH: PUSHJ P,QCHNLT ;SET AUTHOR OF FILE
138 JUMPE B,ASAUT4 ;SETTING AUTHOR TO 0
163 DPB J,[UNAUTH+UNREF(C)]
166 ARAUTH: PUSHJ P,QCHNLT ;READ CREATOR OF FILE
167 LDB B,[UNAUTH+UNREF(C)]
168 MOVEI A,0 ;RETURN VALUE IS 0 IF UNKNOWN OR ILLEGAL AUTHOR
172 MOVEI B,2000-<NUDSL*2>(B)
178 ASREAP: PUSHJ P,QCHNLT ;SET NO REAP BIT
179 DPB B,[.BP (UNREAP),UNRNDM(C)]
182 ARQDAT: CONO PI,CLKOFF ;GET DSK TIME AND DATE
185 MOVE B,QDATEI ;2ND VALUE = DATE & TIME SYS CAME UP, IN DISK FORMAT.
189 ADSKUP: PUSHJ P,QCHNLT ;SET CREATION DATE, REF DATE AND CLEAR DUMP BIT
196 DPB TT,[UNREFD+UNREF(C)]
201 DELEWO: TLNN R,%CLSQ ;DELETE WHILE OPEN
202 JRST OPNL34 ;WRONG TYPE DEVICE
207 MOVE A,UNFN1(C) ;Get names of file being hacked.
210 PUSHJ P,MNGDIR ;If this is a sanctified dir
211 PUSHJ P,SYSDSK ; get SYS job to tattle about it.
214 MOVSI T,%QADEL ;SET DELETE BIT IN QSK CHNL
216 MOVSI T,UNCDEL ;AND IN FILE
221 ;RETURNS (1) FILE LENGTH IN BYTES (BYTE SIZE CURRENTLY OPEN IN)
222 ; (2) BITS PER BYTE (BYTE SIZE CURRENTLY OPEN IN)
223 ; (3) FILE LENGTH IN BYTES (BYTE SIZE WRITTEN IN)
224 ; (4) BITS PER BYTE (BYTE SIZE WRITTEN IN)
226 NFILLEN:PUSHJ P,QCHNLT
229 JRST OPNL34 ;NOT A FILE
232 JRST NFILL1 ;READ CHANNEL OR WRITE-OVER, GET FILE'S STORED LENGTH.
233 MOVE A,QFBLNO(R);NORMAL WRITE, GET ACCESS POINTER.
235 JRST NFILL2 ;NO BUFFER ACTIVE
236 ADD A,QMPBSZ(R) ;END OF CURRENT BUFFER
237 SUB A,QSMPRC(R) ;BACK UP TO CURRENT LOC
238 NFILL2: PUSHJ P,QUDULK
239 LDB B,[QSBSIZ(R)] ;CURRENT BYTE SIZE
240 MOVE D,B ;WRITTEN BYTE SIZE SAME AS CURRENT
241 MOVE C,A ;WRITTEN LENGTH SAME AS CURRENT
244 NFILL1: LDB TT,[UNDSCP+UNRNDM(C)]
246 HLL TT,QBTBLI(I) ;GET DESCRIPTOR POINTER
247 LDB E,[UNWRDC+UNRNDM(C)]
249 MOVEI E,2000 ;E GETS NUMBER OF WORDS IN LAST BLOCK
250 LDB D,[UNBYTE+UNREF(C)] ;D GETS BYTE INFO
251 ANDI C,-2000 ;C GETS BASE ADDR OF DIR
252 ADDI TT,UDDESC(C) ;TT GETS DESC PNTR
253 SETOM A ;INITIALIZE NUMBER OF BLOCKS IN FILE
254 PUSHJ P,NFLLN1 ;A GETS NUMBER OF BLOCKS IN FILE MINUS ONE
256 IMULI A,2000 ;NUMBER OF WORDS IN COMPLETE BLOCKS
257 ADD A,E ;ADD WORDS IN LAST BLOCK
258 PUSHJ P,QBDCD ;D GETS BYTE SIZE, E NUMBER OF RESIDUE BYTES
260 IDIV Q,D ;Q GETS BYTES PER WORD
261 MOVE C,A ;C WRITTEN LENGTH, A CURRENT (B.S. DIFFERENT)
262 IMUL C,Q ;CONVERT WORD LENGTH TO BYTES
263 SUB C,E ;C NOW HAS CORRECT WRITTEN LENGTH
264 IMUL E,D ;E GETS NUMBER OF RESIDUE BITS
265 LDB B,[QSBSIZ(R)] ;B GETS BYTE SIZE OPENED IN
266 IMULI A,@QSBYTE(R) ;A GETS LENGTH IN THOSE SIZE BYTES
267 IDIV E,B ;NUMBER OF RESIDUE BYTES, -ROUNDING DOWN-
268 SUB A,E ;ADJUST THE LENGTH
269 JRST POPJ1 ;RETURN VALUES IN A,B,C,D
271 NFLLN2: ADD A,B ; NEXT N BLOCKS
272 NFLLN1: ILDB B,TT ; GET NEXT DESC BYTE
273 JUMPE B,CPOPJ ; NO MORE
277 AOJA A,NFLLN1 ; SKIP-N, TAKE-1
279 JRST NFLLN1 ; IGNORE WRITE-PLACEHOLDER
280 REPEAT NXLBYT, IBP TT ; LOAD-ADDRESS, TAKE-1
283 ;DIRSIZ - READ OR SET DISK QUOTAS, READ # BLOCKS IN ALL FILES IN DIRECTORY.
284 ;1ST VALUE IS GRIM REAP QUOTA,,DIR SIZE
285 ;2ND VALUE IS 0 OR PACK#,,ALLOCATION FOR DIR ALLOCATED TO SPECIFIC PACK
286 ;LH OF 2ND ARG SETS GRIM REAP QUOTA; 3RD ARG SETS PACK#,,ALLOCATION
294 NDIRS1: MOVE B,UDALLO(C)
298 HLRZS D ;PACK ALLOCATED TO
301 MOVEI E,NQS-1 ;UPDATE ALLOC DRIVE NUM
304 NDIRS2: MOVEM E,QSALLO(H)
308 SUBTTL DISK OPEN ROUTINES
310 %DO==1,,525252 ;Special mode bits for disk opens.
311 %DOWOV==100000 ;Write over mode
312 %DONRF==10 ;Don't set ref-date
313 %DONLK==20 ;Don't chase links; actually open the link itself.
314 %DORWT==40 ;Make readers wait (used on opens for write or write-over).
317 TPLO: MOVE C,[SIXBIT /.LPTR./] ;PSEUDO LINE PRINTER (DISC)
320 AOS A,TPLFNO ;GENERATE RANDOM FILE NAME
324 COMO: SKIPA C,[SIXBIT /COMMON/] ;.OPEN ENTRY FOR "COM" DEVICE
325 SYSO: MOVSI C,(SIXBIT /SYS/) ; " FOR "SYS" DEVICE
326 TPLO2: MOVEM C,USYSN1(U)
330 QSKPO: MOVSI TT,-NQS ;PACK # OPEN
332 AOBJN TT,.-1 ;I <= PHYSICAL UNIT WITH SPECIFIED PACK
336 CAIE W,4 ;IF RENAME/DELETE, OK, DOESN'T TOUCH FILE ANYWAY
337 JRST OPNL16 ;OTHERWISE COMPLAIN PACK NOT MOUNTED
339 QSKUO: CAIGE I,NQS ;DISK UNIT # OPEN
340 SKIPE QACT(I) ;I <= UNIT #
341 JRST OPNL10 ;BAD UNIT # OR NOT ENGAGED
342 IFE MCOND DM,[ ;; Security check in reserved pack feature only on DM.
344 JUMPN W,QSKOB ;WRITE-OVER OR RENAME OK.
345 JUMPGE D,QSKOB ;READ OK.
346 SKIPE QRESRV(I) ;WRITE: IS PACK ON THIS DRIVE RESERVED?
347 JRST OPNL10 ;YES, CAN'T WRITE ON IT.
352 ;DNRF: DEVICE IS LIKE DSK: BUT DOESN'T SET REFERENCE DATE
353 DNRFO: TRO D,%DONRF/2 ;SET MODE BIT AND DROP INTO QSKO
355 ; Regular DSK: device
357 ; RH(D) has open mode, rotated 1 bit right.
358 ; W has operation code (0=r/w, 2=link, 4=del/rnm, 1=wov)
360 QSKO: MOVNI I,1 ;DSK OPEN, I <= # DETERMINED BY SYS
361 QSKOB: MOVEM I,EPDL(U) ;SAVE DISK #
364 JUMPE A,QSKOB2 ;IF RENAME OF OPEN FILE TRAP OUT
365 QSKOA: MOVE I,MDSK ;IS MFD IN?
366 PUSHJ P,QMCH1 ;READ IN MFD OF MASTER DISK
367 CLEARM QLD(U) ;LINK DEPTH
371 JUMPL D,OPNL11 ;MUST BE NORMAL READ
372 JRST QMLSTF ;USER WANT TO READ THE MASTER DIRECTORY
374 MFDCK: CAMN A,[SIXBIT /M.F.D./]
375 CAME B,[SIXBIT /(FILE)/]
379 SYSDS2: PUSHJ P,QFLD ;H <= PTR TO USER DIR TABLE
380 PUSHJ P,QSKO1 ;LOSER DIR NOT IN CORE
383 PUSHJ P,QUDLK ;RETURN WITH SOS OF QSNNR ON LSWPR
386 JRST QSKDP1 ;PAW OVER USER DIRECTORY
387 QSKDP2: PUSHJ P,QUDULK
389 JRST QSKDP9 ;NOT SPECIAL DIRECTORY FILE
392 JRST QLISTF ;USER WANTS TO READ HIS USER DIRECTORY
394 QSKDP9: JUMPN W,QSKDPY ;If doing IO?
395 SKIPL D ; and reading
396 JRST QSKDPZ ; then don't bother with "security".
397 QSKDPY: PUSHJ P,MNGDIR ;Else if this is a sanctified dir
398 PUSHJ P,SYSDSK ; get SYS job to tattle about it.
399 QSKDPZ: JUMPL D,QWRO ;WRITE
401 JRST QRNAM ;RENAME/DEL
403 JRST QALINK ;MAKE LINK
405 QWROR: JUMPE A,QPNL11 ;ALSO ENTER FOR VARIOUS WRITE OVER, COPY OVER MODES
407 PUSHJ P,QCHNF ;GET CHANNEL FOR READ
410 PUSHJ P,QUDLK ;LOCK USER DIR
411 PUSHJ P,QLOOK ;LOOK UP FILE
412 JRST [ PUSHJ P,QROR1C ;Not found => decide whethe error or wait.
413 POPJ P, ;Error (error code already set up).
414 PUSHJ P,QUDULK ;If retrying, first unlock directory,
415 PUSHJ P,LSWPOP ;Return the channel,
416 PUSHJ P,UDELAY ;Wait a little while,
417 JRST QWROR] ;Try again.
418 TRNE D,3 ;SKIP IF UNIT ASCII MODE
420 MOVE J,[440700,,5] ;BYTE SIZE IS 7 BITS
422 QSKO2: HLLZ J,QSBYTE(E) ;GET PROPER BYTE POINTER LH
424 TRNN D,%DONRF/2 ;3.4 BIT IN OPEN IMPLIES DONT SET REFERENCE DATE
425 PUSHJ P,QFREF ;"REFERENCE" FILE
428 HRRZM C,QUDFPR(E) ;SET UP PTR FROM CHNL TO FILE NAME AREA
429 LDB TT,[UNDSCP+UNRNDM(Q)] ;FOUND FILE SET UP CHNL
430 MOVEM TT,QDIRP(E) ;SET UP CHAR PTR TO DESC AREA
433 JRST QLINK ;FILE IS A LINK
435 SKIPE QLD(U) ;IF WE TRACED A LINK TO OPEN THE FILE, REMEMBER THAT.
440 LDB J,[UNPKN+UNRNDM(Q)] ;GET PACK NUMBER FILE IS ON
443 AOBJN I,.-1 ;TRANSLATE LOGICAL TO PHYSICAL DISK UNIT
444 JUMPGE I,QPKNF ;PACK NOT ON *
445 HRRZM I,QDSKN(E) ;SET CHNL DISK NUMBER
446 JUMPL D,QWROR1 ;REALLY WANT TO WRITE OVER, ETC
447 MOVEI TT,%QMRD ;PUT CHANNEL IN NORMAL READ MODE
449 QOEX1: PUSHJ P,QUDULK ;UNLOCK USER DIR
450 PUSHJ P,LSWDEL ;QUSR ENTRY
451 PUSHJ P,LSWDEL ;QSNNR ENTRY
458 JSP Q,OPSLC7 ;SET UP IOCHNM AND DEPART
464 QWROR1: SOJN W,OPNL12 ;NORMAL WRITE OVER MODE
465 HRRZS H ;CLEAR GARBAGE IN USER DIR NUM
466 HRRZS E ;CLEAR GARBAGE IN CHNL NUM
467 HRRZ J,QUDFPR(E) ;PICK UP LOCN OF FILE WITH U.F.D
468 MOVSI I,-NQCHN ;MAKE SURE THIS FILE NOT OPEN FOR READING
469 QROR1A: CAIE E,(I) ;DONT GET FAKED OUT BY OWN CHNL
477 QROR1B: AOBJN I,QROR1A
480 IORM TT,UNRNDM(Q) ;SET WRITE BIT
486 PUSH P,E ;CONVERT FROM ORIGINAL BYTE SIZE TO ONE OPENED IN NOW
487 LDB D,[UNBYTE+UNREF(Q)]
488 PUSHJ P,QBDCD ;GET INFO FROM ORIGINAL WRITE OF FILE
490 IDIV Q,D ;BYTES PER WORD
491 SUB Q,E ;# VALID BYTES
492 IMUL Q,D ;VALID BITS IN LAST WORD
493 POP P,E ;RESTORE QSK CHNL #
494 HRRZ R,QSBYTE(E);BYTES PER WORD IN NEW BYTE SIZE
495 LDB J,[QSBSIZ(E)] ;BITS PER BYTE IN NEW BYTE SIZE
496 IDIV Q,J ;NUMBER OF NEW-SIZE BYTES IN LAST WORD
497 SUB R,Q ;RESIDUE IN NEW-SIZE BYTES
498 LDB Q,[QSBSIZ(E)] ;NEW BYTE SIZE
499 PUSHJ P,QBENC ;RH(Q) GETS NEW BYTE INFO
501 DPB Q,[UNBYTE+UNREF(R)] ;CLOBBER FILE'S BYTE SIZE
511 DPB TT,[UNREFD+UNREF(Q)]
515 MOVSI TT,%QAMWO ;WRITE OVER MODE
516 IORM TT,QSRAC(E) ;LEAVE %QMIDL UNTIL FIRST .IOT SINCE
517 JRST QOEX1 ; THE USER WILL PROBABLY DO A .ACCESS
519 ;Call here if lookup fails on open.
520 ;Either signal some error and return,
521 ;or skip-return if caller should wait and retry the lookup.
522 ;Assumes H has dir slot, Q has address of filename block,
523 ;E has channel number allocated for this open.
525 QROR1C: HRRZ C,QSNLCN(H)
527 SKIPL Q ;SEE IF STILL POINTED INSIDE DIR
529 JRST QROR1D ;NO - REALLY FNF
531 CAMN A,UNFN1(Q) ;DO NAMES MATCH?
533 JRST QROR1D ;NO - REALLY FNF
534 HRRZ J,Q ;Find channel that has this file open.
537 HRRZS H ;Clear garbage in user dir num
538 HRRZS E ;Clear garbage in chnl num
540 QROR1E: CAIE E,(I) ;Dont get faked out by our own chnl.
546 ;Found the channel. Does it want us to wait?
549 JRST OPNL23 ;He didn't say so => get "file locked".
552 QROR1F: AOBJN I,QROR1E
553 JRST POPJ1 ;Cannot find channel => maybe was closed. Retry.
556 JRST OPNL4 ;FILE NOT FOUND
557 JRST OPNL47 ;LINK WAS FOUND, BUT NOT THE FILE IT POINTED TO
559 ;COME HERE FOR RENAME-WHILE-OPEN
560 QSKOB2: HRRZ A,B ;DO RENAME WHILE OPEN HERE TO AVOID
561 CAIL A,20 ;IN CASE SYS NAME HAS CHANGED
580 PUSHJ P,QGRLSC ;EITHER NAME > OR <?
581 JRST OPNL11 ;BOTH-BARF
582 PUSHJ P,QFNG ;ONE- COMPUTE EFFECTIVE FILE NAME
584 PUSHJ P,MNGDIR ;If RENMWOing in sanctified directory
585 PUSHJ P,SYSDSK ; Tattle.
586 MOVE I,Q ;IN CASE GO TO QRNAM4
587 LDB TT,[$QAMOD,,QSRAC(E)]
588 SKIPL QSCRW(E) ;SKIP IF WRITE BLOCK (WRITE FILE) MAYBE 0 FOR WRITEOVER
589 JUMPE TT,QRNAM4 ;JUMP IF READ FILE
596 SUBTTL PAW OVER USER DIRECTORY
598 QSKDP1: ANDCAB TT,QSNLCN(H)
606 ADDI C,(TT) ;ADDR OF BEGINNING OF NAME AREA
607 MOVEI D,2000(TT) ;D => FROM POINTER
608 MOVE I,D ;I => TO POINTER
609 HRLOI E,377777 ;PREVIOUS FN1 (BIT 4.9 COMPLEMENTED)
611 MOVEI J,0 ;J NEGATIVE => NEED SORT, NON-ZERO => DIR MODIFIED
612 QSKDP4: SUBI I,LUNBLK
613 QSKDP5: SUBI D,LUNBLK
620 JRST QSKDP5 ;NAME BLOCK FREE
622 QSKDP3: MOVE Q,UNRNDM(D)
624 JRST QSKDPR ;NOT OPEN FOR WRITE OR BEING DELETED
625 HLLOS J ;NEED TO WRITE OUT DIR
630 QSKDP7: PUSHJ P,QGRLSC ;DON'T CREATE ANY FILE WITH NAME OF < OR >
631 AOJA A,QSKDPA ;CHANGE BOTH JUST TO BE SURE
633 MOVE Q,QSNLCN(H) ;SEE IF THAT NAME EXISTS
634 MOVEI Q,2000-LUNBLK(Q) ;THERE MAY BE DUPLICATE ENTRIES
635 QSKDPU: CAMN A,UNFN1(Q) ;DURING THIS SEARCH BUT IT DOESN'T
636 CAME B,UNFN2(Q) ;MATTER
638 CAIE Q,(D) ;DON'T CHANGE NAME IF NOT DUPLICATE
639 QSKDPA: AOJA B,QSKDP7 ;FOUND IT. CHANGE SECOND NAME
640 QSKDPT: SUBI Q,LUNBLK
649 HRLZ Q,D ;RELOCATE FILE BLOCK
652 QSKDP6: JUMPL J,QSKDP4 ;ALREADY NEEDS SORT
653 MOVE B,UNFN2(D) ;MAY NOT HAVE YET IF GOT HERE FASTEST WAY
659 JRST QSKDP4 ;ORDER OK
665 QSKDP8: ADDI I,LUNBLK ;I POINTED TO EMPTY SLOT
672 SETZM (D) ;CLEAR VACATED AREA
676 QSKDPV: JUMPL J,QSKDPS ;SORT
681 QSKDPK: MOVE W,QSNLCN(H)
683 HLRZ A,UDALLO(W) ;IF THIS DIR HAS ALLOCATION
685 MOVEI B,NQS-1 ;CONVERT PACK # TO DRIVE #
689 QSKBK0: SETO A, ;ALLOCATED PACK NOT MOUNTED, USE ANY
690 MOVEM A,QSALLO(H) ;SAVE DRIVE # (-1 IF NONE)
695 QSKBK1: CAIL A,2000(W) ;COUNT BLOCKS USED
700 LDB B,[UNDSCP+UNRNDM(A)]
703 ADDI B,UDDESC(W) ;B GETS BYTE PNTR TO DESC
709 JRST [ADDM C,UDBLKS(W) ? JRST QSKBK4]
711 JRST [AOS UDBLKS(W) ? JRST QSKBK4]
716 QSKBK3: ADDI A,LUNBLK
727 QSKDPS: MOVEI T,LUNBLK
729 QSKDPB: MOVEI Q,(I) ;BEGINNING OF NAME AREA
731 MOVEI Q,2000-LUNBLK(TT) ;START AT END
736 TDZA J,J ;0 => SORTED -1 => MAKE ANOTHER PASS
747 QSKDPC: SKIPN A,UNFN1(Q)
752 QSKDPD: MOVE B,UNFN2(Q)
755 SKIPE E,(P) ;FIRST ENTRY
757 QSKDPG: MOVEM A,-2(P)
762 QSKDPF: JUMPL T,QSKDPJ
769 QSKDPH: REPEAT LUNBLK,[
777 QSKDPJ: CAMGE A,-2(P)
785 SUBTTL OPEN FOR WRITE
787 ;RETURNS WITH QUSR(E) AND QSNLCN(E) ON LSWPR
788 QWRO2: JUMPE A,QPNL11
790 SKIPGE I,EPDL(U) ;PICK UP DESIRED DISK UNIT
791 JRST QWRO2A ;SYSTEMS CHOICE
794 BUG ;WE LOST SOMEHOW...
796 SKIPL QDPWF(I) ;TUT IN BUT NOT PAWED OVER
797 TLNE TT,40000 ;TUT NOT IN
798 PUSHJ P,QTCH1 ;READ IN TUT OF DISK INVOLVED
799 PUSHJ P,QCHNF ;GET CHANNEL
804 MOVEM TT,QSBYTE(E) ;UNIT ASCII MODE, BYTE SIZE=7
805 PUSHJ P,QUDLK ;LOCK USER DIRECTORY
806 PUSHJ P,QGRLSC ;CHECK < AND >
808 PUSHJ P,QFNG ;REPLACE WITH COMPUTED EFFECTIVE NAME
809 PUSHJ P,QFREEF ;FIND FREE FILE NAME AREA AND STORE IN QDIRP(E)
810 JRST QFDF ;FILE DIR FULL
811 MOVSI TT,UNWRIT ;SET WRITE IN PROGRESS
814 DPB TT,[UNPKN+UNRNDM(Q)]
815 PUSHJ P,QAUTH ;SET FILE AUTHOR, MAY NOT PCLSR
818 SETOM QSCRW(E) ;SET CHNL WRITE SWITCH
824 JRST QWRO2B ;THIS DIR GOES ON A PARTICULAR UNIT
826 SKIPGE I,QWRU ;GET CURRENT WRITING UNIT
827 JRST QWRO2E ;NO CURRENT UNIT, GO FIND ONE
830 JRST QWRO2B ;ENOUGH ROOM ON PREFERRED UNIT
831 QWRO2E: SETOB T,I ;NOT MUCH SPACE LEFT TRY OTHER UNITS
833 QWRO2C: SKIPGE QACT(E) ;SKIP ON UNIT ACTIVE
835 IFN QRSRVP,SKIPN QRESRV(E) ;DONT CHOOSE THIS PACK IF RESERVED
836 CAML T,QSFT(E) ;NOTE QSFT IS -1 IF TUT NEVER BEEN READ IN
837 JRST QWRO2D ;OTHERWISE CONTAINS VALID BLOCK COUNT
840 QWRO2D: AOBJN E,QWRO2C
842 BUG ;NO ACTIVE UNRESERVED UNITS
844 JRST QWRO2B ;DON'T WRITE MFD IF UNCHANGED
851 QWRO: JUMPN W,QWROR ;REALLY WANT TO MODIFY OR OTHERWISE HACK AN EXISTING FILE
852 PUSHJ P,QWRO2 ;MAKING NEW FILE, DECIDE WHICH UNIT TO PUT IT ON
853 SETOM QMFTP(E) ;TRACK TO SCAN IN TUT
857 MOVEI TT,%QMWRT ;ENTER NORMAL WRITE MODE
865 SUBTTL File hacking tracking
867 ; MNGDIR checks the file name (sname in C)
868 ; Fails to skip if the file is an important system file.
869 ; Skips if the file is of the everyday sort.
872 IFN KL10P, CAME C,[SIXBIT /.KLFE./]
873 CAIN TT,'SYS ;A sys directory?
875 CAME C,[SIXBIT /ACOUNT/]
878 CAME C,[SIXBIT /DEVICE/]
879 CAMN C,[SIXBIT /CHANNA/]
881 AOS (P) ;Not a system directory. skip return.
884 ; SYSDSK notifies the SYS job to print a message on the
885 ; console about the file being hacked.
886 ; File names in C;A B, the opcode in W (or zero) specifies the hacking.
888 SYSDSK: JUMPE U,CPOPJ ;Avoid deadly embrace!
889 MOVSI T,SCLWRT ;Writing on SYS directory.
890 PUSHJ P,CWAIT ;Take turns like nice little lusers.
891 TDNE T,SUPCOR ;Wait for previous req to finish.
892 MOVE TT,W ;Check file operation code.
893 CAILE TT,4 ;If impossible opcode
894 SETZ TT, ; probably supposed to be R/W.
895 MOVEM TT,SWMOD ;Store opcode.
897 MOVEM TT,SWUNAM ;Luser.
902 MOVEM C,SWFN3 ;Sname.
903 IORM T,SUPCOR ;Notify the SYS job.
904 JRST CLKONJ ;Turn on the clock and return.
907 SUBTTL DIRECTORY ROUTINES
909 QFREEF: PUSH P,A ;Q_PTR TO USER DIR FREE FILE QDIRP(E)_PTR TO FREE DESC AREA
910 PUSH P,B ;GET FREE FILE AREA
912 MOVEI I,0 ;SIGNAL NO GC YET
913 QFREFA: SETZM QUDFPR(E) ;CLEAR SO WILL NOT POINT TO RANDOMNESS IN CASE OF G C
917 BUG ;FREE DESC POINTER OUT OF RANGE
920 CAIL Q,-UDDESC-7-LUNBLK(C)
921 JRST QAGARB ;NOT ENOUGH ROOM BETWEEN DESC AND NAME AREAS
922 PUSHJ P,QLGLK ;FIND WHERE FILE OUGHT TO GO
923 JRST QFREFF ;DIR WAS EMPTY
925 JRST QFREFE ;GOES AT END OF DIR
926 QFREFC: CAMN A,UNFN1(J)
930 TLNE C,UNIGFL ;* FILES MUST COME AFTER NON * FILES
931 JRST QFREFE ;OF SAME NAME
936 JRST QFREFF ;GOES AT BEGINNING
940 QFREFF: SUBI Q,LUNBLK ;Q -> NAME BLOCK FILE WILL GO IN
941 QFREFD: MOVNI T,LUNBLK ;ALLOCATE MORE SPACE FOR NAME AREA
943 HRRZ A,UDESCP(TT) ;FIRST FREE DESCRIPTOR LOC
944 DPB A,[UNDSCP+UNRNDM(Q)];STORE IN FILE AREA
945 MOVEM A,QDIRP(E) ;STORE IN CHANNEL
946 MOVEI B,6*UFDBPW+1 ;ENOUGH FOR A LINK WITH EVERY CHAR QUOTED PLUS ONE ZERO
947 ADDM B,UDESCP(TT) ;ALLOCATE MORE SPACE FOR DESC AREA
950 HRRZM B,QUDFPR(E) ;ASSOCIATE CHANNEL WITH FILE
952 SKIPL B,QDATE ;GET TIME AND DATE
955 MOVEM B,UNDATE(Q) ;SET CREATION DATE
958 DPB B,[UNREFD+UNREF(Q)] ;SET REFERENCE DATE
959 IDIVI A,UFDBPW ;GET WRD AND CHAR ADRS
966 BUG ;DESCRIPTOR AREA ALREADY OCCUPIED
971 BUG ;NOT FOLLOWED BY ZERO
975 MOVEM A,UNFN1(Q) ;SET FILE NAMES
979 QAGARB: JUMPL I,QNOFRE ;IF GC WAS ALREADY TRIED, DON'T TRY IT AGAIN - GIVE UP.
980 PUSHJ P,QGC ;GC. BTW, IT IS OK TO PCLSR HERE.
982 MOVNI I,1 ;SIGNAL GC HAS BEEN TRIED
985 ;MAKE ROOM FOR FILE BEFORE J. Q POINTS TO NEW EMPTY FILE SLOT
1001 QINSR1: HRRZ TT,QUDPR(A)
1011 QINSR2: AOBJN A,QINSR1
1019 ;DIR NOT IN CORE. GET IT FROM DISK, CREATE IT IF DOESN'T ALREADY
1020 ; EXIST, OR GIVE NO SUCH DIRECTORY ERROR.
1021 ;C HAS SNAME. RETURNS DIRECTORY NUMBER IN H.
1024 QSKOSW ;PREVENT TIMING ERROR IF TWO PCS SHOULD
1025 PUSHJ P,QFLD ; ATTEMPT TO BRING IN SAME DIRECTORY
1027 MOVEI T,2 ;SOMEONE ELSE BROUGHT IT IN, RELEASE QSKOSW
1028 JRST LSWPON ;BUT LEAVE QSNNR(H) LOCKED.
1032 PUSHJ P,QFL ;LOOK UP DIR IN MFD, RET TRACK IN J
1033 JRST QSKON ;NON EXISTENT
1034 PUSHJ P,QFLDF ;FIND FREE LOSER DIR SLOT
1036 PUSHJ P,QCHNF ;FIND FREE CHNL (TO READ IN DIR)
1037 MOVEM C,QSNUD(H) ;SET USER NAME IN DIR SLOT
1038 MOVEM J,QSLGL(E) ;REQUEST READ IN OF USER DIR FROM TRACK IN J
1042 PUSHJ P,LSWPON ;RELEASE QSKOSW, LEAVE SOSSET OF QSNNR(H)
1043 POP P,I ;GO AWAY WILL HANG UP WAITING IN QUDLK
1044 POP P,J ;DIR IS LOCKED BUT NOT ON LSWPR, PI WILL UNLOCK AFTER READIN
1047 QNOFRE: POP P,I ;NO FREE FILES AVAIL
1050 QPNL24: PUSHJ P,OPNL24
1053 QPNL20: PUSHJ P,OPNL20
1055 PUSHJ P,OPNL47 ;FOUND LINK, BUT IT POINTS TO NON-EXISTENT DIRECTORY
1058 AUTOCR: ;AUTOMATICALLY CREATED DIRECTORIES
1059 IFN TPLP+UNSPLP,SIXBIT /.LPTR./ ;FOR TPL SPOOLING
1060 SIXBIT /.MSGS./ ;FOR MESSAGES TO ALL LOSERS
1061 SIXBIT /.MAIL./ ; Programs like to write mail here
1062 SIXBIT /CRASH/ ; Programs like to dump themselves here
1063 SIXBIT /.TEMP./ ; Programs like to write randomness here
1066 QSKON: JUMPE C,QPNL20 ;DON'T ALLOW ZERO USER NAME
1069 QSKONA: CAMN C,AUTOCR(TT)
1072 CAMN A,[SIXBIT /..NEW./]
1073 CAME B,[SIXBIT /(UDIR)/]
1076 BUG INFO,[DSK: DIR ],SIXBIT,C,[CREATED BY ],SIXBIT,UNAME(U),SIXBIT,JNAME(U)
1079 JRST QPNL24 ;NO MFD SLOTS AVAILABLE
1083 QSKONE: PUSHJ P,QFLDF ;FIND FREE DIR SLOT
1087 JRST [PUSHJ P,LSWPOP ;QMDRO
1088 PUSHJ P,LSWPOP ;QSNNR
1089 PUSHJ P,UDELAY ;HOPEFULLY MEMORY WILL APPEAR SHORTLY
1092 SOS NQFUS ;NO TIMING ERR DUE TO QSKOSW
1094 DPB J,[MUR,,MEMBLT(A)]
1095 DPB H,[MNUMB,,MEMBLT(A)]
1106 MOVE B,QACTB ;NOW PUT UFD INTO MFD
1108 MOVE TT,MDNAMP(B) ;LOOK FOR A FREE SLOT
1110 QSKONC: TRNN TT,1777
1120 QSKOND: MOVNI TT,LMNBLK ;NO FREE SLOTS, SO EXTEND DOWNWARD
1124 SUBI TT,2000-2*NUDSL ;GET DISK BLOCK NUMBER
1125 IFN KA10P, SKIPGE TT
1126 IFE KA10P, CAIGE TT,2 ; Don't clobber 'HOM' blocks
1127 BUG ;TOO MANY UFDS (NQFUS CHECK DIDN'T WORK)
1130 MOVE TT,QACTB ;UNLOCK UFD AND CAUSE IT TO GET WRITTEN
1132 PUSHJ P,QMULK ;UNLOCK MFD
1140 QALINK: MOVE I,MDSK ;ENTER WITH QSNNR ON LSWPR
1142 PUSHJ P,QWRO2 ;MAKES NEW FILE WITH MINIMUM OF 37 BYTES OF DESC SPACE
1143 MOVSI A,UNLINK ; AND ADDS QUSR AND QSNLCN ON LSWPR
1144 IORM A,UNRNDM(Q) ;SET LINK BIT
1145 MOVE A,E ;QSK CHANNEL NUMBER
1146 MOVE C,SRN5(U) ;SNAME LINKED TO
1149 MOVE C,SRN3(U) ;FN1 LINKED TO
1152 MOVE C,SRN4(U) ;FN2 LINKED TO
1155 MOVE E,A ;QSK CHANNEL NUMBER FOR QCHNRT
1156 MOVEI R,EPDL(U) ;DON'T CLOSE A REAL IOCHNM WORD
1157 PUSHJ P,QSOCL4 ;CLOSE CHNL & FILE
1158 PUSHJ P,LSWDEL ;DELETE QUSR, HAS BEEN SETOM'ED
1159 PUSHJ P,LSWDEL ;DELETE QSNRR, HAS BEEN SOS'ED
1162 LDEP: MOVEI E,6 ;STORE SIXBIT FROM C INTO LINK DESC
1163 LDEPL: MOVEI B,0 ;GET NEXT CHAR
1165 JUMPE B,LDEPS ;*THIS ALLOWS EMBEDDED BLANKS.
1171 SOS E ;NUMBER OF CHARACTERS LEFT IN WORD
1172 JUMPN C,LDEPL ;JUMP IF ANY MORE NON-BLANK CHARS TO STORE
1174 JUMPE E,POPJ1 ;JUMP IF STORED 6 CHARACTERS
1175 POPJ P, ;STORED FEWER, NEED TERMINATOR
1177 LDEPS: MOVEI D,': ;THIS CHAR NEEDS TO BE QUOTED
1181 ;LINK ENCOUNTERED DURING LOOKUP
1183 QLINK: TRNE D,%DONLK/2 ;CHECK 3.5 BIT IN OPEN MODE
1184 JRST QOLINK ;JUMP IF DON'T CHASE LINKS MODE
1187 JRST OPNL27 ;LINK DEPTH EXCEEDED
1188 PUSH P,E ;SAVE XR NEEDED BY LSWPOP OF QUSR ENTRY
1199 JUMPE J,QL3 ;END DESC
1201 JRST QL4 ;QUOTE NEXT CHAR
1203 TLZA I,770000 ;TERMINATE THIS WORD
1207 QL4: ILDB J,TT ;GET CHAR THAT WAS QUOTED
1210 QL3: EXCH A,C ;END OF DESC REACHED
1211 EXCH A,B ;MAKE A FN1 B FN2 C SNM
1214 PUSHJ P,QUDULK ;UNLOCK DIR
1215 POP P,E ;RESTORE XR USED BY LSWPOP OF QUSR ENTRY
1216 PUSHJ P,LSWPOP ;QUSR ENTRY
1217 PUSHJ P,LSWPOP ;QSNNR ENTRY
1218 PUSHJ P,OPBRK ;IF TRYING TO BE PCLSRED, SUBMIT
1221 QOLINK: MOVSI TT,%QALNK ;OPENING UP A LINK
1222 IORM TT,QSRAC(E);DON'T ALLOW FILE-ONLY OPERATIONS SUCH AS IOT
1223 JUMPL D,QWROR1 ;LEAVE RH(QSRAC)=%QMIDL SO PI LEVEL WON'T MESS WITH IT
1224 JRST QOEX1 ;AND FINISH OPENING
1228 QMCH1: CONO PI,UTCOFF
1231 AOJE TT,QMCH2 ;NOT ON WAY IN
1232 QMCH3: CONO PI,UTCON
1242 CAME TT,[SIXBIT /M.F.D./]
1243 BUG HALT,[MFD CLOBBERED]
1244 QMCH1A: MOVEI E,2000-LMNBLK*NUDSL(E)
1245 IFN KA10P, SETZM NQFUS
1247 MOVNI TT,2 ;PROTECT DEC 'HOM' BLOCKS SO KLDCP OR 8080
1248 MOVEM TT,NQFUS ; CAN FIND ITS CRUFT
1250 QMCH1E: LDB TT,[1200,,E]
1257 QMCH2: SOS QMDRO ;INDICATE ON WAY IN
1260 BUG ;DON'T WANT TO WAIT FOR CHANNEL?
1262 MOVEI TT,MFDBLK ;MFD TRACK
1271 QTCH1: CONO PI,UTCOFF
1274 JRST QTCH2 ;GO READ IT IN
1276 QTCH1A: PUSHJ P,QTLOCK ;TO MAKE SURE IT'S IN
1278 JRST QTULK ;ALREADY PAWED OVER
1286 IMULI E,DECADE ;ROUND SWAPPING ALLOC TO MULTIPLE OF A DECADE
1289 PUSH P,E ;FIRST TRACK OF NON-SWAPPING (FILE) AREA
1290 MOVE E,QTUTP(T) ;ROUND TUT POINTER TO MULTIPLE OF A DECADE
1294 CAMGE E,(P) ;KEEP IT WITHIN THE FILE AREA
1300 BUG HALT,[PACK ID ],OCT,E,[IN TUT FOR UNIT ],DEC,I,[DIFFERS FROM HARDWARE PACK ID],OCT,QPKID(I)
1302 IFE DC10P, MOVEM E,QPKID(I)
1311 CLEARM QSFTS(I) ;FREE SPACE IN SWAPPING AREA
1319 AOS QSFT(I) ;BLOCK IN NON-SWAPPING AREA
1321 AOS QSFTS(I) ;BLOCK IN SWAPPING AREA
1331 QTCH2: SETOM QDPWF(I)
1335 BUG ;DON'T WANT TO WAIT FOR CHANNEL?
1338 MOVEI TT,MFDBLK ;TELL PI LEVEL TO READ IT ALL IN
1341 LDB TT,[121000,,QTUTO(I)]
1348 ;ROUTINE TO ACCESS TUT
1349 ;CALL WITH DISK UNIT NUMBER IN I, BLOCK NUMBER IN D
1350 ;RETURNS IN D AN LDB-STYLE POINTER TO THE TUT AND IN B THE BYTE
1351 ;THAT YOU WOULD GET BY LDB'ING THAT POINTER.
1353 ;CALLER MUST LOCK TUT
1355 TUTPNT: MOVE B,QTUTO(I)
1358 BUG ;BLOCK NUMBER NOT IN RANGE COVERED BY TUT
1368 QSTRT1: CONSO DC0,DSKCHN
1369 SETOM QHUNGF ;SOMEONE PUSHED RESET BUTTON, RECOVER AT PI LEVEL
1370 CONO DC0,DCSET+DCIENB+DSKCHN ;ENABLE IDLE INTERRUPT
1372 IFN RP10P+RH10P+RH11P,[
1379 IFN RP10P+RH10P+RH11P,[ ;START DISK WITH UTC ALREADY OFF
1380 QSTRT1: SETOM QGTBZY ;NOTE: TURNS UTC BACK ON BUT NOT CLOCK
1381 IFN RP10P, CONSO DPC,20 ;ONLY IF DISK IDLE
1382 IFN RH10P, CONSO DSK,%HIBSY
1383 IFN RH11P, IORDQ TT,%HRCS1
1384 IFN RH11P, TRNE TT,%HXRDY
1389 ;TRY TO FLUSH UNNEEDED UFDS FROM CORE.
1390 ;ARG IN C IS ROUTINE TO FREE THE MEMORY.
1391 ;CALL WITH UDRSW SIEZED, OR WITH PI 2 IN PROGRESS AND UDRSW NOT LOCKED BY ANYONE
1392 ;CLOBBERS H, TT. DOESN'T SKIP.
1393 QDFLS: MOVSI H,-QNUD
1394 QDFLS1: SKIPE QSNUD(H)
1396 QDFLS2: AOBJN H,QDFLS1 ;CAN'T FLUSH IF SLOT NOT USED OR CHANNELS OPEN IN DIR
1401 JRST QDFLS2 ;CAN'T FLUSH IF LOCKED OR NOT WRITTEN OUT
1402 PUSHJ P,QDFCHK ;CHECK THAT NO POINTERS TO THIS DIRECTORY REMAIN
1403 CLEARM QSNUD(H) ;FLUSH
1408 PUSHJ P,(C) ;RETURN THE MEMORY
1410 JRST QDFLS2 ;TRY FLUSHING SOME MORE
1412 ;CALL WITH UFD SLOT# IN H, WHEN YOU THINK THAT UFD IS FREE.
1416 QDFCH1: SKIPGE QUSR(C)
1421 BUG ;IT WASN'T REALLY FREE, MAYBE QSNNR IS SCREWED UP?
1427 ;FIND A FREE UFD SLOT, RETURN INDEX IN H. PUTS QSNNR ON LSWPR.
1435 PUSH P,C ;ALL UFD SLOTS IN USE, TRY FLUSHING SOME
1442 PUSHJ P,LSWPOP ;UDRSW
1443 PUSHJ P,UDELAY ;WAIT 1/2 SECOND THEN TRY AGAIN, INCLUDING QDFLS
1446 QFLDF1: SKIPN QSNNR(H) ;SLOT ALREADY GOBBLED
1447 SKIPE QSNUD(H) ;OR ALREADY OCCUPIED
1448 AOBJN H,QFLDF1 ;MEANS CAN'T TAKE IT
1450 BUG ;NONE FREE, QFUD OUT OF PHASE WITH REALITY
1453 MOVSI TT,600000 ;DOUBLE LOCK
1457 PUSHJ P,LSWPOP ;UDRSW
1463 QFLDRT: SKIPL A,AC0S+H(U)
1468 JUMPG T,CPOPJ ;HOW DID SOMEONE ELSE GET IT?
1470 AOS QFUD ;READ-IN NEVER STARTED, SLOT BECOMES FREE
1471 POPJ P, ;OK TO LEAVE 600000,, SET IN QSNLCN
1474 ;IF IN CORE, SET H TO UFD SLOT#, AOS QSNNR, PUT ON LSWPR, AND SKIP.
1475 ;IF DIRECTORY NOT IN CORE, NO SKIP. CLOBBERS T,TT.
1478 QFLD1A: MOVSI H,-QNUD
1479 QFLD1: CAME C,QSNUD(H)
1481 JUMPGE H,LSWPOP ;JUMP ON FAILED TO FIND USER.
1482 QFLD2A: AOSG QSNNR(H)
1483 BUG ;MUST HAVE GOTTEN NEGATIVE SOMEHOW
1484 PUSHJ P,LSWPOP ;UDRSW
1487 ;THIS IS AN ATTEMPT TO FIND A BUG.
1499 ;C <=SYS NAME, RETURNS TRACK ADDR OF DIR IN J, SKIPS IF FINDS LOSER
1508 ADD Q,MDNAMP(Q) ;PTR TO USER AREA
1509 QFL1: LDB J,[1200,,Q]
1516 QFL2: SUBI J,2000-LMNBLK*NUDSL ;J <= TRACK ADDR OF USER DIR
1522 ;ROUTINE TO ASSIGN A DISK CHANNEL.
1523 ;ARGS: U USER TO GO IN QUSR, H UFD SLOT# TO GO IN QUDPR, I DSK# TO GO IN QDSKN
1524 ;RETURNS QSK CHNL INDX IN E.
1525 ;DOESN'T DO A LOSSET OF QCHNRT, BUT CALLER MAY WANT TO.
1526 ;CLOBBERS T. NEVER SKIPS.
1528 QCHNF: PUSHJ P,SWTL ;PREVENT ANYONE ELSE FROM ALLOCATING CHANNELS
1532 JRST QCH2 ;SOME CHANNELS ARE AVAILABLE, GO FIND ONE
1533 PUSHJ P,LSWPOP ;QCHSW
1538 QCH2: SKIPGE QSRAC(E) .SEE %QALOK
1543 BUG ;WHERE DID THAT FREE CHANNEL GO?
1545 QCH1: HRRZS E ;CHANNEL ALLOCATED, INITIALIZE VARIABLES
1549 SETOM QSLGL(E) ;IN CASE OF WRITE-OVER ON 0-LENGTH FILE.
1556 SETZM QSRAC(E) .SEE %QMIDL
1560 MOVE T,[444400,,1] ;ASSUME BYTES=WORDS, WILL BE FIXED LATER
1564 SETZM QUDFPR(E) ;NOT YET SET UP TO ANY PARTICULAR FILE
1565 MOVEM U,QUSR(E) ;CHANNEL IS NOW IN-USE
1570 ;LOSSET ROUTINE TO RETURN TENTATIVELY ASSIGNED QSK CHNL
1571 ;E HAD BETTER CONTAIN THE QSK CHANNEL NUMBER AT "ALL" TIMES
1572 QCHNRT: SKIPL T,AC0S+E(U)
1575 HRRZ A,U ;LSWPOP MESSES WITH LH(U)
1582 SUBTTL DELETE, RENAME
1583 ;COME HERE FOR DELETE, OR RENAME NOT WHILE OPEN, ON DISK.
1585 QRNAM: SKIPN SRN3(U)
1605 JRST QROR1C ] ;GIVE FILE NOT FOUND OR FILE LOCKED
1610 JRST QPNLBN ;FILE ALREADY EXISTS
1612 QRNAM4: PUSHJ P,QLOOK
1614 CAME I,Q ;ALLOW RENAME THAT DOESN'T CHANGE NAMES.
1617 MOVSI TT,UNDUMP ;SAY FILE NOT DUMPED.
1619 MOVNI E,1 ;TELL QFREF NOT TO CLOBBER NON-EX DISK CHNL.
1620 PUSHJ P,QFREF ;"REFERENCE" FILE
1621 PUSHJ P,QRELOC ;STORE NEW NAMES IN DIR
1622 QRNAM2: MOVE TT,QACTB
1624 QRNAM1: MOVE U,USER ;U MAY NOT HAVE USER IF CAME HERE FROM LOGOUT
1628 QGRLSC: CAME A,[SIXBIT />/] ;SKIP NONE IF BOTH A+B ARE SPECIAL
1629 CAMN A,[SIXBIT /</] ;ONCE IF ONE IS
1631 CAME B,[SIXBIT />/] ;AND TWICE IF NEITHER
1638 ;MOVE FILE POINTED TO BY Q SO THAT NEW NAMES A AND B WILL BE IN
1647 PUSHJ P,QLGLK ;SEE WHERE FILE MUST GO
1650 QRLOCK: CAIL J,2000(TT)
1661 QRLOCJ: HRRZ Q,-3(P) ;WHERE FILE IS NOW
1664 JRST QRLOCS ;SAME PLACE
1665 REPEAT LUNBLK, PUSH P,.RPCNT(Q)
1669 QRLOCC: SUBI TT,LUNBLK
1672 BLT D,2*LUNBLK-1(TT)
1676 REPEAT LUNBLK, POP P,LUNBLK-.RPCNT-1(J)
1687 QRLOCE: MOVSI TT,-NQCHN
1688 QRLOCF: HRRZ E,QUDPR(TT)
1700 QRLOCG: AOBJN TT,QRLOCF
1716 QRLOCD: MOVNI D,LUNBLK
1721 QRLOCI: HRRZM J,QUDFPR(TT)
1724 QRLOCS: MOVEM A,UNFN1(Q)
1734 LDB J,[UNPKN+UNRNDM(Q)]
1735 QDELTA: MOVSI I,-NQS
1738 JUMPGE I,QPKNF6 ;PACK OF FILE NOT MOUNTED
1739 QDEL5: PUSHJ P,QUDULK
1741 JRST QDFNF ;GONE AWAY BETWEEN LOCKS
1744 QDEL5A: ;DELETE LINK
1745 MOVE I,MDSK ;RANDOM EXISTANT UNIT
1748 QPKNF6: PUSHJ P,QUDULK
1749 PUSHJ P,QPKNFP ;MAYBE JUST TUT NOT IN YET?
1750 JRST QDEL ;YUP, GOT IT NOW, TRY AGAIN
1751 PUSHJ P,QUDLK ;NO, FILE IS ON NOT-MOUNTED PACK
1752 PUSHJ P,QLOOK ;SO GET IT AGAIN
1753 JRST QDFNF ;GONE AWAY BETWEEN LOCKS, LOSE
1754 ;AND DELETE IT WITHOUT HACKING TUT
1755 QDFPK: LDB A,[UNDSCP+UNRNDM(Q)] ;POINTER TO DESCRIPTION AREA
1756 PUSHJ P,QSQSH ;REMOVE ENTRY
1769 QNFDL3: REPEAT NXLBYT,[IDPB C,A
1774 QAUTH: PUSH P,B ;STORE UFD INDEX OF FILE'S CREATOR
1775 PUSH P,C ;THIS IS NOT ALLOWED TO PCLSR. WE SEARCH THE MFD
1776 PUSH P,J ;WITHOUT LOCKING IT WHICH SHOULD BE ALL RIGHT SINCE
1777 PUSH P,I ;UFD'S DON'T MOVE AROUND AND THE MFD IS WIRED IN 1 PLACE IN CORE.
1781 JRST QAUTH1 ;UNAME = SNAME
1783 SKIPA ;NOT FOUND IN MFD
1786 MOVEI J,5 ;STRIP OFF ANY NUMERICS
1787 MOVE TT,[440600,,UNAME(U)]
1797 SKIPA ;NO NON-LETTERS
1799 QAUTH3: PUSHJ P,QFL0
1800 SKIPA C,HSNAME(U) ;CAN'T CONVERT UNAME IN ANY FORM, TRY HSNAME AS LAST RESORT
1803 SETOM J ;CAN'T ENCODE AUTHOR AT ALL
1804 QAUTH1: DPB J,[UNAUTH+UNREF(Q)]
1813 ;Q=0 => LOOK UP FILE TO DELETE
1814 ;Q .NE. 0 => DELETE FILE POINTED TO BY QUDFPR OF CHNL IN D
1815 ;H MUST HAVE DIR SLOT INDEX
1817 QDLA1: PUSHJ P,SLUGH
1824 SETO D, ;NO ASSOCIATED CHANNEL
1825 QDLA3: LDB A,[UNLNKB+UNRNDM(Q)]
1826 LDB TT,[UNPKN+UNRNDM(Q)]
1828 JUMPE A,QDELA1 ;ON DIFFERENT DISK (DIDN'T LOCK RIGHT TUT TRY AGAIN)
1833 JRST QDEL2 ;IGNORE CHANNEL (IF ANY) WHOSE CLOSING CAUSED THIS
1835 SKIPL QSCRW(J) ;ONLY LOOK AT READ CHNLS
1842 MOVSI TT,%QADEL ;FOUND CHNL WITH THIS FILE OPEN
1843 IORM TT,QSRAC(J) ;DELETE FILE WHEN THIS CHNL CLOSED
1844 MOVSI TT,UNCDEL ;SET DELETED BIT
1846 QDEL4: MOVE TT,QACTB
1850 QDEL4B: PUSHJ P,QTULK
1855 QDLA2: MOVE Q,QUDFPR(D) ;COMPUTE FILE ADR FROM CHNL IN D
1856 ADD Q,QSNLCN(H) ;DIR MAY HAVE MOVED
1862 QCDLWO: PUSH P,R ;OUTPUT CLOSE BUT FILE WAS DELEWO'ED
1863 SETZM QSCRW(D) ;FAKE OUT ERROR CHECK AT QSQSH6
1865 QSICLD: MOVE H,QUDPR(D) ;ENTRY FROM INPUT CLOSE, FILE WAS DELETED
1874 BUG ;FILE ISNT THERE?
1876 MOVE H,QUDPR(D) ;DIRECTORY NUMBER
1877 SETOM QUSR(D) ;FREE THE DISK CHANNEL
1881 QDELA1: PUSHJ P,QDEL4B ;NOT OUR DISK IN J
1883 MOVE J,TT ;DISK ITS REALLY ON
1884 QDELA2: MOVSI I,-NQS ;TRANSLATE PACK # IN J TO DRIVE # IN I
1890 QSOCLD: PUSH P,D ;DELETE FILE WHEN CLOSING OVER IT
1892 LDB J,[UNPKN+UNRNDM(Q)]
1900 QPKNF1: PUSHJ P,QPKNFP ;MAYBE TUT NOT IN YET?
1901 JRST QDELA2 ;YUP, TRY AGAIN
1904 JRST QUDULK ;GONE AWAY BETWEEN LOCKS
1905 JRST QDFPK ;GO DELETE OFF OF NON-MOUNTED PACK
1907 QDL2: PUSHJ P,QTULK ;DELETE LINK
1909 PUSHJ P,LSWPON ;UNLOCK QCHSW
1910 QDLINK: LDB E,[UNDSCP+UNRNDM(Q)]
1919 QDL1: DPB B,E ;CLEAR OUT THE CHAR
1921 IDPB B,E ;CLEAR A QUOTED CHAR WITHOUT LOOKING AT IT
1924 PUSHJ P,QSQSH ;REMOVE ENTRY
1930 QDEL2: AOBJN J,QDEL1 ;CHECK NEXT DISK CHANNEL
1931 MOVE C,UNRNDM(Q) ;NOT OPEN, SO REALLY DELETE IT
1938 HLL C,QBTBLI(D) ;GET DESCRIPTOR POINTER IN C AND TT
1941 PUSHJ P,NFLLN1 ;A GETS NUMBER OF BLOCKS IN FILE
1943 SKIPN D,QSFBT(H) ;SEE IF ENOUGH QSFBT STORAGE EXISTS
1945 QDEL10: HLRE B,(D) ;NUMBER OF FREE LOCATIONS IN THIS PAGE
1946 ADD A,B ;DECREASE LOCATIONS NEEDED
1949 QDEL11: JUMPLE A,QDEL12 ;JUMP IF SUFFICIENT STORAGE EXISTS
1950 PUSHJ P,TCALL ;GET MORE
1952 JRST [ MOVE U,USER ;U MAY NOT HAVE USER IF CAME FROM LOGOUT
1953 PUSHJ P,LSWCLR ;HAVE TO WAIT FOR MEMORY
1954 PUSHJ P,MQTEST ;AVOID DEADLOCKS BY UNLOCKING EVERYTHING
1958 DPB D,[MUR,,MEMBLT(A)]
1964 EXCH A,QSFBT(H) ;ADD TO FRONT OF LIST
1966 MOVE A,(P) ;GET BACK NUMBER OF BLOCKS NEEDED
1967 JRST QDEL10 ;SEE IF THERE ARE ENOUGH NOW
1969 QDEL12: POP P,A ;GET RID OF BLOCKS COUNT
1970 PUSHJ P,QSQSH ;REMOVE ENTRY, CANNOT PCLSR AFTER THIS
1971 CLEARB J,D ;J GETS NUMERIC TRACK NUMBER, D BYTE POINTER TO TUT
1972 MOVE TT,QTUTO(I) ;D ZERO SO WILL HALT IF DESC DOESN'T START WITH LOAD-ADDR!
1973 MOVE Q,QSFBT(H) ;Q -> AOBJN POINTER FOR STORING BLOCK NUMBERS
1974 QDEL3: ILDB B,C ; INTO QSFBT AS DESCRIPTORS ARE ZEROED OUT
1975 MOVEI A,0 ;I DISK, C BP TO DESCRIPTOR, A,B,E TEMP.
1977 JUMPE B,QDEL4 ;END OF FILE DESCRIPTION
1983 BUG ;OOPS, OUT OF QSFBT STORAGE
1984 SKIPL E,(Q) ;PICK UP AOBJN POINTER
1985 JRST [ MOVE Q,1(Q) ;THIS PAGE FULL, TRY NEXT
1987 MOVEM J,(E) ;STORE DISK,,BLOCK FOR LATER FREEING
1989 MOVEM E,(Q) ;INCREMENT POINTER
1990 MOVE E,QSNLCN(H) ;DECREASE DIR'S BLOCKS-USED
1996 BUG ;TUT SHOWS TRACK NOT USED
1997 AOS J ;DO NEXT BLOCK IN CONTIGUOUS GROUP
2001 IFN NXLBYT-2, .ERR THIS ROUTINE AND OTHERS KNOW IMPLICITLY THAT NXLBYT=2
2002 QDEL6: MOVEI D,0 ;LOAD ADDRESS
2006 DPB A,C ;A HAS ZERO FROM QDEL3
2013 ADD D,[TUTBYT_14,,] ;MAKE INTO ILDB-TYPE POINTER
2022 QDEL7A: MOVEI B,1 ;LOAD ADDRESS OR SKIP AND TAKE, SO ONLY ONE TRACK
2025 QDFNF: PUSHJ P,OPNL4
2028 QDELB: CONO PI,UTCON
2031 ;PERFORM BLOCK-FREEING SPECIFIED BY QFBTS
2032 QDLFBT: CONO PI,UTCOFF ;PROTECT QFBTS
2038 HRRZ T,(B) ;FIRST FREE LOCATION
2039 SUBI T,2(B) ;NUMBER OF LOCATIONS TO DO
2042 AOBJP A,QDLFB9 ;A NOW -> BLOCKS TO FREE, & CHECK FOR EMPTY
2043 SETO I, ;NO TUT LOCKED YET
2044 QDLFB1: HLRZ J,(A) ;DISK NUMBER
2045 CAMN J,I ;MAKE SURE RIGHT TUT IS LOCKED
2051 QDLFB2: HRRZ D,(A) ;BLOCK NUMBER TO FREE
2053 CAIGE B,TUTMNY ;USED IN "MANY" FILES(1,2,...,TUTMNY,TUTLK)
2054 SOJL B,[JRST 4,.] ;HALT IF TUT SHOWS TRACK NOT USED
2055 JUMPN B,QDLFB3 ;NOT LAST USE
2056 HRRZ T,(A) ;BLOCK NUMBER AGAIN
2060 AOS QSFTS(I) ;TRACK IN SWAPPING AREA
2061 QDLFB3: DPB B,D ;DECREASE USAGE COUNT IN TUT
2064 QDLFB9: MOVEI A,-1(A) ;GET AN ADDRESS ON THAT PAGE
2065 LSH A,-10. ;DONE WITH THIS PAGE, FREE IT
2066 PUSHJ P,TMEMR ;RETURN PAGE TO FREE AND TRY FOR MORE
2070 ;REMOVE HOLE FROM NAME AREA AT Q
2086 QSQSH1: SUBI C,LUNBLK
2095 REPEAT LUNBLK,SETZM .RPCNT(A)
2099 SUBI C,(TT) ;INDEX OF DELETED FILE
2100 HRRZI TT,-LUNBLK(A) ;INDEX OF OLD BEGINNING OF NAME AREA
2102 QSQSH3: HRRZ B,QUDPR(A)
2111 JRST QSQSH6 ;PNTR TO FLUSHED HOLE, CHECK IF READ CHNL
2112 CAIG B,(C) ;IF AFTER DELETED FILE DON'T RELOCATE
2116 JRST QSQSH4 ;READ CHNL
2120 BUG ;CHNL WRITING BUT BEING WRITTEN BIT NOT SET
2121 QSQSH4: AOBJN A,QSQSH3
2128 QSQSH6: MOVE B,QSRAC(A) ;FOUND PNTR TO DELETED FILE
2129 TLNE B,%QADEL ;SKIP IF NOT DELETE AFTER CLOSE
2130 SKIPGE QSCRW(A) ;ALSO ERROR IF NOT READ CHNL
2132 JRST QSQSH4 ;WAS DELETE AFTER CLOSE ON READ CHNL
2134 SUBTTL DIRECTORY LOOK UP, > FEATURE
2136 ;A contains the FN1 and B contains the FN2.
2137 ;H is the index of the directory slot. The dir must be locked.
2139 ;Returns the address of the filename block in Q.
2142 ;Internally, J and Q point to the bottom and top of the
2143 ;area of the dir we are still searching.
2144 ;Bit 4.9 of J is set to indicate one of the names is ">".
2145 ;C used as a flag: sign bit says creating a file.
2146 ;Bit 1.1 of C says FN2 is > or <.
2148 ;Look for place to create new file,
2149 ;and generate new version for >.
2150 QFNG: MOVEM Q,EPDL3(U)
2152 ;Look for existing files only
2156 MOVEI Q,2000-LUNBLK(J)
2161 JRST QLOOKA ;4.9 BIT OF J SET IF >
2169 JRST POPJJ ;J IS OFF THE END OF THE BLOCK
2172 QLK1: CAMN A,UNFN1(Q)
2176 TLNN C,UNIGFL ;BEING WRITTEN OR DELETED
2178 SUBI Q,LUNBLK ;SEARCH THROUGH * FILES
2190 ;REFERENCE FILE POINTED TO BY Q
2191 QFREF: LDB C,[UNREFD+UNREF(Q)]
2192 CAME E,[-1] ;IF A DISK CHNL IN USE,
2193 HRLM C,OLDRDT(E) ;SAVE OLD REF DATE IN DSK CHNL VAR
2194 SKIPGE T,QDATE ; If date unknown
2195 POPJ P, ; don't clobber
2196 HLRZ T,T ; Just get date part
2197 CAMN C,T ; If same as old date
2198 POPJ P, ; no need to do anything
2199 DPB T,[UNREFD+UNREF(Q)]
2200 MOVE T,MDSK ;MAKE MDSK WRITE OUT
2205 QLOOKA: CAME B,[SIXBIT /</]
2207 JRST POPJJ ;MUST BE READ RETN FILE NOT FOUND
2208 QLOOK1: JUMPGE C,QLOOK9
2210 TLO J,400000 ;IF WRITING, TURN "<" INTO ">"
2214 PUSH P,[-1] ;BEST INDEX
2215 PUSH P,[SETZ] ;BEST "NUMERIC" PART
2216 PUSH P,[SETZ] ;BEST ALPHA PART
2223 JUMPGE C,[ SKIPGE -2(P) ;FILE LOCKED, REMEMBER IT IF WE HAVE NO BETTER,
2224 HRRM Q,-2(P) ; BUT DON'T CONSIDER IT IF READING
2225 JRST QLOOK3 ] ;BUT IF WRITING, CONSIDER ALL FILES
2226 SKIPE TT,@QLKI1+1(C)
2227 QLOOK6: TRNE TT,77 ;RIGHT ADJ
2233 QLOOK8: LDB D,[600,,TT]
2236 JRST QLOOK7 ;NOT A DIGIT
2237 QLOK5B: TRNE I,77 ;RIGHT ADJ LOW NON NUM PART
2241 QLOK5A: TLC TT,400000 ;AVOID CAM LOSSAGE
2244 JRST QLOK5D ;FIRST MATCH
2245 JUMPGE J,QLOK5E ;GET LEAST
2246 CAMGE TT,-1(P) ;GET GREATEST
2251 JRST QLOOK3 ;NOT AS GOOD
2252 QLOK5D: HRRZM Q,-2(P)
2255 QLOOK3: SUBI Q,LUNBLK
2258 QLOK5E: CAMLE TT,-1(P)
2266 QLOOK7: LSHC TT,-6 ;LOW DIGIT NOT NUMERIC
2267 JUMPN TT,QLOOK8 ;NO NUMERIC DIGITS AT ALL ("BIN", MAYBE?)
2268 JUMPL J,QLOK5B ;IF LOOKING FOR GREATEST, LET THIS BE LEAST
2269 MOVNI TT,1 ;GREATEST IF LOOKING FOR LEAST
2272 QLOOK2: JUMPL C,QFNG1 ;REALLY WANT TO MAKE F.N.'S FOR WRITE
2274 POP P,C ;BEST "NUMERIC" PART
2280 MOVE A,UNFN1-1(Q) ;ACTUAL MATCHED FILE NAMES
2282 SOJGE Q,POPJJ1 ;FOUND A FILE THAT WASN'T LOCKED
2287 JRST QFNG2 ;NOT FOUND START W/ 1
2294 JRST QFNG4 ;REACH END OF NUMERIC FIELD
2299 QFNG5A: TLNE TT,770000
2304 QFNG2: MOVSI TT,(SIXBIT /1/)
2305 QFNG3A: MOVEM TT,A(C) ;STORE INTO A OR B AS APPRO
2319 QFNG4: TLNN TT,770000 ;SKIP ON ALREADY 6 CHAR NAME
2324 QFNG4B: TLNN I,770000
2329 QLKI1: CAME B,UNFN2(Q)
2333 QPKNF: MOVE C,QSNUD(H)
2334 PUSHJ P,QUDULK ;UNLOCK DIR
2335 PUSHJ P,LSWPOP ;QUSR ENTRY
2336 PUSHJ P,LSWPOP ;QSNNR ENTRY
2339 PUSHJ P,OPNL16 ;PACK NOT MOUNTED
2342 QPKNFP: MOVSI I,-NQS
2343 QPKNF3: SKIPGE QACT(I)
2348 JRST QPKNF2 ;PACK NOT IN OR NOT PAWED OVER
2349 QPKNF4: AOBJN I,QPKNF3
2352 QPKNF2: JRST QTCH1 ;MAYBE THIS UNIT HAS GOODIES
2354 QFDF: PUSHJ P,OPNL5 ;FILE DIR FULL ON WRITE
2357 QPNL13: PUSHJ P,OPNL13
2360 QPNL22: PUSHJ P,OPNL22
2364 QPNL11: PUSHJ P,OPNL11
2367 ;ROUTINE TO FIND PLACE IN DIRECTORY WHERE A B WOULD GO
2368 ;SKIPS ONLY IF DIRECTORY CONTAINS AT LEAST ONE FILE
2369 ;FOR INSERTION, FILE GOES BEFORE PNTR RETURNED IN J
2370 ;RETURNS PNTR IN Q TO BEGINNING OF NAME AREA
2371 ;(ONLY WORKS FOR LUNBLK = 5)
2372 QLGLK: HRRZ J,QSNLCN(H)
2376 POPJ P, ;DIRECTORY EMPTY
2381 ADDI J,600 ;128. NAME BLOCKS FROM END
2382 REPEAT 7,[ ;THIS CODE DELIBERATELY NOT INDENTED. NEED 4 DIMENSIONS.
2390 ADDI J,<1_<7-.RPCNT>>*LUNBLK
2391 SUBI J,<1_<6-.RPCNT>>*LUNBLK
2404 QLGL2: ADDI J,LUNBLK
2415 ;CALL BY JSP E,QLGLE
2416 QLGLE: MOVE D,UNFN2(J)
2424 SUBTTL LOCKING ROUTINES
2426 QMLOCK: PUSHJ P,LSWTL
2439 QTLOCK: PUSHJ P,LSWTL
2452 QUDLK: PUSHJ P,LSWTL
2466 QBTBLI: 440600,, ;IF GOING TO ILDB
2476 TBTBLI: REPEAT 1+TUTEPW, TUTBP-<.RPCNT*TUTBYT*010000,,>
2478 SUBTTL DIRECTORY GARBAGE COLLECTOR
2480 ; MOVE H, directory number
2481 ; lock the directory
2483 ; return if directory full.
2486 ; All pointers to directory relocated appropriately.
2488 ; Called from disk open routines if a new file is to be created
2489 ; and there are less than 6+LUNBLK words in the free area of the directory.
2490 ; Called from QSBWG if %QAFUL is set in QSRAC.
2491 ; %QAFUL means "must have successful GC before committing another track to this file."
2494 ; This GC allocates an extra block of core for temporary storage.
2495 ; If no memory is free in low half, waits without unlocking directory.
2496 ; Can possibly PCLSR. No deadly embrace to not unlock directory since
2497 ; it can't be flushed from core anyway and it's not holding anything else in.
2499 QAPBMN==NXLBYT+3 ;minimum number of descriptor bytes which
2500 ; must be available at the end of a file to
2501 ; commit another track to the file.
2502 ;1 for a take-N, NXLBYT+1 for jump, 1 for ending zero.
2503 QAPBMX==36. ;maximum number of descriptor bytes to allocate at a time.
2505 QGC: IRPC X,,ABCDQIJTR
2509 ;Old GC prints message on system console. Any reason to with fast one?
2511 ; validate the directory
2513 QGC00: SKIPL A,QSNLCN(H)
2514 BUG ;directory not locked
2516 MOVEM C,LASTGC ;save name of last dir GCed
2518 BUG ;directory clobbered
2521 BUG ;name pointer out of bounds
2524 CAIL D,-UDDESC*UFDBPW(C)
2525 BUG ;descriptor/name overlap
2527 ; Get a block of core to use for temporary storage.
2528 ; The block is left in the "in-process" state.
2533 JRST [ PUSHJ P,UDELAY ;no core available in low half
2534 JRST QGC00 ] ;so wait, then loop back to beginning
2536 MOVEI B,1(A) ;zero it out
2540 EXCH Q,A ;A -> directory, Q -> temporary core
2543 ; Scan the directory and count:
2545 ; J files open for writing
2546 ; R active bytes of descriptor
2550 MOVEI B,2000(A) ;end of name area
2551 ADD A,UDNAMP(A) ;start of name area
2553 JRST QGC19 ;jump if all files done
2556 BUG ;zero name block?
2557 AOJA I,QGC12 ;file exists
2559 QGC11: ADDI A,LUNBLK ;advance to next file
2560 AOJA R,QGC10 ;also count the zero byte that ends the descriptor
2562 QGC12: MOVE C,UNRNDM(A)
2565 ANDI C,.BM UNDSCP ;get descriptor ptr (undscp has pos=0)
2568 ADDI C,UDDESC-2000(B)
2572 QGC13: ILDB T,C ;get byte of descrip
2575 AOJA R,QGC13 ;1-byte desc
2576 REPEAT NXLBYT, IBP C ;multi-byte desc
2580 QGC14: ILDB T,C ;count bytes of link descriptor
2583 AOJA R,[IBP C ;quoted
2588 ; Compute number of bytes of descriptor to add after each
2589 ; file open for output. If > QAPBMX, set to QAPBMX.
2590 ; If < QAPBMN, take directory-full exit.
2592 QGC19: MOVE C,I ;save number of files
2593 IMULI I,LUNBLK*UFDBPW ;number of bytes in name area
2594 ADDI R,UDDESC*UFDBPW(I) ;R := total number of bytes claimed
2595 MOVEI A,2000*UFDBPW-1
2596 SUB A,R ;A := number of bytes left
2598 IDIV A,J ;number of bytes available to extend open files
2600 JRST QGC69 ;if < minimum, dir. full
2602 MOVEI A,QAPBMX ;limit to at most QAPBMX bytes at a time
2605 ; A = number of bytes of room to leave after each file open for writing
2606 ; B -> name block under consideration
2607 ; C -> old descriptors
2608 ; D = disk channel number under consideration. Also D = C+1
2609 ; J counts new descriptor bytes generated
2610 ; Q -> new descriptors (in temporary core block)
2611 ; R -> base of directory
2614 HRRZ R,QSNLCN(H) ;old dir
2615 ADDI Q,UDDESC ;new dir
2622 QGC20: CAIL B,2000(R)
2623 JRST QGC40 ;all files done
2624 LDB C,[UNDSCP UNRNDM(B)] ;get old desc ptr
2625 DPB J,[UNDSCP UNRNDM(B)] ;store new desc ptr
2627 ; Loop over all disk channels, relocating the ones that point to this file
2630 QGC31: HRRZ T,QUDPR(D)
2633 AOBJN D,QGC31 ;not in use or not same directory
2634 JUMPGE D,QGC39 ;jump if all disk channels done
2637 JRST QGC32 ;not same file
2638 MOVE T,J ;relocate descriptor pointer
2641 QGC32: AOBJN D,QGC31
2643 QGC39: IDIVI C,UFDBPW ;make desc pntr into byte pointer
2649 QGC21: ILDB T,C ;copy descriptor bytes of a file into temporary core
2660 QGC22: ILDB T,C ;copy descriptor bytes of a link into temporary core
2669 QGC23: MOVE T,UNRNDM(B)
2672 ADD J,A ;file being written, increase desc area
2677 QGC25: ADDI B,LUNBLK ;next file
2678 AOJA J,QGC20 ;also account for final zero at end of descriptor
2680 ; Paranoia: check that all disk channels to this directory look OK
2682 QGC40: MOVEM J,UDESCP(R) ;store free-desc pointer
2683 LDB A,[1200,,Q] ;last word used by descriptors
2686 ANDI Q,-2000 ;base of temp core block again
2688 QGC41: HRRZ T,QUDPR(A)
2691 AOBJN A,QGC41 ;channel not in use, or to some other dir
2692 JUMPGE A,QGC49 ;all channels done
2693 SKIPN B,QUDFPR(A) ;get file open on this channel
2694 JRST QGC42 ;channel not set up to any particular file
2697 BUG ;file pointer screwed
2699 SKIPL J,QDIRP(A) ;get descriptor pointer
2701 BUG ;descriptor pointer screwed
2702 LDB C,[UNDSCP UNRNDM(B)]
2703 CAIGE B,2000-LUNBLK(R) ;skip if last file in dir
2704 LDB D,[UNDSCP UNRNDM+LUNBLK(B)] ;else get desc pntr for next file
2705 CAIL B,2000-LUNBLK(R)
2706 MOVEI D,2000*UFDBPW ;but if last file, get infinity
2707 CAML J,C ;verify that QDIRP points to this file
2710 QGC42: AOBJN A,QGC41 ;do next channel
2712 ; If you thought that was paranoid, get a load of this:
2714 QGC49: MOVE B,UDNAMP(R)
2716 QGC50: CAIL B,2000(R)
2718 LDB C,[UNDSCP UNRNDM(B)]
2720 IDIVI C,UFDBPW ;NOTE if UNDSCP = 0 we depend on bytes
2721 HLL C,QBTBL(D) ; off left end of word LDB'ing as zero
2725 BUG ;descriptor not preceeded by zero
2727 TRZ J,#.BM UNDSCP ;LH(J) flags, RH(J) just desc pntr
2734 REPEAT NXLBYT, IBP C
2746 QGC53: TLNE J,UNWRIT ;RH(J) has desc pntr to the zero that ends the file
2747 ADDI J,QAPBMN ;if being written, needs room for one more track
2748 CAIL B,2000-LUNBLK(R) ;now set D to point to next descriptor area
2749 SKIPA D,UDESCP(R) ;do this instr if last file in dir
2750 LDB D,[UNDSCP UNRNDM+LUNBLK(B)] ;else get next file's desc pntr
2752 BUG ;descriptors overlap
2756 ; Copy the descriptors back into the directory
2758 QGC60: MOVSI C,UDDESC(Q) ;make BLT pointer to copy it back
2760 MOVE B,UDNAMP(R) ;use same BLT to zero out the free area
2767 QGC69: LDB A,[121000,,Q] ;core block number of temporary page
2768 PUSHJ P,TMEMR ;return it
2769 MUINP ;verifying that it is the right one.
2775 SUBTTL INTERPRET DESCRIPTORS
2777 QFNTR: MOVE H,QUDPR(A) ;BYTE # IN Q CHNL # IN A
2778 PUSHJ P,QUDLK ;DONT SKIP IF OFF FILE
2779 MOVE T,QSNLCN(H) ;RETN BLOCK IN QSLGL(A) AND QSBI(A) DIR PNTR IN QDIRP(A)
2780 ADD T,QUDFPR(A) ;FIRST ADR OF BLOCK IN QFBLNO(A)
2781 LDB TT,[UNDSCP+UNRNDM(T)] ;CHAR ADR OF FILE BEG
2782 MOVEM TT,QDIRP(A) ;SKIPS IF FINDS BLOCK AND LEAVES USER DIR LOCKED
2785 CLEARB J,QSLGL(A) ;J HAS ORG OF FIRST NON-EX-BLOCK IF OFF END OF FILE
2786 QFNT1A: PUSHJ P,QFNT1
2787 JRST QUDULK ;OFF END OF FILE RETN NOT SKIPPING
2789 JRST QFNT7 ;LOCATED BLOCK CONTAINING WORD
2793 QFNTN: MOVE H,QUDPR(A) ;LIKE ABOVE BUT SCAN FORWARD ONLY FROM CURRENT SPOT
2796 CAIA ;EOF, DON'T SKIP RETURN
2801 QFNT1: SKIPE QSBI(A) ;DECODE NEXT BLOCK, CHNL IN A, SKIP UNLESS EOF.
2802 JRST QFNT2 ;BLOCK # IN QSLGL FILE ADR IN J (TAKE N PENDING)
2803 QFNT3: PUSHJ P,QMPDCH ;GOBBLE NEXT CHR OF DESC IN R (POINTED TO BY QDIRP) INCR QDIRP
2804 CAIN R,UDWPH ;ALSO RET BYTE PNTR IN TT
2806 JUMPN R,QFNT8 ;NOT OFF END OF FILE
2813 JRST QFNT6 ;SKIP AND TAKE
2817 QFNT5: MOVEI J,2000 ;ACTIVE BYTES IN BLOCK
2822 QFNT7: MOVSI T,%QALBK ;SET UP PROC LAST BLOCK FLG AND RETN
2823 ANDCAM T,QSRAC(A) ;CLEAR LAST BLOCK OF FILE BIT
2825 JRST QFNT7A ;NOT LAST BLOCK
2826 ILDB R,TT ;GET NEXT CHR IN DIR
2828 IORM T,QSRAC(A) ;PROCESSING LAST BLOCK
2829 QFNT7A: AOS QSBI(A) ;FAKE OUT PI ROUTINE WHICH WILL TRY TO INCREMENT
2833 QFNT4: MOVEI J,0 ;LOAD ADR
2842 QFNT6: MOVEI J,1-UDTKMX(R)
2847 SUBTTL DISK CHANNEL DATA AREAS
2849 QBFP: BLOCK NQCHN ;BUFFER LIST LH LAST RH FIRST
2850 ;READ: PI IN MP OUT. WRITE: MP IN PI OUT.
2851 SINLST: BLOCK NQS ;SWAP-IN LISTS FOR EACH DISK
2852 SOUTLS: BLOCK NQS ;SWAP-OUT LISTS FOR EACH DISK
2854 ;READ/WRITE LISTS LINK THROUGH MLO IN MEMBLT.
2855 ;LH(MEMPNT) HAS DISK ADDR, RH(MEMPNT) HAS # BYTES IN BLOCK IF FILE READ
2856 ;MWC IN MEMBLT HAS WORD COUNT IF WRITE (FOR EXTRA-WORDS)
2858 QFCHN: NQCHN ;NUMBER OF FREE QSK CHNLS (NOT COUNTING DIR WRITE AND SWAP CHANNELS)
2860 QUSR: REPEAT NQCHN,-1 ;USER
2861 DWUSR: -1 ;0 IF DIR WRITE ACTIVE
2862 SWUSR: REPEAT NQS,-1 ;0 IF SWAP XFER ACTIVE
2863 QDIRP: BLOCK NQCHN ;CHAR ADR PNTR TO DESC AREA FOR FILE
2864 QSLBLK: BLOCK NQCHN+NQS+1 ;LAST BLOCK NUMBER OF FILE WRITTEN
2865 QSLGL: BLOCK NQCHN ;LAST QSGL
2866 QSGL: REPEAT NQCHN+NQS+1,-1 ;-1 IDLE + ACTIVE TRACK
2867 ;LAST NQS+1 FOR FD WRITE AND SWAPPING
2868 QSBI: BLOCK NQCHN ; COUNT CONSECUTIVE BLOCKS
2869 QSBFS: BLOCK NQCHN ;NUMBER OF BUFFS THIS CHNL +1 IF EOF AT PI WITH QSBFS=0
2870 QPCLSR: BLOCK NQCHN ;PCLSR STATUS OF MAIN PROGRAM - LOAD SYSTEM CALL
2871 QSMDN: BLOCK NQCHN ;MAIN PRGM ACTIVE BUFFER NUM
2872 OLDRDT: BLOCK NQCHN ;STORAGE FOR PREVIOUS REFERENCE DATE
2873 QSRAC: BLOCK NQCHN+1
2874 REPEAT NQS, %QMSWP ;SWAPPING CHANNELS START OUT IN SWAP MODE
2876 %QALOK==400000 ;4.9 CHNL LOCKED (NOT USED)
2877 %QAEFR==200000 ;4.8 EOF REACHED READ
2878 %QAEFW==100000 ;4.7 EOF WRITE
2879 %QACTH==40000 ;4.6 DONT RELOAD. CORE JOB HUNG ON ACTIVE BUFFER
2880 %QAFUL==20000 ;4.5 GC DIR BEFORE COMMITTING ANOTHER BLOCK TO FILE
2881 %QADEL==10000 ;4.4 DELETE WHEN CLOSED
2882 %QAACC==4000 ;4.3 FILE ADDRESS ALTERED BY .ACCESS OR OTHERWISE
2883 %QAPAR==2000 ;4.2 NON RECOV PARITY ERR (OR OTHER DISK ERR) AT PI
2884 %QAOUT==1000 ;4.1 ASSOC USER OUT DONT RELOAD (NOT IMPLEM.)
2885 %QALBK==400 ;3.9 READ CHNL PROCESSING LAST BLOCK FLAG
2886 %QAMPU==200 ;3.8 UPDATE QSMPRP, QSMPRC ON NEXT BUFFER GOBBLE
2887 %QAWOV==100 ;3.7 FILLING OUT LAST BLK OF FILE IN WRITE OVER MODE PAST ORIG EOF
2888 %QALNK==40 ;3.6 FILE IS REALLY A LINK
2889 %QALOP==20 ;3.5 LINKS WERE TRACED IN OPENING THIS FILE.
2890 %QARWT==10 ;3.4 MAKE WOULD-BE READERS WAIT (RATHER THAN GETTING FILE LOCKED ERROR)
2891 %QAFNY==4 ;3.3 "FUNNY BLOCK", WORD COUNT IN LAST WORD
2892 $QAMOD==220200 ;3.2-3.1 READ/WRITE MODE 0 NORMAL 1 WRITE OVER 2 COPY OVER WRITE
2893 %QAMWO==1 ;3.1=1 => WRITE-OVER MODE.
2894 %QM==777777 ;RH CHANNEL MODE. INDEX INTO ACTION TABLES USED AT PI LEVEL.
2895 .SEE %QMIDL ;FOR TABLE OF CHANNEL MODES
2897 QDSKN: BLOCK NQCHN ;DISK UNIT NUMBER
2898 DWSKN: 0 ;DISK WRITING DIR ON
2899 SWSKN: REPEAT NQS,.RPCNT ;DISK SWAP XFER
2900 QSCRW: BLOCK NQCHN ;0 READ -1 WRITE
2903 QSCABN: BLOCK NQCHN ;ACTIVE BUFFER NUMBER PI LEVEL OR -1 IF NONE
2904 DWABN: -1 ;DISK D.W. A.B.N
2905 SWABN: REPEAT NQS,-1 ;SWAP ABN
2906 QUDPR: BLOCK NQCHN ;NUMBER OF ASSOCIATED USER DIR PNTR
2907 QUDFPR: BLOCK NQCHN ;RELATIVE PNTR TO FILE AREA, ZERO IF NO PARTICULAR FILE
2908 QMPTN: BLOCK NQCHN ;HAS LAST TRACK STORED IN DIRECTORY
2909 QMPTC: BLOCK NQCHN ;MAIN PRGM TRACK COUNT
2910 QMTTR: BLOCK NQCHN ;TRACK RESERVED OR -1
2911 QMFTP: BLOCK NQCHN+1 ;TRACK NUMBER FOR SCAN FOR FREE TRACKS IN TUT ON WRITE
2912 REPEAT NQS,NUDSL; DITTO FOR SWAP CHANNELS
2913 QERRS: BLOCK NQCHN+NQS+1 ;NUMBER ERRORS TRYING LAST OP
2914 QSMPRP: BLOCK NQCHN ;MAIN PRGM BYTE POINTER
2915 QSMPRC: BLOCK NQCHN ;M.P. COUNT (BYTES LEFT IN BUFFER)
2916 QSBYTE: BLOCK NQCHN ;LH BYTE PNTR (P=44), RH BYTES PER WORD
2917 QSBSIZ==300600,,QSBYTE ;BYTE POINTER TO CHANNEL BYTE SIZE
2918 QFBLNO: BLOCK NQCHN ;BYTE # IN FILE OF BEG OF BLOCK BEING PROCESSED AT M.P. LEVEL
2919 QRADAD: BLOCK NQCHN ;DESIRED BYTE ADR (LOOKED AT IF %QAACC OR %QAMPU IN QSRAC SET)
2920 QPIBSZ: BLOCK NQCHN ;NUMBER OF BYTES IN BLOCK ACTIVE AT P.I. LEVEL (READ)
2921 ;BIT 4.9 => GET FROM LAST WORD IN BLOCK (%QAFNY)
2922 QMPBSZ: BLOCK NQCHN ;NUMBER OF BYTES IN MN PROG ACTIVE BUFFER
2923 QLDPTR: BLOCK NQCHN .SEE NLDSBQ ;DURING SBLK LOADING, HOLDS THE AOBJN POINTER
2924 ;INTO USER CORE FOR DOING A DISK TRANSFER ON.
2925 QSMMP: BLOCK NQS ;MMP ADDRESS OF BLOCK ACTIVE ON SWAPPING CHANNEL
2927 ;VARIABLES FOR CURRENT TRANSFER
2929 QSDU: -1 ;UNIT TRANSFERING DATA, -1 IF NONE.
2930 QSDCH: -1 ;CHNL READY TO BE TRANSFERED ON QSDU
2931 QERS1: -1 ;ERR VERIFY SWITCH -1 NO ERR 0 EXPECTING COMPLETION OF VERIFY OP
2932 QDWIP: 0 ;NUMBER OF DIR WRITE IN PROGRESS 4.9=1=>MASTER
2935 QSDU1: -1 ;QSDU FOR OTHER CONTROLLER
2936 QSDCH1: -1 ;ASSOCIATED CHANNEL
2937 QTUNT1: -1 ;UNIT TO TRANSFER NEXT
2938 QTCHN1: -1 ;CHANNEL TO TRANSFER NEXT
2943 LQTM1: 0 ;TIME LAST TRANSFER STARTED
2946 ;MASTER FILE DIRECTORY
2948 QMDRO: -1 ;ORIGIN OF MASTER DIR 4.9 IF LOCKED
2951 ;4.5, 4.4, 4.3, ... CHANGED + NOT WRITTEN UNIT 0, 1, 2, ...
2952 ;3.2=1 NOT RECONCILED (NQFUS NOT SET UP)
2953 ;3.1-3.5 MUST BE ZERO (AT LEAST AFTER ITS RECONCILED)
2954 QAMDNO: -1 ;ASCENDING MASTER DIRECTORY NUMBER, -1 NOT SET UP
2955 NQFUS: 0 ;NUMBER OF FREE LOSER SLOTS IN MFD
2957 ;TRACK UTILIZATION TABLES
2959 QTUTO: REPEAT NQS,-1 ;ADDRESS OF TUT. LH SIMILAR TO QMDRO
2961 ;4.8 READ-IN NOT STARTED YET
2962 ;4.6 NOT READ IN YET
2963 ;CHANGED AND NOT WRITTEN ON UNIT
2964 ;0 = 4.5 1 = 4.4 2 = 4.3 3 = 4.2 4 = 4.1
2966 ;3.1-3.5 MUST BE ZERO
2967 QDPWF: BLOCK NQS ;-1 TUT NOT RECONCILED (CALL QTCH1)
2968 QTWRTM: BLOCK NQS ;TIME TUT LAST WRITTEN
2969 QSFT: REPEAT NQS,-1 ;NUMBER TRACKS FREE IN USER AREA
2970 QSFTS: BLOCK NQS ;NUMBER TRACKS FREE IN SWAPPING AREA
2971 QPKNM: BLOCK NQS ;NAME OF PACK
2972 QPKID: REPEAT NQS,-1 ;PACK ID OF DISK ON DRIVE
2974 QRESRV: REPEAT NQS,-1 ;NON-ZERO => PACK ON THIS DRIVE RESERVED. SET FROM TUT.
2975 ;NOT 0 AND NOT -1 => SIXBIT DEVICE NAME FOR "SECONDARY" PACK
2977 NTBL: ;NUMBER OF BLOCKS IN TUT ON THIS DRIVE
2978 IFE T300P, REPEAT NQS, NTUTBL
2980 REPEAT T300P, NTUTBL
2981 REPEAT NQS-T300P, NTUTB1
2984 ;POSITIONER VARIABLES (INDEXED BY PHYSICAL DRIVE)
2986 QSKT1: REPEAT NQS,-1 ;CHANNEL POSITIONER SET FOR OR -1 IF NONE
2987 QRCAL: REPEAT NQS,0 ;-1 IF RECALIBRATING
2988 QSPPS: REPEAT NQS,-1 ;INTENDED POSITIONER POSITION (NOT USED???)
2989 QSEEK: BLOCK NQS ;-1 IF SEEKING
2990 QPOS: REPEAT NQS,-1 ;CURRENT CYLINDER
2991 QPOSGL: BLOCK NQS ;CYLINDER TRYING TO POSITION TO
2993 QRCTIM: BLOCK NQS ;RECALIBRATE TIMEOUT IN HALF SECONDS. THE ATTNS
2994 ];DC10P ; TEND TO GET LOST FOR SOME REASON
2996 ;MISCELLANEOUS DISK VARIABLES
2998 QACT: REPEAT NQS,0 ;ONLY USE UNITS WITH 0
2999 QACTB: 0 ;4.5 UNIT 0 ACT 4.4 1 ACT 4.3 2 4.2 3 4.1 4
3001 QWBUFS: 0 ;TOTAL NUMBER OF WRITE BUFFERS ACTIVE
3003 QWBFMX: 10.*DC10P+15.*RP10P+30.*RH10P+20.*RH11P ;MAX # ALLOWED. SHOULD BE
3004 ; ABOUT 1 SEC DISK XFER.
3005 QHUNGF: 0 ;-1 => DISK CONTROL HUNG, PI LEVEL SHOULD RESET, RECALIBRATE, RETRY
3006 NTQHNG: BLOCK NQS ;NUMBER OF TIMES TRANSFER HUNG ON THIS UNIT
3008 QTUNT: 0 ;UNIT TO TRANSFER ON NEXT
3010 QLCHN: 0 .SEE QINT2C
3011 QWRU: -1 ;DEFAULT WRITE UNIT (-1 if there isn't a default unit yet)
3012 MDSK: 0 ;DRIVE # OF MASTER DISK
3013 QACTTM: -1 ;SETOM ON READ OR WRITE DATA TRANSFER
3014 ;AOS AT SSLCK IF + OK TO WRITE DIRS
3015 ;IE DON'T TIE UP DISK TO WRITE DIR UNLESS THINGS ARE QUIET
3016 QDWFAR: -10. .SEE QINT3 ;WRITE DIRS SOME OF THE TIME ANYWAY
3017 LQTM: 0 ;TIME AT WHICH LAST COMMAND GIVEN TO DISK
3018 QFTTHR: 600. ;IF FREE TRKS ON QWRU GOES BELOW THIS, SWITCH TO UNIT WITH MOST FREE TRACKS
3019 QRDAHD: IFE MCOND DM,[0] .ELSE 2 ;NUMBER OF BLOCKS TO READ AHEAD
3021 LASTGC: 0 ;NAME OF LAST DIRECTORY TO GET GC'ED
3025 QNUD==40. ;NUMBER USER DIRECTORIES
3027 QFUD: QNUD ;NUMBER OF FREE UFD SLOTS
3029 QSNUD: BLOCK QNUD ;USER NAME OR 0 IF FREE
3030 QSNLCN: BLOCK QNUD ;4.9 LOCKED, 4.8 ALSO NOT IN CORE RH CORE ADR
3031 .SEE DCHBT ;4.6 =1 NOT PAWED OVER 4.5 CHNGD AND NOT WRITTEN ON UNIT 0
3032 ;4.4 UNIT 1 4.3 UNIT 2 4.2 UNIT 3 4.1 UNIT 4
3033 ;3.9 UNIT 5 3.8 UNIT 6 3.7 UNIT 7
3034 %QUDWM==40 ;3.6 WRITE IMMEDIATELY ON MASTER DISK
3035 ;@ + XR BITS MUST = 0
3037 QSNNR: BLOCK QNUD ;NUMBER PC'S LOOKING AT THIS IE
3038 ;+1 FOR FILE OPEN AND USER IN CORE(?)
3039 QSNMI: BLOCK QNUD ;TRACK N OF USER DIR IF NOT NEWLY CREATED
3040 QSFBT: BLOCK QNUD ;FREED-BLOCKS-TABLE. HEAD OF A LIST OF PAGES,
3041 ;THREADED THROUGH THE SECOND WORD AND ENDING WITH
3042 ;ZERO. FIRST WORD IS AOBJN POINTER TO FREE PART
3043 ;OF PAGE. FROM THIRD WORD UP TO BELOW WHERE AOBJN
3044 ;POINTS ARE WORDS UNIT,,BLOCK WHICH RECORD DISK
3045 ;BLOCKS TO BE FREED ONCE THE DIR HAS BEEN WRITTEN
3046 ;OUT TO THE MASTER DISK. ELIMINATES REUSED ADDRESS
3047 ;PROBLEMS BY GUARANTEEING THAT IF THE SYSTEM SHOULD
3048 ;CRASH AT ANY TIME, THERE CANNOT BE TWO DIRECTORIES
3049 ;ON DISK THAT BOTH POINT TO THE SAME BLOCK.
3052 QSALLO: BLOCK QNUD ;-1 OR DRIVE # DIRECTORY ALLOCATED TO
3057 UDRSW: -1 ;USER DIR AREA LOCKED
3059 QCHSW: -1 ;CHNL AREA LOCKED
3061 QSKOSW: -1 ;QSKO1 LOCKED (USER DIR READIN)
3064 ;LIST OF PAGES CONTAINING BLOCKS WHICH CAN NOW BE FREED. MOVED TO
3065 ;HERE FROM QSFBT WHEN THE DIR IS WRITTEN OUT. THE ACTUAL FREEING
3066 ;IS DONE BY THE CORE JOB.
3070 ;VARIABLES FOR SYSTEMS CONCEPTS DISK CONTROL
3073 QRCSW: 105 ;- NO READ COMPARE 0 COMPARE WRITES + COMPARE ALL
3074 QCST: 0 ;CONI DC0, AT QINT
3075 QERST: 0 ;HAS CONI DC1, BITS WHEN AN ERROR HAPPENS
3076 PKIDM: 0 ;-1 WAITING FOR PACK ID TO BE READ
3077 RPKID: -1 ;PACK ID READ INTO HERE BY DISK CONTROL
3078 QDRSTS: 0 ;DRIVE STATUS WORD STORED BY DISK CONTROL
3081 0 ;FOR BLT INTO QXWDS
3086 QCHPR2: DCOPY (-2000_2&37774)
3087 DCOPY (-NXWDS_2&37774)QXWDS
3088 QCHPR4: DHLT ;OR DRC
3089 QCHPR3: DCCOMP (-2000_2&37774)
3090 DCCOMP (-NXWDS_2&37774)QXWDS
3093 GPKID: DSPC+DSCRHD+DSWNUL+DUNENB+TUTCYL_11.+TUTSRF_6+TUTSEC
3096 QRECAL: DSPC+DSRCAL+DUNENB
3099 ;VARIABLES FOR DEC RP10 DISK CONTROL
3102 QERST: 0 ;CONI DPC, ON ERROR
3103 QERDTI: 0 ;DATAI DPC, ON ERROR
3104 QCST: 0 ;CONI DPC, AT QINT
3105 QCHPRG: 0 ;SEEK COMM
3106 IFN KA10P, QIOWD: -2000,, ;XFER DATA (HRRM ADR-1 IN RH)
3114 QGTBZY: 0 ;FLAG FOR SOFTWARE AT INT
3117 QRCSW: 0 ;NON-ZERO TO ENABLE READ-COMPARING
3118 RDCPHS: 0 ;0 NORMAL, -1 DOING OPERATION WHICH SHOULD BE READ-COMPARED
3119 ; AFTERWARD, + DOING READ-COMPARE
3121 RCIOWD: BLOCK 2 ;CHANNEL PROGRAM FOR READ INTO QRCBUF
3122 ];KA10P ;ON KL WE HAVE TO PUT IT IN THE EPT!
3126 ;VARIABLES FOR DEC RH10 DISK CONTROL
3129 QCHPRG: 0 ;DATA TRANSFER COMMAND
3130 QCHPGA: 0 ;ADDRESS (CYL IN LH, TRACK-SECTOR IN RH)
3131 NCSHI: 0 ;NUMBER OF CACHE INVALIDATES
3132 NCSHIL: 0 ;NUMBER OF LOOPS WAITING FOR CACHE INVALIDATES
3133 NCSHU: 0 ;NUMBER OF CACHE UNLOADS
3134 NCSHUL: 0 ;NUMBER OF LOOPS WAITING FOR CACHE UNLOADS
3135 QERST: 0 ;CONI AT LAST ERROR (LEAVE THIS THROUGH QECPAT IN SAME ORDER)
3136 0 ;DATAI AT LAST ERROR
3137 QERSTS: 0 ;%HRSTS AT LAST ERROR
3138 QERER1: 0 ;%HRER1 AT LAST ERROR
3139 QERER2: 0 ;%HRER2 AT LAST ERROR
3140 QERER3: 0 ;%HRER3 AT LAST ERROR (IBM WOULD CALL THIS A CHANNEL LOGOUT AREA)
3141 QERDCL: 0 ;%HRDCL AT LAST ERROR
3142 QECPOS: 0 ;%HRPOS AT LAST ERROR
3143 QECPAT: 0 ;%HRPAT AT LAST ERROR
3144 QCST: 0 ;CONI AT LAST INTERRUPT
3145 QGTBZY: 0 ;FLAG FOR SOFTWARE-CAUSED INTERRUPT
3146 QECCS: BLOCK NQS ;NUMBER OF ECC CORRECTED ERRORS, PER DRIVE
3147 QECCAD: BLOCK NQS ;DISK ADDRESS OF MOST RECENT ECC CORRECTED ERROR
3148 RHDATO: -1 ;LAST DATAO DSK, FOR DEBUGGING
3149 ECCPAG: BLOCK 8 ;TEMP FOR SAVING PAGE MAP VARS AT QECC (WITH SPM)
3150 NQDRE: BLOCK NQS ;# MASSBUS TIMEOUTS PER DRIVE.
3151 NQSATN: BLOCK NQS ;# SPURIOUS ATTENTIONS IN MID-TRANSFER
3152 NQEATN: BLOCK NQS ;# ATTENTIONS REPORTING ERRORS
3155 ;VARIABLES FOR DEC RH11 DISK CONTROL (ON THE KS10 UNIBUS)
3158 QCHPRG: 0 ;DATA TRANSFER COMMAND
3159 QCHPGA: 0 ;ADDRESS (CYL IN LH, TRACK-SECTOR IN RH)
3160 QIOWD: 0 ; BA,,WC for RH11
3161 QCST: 0 ;CS1 AT LAST INTERRUPT
3162 QGTBZY: 0 ;FLAG FOR SOFTWARE-CAUSED INTERRUPT
3164 QERST:: ;Gubbish saved at last error
3165 QERCS1: 0 ; CS1 Control & Status 1
3166 QERCS2: 0 ; CS2 Control & Status 2
3167 QERSTS: 0 ; STS Drive status
3168 QERBA: 0 ; BA Unibus address for transfer
3169 QERWC: 0 ; WC Word count for transfer
3170 QERER1: 0 ; ER1 Error 1
3171 QERER2: 0 ; ER2 Error 2
3172 QERER3: 0 ; ER3 Error 3
3174 QECPOS: 0 ; POS ECC position
3176 QECPAT: 0 ; PAT ECC pattern
3177 QERMAP: 0 ? 0 ; Unibus map to disk buffer
3179 QECCS: BLOCK NQS ;NUMBER OF ECC CORRECTED ERRORS, PER DRIVE
3180 QECCAD: BLOCK NQS ;DISK ADDRESS OF MOST RECENT ECC CORRECTED ERROR
3182 NQSATN: BLOCK NQS ;# SPURIOUS ATTENTIONS IN MID-TRANSFER
3183 NQEATN: BLOCK NQS ;# ATTENTIONS REPORTING ERRORS
3184 NQOFFL: BLOCK NQS ;# TIMES DISK WENT OFFLINE
3187 DIRHNG: 0 ;LH POINTS TO LIST OF DIRHNG DEVICE CHANNELS,
3188 ;CHAINED THROUGH LH'S OF IOCHNM WORDS.
3189 ;0 MEANS END OF LIST
3190 ;MODIFY ONLY WITH THE CLOCK OFF.
3191 ;EACH DIRHNG DEVICE CHANNEL'S IOCHST WORD RH CONTAINS THE
3192 ;TRACK NUMBER OF THE DIRECTORY IT IS LOOKING AT.
3199 QATTNS: REPEAT NQS,500000+.RPCNT_14,,1_<10-.RPCNT>
3200 ;WORDS TO CLEAR ATTNS AND SELECT DRIVES
3206 DCHBT: 20000,, ;BIT SET IF DIR NOT WRITTEN OUT ON UNIT
3214 IFL .-DCHBT-NQS,.ERR YOU BETTER FIND ANOTHER BIT FOR QACTB,QSNLCN,QTUTO
3217 QTRAN: 0 ;FORMERLY MAPPED 203 CYL VIRTUAL DRIVES TO 406 CYL CALCOMPS
3218 1 ;4.9 => 2ND HALF OF PHYSICAL DRIVE
3219 2 ;(DOESN'T DO ANYTHING NOW THAT MEMOWRECKS ARE GONE,
3220 3 ; BUT KEEP AROUND IN CASE EVER NEEDED AGAIN.)
3225 IFL .-QTRAN-NQS, .ERR BARF AT QTRAN
3228 SUBTTL DISK CLOSE ROUTINES
3234 ANDCAM Q,QSRAC(A) ;FLUSH RANDOM ACCESS HACKERY
3235 PUSHJ P,QICLW1 ;WAIT FOR INPUT TO STOP
3237 TLNE TT,%QADEL ;DELETE?
3239 MOVE H,QUDPR(D) ;DIRECTORY NUMBER
3242 QICLX: SOSGE QSNNR(H) ;FREE DIRECTORY CHANNEL HAD BEEN USING
3248 QICLW1: MOVE D,A ;IDLE CHANNEL AND FLUSH READ BUFFERS
3256 QSICL3: HLLZS QSRAC(D) .SEE %QMIDL ;STOP PI
3258 QSICL5: PUSHJ P,QSBRB1 ;RETURN M.P. BUFFER IF ANY
3259 QOCL7: HRRZ A,QBFP(D) ;ALSO ENTER TO RETURN UNUSED READ BUFFER ON WRITE OVER MODE
3260 QSICL2: JUMPE A,QSICL6
3261 LDB C,[MLO,,MEMBLT(A)]
3267 QSICL6: SETZM QBFP(D)
3270 QSICL4: MOVEI A,%QMRD1 ;STOP PI AFTER THIS BLOCK
3273 SKIPL QSGL(D) ;WAIT FOR CHANNEL TO DEACTIVATE
3278 QOCL: PUSHJ P,QSOCL5 ;CLEAN UP THE DISK CHANNEL
3279 QSOCL4: MOVE D,A ;ENTRY FROM QALINK
3280 QSOCL6: MOVE Q,QUDFPR(D)
3285 JRST QCDLWO ;DELETED (PRESUMABLY VIA DELEWO)
3286 MOVE A,UNFN1(Q) ;Get names of file being hacked.
3288 PUSHJ P,QLOOK ;FILING OVER ANYTHING?
3292 CAMN I,Q ;BEING WRITTEN BITS WENT AWAY?
3293 BUG ;TRYING TO DELETE THE FILE WE'RE WRITING
3294 PUSHJ P,QSOCLD ;YES FLUSH IT
3295 PUSHJ P,QUDLK ;RELOCK DIR UNLOCKED BY QSOCLD ETC
3296 JRST QSOCL6 ;MAKE SURE ONE HASN'T REAPPEARED WHILE DIR UNLOCKED
3298 QSOCL5: LDB H,[$QAMOD,,QSRAC(A)]
3299 JUMPN H,QOCL6 ;DONT HACK ACTIVE WD COUNT IN WRITEOVER MODE
3300 QOCL6A: MOVN D,QSMPRC(A) ;- NUMBER OF BYTES IN BLOCK NOT USED
3301 ADDB D,QMPBSZ(A) ;ADJUST BYTE COUNT OF LAST BLOCK TO REFLECT WHATS USED
3302 CLEARM QSMPRC(A) ;SO WILL BE A NOOP IF PCLSR OUT AND COME BACK THRU HERE
3303 QOCL4: MOVSI Q,%QAEFW
3304 IORM Q,QSRAC(A) ;SET EOF BIT FOR QSBWW AND QUDS
3306 SKIPL QSMDN(A) ;NO M.P. BUFFER ANYWAY
3307 JUMPE D,QOCL1 ;ABOUT TO WRITE NULL BLOCK, DON'T
3308 QOCL5: PUSHJ P,QSBWW
3310 PUSHJ P,[ SKIPGE QSCRW(T) ;WAIT FOR CHANNEL EITHER LEAVING WRITE MODE
3311 SKIPN QSBFS(T) ;OR WRITING OUT ALL ITS BUFFERS, I.E. PI LEVEL
3312 JRST POPJ1 ;ISN'T GOING TO DO ANYTHING MORE TO IT.
3315 SKIPE QBFP(A) ;MAKE SURE IF QSBFS NON-ZERO THAT IS ONLY EOF
3316 BUG ;NOT A BUFFER SITTING AROUND FORGOTTEN
3317 QOCL3: MOVE H,QUDPR(A)
3319 SKIPN D,QMPTC(A) ;SKIP ON NEXT "N" STILL PENDING
3321 PUSHJ P,QUDS ;STORE IT AWAY
3325 QOCL6: SKIPGE QSCRW(A) ;WAIT FOR CHANNEL TO IDLE OR HANG UP IN READ
3338 SOS B,QSBFS(A) ;COMPENSATE FOR EXTRA AOS ON EOF READ
3342 JRST QOCL6A ;HACKING LAST BLOCK PAST EOF, UPDATE ACTIVE WD COUNT
3345 QOCL1: PUSHJ P,QSBRB ;DISCARD BUFFER
3349 AOS QSFT(D) ;RESTORE TRACK
3352 QSOCL3: MOVE Q,QUDFPR(D)
3356 ANDCAM T,UNRNDM(Q) ;CLEAR WRITE IN PROG
3358 MOVE T,UDNAMP(TT) ;MAKE SURE IT GOES BEFORE * FILE OF SAME NAME
3361 JRST QSOC3E ;NO PREV FILE
3363 QSOC3A: SUBI J,LUNBLK
3366 JRST QSOC3B ;PREV FILE HAS DIFFERENT NAME
3371 REPEAT LUNBLK, PUSH P,.RPCNT(J)
3375 REPEAT LUNBLK, POP P,LUNBLK-.RPCNT-1(Q)
3379 QSOC3D: HRRZ A,QUDPR(T)
3387 QSOC3F: AOBJN T,QSOC3D
3388 QSOC3E: SETOM QUSR(D) ;FREE THE DISK CHANNEL
3393 CAMN C,[SIXBIT /.LPTR./]
3394 IORM TT,SUPCOR ;CLOSING FILE ON TPL DEVICE SO SET FLAG FOR SYS JOB
3396 CAMN C,[SIXBIT/.MAIL./]
3397 AOS NQMFWR ;CLOSING FILE ON .MAIL. => BUMP COUNT TO WAKE MAILER DEMON
3399 CAMN C,[SIXBIT/.XGPR./]
3400 AOS NXGPFW ;WAKE XGPSPL
3402 MOVE A,QSNMI(H) ;TELL DIRHNG DEVICE ABOUT IT
3404 MOVE TT,QACTB ;DIR CHANGED (AT LEAST WRITE-IN-PROG BIT TURNED OFF)
3410 SETZM (R) ;CLEAR IOCHNM WORD.
3413 QSOC3B: ADDI J,LUNBLK
3416 QOCLR: MOVE Q,QSRAC(A) ;CLOSE UNIT ASCII OUTPUT
3418 TLNN Q,%QAMWO+%QALNK
3419 PUSHJ P,QOCLPD ;PUT NEEDED PADDING UNLESS NOT A FILE OR NOT AT END
3422 QOCLPD: LDB Q,[360600,,QSMPRP(A)] ;NUMBER OF BITS NOT WRITTEN IN LAST WORD
3424 POPJ P, ;LAST WORD NOT WRITTEN AT ALL
3425 LSH Q,18.+6 ;FILL THOSE BITS WITH ^CS
3428 SKIPLE QSMPRC(A) ;INHIBIT STORE IF NO BUFFER ETC.
3432 SUBTTL DISK INTERRUPT ROUTINES
3434 OVHMTR QIN ;DISK INTERRUPT LOW-LEVEL
3441 TRNN TT,200000 ;END OF CYLINDER
3446 IDIVI D,NBLKSC ;IS IT LEGITIMATE?
3447 SKIPL QSDU ;IF NO TRANSFER IN PROGRESS, IGNORE
3448 CAIN E,NBLKSC-1 ;IS LEGITIMATE FOR LAST BLOCK IN CYLINDER
3450 BUG PAUSE,[MAYBE DISK CONTROL IS WRITING ALL OVER THE DISK AGAIN]
3452 TDNE TT,[17177700] ;ANY ERRORS?
3455 SKIPGE QSDU ;DONT CLOB CMD BUF TO CLR ATTS DURING DATA XFER
3456 TRNN R,776 ;ANY ATTNS
3458 LDB I,[11000,,R] ;YES,FIND WHICH DRIVE
3459 JFFO I,.+1 ;CLOBBERS Q
3462 QINTAT: DATAO DPC,QATTNS(Q) ;CLEAR ATTNS
3465 JRST QRECAT ;NOT ON CYLINDER, RECALIBRATE
3470 JRST QRECAT ;SEEK TO THE WRONG PLACE (CALCOMPS LIKE TO DO THIS)
3471 MOVEM A,QPOS(Q) ;REMEMBER WHERE IT IS AT
3474 JRST QINT ;TRY AGAIN
3476 QINTA: SKIPGE Q,QSDU
3477 JRST QINT1 ;NOT EXPECTING DATA COMPLETION - FIND NEW TRANSFER
3480 JRST DSKEX ;TRANSFER STILL IN PROGRESS, DISMISS
3484 JRST QHE ;XFER HUNG, RECALIBRATE AND RETRY
3485 JRST QINTA1 ;TRANSFER COMPLETE...
3488 CONI DPC,TT ;THIS LOOKS REDUNDANT BUT APPARENTLY IS NECESSARY
3489 ;DUE TO TIMING OF THE DISK-NOT-READY CONDITION
3490 CONO DPC,175700+DSKCHN ;RESET CONDITIONS
3493 CONSZ DPC,20 ;WAIT FOR UNBUSY
3495 MOVE Q,QSDU ;FOR QOVR
3497 TRNE TT,20000 ;OVERRUN
3499 TRNE TT,2000 ;NOT READY
3501 TDNE TT,[12010700] ;BITS 14,16,23,27-29 ARE LOSERS
3502 BUG HALT,[DSK: TOTALLY FATAL ERROR, CONI=],OCT,QERST
3503 TLNE TT,5 ;WD OR SECTOR PARITY ERROR
3505 TRNE TT,1000 ;WRITE LOCKED
3507 TRNE TT,40000 ;SEARCH FAILED
3509 TRNN TT,100000 ;POWER FAILURE
3511 CONSZ DPC,100000 ;TRY IT AGAIN
3515 QINTE1: TLNE R,10 ;FILE UNSAFE--NEED OPERATOR INTERVENTION
3516 BUG PAUSE,[DSK: FILE UNSAFE UNIT ],DEC,Q
3519 TLNE R,110 ;POSITION FAILURE (OR PROCEEDED FILE UNSAFE)
3521 AOS NQSE(Q) ;SPURIOUS ERROR
3524 QIRWRE: BUG PAUSE,[DSK: WRITE LOCKED UNIT ],DEC,Q
3527 QNRDY: LDB Q,[410300,,R] ;WHICH DPC
3529 SKIPGE QRCAL(Q) ;NOT SEEKING OR RECALIBRATING IS ERROR
3531 BUG PAUSE,[DSK: UNIT ],DEC,Q,[NOT READY]
3538 SKIPL PKIDM ;GETS SPURIOUS DIPE WHEN READING PACK ID
3539 CONSO DC1,7777 ;RUMOR THAT DSSERR DOESN'T ALWAYS SET
3544 QINTA: SKIPGE Q,QSDU
3545 JRST QINT1 ;NOT EXPECTING DATA COMPLETION, FIND NEW TRANSFER
3546 CONSZ DC0,DSSRUN+DSSACT
3547 JRST DSKEX ;ACTIVE OR RUN, TRANSFER IN PROGRESS, DISMISS
3548 AOSN PKIDM ;SKIP IF NOT FINISHED READING PACK ID
3551 JRST QHE ;XFER HUNG, RECALIBRATE AND RETRY
3553 JRST QEROK ;OK ON VERIFY
3554 JRST QINTA1 ;TRANSFER COMPLETE...
3557 CONO DC0,DCCLR+DCERR+DSKCHN ;CLEAR ERRORS
3560 CONSZ DC0,DSSRUN+DSSACT
3561 JRST .-1 ;ACTIVE OR RUN?
3563 JRST QERL1 ;VERIFY ALSO LOST
3564 TRNE TT,DOFFL+DPROT+DDOBSY+DNXM+DCPERR
3565 JRST QINTE1 ;REALLY LOST BIG
3568 TRNE TT,DWTHER+DFUNSF ;SEEK INC, END DISK, WATCHDOG, OR UNSAFE
3569 JRST QHE ;TRY TO RECALIBRATE
3571 TRZ TT,DRLNER ;IGNORE LENGTH ERROR IF READING PACK #
3572 TRNE TT,DIPE+DRLNER+DRCER+DCKSER
3576 AOS NQSE ;SPURIOUS ERROR (NOT LENGTH ERROR IN PKIDM)
3577 JRST QINTX ;SPURIOUS ERROR
3579 QINTE1: TRNE TT,DOFFL
3580 BUG PAUSE,[DSK: UNIT ],DEC,Q,[OFFLINE]
3582 BUG PAUSE,[DSK: UNIT ],DEC,Q,[WRITE PROTECTED]
3584 BUG PAUSE,[DSK: DATAO WHEN BUSY]
3586 BUG PAUSE,[DSK: MEM PAR OR NXM ERROR]
3590 CONO DC0,DCCLR+DCCATT+DSKCHN ;CLEAR ATTENTION
3591 LDB Q,[DSATDN Q] ;ATTENTION DRIVE NUMBER
3596 CONO DC0,DCCLR+DCATEB+DSKCHN ;CLEAR ATTENTION ENABLE
3599 ;THIS IS CALLED EVERY HALF SECOND
3600 QRCTMO: MOVEI Q,NQS-1
3606 BUG INFO,[DSK: RECAL TIMEOUT UNIT],DEC,Q
3608 CONO DC0,DCCLR+DCATEB+DSKCHN ;CLEAR ATTENTION ENABLE I GUESS
3614 ;;; RHCLRC(Q) Clear controller errors and select drive Q
3615 ;;; RHSLCT(Q) Select drive Q
3616 ;;; RHCMD(A) Command in A to current drive
3617 ;;; RHCLRD Clear current drive
3618 ;;; RHCHEK Check for immediate bad news
3619 ;;; All return CS1 in A
3621 RHSLCT: IOWRQ Q,%HRCS2
3622 RHCHEK: IORDQ A,%HRCS1
3623 TRNE A,%HXTRE+%HXMCP
3624 BUG HALT,[DSK: MASSBUS ERROR, CS1=],OCT,A
3627 RHCLRC: IOWRQ Q,%HRCS2 ; Must select drive before clearing controller
3628 MOVEI A,%HXTRE+%HXIE+%HMNOP
3630 RHCLRD: MOVEI A,%HXIE+%HMCLR
3642 TRNE TT,%HXTRE+%HXMCP
3644 TRNN TT,%HXSC ; Perhaps some drive needs attention?
3645 JRST QINT0 ; Not unless SC is set!
3648 QINT0: SKIPGE Q,QSDU
3649 JRST QINT1 ; Not expecting completion of transfer.
3651 JRST DSKEX ; Transfer still in progress.
3653 JRST QHE ; Transfer hung, recalibrate and retry.
3654 PUSHJ P,RHSLCT ; Select that drive.
3655 IORDQ A,%HRSTS ; Get its status.
3656 TRNE A,%HSERR ; Just in case %HXTRE didn't get set (by
3657 JRST QINTE ; analogy with RH10)...
3658 JRST QINTA1 ; Transfer complete...
3660 QINTAT: MOVNI Q,-35.(B)
3664 IOWRQ A,%HRATN ; Turn off attention bit.
3668 JRST [ AOS NQSATN(Q) ; Ignore attention in mid-transfer.
3671 JRST QINTA2 ; Ignore this drive.
3673 IORDQ B,%HRSTS ; Get status of drive with attention.
3674 TRC B,%HSMOL+%HSDPR+%HSRDY
3675 TRNN B,%HSMOL+%HSDPR+%HSRDY+%HSVV
3676 PUSHJ P,QOFFL ; Went offline and came back online
3677 TRNE B,%HSERR+%HSPIP
3678 JRST [ PUSHJ P,RHCLRD ; Drive barfing not during transfer
3679 AOS NQEATN(Q) ; so clear it
3680 JRST .+1] ;THEN CLEAR SEEK AND RECALIBRATE FLAGS
3681 SETZM QSEEK(Q) ;POSITIONING COMPLETION
3682 IFE RM03P,[ ;No %HRCCY register on damn RM03s
3684 MOVEM A,QPOS(Q) ;UPDATE CURRENT CYLINDER
3686 SETOM QSKT1(Q) ;SEEK TO WRONG PLACE
3689 MOVE A,QPOSGL(Q) ;On RM03, jump to conclusion
3692 SETZM QRCAL(Q) ;NO LONGER RECALIBRATING
3693 JRST QINT0 ;IF NO XFER ACTIVE, MAYBE CAN START ONE ON
3696 QINTA2: SETOM QSKT1(Q) ;DON'T TRUST POS
3699 ; Went offline and came back online
3700 QOFFL: TRC B,%HSMOL+%HSDPR+%HSRDY ;Recover %HRSTS
3704 BUG INFO,[DSK: UNIT #],DEC,Q,[CAME BACK ONLINE, CS1=],OCT,A,[STS=],OCT,B,[ER1=],OCT,C,[ER2=],OCT,D,[ER3=],OCT,E
3706 MOVEI A,%HMCLR ;Clear the drive
3708 MOVEI A,%HMRDP ;I said, clear the drive!
3711 IOWRQ A,%HROFS ;No offset, 18 bits, ECC on, HCI off
3712 MOVEI A,%HMACK ;Turn %HSVV back on so drive will work
3717 IRPS X,,[CS1 CS2 BA WC POS PAT] ; First get status of controller
3721 IORDQ A,UBAPAG+QUBPG_1 ; Unibus map counts as part of
3722 MOVEM A,QERMAP ; controller status.
3723 IORDQ A,UBAPAG+QUBPG_1+1
3725 SKIPGE Q ; Try hard to guess the drive.
3726 LDB Q,[$HYDSK QERCS2]
3727 PUSHJ P,RHCLRC ; Clear controller errors and select drive
3728 ; so that we can read its status too.
3729 TRNN A,%HXRDY ; Why would controller be busy? (RH10
3730 BUG ; code checks for this...)
3731 IRPS X,,[STS ER1 ER2 ER3]
3735 MOVE A,QERCS1 ; A: CS1
3736 MOVE R,QERCS2 ; R: CS2
3737 SKIPN QERER2 ; Bad news
3740 TRNN A,%HXMCP ; Real bad news
3741 TRNE R,%HYWCE+%HYPE+%HYNED+%HYNEM+%HYPGE+%HYMXF
3742 BUG HALT,[DSK: UNIT #],DEC,Q,[LOSING. CS1=],OCT,A,[ CS2=],OCT,R
3743 TRNE R,%HYDLT+%HYMDP ; Data bus losing?
3745 MOVE A,QERSTS ; Check Drive Status
3746 TRC A,%HSVV+%HSRDY+%HSDPR+%HSMOL ; Better be all on!
3747 TRCE A,%HSVV+%HSRDY+%HSDPR+%HSMOL
3750 JRST [ AOS NQSE(Q) ; Spurious?
3752 MOVE B,QERER1 ; Check the main error register
3753 TRNE B,#<%H1ECC+%H1DTE+%H1CRC+%H1HCE+%H1ECH+%H1FER+%H1PAR>
3754 JRST UNSAFE ; Those not listed above are considered "hard"
3755 CAIN B,%H1ECC ; Correct correctable error if that is the
3756 JRST QECC ; only problem.
3757 PUSHJ P,QINTER ; Else print message and reset drive
3758 TRNE B,%H1DTE+%H1CRC+%H1HCE+%H1FER ; These require recalibration
3760 TRNE B,%H1ECC+%H1ECH+%H1PAR ; These require reread
3762 JRST QOVR ; No error bits set? (How can this
3763 ; happen?) Go and retry...
3765 ;;; Controller error:
3766 QINTE1: BUG INFO,[DSK: ERR UNIT #],DEC,Q,[CS1=],OCT,QERCS1,[CS2=],OCT,QERCS2
3770 QINTER: BUG INFO,[DSK: ERR UNIT #],DEC,Q,[ER1=],OCT,QERER1,[ER2=],OCT,QERER2,[ER3=],OCT,QERER3,[STARTING DISK ADDR=],OCT,QCHPGA
3771 JRST RHCLRD ; Reset error status in drive
3773 ;;; Come here for drive unsafe and similar bad things. May be set to
3774 ;;; either halt or attempt retry (via USFHLT variable). Note that when we
3775 ;;; get here the state of the drive has not yet been disturbed.
3776 UNSAFE: SKIPE USFHLT
3777 BUG PAUSE,[DSK: TOO MANY ERRORS]
3778 MOVEI A,2 ;HALT IF ANOTHER ERROR WITHIN 1/2 - 1 SECOND
3780 PUSHJ P,QINTER ;GIVE ERROR MESSAGE AND RESET DRIVE
3782 JRST QHE ;RECALIBRATE AND RETRY
3783 JRST QREC ;Just recalibrate, no transfer to retry
3785 QECC: PUSHJ P,RHCLRD ; Reset drive
3786 CAME Q,QSDU ; ECC error better be for transfer in
3789 TRNN A,10 .SEE %HMRED
3790 BUG ; ECC error should only happen during read.
3791 LDB A,[$UPPAG QERMAP]
3793 DPB A,[.PAREP+EXEUMP] ; Point parity error page at buffer.
3794 CLRPT 400000+PAREP_12 ; Get it into our map now.
3795 CLRPT 401000+PAREP_12 ; Both halves...
3797 SUBI J,1000+QUBPG_14 ; Correct to relative byte address of start
3799 TRNE J,770777 ; Should always be aligned on sector boundary
3800 BUG ; and within a single block, right?
3801 LSH J,-2 ; J: Address of first word of losing sector
3803 MOVE A,QECPOS ; Get error position
3804 SOJL A,QDE ;HARDWARE POS IS OFF BY 1; IF 0 NOT CORRECTABLE
3805 IDIVI A,36. ;CONVERT TO WORD NO AND BIT NO
3807 JRST [ ADDI B,36. ;LAST WORD IN SECTOR - HACK IT TO AVOID NXM
3809 ADDI J,400000+PAREP_12(A) ; J: Address of losing word-pair
3810 ; (In parity error page.)
3811 MOVE U,B ;SAVE BIT NUMBER
3812 MOVS B,(J) ;GET FIRST LOSING WORD
3813 MOVS C,1(J) ;GET SECOND LOSING WORD
3814 MOVE D,QECPAT ;GET ERROR PATTERN
3815 SETZ E, ;MAKE INTO DOUBLE-WORD
3816 ROTC D,(U) ;ALIGN IT
3817 XOR B,D ;FIX THE BAD BITS
3819 MOVSM B,(J) ;PUT CORRECTED DATA BACK
3822 DPB A,[.PAREP+EXEUMP] ;FLUSH THE DISK BUFF FROM MAP
3823 CLRPT 400000+PAREP_12
3824 CLRPT 401000+PAREP_12 ; Both halves...
3826 AOS QECCS(Q) ;LOG THE LOSS
3827 LDB E,[111000,,QERBA] ; E: Number of sectors transferred (including
3828 SUBI E,QUBPG_3 ; ECC sector)
3830 LDB B,[$HASEC A] ;Compute disk address of failing sector:
3832 IDIVI B,NSECS ; C: sector
3838 HLRZ A,A ; A: cylinder
3839 MOVE D,QSDCH ; D: chnl
3840 BUG INFO,[DSK: ECC CORRECTED ERROR, UNIT #],DEC,Q,[CYL ],DEC,A,[HEAD ],DEC,B,[SEC ],DEC,C,[QSRAC],OCT,QSRAC(D)
3842 JRST QINTA1 ;XFER COMPLETE
3844 LDB B,[$HASEC QCHPGA] ;NOW DETERMINE WHERE TO RESUME TRANSFER
3847 DPB C,[$HASEC QCHPGA]
3848 LDB C,[$HATRK QCHPGA]
3850 DPB C,[$HATRK QCHPGA] ;NO NEED TO IDIVI A,NHEDS SINCE NEVER CROSS
3853 HRL E,QERWC ; Reassemble "iowd" from
3854 HRR E,QERBA ; saved parts. (Don't trust stuff saved
3855 MOVEM E,QIOWD ; in controller more than we have to.)
3856 HRRZ C,QSDCH ;FOR QECCX
3857 JRST QECCX ;MORE TO DO, CONTINUE XFER
3870 MOVSI A,%HRATN ;FIND DRIVES NEEDING ATTENTION
3873 QINT0: SKIPGE Q,QSDU
3874 JRST QINT1 ;NOT EXPECTING COMPLETION OF TRANSFER
3876 JRST DSKEX ;NO COMPLETED TRANSFER
3878 JRST 4,.-1 ;TRANSFER STILL IN PROGRESS??
3880 JRST QHE ;XFER HUNG, RECALIBRATE AND RETRY
3881 MOVSI A,%HRSTS(Q) ;SOMETIMES %HSERR SETS AND %HIERR DOESN'T!
3885 JRST QINTA1 ;XFER COMPLETE...
3887 QINTAT: MOVNI Q,-35.(B) ;LOW BIT IS DRIVE 0
3889 MOVEI A,1 ;TURN OFF ATTENTION (DRIVE MAY BE LOSING
3890 LSH A,(Q) ;IN SUCH A WAY THAT READING %HRSTS DOESN'T CLEAR ATTN)
3894 JRST [ AOS NQSATN(Q) ;IGNORE ATTN IN MID-TRANSFER
3896 MOVSI A,%HRSTS(Q) ;GET STATUS OF DRIVE WITH ATTENTION
3897 PUSHJ P,RHGET ;THIS ALSO CLEARS THE ATTENTION BIT
3899 JRST QINTA2 ;IGNORE THIS DRIVE
3900 TRNE A,%HSERR+%HSPIP
3901 JRST [ MOVSI A,%HRDCL(Q)
3902 HRRI A,%HMCLR ;DRIVE REPORTING ERROR NOT DURING TRANSFER
3903 PUSHJ P,RHSET ;SO CLEAR THE DRIVE
3905 JRST .+1 ] ;THEN CLEAR SEEK AND RECALIBRATE FLAGS
3906 SETZM QSEEK(Q) ;POSITIONING COMPLETION
3909 MOVEM A,QPOS(Q) ;UPDATE CURRENT CYLINDER
3911 SETOM QSKT1(Q) ;SEEK TO WRONG PLACE
3912 SETZM QRCAL(Q) ;NO LONGER RECALIBRATING
3913 JRST QINT0 ;IF NO XFER ACTIVE, MAYBE CAN START ONE ON THIS UNIT NOW
3915 QINTA2: SETOM QSKT1(Q) ;DON'T TRUST POS
3918 ;INPUT FROM MASSBUS - ADDRESS IN LH(A), RETURNS DATA IN A
3920 RHGET: TLZA A,%HRLOD
3922 ;OUTPUT TO MASSBUS - ADDRESS IN LH(A), DATA IN RH(A)
3926 MOVEM A,RHDATO ;SAVE FOR REBUGGING
3927 MOVEI A,5 ;WAIT 3 USEC FOR BUS CYCLE
3931 BUG HALT,[DSK: MASSBUS ERROR, DATAO=],OCT,RHDATO,[DATAI=],OCT,A
3932 ANDI A,177777 ;RETURN 16-BIT REGISTER CONTENTS
3937 CONO DSK,%HOCLR+%HORAE+%HOATN+DSKCHN ;RESET CONTROLLER SO DRIVE STATUS MAY BE READ
3939 JRST .-1 ;SOMETIMES CONTROLLER IS BUSY??
3942 SKIPGE Q ;TRY HARD TO GUESS THE RIGHT DRIVE!
3943 LDB Q,[$HCDRV R] ;CURRENTLY SELECTED DRIVE
3944 IRPS X,,[%HRSTS %HRER1 %HRER2 %HRER3 %HRDCL %HRPOS %HRPAT]
3945 MOVSI A,X(Q) ;GET STATUS OF DRIVE
3947 MOVEM A,QERST+.IRPCNT+2
3949 SKIPN QERER2 ;FILE UNSAFE
3953 AOS NQDRE(Q) ;THIS BIT SUSPECTED OF BEING SET RANDOMLY.
3954 ;;CHECK FOR IRRECOV (?) HARDWARE LOSSAGE. EVEN MORE SO THAN 'UNSAFE'
3955 TDNE TT,[%HIILF+%HISDE+%HINXM+%HIDRE+%HIILC+%HIPWR]
3956 BUG HALT,[DSK: UNIT ],DEC,Q,[ LOSING. RH10 CONI= ],OCT,QERST
3957 IFN KS10P, .ERR So whats this all about?
3959 TLNN TT,(%HIDPE+%HICPE) ;IF CHANNEL DETECTS PARITY ERROR, CAUSE
3960 JRST QINTE0 ;PROCESSOR PARITY SWEEP WHICH WILL PROBABLY
3961 MOVSI A,SCLPAR ;CRASH THE SYSTEM ANYWAY. BEATS LOOPING!
3962 TDNN A,SUPCOR ;BUT DON'T CAUSE CLKB1E+7 HALT
3964 BUG CHECK,[DSK: MEM PAR ERR, QICWA/],OCT,QICWA,OCT,QICWA+1,[QIOWD/],OCT,QIOWD
3967 TDNE TT,[%HIOVR+%HICOV+%HIDPE+%HICPE+%HIBPE]
3968 JRST QINTE1 ;OVERRUN OR PARITY ON CONTROL BUS OR CHANNEL BUS - RETRY
3969 MOVE A,QERSTS ;DRIVE EXCEPTION, CHECK DRIVE STATUS
3970 TRC A,%HSVV+%HSRDY+%HSDPR+%HSMOL ;THESE BITS BETTER ALL BE ON
3971 TRCE A,%HSVV+%HSRDY+%HSDPR+%HSMOL
3972 BUG ;DRIVE TURNED OFF? MAYBE 11 HACKING THIS DRIVE?
3974 JRST [ AOS NQSE(Q) ;SPURIOUS?
3976 MOVE B,QERER1 ;CHECK THE MAIN ERROR REGISTER
3977 TRNE B,#%H1SOF ;ANY HARD ERRORS?
3979 CAIN B,%H1ECC ;IF JUST A CORRECTABLE ERROR,
3980 JRST QECC ;GO CORRECT IT
3981 PUSHJ P,QINTER ;OTHER SOFT ERROR, PRINT MESSAGE AND RESET DRIVE
3982 TRNE B,010620 ;SEARCH ERROR, OR HEADER READ OR FORMAT ERROR OR DRIVE TIMING
3983 JRST QHE ;REQUIRES RECALIBRATE
3984 TRNE B,100110 ;BUS PARITY OR ECC "HARD"
3985 JRST QDE ;REQUIRES RE-READ, GIVE UP AFTER N
3986 JRST QOVR ;NO ERROR BITS, PRINT MESSAGE AND RETRY
3989 QINTE1: BUG INFO,[DSK: ERR UNIT #],DEC,Q,[CONI=],OCT,QERST,[DCL=],OCT,QERDCL
3993 QINTER: BUG INFO,[DSK: ERR UNIT #],DEC,Q,[ER1=],OCT,QERER1,[ER2=],OCT,QERER2,[ER3=],OCT,QERER3,[STARTING DISK ADDR=],OCT,QCHPGA
3994 MOVSI A,%HRDCL(Q) ;NOW RESET ERROR STATUS IN DRIVE
3998 ;COME HERE FOR DRIVE UNSAFE AND SIMILAR BAD THINGS. MAY BE SET TO
3999 ;EITHER HALT OR ATTEMPT RETRY (VIA USFHLT VARIABLE). NOTE THAT WHEN
4000 ;WE GET HERE THE STATE OF THE DRIVE HAS NOT YET BEEN DISTURBED.
4001 UNSAFE: SKIPE USFHLT
4002 BUG PAUSE,[DSK: TOO MANY ERRORS]
4003 MOVEI A,2 ;HALT IF ANOTHER ERROR WITHIN 1/2 - 1 SECOND
4005 PUSHJ P,QINTER ;GIVE ERROR MESSAGE AND RESET DRIVE
4006 JRST QHE ;RECALIBRATE AND RETRY
4008 QECC: MOVSI A,%HRDCL(Q) ;RESET ERROR STATUS IN DRIVE
4011 CAME Q,QSDU ;CORRECT AN ECC ERROR
4012 BUG ;BARF ... NO TRANSFER IN PROGRESS
4015 BUG ;BARF ... SHOULDN'T HAPPEN DURING WRITE
4016 SKIPN A,QICWA+1 ;GET ADDRESS OF LAST WORD READ
4017 JRST 4,.-1 ;CHANNEL OUGHT TO HAVE STORED CONTROL WORD BY NOW
4019 TDZ J,[177+.BM $DFCWA] ;J := ADDRESS OF FIRST WORD IN LOSING SECTOR
4020 LDB A,[$DFCAD QIOWD]
4022 SOS H,A ;# WORDS SUCCESSFULLY XFERED.
4023 CAIL H,0 ;CHECK IF CHANNEL STORED BAD ADDRESS
4025 JRST QDE ;THIS SHOULD NEVER HAPPEN, BUT IT DOES, FREQUENTLY
4026 MOVE A,QECPOS ;GET ERROR POSITION
4027 SOJL A,QDE ;HARDWARE POS IS OFF BY 1; IF 0 NOT CORRECTABLE
4028 IDIVI A,36. ;CONVERT TO WORD NO AND BIT NO
4030 JRST [ ADDI B,36. ;LAST WORD IN SECTOR - HACK IT TO AVOID NXM
4032 ADD J,A ;J := ADDRESS OF LOSING WORD-PAIR
4034 ANDI J,1777 ;GET ADDR OF PAR ERR PAG
4035 ADDI J,400000+2000*PAREP ;IN EXEC ADDRESS SPACE
4036 IORI A,600000 ;MAKE THAT PAGE POINT TO THE DISK BUFFER
4037 DPB A,[.PAREP+EXEUMP]
4038 SPM ECCPAG ;GET IT INTO OUR MAP.
4040 MOVE U,B ;SAVE BIT NUMBER
4041 MOVS B,(J) ;GET FIRST LOSING WORD
4042 MOVS C,1(J) ;GET SECOND LOSING WORD
4043 MOVE D,QECPAT ;GET ERROR PATTERN
4044 SETZ E, ;MAKE INTO DOUBLE-WORD
4045 ROTC D,(U) ;ALIGN IT
4046 XOR B,D ;FIX THE BAD BITS
4048 MOVSM B,(J) ;PUT CORRECTED DATA BACK
4051 DPB A,[.PAREP+EXEUMP] ;FLUSH THE DISK BUFF FROM MAP
4054 AOS QECCS(Q) ;LOG THE LOSS
4057 LSH E,-7 ;NUMBER OF SECTORS TRANSFERRED (INCLUDING ECC SECTOR)
4058 LDB B,[$HASEC A] ;GET DISK ADDR OF FAILING SECTOR
4064 DPB B,[$HATRK A] ;NO NEED TO DIVIDE BY NHEDS SINCE NEVER CROSS CYLINDERS
4068 BUG INFO,[DSK: ECC CORRECTED ERROR, UNIT ],DEC,Q,[CYL ],DEC,A,[HEAD ],DEC,B,[SEC ],DEC,C,[QSRAC],OCT,QSRAC(D)
4069 LDB B,[$HASEC QCHPGA] ;NOW DETERMINE WHERE TO RESUME TRANSFER
4072 DPB C,[$HASEC QCHPGA]
4073 LDB C,[$HATRK QCHPGA]
4075 DPB C,[$HATRK QCHPGA] ;NO NEED TO IDIVI A,NHEDS SINCE NEVER CROSS CYLINDERS
4076 HRRZ C,QSDCH ;FOR QECCX
4077 LDB A,[$DFCWA QICWA+1] ;LAST CONTROL WORD PROCESSED
4078 SUBI A,1 ;CRETINOUS DF10
4080 BUG ;CHANNEL STORED BAD ADDRESS?
4082 MOVEI A,200(H) ;# WORDS ALREADY DONE.
4083 DPB A,[$DFWC A] ;PUT IT IN BOTH FIELDS.
4084 ADDB A,@QICWA ;ADVANCE C.W. TO REMAINING STUFF
4086 JRST QECCX ;MORE TO DO, CONTINUE XFER
4087 AOS QICWA ;ELSE ADVANCE TO NEXT C.W.
4089 JRST QECCX ;MORE TO DO, CONTINUE XFER
4090 JRST QINTA1 ;XFER COMPLETE
4094 T3INT: SETZM DSCDON ;CLEAR DONE FLAG THAT GOT US HERE
4095 SKIPGE QSDU1 ;OPERATION COMPLETE?
4096 JRST QINT1 ;NO, GO FIND SOMETHING TO DO
4097 HRRZ Q,DSCDRV ;YES, GET DRIVE OPERATION WAS ON
4100 CAME Q,QSDU1 ;TERMINATION ON DRIVE WE EXPECTED?
4101 BUG ;DRIVE NUMBER CLOBBERED?
4102 SETZM QRCAL(Q) ;PRESUMABLY NOT RECALIBRATING ANY MORE.
4103 MOVE A,DSCCMD ;COMMAND THAT JUST COMPLETED
4104 CAIN A,%DMREC ;WAS IT A RECALIBRATE?
4105 JRST QINT1E ;IF SO, CONTROLLER IS IDLE NOW
4106 MOVE C,QSDCH1 ;CHANNEL
4107 HRLZ E,DSCFLT ;CHECK FOR ERRORS
4109 JUMPE E,QINTI ;OPERATION COMPLETED UNEVENTFULLY
4110 MOVE D,DSCHED ;GET DISK ADDRESS AS CYL,,HEAD_9+SECTOR
4114 SKIPN QERRS(C) ;PRINT ONLY ONCE, NOT ON RETRIES
4115 BUG INFO,[DSK: T-300 ERR UNIT ],DEC,Q,[FAULT=],OCT,DSCFLT,[STATUS=],OCT,DSCSTS,[CMD=],OCT,DSCCMD,[CYL-SURF-SEC=],OCT,D
4116 TRZE E,%DSRTR+%DSECC ;THESE ARE NOT ERRORS
4118 JUMPE E,QINTI ;OPERATION COMPLETED SUCCESSFULLY (WITH INTERVENTION OF 2561)
4120 TRZ T,%DSECH+%DSIDE+%DSHCE
4121 JUMPN T,T3INT2 ;CONSIDER USING ERROR RECOVERY FEATURES
4122 TRNE A,%DMRED ;IF COMMAND IS A READ
4123 TRNE A,10 ;AND WE HAVEN'T TRIED THEM ALL
4125 AOS NQSE(Q) ;COUNT "SOFT ERRORS" (NOT "SPURIOUS" IN T-300 CASE)
4126 AOJA A,T3IO1 ;GO RETRY OPERATION USING NEXT FEATURE
4128 T3INT2: TLNN E,-1 ;ANY FAULT? PROBABLY UNRECOVERABLE BUT TRY RECALIBRATE
4129 TRNE E,%DSIDE+%DSHCE+%DSSKE+%DSOFL+%DSFLT ;DISK CONDITION THAT CALLS FOR RECAL
4131 JRST T3DE ;TRY OPERATION AGAIN. PROBABLY WILL LOSE BUT TRY.
4134 OVHMTR QSC ;DISK SCHEDULER (AND HIGHER-LEVEL INTERRUPT STUFF)
4136 QINTA1: SKIPL C,QSDCH ;XFER COMPLETE
4137 QINTI: SKIPGE A,QSCABN(C) ;CHANNEL IN C
4138 BUG ;MEMBLT INDEX IN A
4139 MOVE R,A ;BUFFER ADDRESS IN R
4140 IFN KL10P,[ ;QSRAC IN D, QSK# IN Q
4141 SKIPL QSCRW(C) ;IF READ, FLUSH CACHE AGAIN
4142 JRST [ PUSHJ P,CSHSWP ;SINCE USER MIGHT HAVE TOUCHED ABS PAGE
4144 MOVE A,R ;A WAS CLOBBERED
4148 SKIPL QSCRW(C) ;ON KS, CAN ONLY CLEAR THE WHOLE CACHE
4156 TLNE D,%QAPAR ;IGNORE IF LOSING ANYWAY (E.G. SEARCH ERR)
4161 SKIPE TT,RDCPHS ;NEED TO READ-COMPARE?
4162 JRST QRC1 ;READ-COMPARE STARTING OR FINISHED
4167 XCT .+1(D) ;INVOKE COMPLETION HANDLER
4169 %QMIDL::JRST 4,QINT1 ;IDLE - SHOULDN'T BE ACTIVE
4170 %QMRD:: JRST QRDFIN ;READ
4171 %QMWRT::JRST QWRFIN ;WRITE
4172 %QMWOV::JRST QWOVFN ;WRITE-OVER MODE
4173 %QMRD1::JRST QRD1FN ;READ BLOCK AT A TIME MODE
4174 JRST 4,QINT1 ;ILL CODE
4175 %QMUDR::JRST QUDRIN ;USER DIR IN
4176 %QMMDR::JRST QMDRIN ;MASTER DIR IN
4177 %QMTTR::JRST QTUTIN ;TUT IN
4178 %QMUDW::JRST QUFDWF ;USER DIR WRITE
4179 %QMMDW::JRST QMFDWF ;MASTER DIR WRITE
4180 %QMTTW::JRST QTUTWF ;TUT WRITE
4181 %QMSWP::JRST QSWPFN ;SWAP FINISHED
4182 JRST 4,QINT1 ;ILL CODE
4183 JRST 4,QINT1 ;ILL CODE
4184 JRST 4,QINT1 ;ILL CODE
4186 IFN %QMMAX-20, .ERR %QMMAX MUST BE A POWER OF 2
4189 ;CHANNEL DIDN'T TRANSFER EXACTLY 2000 WORDS
4190 QDFLOS: MOVEI D,1777(R) ;EXPECTED TERMINATION ADDRESS
4191 HRRZ B,QICWA+1 ;ACTUAL TERMINATION ADDRESS
4195 BUG HALT,[DSK: CHANNEL TRANSFERRED UP TO ],OCT,B,[RATHER THAN],OCT,D,[DISK IS CLOBBERED NOW.]
4197 QDFLZ1: BUG PAUSE,[DSK: CHANNEL TRANSFERRED UP TO ],OCT,B,[RATHER THAN],OCT,D
4201 ;;; SOFTWARE READ-COMPARE ROUTINES
4204 IFE RP10P+RH10P, .ERR READ-COMPARE ONLY CODED FOR RP-10 AND RH10
4205 ;IFE KA10P, .ERR READ-COMPARE ONLY CODED FOR KA-10
4207 ;;; REGULAR OPERATION COMPLETE, DO A READ-COMPARE TO BE SURE
4209 IFN T300P, CAIGE Q,T300P ;NO READ/COMPARE IF THIS IS T-300 CONTROLLER
4210 TLNE D,%QAPAR ;GIVING UP WITH FATAL ERR?
4211 JRST QRC0 ;NO READ-COMPARE THEN
4212 JUMPG TT,QRC2 ;JUMP IF READ-COMPARE COMPLETED
4213 MOVE E,QSGL(C) ;DISK BLOCK
4214 PUSHJ P,QPOSR ;E GETS DATAO WORD
4216 IOR E,[DREADC+7000+RCICWA] ;MAKE READ COMMAND
4217 CONO DPC,175700+DSKCHN
4218 MOVE T,[-2000,,QRCBUF-1] ;STORE CHANNEL PROGRAM
4224 DATAO DPC,E ;START DISK
4227 MOVE T,[-2000_4,,QRCBUF-1] ;DF10-C CHANNEL PROGRAM
4234 CONSZ 200000 ;IT'S INEFFICIENT, BUT WHAT THE HELL
4236 CONO DSK,%HOCLR+%HORAE+%HOATN+DSKCHN
4238 HRR A,E ;HEAD AND SECTOR (CYL DOESN'T CHANGE)
4240 MOVEI A,%HMRED+<RCICWA_6>
4242 PUSHJ P,RHSET ;START DISK
4244 MOVEM T,RDCPHS ;RDCPHS POSITIVE MEANS DOING RD/CMP NOW
4245 JRST DSKEX ;AWAIT COMPLETION
4247 ;;; READ-COMPARE COMPLETED. CHECK IT.
4248 QRC2: SPM PARPG ;SET UP MAP TO PAGE BEING READ/WRITTEN
4249 MOVEI T,600000+PMCSHM(A)
4250 DPB T,[.PAREP+EXEUMP]
4252 MOVEI H,0 ;H DIFFERENCE COUNT
4254 PUSH P,A ;WILL DO COMPARE LOOP IN ACS
4257 MOVSI E,-2000 ;E ADDRESS WITHIN PAGE
4258 MOVSI D,[ MOVE T,400000+PAREP*2000(E) ;A
4267 MOVSI E,-2000 ;E ADDRESS WITHIN PAGE
4268 MOVE T,400000+PAREP*2000(E)
4272 QRC3: JUMPGE E,QRC5 ;JUMP IF DONE
4273 JUMPG H,QRC4 ;COMPARE ERROR, REPORT IT
4276 MOVE T,-1(P) ;SAVED C
4277 BUG INFO,[DSK: READ-COMPARE ERROR #],DEC,NQCMPE(Q),[UNIT=],DEC,Q,[BLK=],OCT,QSGL(T)
4279 .ELSE BUG INFO,[DSK: READ-COMPARE ERROR #],DEC,NQCMPE(Q),[UNIT=],DEC,Q,[BLK=],OCT,QSGL(C)
4282 CAIG H,4 ;ONLY REPORT FIRST 4 BAD WORDS
4283 BUG INFO,[DSK: READ-COMPARE DIFFERENCE ],OCT,T,OCT,400000+PAREP*2000(E),OCT,QRCBUF(E)
4293 MOVEI T,0 ;CLEAR MAP
4294 DPB T,[.PAREP+EXEUMP]
4296 JUMPE H,QRC0 ;NO DIFFERENCE, I/O OPERATION IS DONE
4297 CAILE H,4 ;FAILED, DO IT ALL OVER AGAIN
4298 BUG INFO,[DSK: READ-COMPARE DIFFERENCES TOTAL],DEC,H
4302 QUFDWF: MOVE TT,QDWIP
4303 CAMN Q,MDSK ;WRITTEN TO MASTER DISK?
4304 SKIPN E,QSFBT(TT) ;AND HAVE SOME BLOCKS TO FREE?
4306 SETZM QSFBT(TT) ;YES, TRANSFER THEM TO QFBTS LIST
4307 MOVE T,E ;E FINDS LAST OF LIST, T RPLACD'D IN THERE
4308 EXCH T,QFBTS ;NCONC QSFBT ONTO FRONT OF QFBTS
4314 AOS NCORRQ ;WAKE UP CORE JOB IF QFBTS HAD BEEN EMPTY
4321 QTUTWF: AOS T,QSGL(C) ;NEXT BLOCK TO GO OUT
4322 AOS QSCABN(C) ;FROM NEXT CORE PAGE
4323 CAIGE T,MFDBLK ;SKIP IF DONE
4324 JRST QINT1E ;WRITE MORE
4328 QDWF: MOVSI E,(SETZ) ;UNLOCK DIR THAT WAS WRITTEN
4329 IOR E,DCHBT(Q) ;COPY ON THIS DISK IS NOW UP TO DATE
4332 HLLZS QSRAC(C) .SEE %QMIDL ;IDLE THE CHANNEL
4334 JRST QINT1A ;DON'T COUNT THIS AS DISK ACTIVITY
4336 QUDRIN: MOVE TT,QUDPR(C) ;USER DIR IN OK
4338 CAME D,QSNUD(TT) ;COMPARE UNAME IN DIR WITH RQ'ED
4340 TLO R,40000 ;NOT PAWED OVER
4344 MOVEI R,MU23UD ;USER DIRECTORY
4348 PUSHJ P,QDIRCK ;VERIFY NOT TOTALLY BASHED TO BEGIN WITH
4349 POP P,C ;CLOBBERS A,B,I
4351 QINTU4: DPB R,[MUR,,MEMBLT(A)]
4352 DPB TT,[MNUMB,,MEMBLT(A)]
4353 QTUTI1: SETOM QUSR(C) ;FREE THE DISK CHANNEL
4357 QMDRIN: TLO R,2 ;NOT RECONCILED
4358 MOVEM R,QMDRO ;MASTER DIRECTORY IN
4360 CAME TT,[SIXBIT /M.F.D./]
4361 BUG HALT,[MFD CLOBBERED]
4364 BUG HALT,[MFD HAS WRONG NUMBER OF DIRECTORIES]
4365 MOVE TT,(R) ;ASCENDING DIR #
4367 MOVEM TT,QAMDNO ;FIRST DISK IN STORE ASCENDING #
4368 MOVEI R,MU23MD ;MASTER DIRECTORY
4372 QTUTIN: AOS T,QSGL(C) ;NEXT BLOCK TO COME IN
4373 AOS QSCABN(C) ;INTO NEXT CORE PAGE
4374 CAIGE T,MFDBLK ;SKIP IF DONE
4375 JRST QINT1E ;READ MORE
4376 HRRZS QTUTO(Q) ;UNLOCK TUT, BUT QDPWF IS STILL SET
4379 QSWPFN: MOVE Q,QDSKN(C)
4381 JRST QSWPF2 ;SWAP READ ERROR (I HOPE)
4382 MOVSI E,MMPTMP ;PAGE NO LONGER IN TRANSIT
4384 BUG ;ALREADY WASN'T?
4388 PUSHJ P,IMEMR ;SWAP-OUT COMPLETE, RETURN MEMORY
4391 MOVSI E,MMPWOD ;PAGE HAS BEEN WRITTEN ON DISK. AND NO LONGER
4392 IORB E,@QSMMP(Q) ;BEING PAGED BEHIND.
4395 MOVE A,QSMMP(Q) ;WE'RE SUPPOSED TO RETURN THE MMP ENTRY
4397 QSWPF2: SETOM SWUSR(Q) ;SWAPPING IDLE
4401 ;SOME ERROR CHECKING
4404 JUMPE TT,QSWPF3 ;ON INITIAL-SWAP-IN, ADDRESS IN MMP IS SUPPOSED TO BE ZERO
4405 LDB TT,[$MMPUN,,(E)]
4411 QSWPF3: LDB TT,[MMMPX,,MEMBLT(A)]
4415 MOVEI TT,MURUSR ;SWAP IN OF PAGE COMPLETED
4416 DPB TT,[MUR,,MEMBLT(A)]
4420 JRST QSWPF2 ;CAN'T PUT IN MAPS IF CIRPSW NOT AVAILABLE.
4421 MOVSI D,(TDNE T,) ;SET UP CHECK USED BY PRIVELEGED USER FEATURE
4425 MOVE C,[2200,,MEMPNT(A)]
4426 PUSHJ P,PPIUM ;PUT PAGE INTO USERS' MAPS
4431 QWOVFN: CLEARM QSCRW(C) ;WRITE OVER SWITCH TO READ MODE
4434 HRRI D,%QMIDL ;TRYING TO CLOSE, STOP CHANNEL
4436 AOS QWBUFS ;COMPENSATE FOR EXTRA SOS BELOW
4438 QWRFIN: TLNN D,%QACTH ;WRITE COMPLETE, RETURN BUFFER
4448 QRD1FN: HLLZS QSRAC(C) .SEE %QMIDL ;BLOCK-AT-A-TIME READ COMPLETE, IDLE THE CHANNEL
4450 QRDFIN: MOVEI B,.BM MLO ;NORMAL READ COMPLETED
4451 ANDCAM B,MEMBLT(A) ;THREAD ONTO CHANNEL LIST
4454 DPB A,[MLO,,MEMBLT(B)]
4458 SKIPL B,QPIBSZ(C) ;GET BYTE COUNT OF BLOCK
4460 HRRZ B,1777(R) ;FUNNY BLOCK, GET FROM LAST WORD
4461 HRRZ TT,QSBYTE(C) ;AND MAKE SURE IT'S NOT TOO BIG
4465 QRDFN1: HRRZM B,MEMPNT(A) ;PASS TO MAIN PROGRAM
4467 IFE DMDSK, LDB B,[XWBLK QXWDS]
4468 .ALSO MOVEM B,QSLBLK(C)
4470 ;XFER COMPLETE, DEACTIVATE CHANNEL
4472 QINT1B: SETOM QACTTM
4473 QINT1A: SETOM QSGL(C)
4476 IFE DC10P, SETOM QSKT1(Q)
4491 ;ACTIVATE CHANNELS, LOOK FOR SEEKS AND TRANSFERS TO BE DONE
4494 SETOM QTUNT ;NO UNIT SELECTED YET
4495 IFN T300P, SETOM QTUNT1
4496 MOVE C,QTCHN ;START SCAN IN SUITABLE PLACE
4500 QINT2L: CAIGE C,NQCHN ;IF DIR-WRITE OR SWAP CHANNEL, DON'T CHECK QUSR
4502 SKIPGE D,QSRAC(C) .SEE %QALOK
4503 JRST QINT2C ;CHANNEL LOCKED OR NOT OPEN, SKIP IT
4506 JRST QINT4 ;JUMP IF CHANNEL ACTIVE ALREADY
4507 TLNE D,%QACTH+%QAOUT
4508 JRST QINT2C ;CHANNEL BLOCKED BY CORE JOB, DON'T ACTIVATE
4511 XCT .+1(D) ;INVOKE ACTIVATE HANDLER
4513 %QMIDL::JRST QINT2C ;IDLE - DON'T ACTIVATE
4514 %QMRD:: JRST QRDACT ;READ
4515 %QMWRT::JRST QWRACT ;WRITE
4516 %QMWOV::JRST QWRACT ;WRITE OVER
4517 %QMRD1::JRST QRDACT ;READ 1 BLOCK
4518 JRST 4,QINT2C ;ILL CODE
4519 %QMUDR::JRST QDRACT ;UFD READ
4520 %QMMDR::JRST QDRACT ;MFD READ
4521 %QMTTR::JRST QDRACT ;TUT READ
4522 %QMUDW::JRST 4,QINT2C ;UFD WRITE - SHOULDN'T LEAVE THIS MODE AROUND
4523 %QMMDW::JRST 4,QINT2C ;MFD WRITE - ..
4524 %QMTTW::JRST QINT5 ;TUT WRITE - MAY BE WRITING SECOND PAGE
4525 %QMSWP::JRST SWPACT ;SWAP
4526 JRST 4,QINT2C ;ILL CODE
4527 JRST 4,QINT2C ;ILL CODE
4528 JRST 4,QINT2C ;ILL CODE
4531 ; ACTIVATION ROUTINES
4533 SWPACT: SKIPL SWUSR(Q)
4534 BUG ;SWAPPING ALREADY ACTIVE ON THIS DISK
4537 MOVEI B,0 ;CHECK FIRST FOR SWAP IN OR OUT
4538 CAIGE A,6 ;ACCORDING TO AVAIL MEM
4540 SKIPN @SWAPL(B) ;IF NO TRAFFIC THAT DIRECTION, CHECK THE OTHER.
4543 JUMPE E,QINT2C ;NO SWAPPING TRAFFIC THIS DISK.
4544 LDB A,[MLO,,MEMBLT(E)] ;TAKE BLOCK OFF LIST
4546 SETZM @SWAPL(B) ;LAST BLOCK, LIST IS NOW EMPTY
4547 HRRM A,@SWAPL(B) ;SET NEW FIRST BLOCK
4548 LDB D,[MMMPX,,MEMBLT(E)]
4549 ADD D,MMPEAD ;GET MMP ADDRESS
4550 LDB TT,[410200,,(D)]
4552 BUG ;THIS PAGE SHOULD BE MARKED IN TRANSIT
4558 HRRZM E,QSCABN+NQCHN+1(Q)
4559 CLEARM SWUSR(Q) ;CHNL ACTIVE
4561 MOVEM E,QSGL+NQCHN+1(Q) ;DISK BLOCK
4562 HRRZS QSRAC+NQCHN+1(Q) .SEE %QMSWP
4563 MOVNM B,QSCRW+NQCHN+1(Q) ;DIRECTION
4564 CLEARM QERRS+NQCHN+1(Q) ;NO ERRORS (YET)
4565 JRST QINT4 ;CHANNEL SUCCESSFULLY ACTIVATED
4568 ; MORE ACTIVATION ROUTINES
4570 QRDACT: TLNE D,%QAACC ;ACTIVATE READ CHANNEL
4571 JRST QINT2C ;NOT IF USER HACKING RANDOM ACCESS NOW
4575 JRST QINT2C ;USER DIRECTORY OUT OR LOCKED
4578 AOS A ;A := TOTAL NUMBER OF BUFFERS
4579 CAMLE A,QRDAHD ;HOW MUCH SHOULD BE READ AHEAD
4580 JRST QINT2C ;BLOATED, DON'T ACTIVATE
4582 JRST QINT4A ;BLOCKS LEFT FROM LAST TIME
4583 QINT4B: PUSHJ P,QIDRCH ;GET NEXT DESC BYTE IN A, ALSO RET BYTE PNTR IN TT
4586 JUMPE A,QEOF ;REACHED READ EOF
4590 JRST QINT4D ;SKIP AND TAKE
4591 MOVEM A,QSBI(C) ;TAKE NEXT N
4594 QINT4G: MOVEM E,QSGL(C)
4596 ANDCAM B,QSRAC(C) ;CLEAR PROCESSING LAST BLOCK IN FILE BIT
4598 IMULI A,2000 ;NUMBER OF BYTES IN A FULL BLOCK
4600 MOVSI D,%QAFNY ;FUNNY FILE
4604 MOVEM A,QPIBSZ(C) ;SET FUNNY BIT
4606 JRST QINT4 ;IF MORE BLOCKS FOLLOW DON'T CHECK EOF
4607 PUSHJ P,QIDRCH ;GET NEXT DESCR BYTE
4608 SOS QDIRP(C) ;CORRECT PNTR
4610 MOVE A,QUDFPR(C) ;THIS IS LAST BLOCK
4612 LDB D,[UNBYTE+UNREF(A)]
4614 IMUL D,E ;NUMBER OF UNUSED BITS IN LAST WORD
4615 LDB E,[QSBSIZ(C)] ;(DEPEND ON DIVIDE ROUNDING DOWN)
4616 IDIV D,E ;NUMBER OF UNUSED BYTES (IN SIZE OPEN)
4617 LDB E,[UNWRDC+UNRNDM(A)];NUMBER OF USED WORDS IN LAST BLOCK
4620 IMULI E,@QSBYTE(C) ;CONVERT TO NUMBER OF BYTES
4621 SUB E,D ;NUMBER OF VALID BYTES IN BLOCK
4622 HRRM E,QPIBSZ(C) ;STORE BYTE COUNT OF LAST BLOCK
4623 IORM B,QSRAC(C) .SEE %QALBK
4627 QINT4D: MOVEI E,1-UDTKMX(A) ;SKIP N AND TAKE 1
4631 QWRACT: SKIPN I,QBFP(C) ;ACTIVATE WRITE CHANNEL
4632 JRST QINT2C ;END OF WRITE LIST FOR NOW
4634 LDB H,[MLO,,MEMBLT(I)]
4637 SETZM QBFP(C) ;LAST BLOCK, LIST NOW EMPTY
4642 QDRACT: MOVE E,QSLGL(C) ;ACTIVATE DIRECTORY-READ CHANNEL
4644 ; JRST QINT4 ;DROPS THROUGH
4646 QINT4: SKIPL QSCABN(C) ;SKIP IF NEED MEMORY
4648 PUSHJ P,IOMQ ;GET MEMORY FOR READ BUFFER
4650 QINT5A: MOVEM A,QSCABN(C)
4652 DPB D,[MUR,,MEMBLT(A)]
4653 DPB C,[MNUMB,,MEMBLT(A)]
4656 IFN DC10P, MOVE TT,QTRAN(Q)
4658 SKIPN QSEEK(TT) ;IGNORE SEEKING DRIVE
4659 SKIPGE QRCAL(TT) ;IGNORE RECALIBRATING DRIVE
4661 IFN T300P,[ ;IGNORE IF FOR CONTROLLER THAT IS NOT READY
4664 SKIPL QTUNT1 ;NOTE CODE HERE IS SIMILAR TO THAT AT QINT2F
4665 JRST QINT2C ;T-300 CONTROLLER BUSY OR ALREADY COMMITTED
4666 HRRZM Q,QTUNT1 ;WILL TRANSFER ON THIS UNIT
4667 HRRZM C,QTCHN1 ;FOR THIS CHANNEL
4668 JRST QINT2C ] ;T-300 CODE IS SIMPLIFIED SINCE NO SEEK OVERLAPS
4674 JRST QINT2F ;ALREADY SET FOR ME
4676 JRST QINT2C ;SET FOR SOME OTHER CHNL
4677 HRRZM C,QSKT1(TT) ;AVAILABLE, SET IT FOR ME
4678 PUSHJ P,QPOSR ;CONVERT DISK ADDRESS TO PHYSICAL
4679 IFN DC10P,[ ;AND INITIATE SEEK
4681 CONSZ DC0,DSSRUN+DSSACT
4685 MOVE TT,QTRAN(Q) ;PRETEND SEEK ALREADY COMPLETE
4688 JRST QINT2F ;DON'T WAIT FOR SEEK, START TRANSFER RIGHT AWAY
4691 TLO E,(DSEEKC) ;DSK SEEK
4698 JRST QINT2F ;IF WE'RE THERE, DON'T SEEK
4702 JRST QINT2C ;THIS ONE SEEKING, GO GET ANOTHER
4705 PUSHJ P,RHSLCT ; Select drive
4707 IOWRQ A,%HRADR ; Set track and sector
4709 IOWRQ A,%HRCYL ; Set cylinder
4711 JRST QINT2F ; On cylinder, don't seek
4714 PUSHJ P,RHCMD ; Start seeking
4716 JRST QINT2C ; Start other drives now?
4719 MOVSI A,%HRCYL(Q) ;STORE ADDRESS IN DRIVE
4725 HLRZ TT,E ;GET CYLINDER PART OF ADDRESS
4727 JRST QINT2F ;ON CYLINDER, DON'T SEEK
4729 MOVSI A,%HRDCL(Q) ;START SEEK
4733 JRST QINT2C ;THIS ONE SEEKING, START OTHER DRIVES
4737 ;CALL HERE TO SWEEP THE CACHE. CORE PAGE # IN R.
4738 ;INSTRUCTION AT CALL+1 SHOULD SKIP IF READING INTO CORE.
4739 ;CLOBBERS A,B,D,E,TT.
4741 CSHSWP: SETZB A,B ;A COUNTS WAIT TIME, B IS SWEEP INSTRUCTION
4743 TLOA B,(SWPUO (R)) ;WRITE - UNLOAD PAGE FROM CACHE
4744 MOVSI B,(SWPIO (R)) ;READ - CLEAR PAGE FROM CACHE
4745 LSH R,1 ;HARDWARE PAGES ARE 1/2 K
4746 XCT B ;SWEEP FIRST HALF-PAGE
4747 MOVE D,[CONSZ 200000]
4750 PUSHJ P,D ;WAIT IN ACS TO MINIMIZE MBOX INTERFERENCE
4751 AOS R ;SWEEP SECOND HALF-PAGE
4755 AOSA NCSHU ;COUNT NUMBER OF TIMES THIS DONE
4757 JRST [ ADDM A,NCSHUL ? JRST .+2 ]
4758 ADDM A,NCSHIL ;AND COUNT NUMBER OF LOOPS IN ACS
4763 ;VARIOUS EXITS FROM CHANNEL-CHECKING ROUTINES
4765 QINT2F: SKIPL QTUNT ;THIS CHANNEL IS READY TO TRANSFER
4766 JRST QINT2C ;ALREADY FOUND A TRANSFER
4767 HRRZM Q,QTUNT ;WILL TRANSFER ON THIS UNIT
4768 HRRZM C,QTCHN ;FOR THIS CHANNEL
4769 QINT2C: CAMN C,QLCHN ;CONTINUE CHANNEL SCAN
4770 JRST QINT2E ;UNLESS CHECKED ALL CHANNELS
4771 QINT2D: CAIL C,NQCHN+1+NQS-1 ;SKIP IF NOT TIME TO WRAP AROUND
4773 AOJA C,QINT2L ;CHECK ANOTHER
4778 SKIPL Q,QTUNT1 ;FOUND XFER FOR T-300?
4781 SKIPGE Q,QTUNT ;FOUND XFER?
4784 ;Q DISK TO TRANSFER ON, C CHANNEL. START (OR RESTART) TRANSFER ON THEM.
4785 QDE1: MOVE R,QSCABN(C)
4794 IFE T300P, MOVEM C,QSDCH
4801 SKIPGE B,QSCRW(C) ;LOAD R/W STATUS IN B
4806 QINT6A: IORI T,7000+QICWA ;DON'T STOP FOR PARITY ERRORS (PLUS INITIAL CHNL ADR)
4808 DPB Q,[DUNFLD+QCHPRG]
4810 DPB R,[121000,,QIOWD]
4811 LDB E,[100300,,R] ;MA15-17
4813 DPB E,[410300,,QIOWD] ;SET UP HIGH ADDR BITS.
4826 CONO DPC,175700+DSKCHN
4828 SETZM RDCPHS ;ASSUME NO READ-COMPARE WANTED
4830 SETOM RDCPHS ;REMEMBER TO READ-COMPARE LATER
4839 BUG ;DONT DO ANYTHING IF NOT WHERE YOU SHOULD BE
4841 DATAO DPC,QCHPRG ;ENTRY ON OVERRUN
4856 QHUNG: CONO DPC,DCLEAR+20+DSKCHN ;DISK NOTICED TO BE HUNG, RESET IT
4857 SETOM QHUNGF ;TELL P.I. LEVEL TO RETRY OPERATION
4860 BUG INFO,[DSK: HUNG ON UNIT ],DEC,QSDU,[QCHPRG=],OCT,QCHPRG
4867 QINT6A: MOVEM T,QCHPRG
4869 LSH R,1 ; Set up Unibus map for RH11 to point at
4870 TRO R,%UQVAL+%UQFST ; the block in question.
4871 IOWRQ R,UBAPAG+QUBPG_1
4873 IOWRQ R,UBAPAG+QUBPG_1+1
4874 MOVE E,[-4000,,QUBPG_14]
4879 QOVR: IORDQ TT,%HRCS1 ; Enter here to recover from PI level lossage
4884 QECCX: ;; Enter here from ECC correction code
4885 PUSHJ P,RHCLRC ; Clear controller errors and select drive
4888 JRST DSKEX ; Punt if not positioned in right place
4889 IOWRQ TT,%HRCYL ; Store cylinder in drive
4891 IOWRQ TT,%HRADR ; Store track and sector
4893 IOWRQ TT,%HRWC ; Store halfword count
4895 IOWRQ TT,%HRBA ; Store Unibus base address
4911 QHUNG: MOVEI A,%HYCLR ; Sock controller in jaw
4914 PUSHJ P,RHSLCT ; Select drive
4915 PUSHJ P,RHCLRD ; Redundantly clear drive
4918 BUG INFO,[DSK: HUNG ON UNIT #],DEC,QSDU,[ADDR=],OCT,QCHPGA
4926 QINT6A: IORI T,QICWA_6 .SEE $HCICWA
4930 LSH R,10. ;ASSEMBLE DF10-C CONTROL WORD
4939 QOVR: CONSZ DSK,20 ;ENTER HERE FOR RECOVER FROM PI HALT, OVERRUN
4945 QECCX: SETZM QICWA+1 ;ENTER HERE FROM ECC CORRECTION CODE
4946 CONO DSK,%HOCLR+%HORAE+%HOATN+DSKCHN
4949 JRST DSKEX ;DONT DO ANYTHING IF NOT WHERE YOU SHOULD BE
4950 MOVSI A,%HRCYL(Q) ;STORE ADDRESS IN DRIVE
4959 SETZM RDCPHS ;ASSUME NO READ-COMPARE WANTED
4961 SETOM RDCPHS ;REMEMBER TO READ-COMPARE LATER
4976 QHUNG: CONO DSK,%HOCLR+%HORST+%HOSTP+DSKCHN ;HUNG, CLEAR CONTROLLER
4981 HRRI A,%HMCLR ;CLEAR DRIVE
4983 BUG INFO,[DSK: HUNG ON UNIT ],DEC,QSDU,[ADDR=],OCT,QCHPGA
4989 QINT6A: MOVEM T,QCHPRG
4991 DPB R,[DCBN+QCHPR2] ;MEM BLOCK #
4992 DPB R,[DCBN+QCHPR3] ;FOR POSSIBLE READ COMPARE
4994 PUSHJ P,QPOSR ;QPOSR ALSO STORES MAPPED UNIT IN QCHPRG
4996 CLEARM QCHPR4 ;STORE DHALT FOR NO RCC
4998 JRST QINT6S ;SWAPPING CHNL
5002 CAIE C,NQCHN ;ALWAYS R COMPARE DIR WRITES
5003 SKIPLE QRCSW ;SKIP ON NOT READ COMP EVERYTHING
5006 JUMPL B,QINT6B ;RCC WRITES
5010 JRST QINT6C ;NOT DIR READ
5011 QINT6B: TLZ E,340000 ;CHANGE TO READ COMPARE
5013 QINT6C: SETOM QERS1 ;ERR VERIFY IND
5014 QOVR: CONSZ DC0,DSSRUN+DSSACT
5016 DATAO DC0,[DJMP QCHPRG] ;ENTRY ON OVERRUN
5017 QOVR1: CONO DC0,DCSET+DCIENB+DSKCHN ;INTERRUPT WHEN DONE
5025 JUMPL B,QINT6B ;RCC WRITES
5026 JRST QINT6C ;NOT READS
5028 QHUNG: CONO DC0,DCCSET+DSKCHN ;HUNG, CLEAR CONTROLLER
5032 BUG INFO,[DSK: HUNG ON UNIT ],DEC,QSDU,[QCHPRG=],OCT,QCHPRG
5037 MOVE T,[QXWDS-1,,QXWDS]
5040 JRST QNT6W2 ;SWAP OR DIR WRITE
5043 MOVEM T,QXWDS+XWSYSN
5052 LDB T,[MWC,,MEMBLT(R)]
5056 IFN DC10P, MOVSI T,(DWRITE)
5057 IFN RP10P, MOVSI T,(DWRITC)
5058 IFN RH10P, MOVEI T,%HMWRT
5059 IFN RH11P, MOVEI T,%HMWRT
5063 T3IO: MOVEM C,QSDCH1 ;THIS IS MORE OR LESS QINT6A FOR T-300
5068 T3IO1: MOVE R,QSCABN(C) ;RE-ENTER HERE TO RETRY WITH COMMAND IN A
5069 LSH R,10. ;FIRST ADDRESS IN TRANSFER
5070 TLO R,730000 ;12-BIT BYTES, START WITH FIRST BYTE IN WORD
5071 MOVSI E,-4 ;SET UP BYTE POINTERS
5075 MOVE D,QSGL(C) ;DO LIKE QPOSR
5096 ;START T-300, COMMAND IN A, DRIVE IN Q
5097 T3CMD: MOVEI TT,2561
5107 CONO DLC,100040+TTYCHN ;INTERRUPT 11
5110 QHUNG1: MOVE Q,QSDU1
5112 BUG INFO,[DSK: HUNG ON T-300 UNIT ],DEC,QSDU
5113 MOVEI TT,5*60.*30. ;SHUT UP FOR FIVE MINUTES
5119 IFN RP10P, PUSHJ P,QERSOFT
5120 IFN DC10P, AOSE PKIDM
5125 JRST .+3 ;GET CKS ERR
5127 AOS NQCMPE(Q) ;# COMPARE ERRORS [WITH NO OTHER ERROR]
5129 IFN T300P,T3DE: ;ENTER HERE FOR ERROR ON T-300
5134 IFN DC10P, JUMPL R,QERV1 ;DO ANOTHER RD/COMP TO SEE IF OK ON DSK (IF WRITE)
5135 QERV2: AOS R,QERRS(C)
5136 TRNN R,10 ;TRY 8 TIMES BEFORE AND AFTER REPOSITION
5139 JRST QDE2 ;TRY REPOSITION ONCE
5140 QERV3: MOVE D,QSRAC(C)
5143 XCT .+1(D) ;INVOKE IRRECOV ERROR HANDLER
5145 %QMIDL::JRST 4,QERV+. ;IDLE CHANNELS SHOULDN'T GET HERE
5146 %QMRD:: JRST QPE2D ;USER DATA
5147 %QMWRT::JRST QDE1 ;WRITE KEEP TRYING
5148 %QMWOV::JRST QDE1 ;..
5150 JRST 4,QERV+. ;ILL CODE
5158 JRST 4,QERV+. ;ILL CODE
5159 JRST 4,QERV+. ;ILL CODE
5160 JRST 4,QERV+. ;ILL CODE
5163 QSWPER: SKIPGE CIRPSW ;TRY XFER AGAIN IF CIRPSW NOT AVAILABLE
5165 JRST QDE1 ;DON'T TRY TO DO ANYTHING ABOUT WRITE ERRORS
5166 MOVE A,QSCABN(C) ;READ - GIVE ALL USERS OF PAGE PARITY ERR
5169 MOVE C,[2200,,MEMPNT(A)]
5172 LDB Q,[2200,,MEMPNT(A)]
5173 DPB Q,C ;REMOVE MEM FROM LOOP
5174 PUSHJ P,IMEMR ;AND GIVE BACK MEM
5175 POP P,Q ;ALTERNATIVELY, COULD LEAVE THE MEM BUT SET MMPBAD
5176 POP P,C ;TO INDICATE THAT THAT MEM COPY OF THE PAGE IS NO GOOD.
5178 DPB D,[410200,,@QSMMP(Q)] ;PAGE IS OUT
5188 JRST QERV2 ;NOT SET FOR RCC
5190 QERL2: CONSZ DC0,DSSRUN+DSSACT
5192 DATAO DC0,[DJMP QCHPR4]
5206 MOVEM R,QERRS(C) ;CLOBBER QERRS
5207 JRST QREC ;AND TRY REPOSITIONING
5210 QERSOFT:LDB A,[DCYL+QCHPRG] ;PARSE STARTING DISK ADDRESS
5211 LDB B,[DCYLXB+QCHPRG]
5214 LDB B,[DSURF+QCHPRG]
5215 LDB D,[DSECT+QCHPRG]
5216 SKIPN QERRS(C) ;PRINT ONLY ONCE, NOT ON RETRIES
5217 BUG INFO,[DSK: SOFT ERR UNIT ],DEC,Q,[CYL ],DEC,A,[STARTING HEAD ],DEC,B,[SEC ],DEC,D,[CONI=],OCT,QERST,[DATAI=],OCT,QERDTI
5221 BUG INFO,[DSK: SEEK ERR DATAO=],OCT,QSEEK(Q),[CONI=],OCT,A,[DATAI=],OCT,E
5227 IFN RP10P, PUSHJ P,QERSOFT
5230 IFN T300P,T3HE: ;ENTER HERE FOR ID ERROR ON T-300
5238 JRST [ SETOM QRCAL(Q)
5241 MOVEM Q,QSDU1 ;CONTROLLER IS TIED UP BY RECAL BECAUSE
5242 JRST QINT1 ] ;IT'S TOO DAMNED PSEUDO-INTELLIGENT
5246 QREC0: DPB TT,[DUNFLD+QRECAL]
5252 MOVEI T,10. ;5-SECOND RECALIBRATE TIMEOUT
5255 CONO DC0,DCSET+DCATEB+DSKCHN ;ENABLE ATTENTION
5258 DPB Q,[DUNFLD+QRECAL]
5263 SETOM QRCAL(Q) ;INDICATE RECALIBRATING THIS DISK
5267 PUSHJ P,RHSLCT ; Select drive
5268 PUSHJ P,RHCLRD ; Clear errors
5270 PUSHJ P,RHCMD ; Recalibrate
5280 PUSHJ P,RHSET ;CLEAR ERROR OUT OF DRIVE.
5282 HRRI A,%HMREC ;RECALIBRATE
5283 PUSHJ P,RHSET ;MAYBE SHOULD TRY OFFSET FIRST?
5291 JRST QINT1 ;LOOK FOR SOME OTHER TRANSFER
5293 QHE2: SKIPL QSCRW(C) ;HANG UP OR POSITIONING ERR (AFTER 5 TRIES)
5294 JRST QERV3 ;IF READ, PERFORM RECOVERY
5296 QPE2D: MOVSI R,%QAPAR ;IRRECOVERABLE ERROR
5300 MOVEM D,QIRCBK ;BLOCK # AT IRRCV ERR
5301 MOVEM Q,QIRUNT ;SAVE UNIT TOO
5303 AOS NIRSWE ;# IRRCV SWAPPING ERRS
5306 JRST QPE2E ;DON'T MESS WITH LOCKED TUT
5308 CAIN B,TUTLK ;PRINT MESSAGE IF NOT YET LOCKED OUT
5312 QPE2E: BUG INFO,[DSK: IRREC DATA ERR #],DEC,QIRRCV,[UNIT=],DEC,QIRUNT,[BLK=],OCT,QIRCBK
5315 QUDER1: MOVEI R,1(Q) ;TRY TO READ DIR FROM OTHER DISKS
5320 JRST QDE1 ;NO OTHER DISK AVAIL TO READ FROM, TRY AGAIN
5322 QUDER4: SKIPGE QACT(R)
5324 HRRZM R,QDSKN(C) ;TRY THIS DISK
5327 JRST [ SETOM QSDU1 ;FREE DRIVE FORMERLY HACKING
5331 IFE DC10P, SETOM QSKT1(Q) ;FREE DRIVE FORMERLY HACKING
5344 QIDRCH: MOVE TT,QDIRP(C) ;CHNL IN C PNTR TO QSNUD IN J LOAD NEXT CHR INTO A
5345 AOS QDIRP(C) ;ALSO RET BYTE PNTR IN TT
5353 QMPDCH: MOVE TT,QDIRP(A) ;CHNL IN A PNTR TO QSNUD IN H LOADS NEXT CHR IN R
5354 AOS QDIRP(A) ;USED AT M.P. LEVEL
5355 QMPDC1: IDIVI TT,UFDBPW ;ALSO RETN BYTE PNTR IN TT
5362 ;REACHED EOF ON READ
5363 QEOF: SOS QDIRP(C) ;AVOID GC UNHAPPINESS
5366 HLLZS QSRAC(C) .SEE %QMIDL ;IDLE THE CHANNEL
5367 AOS QSBFS(C) ;TO UNHANG M.P. WHICH IS WAITING FOR BUF TO APPEAR
5374 TRZE A,20 ; FUNNY FILE BLOCK
5375 IORM E,QSRAC(C); INDICATE SO
5386 ;DECODE UNBYTE SPEC IN D.
5387 ;RETURNS BYTE SIZE IN D, NUMBER OF UNUSED BYTES IN LAST WORD IN E.
5389 JRST [ IDIVI D,100 ? POPJ P, ]
5391 JRST [ IDIVI D,20 ? POPJ P, ]
5393 JUMPGE D,[ IDIVI D,4 ? POPJ P, ]
5398 ;ENCODE BYTE SIZE IN Q AND RESIDUE IN R INTO UNBYTE SPEC IN RH(Q)
5400 JRST [ IMULI Q,100 ? ADDI Q,400(R) ? POPJ P, ]
5402 JRST [ IMULI Q,20 ? ADDI Q,200(R) ? POPJ P, ]
5404 JRST [ IMULI Q,4 ? ADDI Q,44(R) ? POPJ P, ]
5409 JRST QINT3X ;DIR CHNL IN USE
5411 SKIPGE QSDU ;DON'T GET PAST HERE UNLESS BOTH CONTROLLERS ARE IDLE
5419 SKIPG QACTTM ;LAST ACTIVITY TOO RECENT
5427 QMDW: SKIPGE QACT(Q)
5428 JRST QMDWA ;UNIT NOT ACTIVE
5432 HRLI Q,(SETZ) ;INDICATE MFD WRITE IN PROGRESS
5436 HRRZM TT,QSRAC+NQCHN
5440 CAME C,[SIXBIT /M.F.D./]
5441 BUG HALT,[MFD CLOBBERED]
5452 MOVEM TT,QSCABN+NQCHN
5459 QTDW1: SKIPGE QACT(Q)
5468 MOVE TT,TIME ;DON'T WRITE TUTS TOO OFTEN
5469 SUB TT,QTWRTM(Q) ;BECAUSE THE TUT IS LOCKED WHILE IT'S BEING WRITTEN
5477 HRRZM TT,QSRAC+NQCHN
5480 MOVE H,QPKNM(Q) ;VERIFY THAT TUT IS NOT BEING CLOBBERED
5484 BUG HALT,[TUT ],DEC,Q,[CLOBBERED]
5486 MOVEI TT,MFDBLK ;INITIATE WRITING OF FIRST BLOCK OF TUT
5489 LDB TT,[121000,,QTUTO(Q)]
5490 MOVEM TT,QSCABN+NQCHN
5493 QTDWA1: ANDCAM J,QTUTO(Q)
5494 QTDWA: AOBJN Q,QTDW1
5496 QDW4A: MOVE J,QACTB ;BITS CORRESP TO ACTIVE DISKS
5497 QDW4: SKIPE TT,QSNUD(C)
5499 JRST QDW3 ;SLOT VACANT OR LOCKED
5501 JRST QUDW1 ;NEEDS TO BE WRITTEN ON SOME UNIT
5503 QINT3X: ;HERE IF DISK GOING IDLE. CLEAR DONE FLAG.
5504 ;IN 2-CONTROLLER CASE, MAKE SURE WE ONLY DO IT TO THE RIGHT CONTROLLER.
5507 JRST DSKEX ;STUFF NEEDS TO BE DONE BUT CANT NOW
5509 IFN DC10P, CONO DC0,DCCLR+DCIENB+DSKCHN
5510 IFN RP10P, CONO DPC,177710+DSKCHN ;MUST CLEAR "DONE"
5511 IFN RH10P, CONO DSK,%HOCLR+%HOATN+%HORAE+DSKCHN
5512 IFN RH11P, ;; RH11 doesn't need this?
5513 JRST DSKEX ;STUFF NEEDS TO BE DONE BUT CANT NOW
5515 QUDW1: MOVSI J,%QUDWM ;WRITE RIGHT AWAY IF %QUDWM IS ON
5517 SKIPE QSFBT(C) ;OR DISK BLOCKS (AND CORE) WAITING TO BE FREED
5519 SKIPG QACTTM ; ACTIVITY TOO RECENT
5520 SKIPN QSNNR(C) ; THEN ONLY WRITE IF NOTHING POINTING TO DIRECTORY
5524 QUDW4: SKIPGE QACT(Q)
5529 QUDW3: AOBJN Q,QUDW4
5532 QUDW6: ANDCAM J,QSNLCN(C) ;TURN OFF %QUDWM
5533 MOVE Q,MDSK ;AND WRITE ON MASTER DISK (ASSUME MDSK IS ACTIVE AND BIT IN QSNLCN IS SET)
5536 TLNE I,40000 ;IS THIS CODE OBSOLETE? LEFT FROM DAYS OF 1 MFD PER DRIVE?
5537 JRST QUDW2B ;MASTER DIR NOT IN
5539 CAMN Q,MDSK ;SKIP IF NOT WRITING ON MASTER DISK
5540 PUSHJ P,QDIRCK ;BLESS THIS UFD!!!
5542 IORB TT,QSNLCN(C) ;LOCK USER DIRECTORY
5545 MOVE A,1(TT) ;NAME AREA PTR
5547 CAMN J,UDNAME(TT) ;MAKE SURE NOT ABOUT TO WRITE BAD DIRECTORY
5553 CAMLE J,A ;FS PTR BAD?
5561 MOVEM TT,QSCABN+NQCHN
5566 QUDW2B: ANDCAM J,QSNLCN(C) ;CLEAR BIT + GO AWAY
5569 ;GENERALLY GET HERE BY JSP TT,
5570 QUDCLB: BUG HALT,[DIR ],OCT,C,SIXBIT,QSNUD(C),[CLOBBERED]
5572 QDIRCK: PUSH P,TT ;CHECKS FILES FOR REASONABLE DESCRIPTORS -
5573 ; PRECEDING BYTE =0, FIRST BYTE NOT=0
5575 MOVEI B,1777(A) ;END OF NAMES
5576 ADD A,1(A) ;BEGIN NAMES
5580 JRST QDIRC2 ;0 NAME=NO FILE
5581 LDB TT,[1500,,UNRNDM(A)] ;DESC PTR
5582 SOS TT ;TRICK - IF DESC PTR = 0 LDB BELOW GETS 0 BECAUSE P FIELD = 44
5584 HLL TT,SBTBL(I) ;BYTE POINTER
5585 ADDI TT,UDDESC-1777(B)
5590 QDIRC2: ADDI A,LUNBLK
5595 BUG ;TOO BIG EVEN FOR RP03
5627 IFE DMDSK, .ERR CHANGE QPOSR FOR 9-SECTOR BLOCKS!
5631 HRLZ D,E ;CYLINDER IN LH
5637 IOR E,D ;SURFACE IN 1.9-2.4
5638 IOR E,TT ;SECTOR IN 1.1-1.5
5656 DPB TT,[DUNFLD+QCHPRG]
5662 QPOSRI: MOVE TT,QTRAN(Q) ;NEED PACK ID BEFORE PROCEEDING
5663 DPB TT,[DUNFLD+GPKID]
5669 MOVEM A,QPOS(TT) ;WILL SEEK TO HERE AUTOMATICALLY
5671 DATAO DC0,[DJMP GPKID]
5676 QSPKID: CONSZ DC1,1777
5678 LDB TT,[DPKID+RPKID]
5684 SUBTTL DISK IOT ROUTINES
5686 OVHMTR UUO ;MORE RANDOM UUOS
5688 ;BECAUSE .ACCESS MERELY DROPS ITS ARG IN A VARIABLE AND SETS %QAACC,
5689 ;ALL IOT ROUTINES MUST TEST %QAACC AND DO THE REAL WORK OF CHANGING
5690 ;THE ACCESS POINTER IF NECESSARY.
5702 TLNE T,%QAACC+%QALNK
5703 PUSHJ P,QBWRA1 ;RANDOM ACCESS MODE HACK
5707 JSP B,CPOPJ ;TRANSFER TO CHRKT, SIOKT, OR BLKT
5708 QBOV: SETZ QSMPRP(A)
5720 QUAI: MOVEI T,CHRKTI
5724 TLNE T,%QAACC+%QALNK
5728 JSP B,CPOPJ ;TRANSFER TO CHRKTI, SIOKT, OR BLKT
5736 QBWRA1: TLNE T,%QALNK
5738 LDB T,[$QAMOD,,QSRAC(A)] ;SET RANDOM ACCESS PNTRS ON WRITE
5739 SOJN T,QBWRA2 ;IN ORDINARY WRITE MODE
5740 SKIPGE QSCRW(A) ;WAIT FOR CHANNEL TO BECOME IDLE OR HANG UP IN READ
5741 PUSHJ P,UFLS ; WAITING FOR %QAACC TO TURN OFF
5746 MOVE T,QRADAD(A) ;DESIRED ADDRESS
5747 SUB T,QFBLNO(A) ;ACTUAL ADDRESS OF BEG OF CURRENT BUFFER
5748 JUMPL T,QBWRA2 ;XFER ON BEFORE CURRENT BLOCK
5750 SUB T,QMPBSZ(A) ;SIZE OF CURRENT BUFFER IN BYTES
5751 JUMPL T,QBWRA3 ;SAME BLOCK AS NOW
5755 PUSHJ P,QSOCL5 ;CLEAR ANY CURRENT BUFFERS ETC
5758 PUSHJ P,QFNTR ;LOCKS DIR IF SKIPS
5759 JRST QBWRA4 ;OFF END OF FILE
5760 QBWRA5: PUSHJ P,QUDULK
5764 CLEARM QSCRW(A) ;SWITCH TO WRITE OVER MODE
5765 MOVSI Q,%QAMPU+%QAMWO ;SET UPDATE ADR AND WRITE OVER
5768 MOVSI Q,%QAEFR+%QAEFW+%QAACC ;CLEAR EOF, WRITE EOF, AND ACCESS FLAGS
5770 MOVEI Q,%QMRD1 ;AND READ IN THE CURRENT BLOCK
5774 QBWRA4: JUMPE Q,QBWRA0
5775 CAME J,Q ;MIGHT BE ADDING TO END OF FULL BLOCK
5779 QBWRA0: PUSHJ P,QLWO ;OFF END OF FILE AND WAS ACCESSING WD 0
5780 MOVSI C,%QAACC ;SO SWITCH TO NORMAL WRITE MODE AND
5781 ANDCAM C,QSRAC(A) ;TURN OFF RANDOM ACCESS BIT
5787 QBWRA3: SKIPGE TT,QSMDN(A)
5788 BUG ;NO BUFFER REALLY ACTIVE AT M.P.
5792 ANDCAM J,QSRAC(A) ;WAS WRITING IN LAST BLK PAST EOF,
5793 MOVN D,QSMPRC(A) ; UPDATE ACTIVE BYTE COUNT
5794 ADDM D,QMPBSZ(A) ;DECREASE SIZE OF BUFFER TO AMT ACTUALLY WRITTEN
5795 QBWRA7: LSH TT,10. ;ADDRESS OF BUFFER
5796 MOVE T,Q ;SAVE RELATIVE BYTE ADDR WITHIN BUFFER
5797 IDIVI Q,@QSBYTE(A) ;Q = WDS, J = BYTES
5798 ADD TT,Q ;ADDRESS OF DESIRED WORD
5799 HLL TT,QSBYTE(A) ;BYTE POINTER TO FIRST BYTE IN THAT WORD
5800 JUMPE J,.+3 ;ADVANCE TO APPROPRIATE BYTE
5804 SUB T,QMPBSZ(A) ;MINUS # BYTES LEFT IN BLOCK
5806 QBRRA4: MOVSI Q,%QAACC
5810 QSKFRC: MOVN B,QSMPRC(A)
5811 ADD B,QMPBSZ(A) ;NUMBER OF BYTES WRITTEN IN BLOCK
5815 JRST [MOVEM B,QMPBSZ(A) ;IS LAST BLOCK, CHANGE LENGTH
5816 PUSHJ P,QOCLPD ;AND PAD IT (GUARANTEED NO-OP IF WORD MODE CHNL)
5818 SETZM QSMPRC(A) ;BUFFER WILL BE DISPOSED OF
5821 SETZB B,E ;NO BUFFER AFTER ALL
5822 ADD B,QFBLNO(A) ;CURRENT POSITION IN FILE
5825 MOVEM B,QRADAD(A) ;ACCESS BACK ON NEXT IOT
5827 PUSHJ P,[TLNE C,%QAWOV ;WRITE OUT THE BUFFER
5832 PUSHJ P,QOCL2 ;STORE QMPTC IF NECESSARY
5833 IORM E,QSNLCN(H) ;WRITE OUT DIR FAST IF CHANGED
5837 ;.CALL FINISH ON DISK OUTPUT CHANNEL
5838 QSKFIN: HRRZ T,QSRAC(A)
5839 CAIN T,%QMWOV ;IF WRITE-OVER MODE
5840 JRST [ SKIPE QSCRW(A) ;THEN WAIT FOR IT TO SWITCH TO READ MODE
5843 CAIN T,%QMWRT ;IF WRITE MODE
5844 JRST [ SKIPE QSBFS(A) ;THEN WAIT FOR ALL BUFFERS TO GET WRITTEN
5848 MOVE T,MDSK ;HAS THE DIR BEEN CHANGED AND NOT WRITTEN
5849 MOVE T,DCHBT(T) ;YET TO THE MASTER DISK?
5852 MOVSI TT,%QUDWM ;YES, WRITE IT OUT IMMEDIATELY
5853 IORM TT,QSNLCN(H) ;AND DON'T RETURN UNTIL IT IS WRITTEN
5858 QBRRA1: TLNE T,%QALNK
5861 JRST QBRRA2 ;NO MAIN PRGM BUFFER
5866 SUB T,QMPBSZ(A) ;SIZE OF CURRENT BUFFER
5867 JUMPL T,QBRRA3 ;SAME BLOCK AS NOW
5871 PUSHJ P,QICLW1 ;STOP THE CHANNEL AND FLUSH CURRENT BUFFERS
5873 CLEARM QSBFS(A) ;FLUSH POSSIBLE EXTRA AOSES WHEN PI HIT EOF
5876 JRST QBRRA5 ;OFF END OF FILE (DIR ALREADY UNLOCKED)
5882 IORM Q,QSRAC(A) ;SET FLAG TO SET QSMPRP AND QSMPRC ON NEXT BUFFER LOAD
5883 MOVSI Q,%QAEFR+%QAACC ;CLEAR EOF AND .ACCESS FLAGS
5885 MOVEI Q,%QMRD ;START READING AGAIN
5893 JRST IOCER2 ;ACCESS OFF END OF FILE IS ERROR
5894 MOVSI TT,%QAEFR ;BUT ACCESS TO EXACTLY EOF IS OK
5895 IORM TT,QSRAC(A) ;IMITATES WHAT QEOF DOES
5897 SETZM QSMPRC(A) ;AND READS ZERO WORDS
5900 QBRRA3: SKIPGE TT,QSMDN(A)
5904 ;BLKT-SIOKT-CHRKT GET BUFFER ROUTINE FOR WRITE-OVER MODE.
5905 QWOG1: SKIPGE QSCRW(A) ;FETCH BLOCK WRITEOVER MODE
5906 JRST QWOG2 ;STILL WRITING PREVIOUS ONE, WAIT
5907 MOVEI Q,%QMRD1 ;SWITCH INTO READ MODE
5908 SKIPG QSBFS(A) ;IF A BUFFER HAS TO BE READ
5913 ;BLKT-SIOKT-CHRKT GET-BUFFER ROUTINE FOR DISK INPUT.
5914 QSBGB: MOVSI Q,%QAPAR
5919 JUMPE Q,[MOVSI J,%QAEFR ;SAID TO BE BUFFERS, BUT NONE THERE
5921 BUG ;SHOULDN'T HAPPEN EXCEPT AT EOF
5923 LDB J,[MLO,,MEMBLT(Q)]
5926 SETZM QBFP(A) ;LAST BLOCK, LIST NOW EMPTY
5927 HRRZ J,MEMPNT(Q) ;GET SIZE OF BUFFER IN BYTES
5929 LDB TT,[$QAMOD,,QSRAC(A)]
5930 SKIPN TT ;DONT SOS IF IN WRITE OVER MODE
5933 LSH TT,10. ;RETURN ADDR OF BUFFER
5940 MOVE Q,QRADAD(A) ;DIDDLE PNTRS TO TAKE CARE OF RANDOM ACCESS WITHIN BLOCK
5941 SUB Q,QFBLNO(A) ;DESIRED OFFSET WITHIN BLOCK
5943 JUMPL J,IOCER2 ;OFF END OF FILE
5944 JUMPL Q,IOCER2 ;OFF FRONT OF FILE (NEGATIVE .ACCESS PNTR)
5947 ADD TT,Q ;ADJUST BYTE POINTER
5952 MOVSI Q,%QAMPU ;NOW IS SAFE TO TURN OFF FLAG
5956 ;GET-BUFFER DETECTED EOF ON INPUT OR WRITE-OVER.
5957 QSBGB5: CONO PI,UTCON
5961 LDB Q,[$QAMOD,,QSRAC(A)]
5962 SOJN Q,POPJ2 ;ON INPUT, SKIP TWICE TO SIGNAL EOF.
5963 PUSHJ P,QLWO ;LEAVE WRITE OVER MODE
5964 JRST QSBWG ;START NORMAL WRITE
5966 QWOG2: SKIPGE QSCRW(A) ;WAIT FOR WRITE TO FINISH
5968 JRST POPAJ ;NOW RECYCLE AND WAIT FOR READ
5970 ;LEAVE WRITE OVER MODE
5971 QLWO: MOVE H,QUDPR(A)
5974 SETZM QBFP(A) ;WRITEOVER MODE EXTEND FILE (SWITCH TO NORMAL MODE)
5978 HRRZM Q,QMPTN(A) ;STORE BASE TRACK
5979 MOVSI Q,%QAEFR+%QAMWO ;CLEAR EOF AND WRITEOVER
5981 MOVEI Q,%QMWRT ;NORMAL WRITE MODE
5983 CLEARM QMPTC(A) ;TRACK COUNT FOR TAKE N
5984 SETOM QMTTR(A) ;NO TRACK RESERVED
5985 SETOM QMFTP(A) ;GET NEW DECADE RESERVATION
5987 MOVE TT,QDIRP(A) ;SEE IF GARBAGE COLLECTION NEEDED
5990 PUSHJ P,QMPDC1 ;CONV CHAR ADR TO BYTE PNTR (AND LDB IN R)
5997 JRST QLWO1 ;DON'T NEED TO EXPAND F.S.
6002 JRST QSBWG7 ;DON'T HAVE ROOM. GC
6003 MOVEI R,3*6 ;HAVE ROOM
6012 QSBWG7: MOVSI R,%QAFUL ;NO ROOM, GC BEFORE COMMITTING NEXT TRACK
6017 QSBGB2: ANDCAM Q,QSRAC(A) ;DISK READ ERROR
6018 JRST IOCER3 ;TELL USER
6020 ;DISK OUTPUT GET-BUFFER ROUTINE. PRESERVES D FOR BENEFIT OF PDUMP.
6021 QSBWG: MOVE Q,QSRAC(A)
6022 TLNE Q,%QALNK+%QAACC ;DON'T WRITE TO LINK, DON'T LET PDUMP GET
6023 JRST IOCR10 ; FAKED OUT BY USE FORCE OR ACCESS
6026 JRST QWOG1 ;JUMP IF WRITE OVER MODE
6027 HRRZ Q,QBFP(A) ;NORMAL MODE
6028 JUMPE Q,QSBWG1 ;CAN ALWAYS HAVE ONE BUFFER
6031 JRST POPAJ ;TOO MANY WRITE BUFFERS QUEUED
6032 QSBWG1: PUSHJ P,QSTWG
6035 JRST QSBWG5 ;MEM FROZE OR NOT AVAILABLE
6036 MOVE Q,(P) ;DISK CHNL #
6037 DPB Q,[MNUMB,,MEMBLT(A)]
6039 DPB Q,[MUR,,MEMBLT(A)]
6046 MOVEM J,QMPBSZ(A) ;FRESH BLOCK SIZE
6049 QSTWG: MOVSI Q,%QAFUL
6050 TDNE Q,QSRAC(A) ;ROUTINE TO COMMIT A TRACK
6051 JRST QSTWG1 ;DIR FULL, NEED GC BEFORE GROWING FILE
6052 MOVE H,QUDPR(A) ;IF THIS DIRECTORY HAS AN ALLOCATION
6053 MOVE Q,QSNLCN(H) ; ENFORCE IT
6056 JUMPE J,QSTWG0 ;NO ALLOCATION
6057 HRRZ H,UDBLKS(Q) ;GET BLOCKS USED
6059 JRST IOCR13 ;HAS ALLOCATION AND USER IS TRYING TO EXCEED IT
6061 QSTWG0: MOVE J,QDSKN(A)
6062 SOSL QSFT(J) ;RESERVE A TRACK
6064 AOS QSFT(J) ;DISK FULL, GIVE BACK THE TRACK
6065 SKIPE QFBTS ;WAIT FOR ANY PENDING FILE DELETIONS
6066 PUSHJ P,UFLS ; TO COMPLETE AND FREE THEIR BLOCKS
6067 SOSL QSFT(J) ;GOT SPACE NOW?
6069 AOS QSFT(J) ;NO, GIVE UP AND ERR OUT
6072 QSTWG1: MOVE H,QUDPR(A)
6075 JRST IOCR12 ;DIR FULL
6077 ANDCAM Q,QSRAC(A) .SEE %QAFUL
6080 QSBWG5: POP P,A ;GET BACK QSK CHANNEL #
6082 AOS QSFT(J) ;NO MEMORY; GIVE EVERYTHING BACK
6085 ;DISK OUTPUT RELEASE-BUFFER ROUTINE FOR BLKT, SIOKT, CHRKT.
6086 QSBWW: SKIPGE QSMDN(A) ;WRITE BUFFER FROM MN PROG TO CHAIN FOR PI
6087 POPJ P, ;NO WRITE BUFFER ACTIVE
6088 LDB TT,[$QAMOD,,QSRAC(A)]
6089 SOJE TT,QSBWO1 ;WRITE OVER MODE
6091 JRST QTG1 ;TRACK ALREADY RESERVED
6094 PUSHJ P,QGTRK ;GET A TRACK
6097 QTG1: MOVE H,QUDPR(A) ;TRACK IN D
6101 MOVE TT,QMPTN(A) ;GET PREVIOUS TRACK#
6103 JRST QTG2 ;THIS TRACK IS CONSECUTIVE
6104 SKIPN QMPTC(A) ;THIS TRACK NOT CONSEC CHECK COUNT OF PREV CONSEC BLOCKS
6106 PUSH P,D ;NON-ZERO SO STORE IN USER DIRECTORY
6111 QTG3: MOVE J,QMTTR(A) ;DESCRIPTOR WILL BE STORED
6113 SUB D,QMPTN(A) ;CAN TRACK BE SKIPPED TO?
6114 SOJL D,QTG4 ;CAN'T BE SKIPPED TO (NOTE QMPTN HAS NOT BEEN AOS'D)
6115 CAILE D,UDWPH-UDTKMX-1
6117 ADDI D,UDTKMX ;NEXT BLOCK WITHIN N
6118 PUSHJ P,QUDS ;STORE APPROPRIATE SKIP
6120 QTG5: MOVE Q,QSMDN(A) ;CORE BLOCK NUM BEING WRITTEN
6121 MOVE D,QMPTN(A) ;TRACK NUM OF BLOCK ADDING TO FILE
6122 HRLZM D,MEMPNT(Q) ;STORE TRACK NUM
6123 SETOM QMTTR(A) ;INDICATE TRACK USED
6124 MOVE J,QMPBSZ(A) ;LENGTH OF THIS BLOCK
6125 ADDM J,QFBLNO(A) ;INCR BYTE ADR OF START OF CURRENT BLOCK IN FILE
6126 HRRM J,MEMPNT(Q) ;SAVE BYTE COUNT
6128 IDIVI J,@QSBYTE(A) ;CONVERT TO WORD COUNT
6129 JUMPE R,QTG7 ;EXACT MULTIPLE OF WORD
6132 ADDI R,@QSBYTE(A) ;# BYTES RESIDUE IN LAST WORD
6133 QTG7: DPB J,[MWC,,MEMBLT(Q)] ;STORE ACTIVE WORD COUNT
6135 LDB TT,[$QAMOD,,QSRAC(A)]
6136 TLNN D,%QALBK ;LAST BLOCK OF WRITE OVER POSSIBLY
6137 SOJE TT,QTG6 ;WRITEOVER MODE AND NOT LAST BLOCK, DONT UPDATE LAST BLOCK WORD COUNT
6138 MOVE H,QUDPR(A) ;SET UP DIRECTORY CHANNEL
6141 DPB J,[UNWRDC+UNRNDM(D)] ;SET WORD COUNT OF LAST BLOCK
6143 PUSHJ P,QBENC ;ENCODE BYTE CRUFT
6144 DPB Q,[UNBYTE+UNREF(D)]
6151 ANDCAM J,MEMBLT(Q) ;SET END OF LIST INDICATOR IN MEMORY BLOCK
6153 HLRZ J,QBFP(A) ;STORE MEMORY BLOCK IN OUTPUT LIST
6155 DPB Q,[MLO,,MEMBLT(J)]
6156 QSBWW2: HRLM Q,QBFP(A)
6158 SETOM QSMDN(A) ;MN PROG BUFFER NOW WRITTEN
6159 JRST QSTRTR ;START ACTION IF 2311 IDLE AND RETURN
6161 QSBWO1: MOVE Q,QSRAC(A) ;PUT BUFFER IN WRITE-OVER MODE
6162 TLNE Q,%QALBK ;IF NOT HACKING LAST BLOCK
6163 TLNE Q,%QAEFW ;OR HACKING CLOSE
6164 JRST QSBWO2 ;THEN JUST WRITE IT
6168 JUMPE D,QSBWO2 ;BLOCK REALLY FULL
6169 TLNE Q,%QAMPU ;DID WE IOCER2 AT QSBWG4?
6170 JRST IOCER2 ;YES, QSMPRP NOT SET UP, DON'T WRITE ANYTHING
6171 MOVEM D,QSMPRC(A) ;LAST BLOCK NOT REALLY USED UP ("SPRUNG BACK TO LIFE")
6172 ADDM D,QMPBSZ(A) ;EXTRA ROOM IN LAST BLOCK TO FILL UP
6174 IORM D,QSRAC(A) ;FILLING LAST BLK PAST ORIG EOF
6175 POPJ P, ;FINISH OUT BLOCK
6177 QSBWO2: MOVSI D,%QAWOV
6179 MOVE D,QSLGL(A) ;WRITE TRACK BACK WHERE IT CAME FROM
6180 MOVEM D,QMPTN(A) ;PUT TRACK NO WHERE QTG5 CAN FIND IT
6183 SETOM QSCRW(A) ;SWITCH TO WRITE MODE
6189 QTG4: LDB D,[140500,,QMTTR(A)] ;WRITE LOAD ADDRESS
6192 LDB D,[060600,,QMTTR(A)]
6194 LDB D,[0600,,QMTTR(A)]
6198 QGTRK: PUSHJ P,QTLOCK ;GET TRK CHNL IN A DSK IN I RET IN D CLOBBERS E,TT,Q,J,B
6199 QGTK4: PUSH P,R ;ENTER HERE FROM SWAP OUT WITH UTCOFF
6203 QGTK4A: SKIPGE Q,QMFTP(A)
6204 JRST QGTK3A ;FIRST TRACK
6206 HRREI J,-DECADE(J) ;COMPUTE TRACKS REMAINING IN DECADE
6209 ADD D,[TUTBYT_14,,] ;MAKE INTO ILDB-TYPE POINTER
6212 QGTK3: CAML D,QLASTB(R)
6213 JRST QGTK3A ;REACHED END OF DISK
6216 AOJGE J,QGTK3A ;DECADE OUT
6219 QGTK3A: CAILE A,NQCHN
6220 JRST QGTK3C ;SWAP CHANNEL
6221 QGTK3D: MOVEI Q,DECADE
6223 QGTK3B: MOVEM Q,QMFTP(A)
6226 MOVE Q,QSWAPA(R) ;REACHED END OF DSK, RESET TO END OF SWAPPING AREA
6227 ADDI Q,DECADE-1 ;ROUND UP TO A MULTIPLE OF A DECADE
6242 POPJ P, ;CALLED FROM SWAP OUT
6245 QGTK3C: CAML D,QSWAPA(R)
6246 JRST QGTK3D ;IN NON-SWAP AREA
6252 \f;STORE CHR IN D CHNL IN A USER DIR PNTR IN H
6253 ;CANNOT PCLSR NOR GC
6259 CAML I,@QSNLCN(H) ;UDESCP
6260 BUG ;WRITING ABOVE F.S. PNTR?
6266 BUG ;UFD WAS NOT LOCKED
6269 CAIE I,UDWPH ;OK TO CLOBBER UDWPH (NORMALLY DOES AT START OF FILE)
6270 JUMPN I,[JRST 4,.] ;ABOUT TO CLOBBER SOMETHING IN UFD
6272 ILDB I,Q ;MAKE SURE FILE DESC WILL ALWAYS BE FOLLOWED BY ZERO
6275 REPEAT NXLBYT+2,[ ;MAKE SURE THERE'S ROOM FOR ONE MORE TRACK
6281 CAMGE I,@QSNLCN(H) ;UDESCP
6282 JRST QUDSX ;DESC AREA NOT COLLIDING WITH LIM OF DESC SPACE
6287 JRST QUDS1 ;NO ROOM.
6288 MOVEI Q,3*UFDBPW ;EXPAND DESC AREA
6292 QUDS1: MOVSI Q,%QAFUL ;NEED GC BEFORE STARTING ON NEXT TRACK
6295 IORM Q,QSNLCN(H) ;SET DIRECTORY CHANGED
6300 QSBWW1: HRRM Q,QBFP(A)
6310 ADDM TT,QFBLNO(A) ;INCREMENT BYTE ADR IN FILE OF BEG OF NEXT BLOCK
6314 QTG2: MOVE J,QMTTR(A) ;INDICATE WE WILL STORE DESCRIPTOR FOR NEXT TRACK.
6316 AOS D,QMPTC(A) ;NEXT BLOCK IS CONSECUTIVE
6319 SETZM QMPTC(A) ;MAX # CONSECUTIVE BLOCKS, STORE DESC NOW
6323 SUBTTL DIRHNG DEVICE
6325 ;WHENEVER THE DIRECTORY SPECIFIED AS THE SNAME WHEN DIRHNG IS OPENED
6326 ;IS MODIFIED, YOU GET AN INTERRUPT ON THE DIRHNG DEVICE CHANNEL.
6328 ;HERE TO OPEN THE DIRHNG DEVICE. IOCHNM ADDR IN R, SNAME IN USYSN1(U).
6329 DIRHO: MOVE C,USYSN1(U)
6330 PUSHJ P,QFL ;LOOK UP THIS DIRECTORY
6331 JRST OPNL20 ;CALL FAILS IF DIRECTORY DOES NOT EXIST.
6332 HRRZM J,IOCHST-IOCHNM(R) ;DIR EXISTS; STORE TRACK NUMBER IN IOCHST.
6333 DIRHP1: CONO PI,CLKOFF
6334 HLLZ A,DIRHNG ;ADD THIS CHANNEL'S IOCHNM TO THE LIST OF DIRHNG CHANNELS.
6336 MOVEM A,(R) ;SET UP THE IOCHNM WITH IOTTB INDEX AND LIST CHAIN.
6340 ;CLOSE A DIRHNG DEVICE CHANNEL.
6341 DIRHCL: PUSHJ P,DIRHPS ;REMOVE IT FROM THE LIST, AND
6342 SETZM (R) ;MARK IT CLOSED.
6345 ;IOPUSH A DIRHNG DEVICE CHANNEL. REMOVE IT FROM THE LIST OF ALL SUCH.
6346 DIRHPS: MOVEI A,DIRHNG
6348 ;FIND THE PLACE THAT POINTS AT THIS IOCHNM WORD.
6352 SKIPN A,B ;END OF LIST REACHED =>
6353 BUG ;THIS IOCHNM ISN'T IN THE LIST. BUT IT IS SUPPOSED TO BE!
6356 ;A POINTS AT IOCHNM THAT POINTS AT THIS ONE. PATCH THIS ONE OUT OF LIST.
6357 DIRHC2: HLRZ B,(B) ;THE ONE AFTER THIS ONE
6361 ;IOPUSH OR IOPOP THE DIRHNG CHANNEL WITH R -> IOCHNM WORD. I SAYS WHICH OPERATION.
6362 DIRHIP: JUMPE I,DIRHPS ;IOPUSH REMOVES CHANNEL FROM LIST OF ALL DIRHNG CHANNELS.
6364 ;IOPOP A DIRHNG DEVICE CHANNEL. JUST LIKE OPENING IT EXCEPT THAT
6365 ;THE DIRECTORY TRACK NUMBER IS ALREADY IN THE IOCHST.
6366 ;ALSO, WE SHOULD GIVE AN INTERRUPT NOW,
6367 ;IN CASE THE DIRECTORY WAS WRITTEN IN WHILE THE CHANNEL WAS PUSHED.
6368 DIRHPP: PUSHJ P,DIRHP1 ;FIRST, REOPEN THE CHANNEL. LINK IT INTO THE DIRHNG LIST.
6371 SUBI A,IOCHNM(U) ;COMPUTE CHANNEL NUMBER FROM IOCHNM WORD ADDRESS.
6372 MOVE A,CHNBIT(A) ;GET BIT CORRESPONDING TO CHANNEL.
6373 AND A,MSKST2(U) ;GIVE THE INT IF THE INT IS ENABLED.
6377 ;HERE WITH A/ DIRECTORY'S TRACK NUMBER (AS RETURNED BY QFL)
6378 ;TO SIGNAL A WRITE IN THAT DIRECTORY TO ALL DIRHNG DEVICES THAT ARE LOOKING.
6380 DIRSIG: CONO PI,CLKOFF
6382 DIRSI0: HLRZ B,(B) ;GET IOCHNM ADDR OF NEXT DIRHNG DEVICE.
6384 HRRZ C,IOCHST-IOCHNM(B)
6385 CAIE C,(A) ;DOES IT LOOK AT THIS DIRECTORY?
6387 MOVEI C,-IOCHNM(B) ;YES => FIGURE OUT USER INDEX OF JOB IT BELONGS TO.
6389 IMULI C,LUBLK ;C NOW HAS USER INDEX.
6391 ADD D,B ;D GETS CHANNEL NUMBER
6393 AND D,MSKST2(C) ;INTERRUPT THE USER ON THAT CHANNEL, IF IT'S ENABLED.