.MCALL .MODULE .MODULE TM,VERSION=18,COMMENT= ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion of the above copyright notice. This software, or ; any other copies thereof, may not be provided or otherwise ; made available to any other person except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. .SBTTL CONDITIONAL ASSEMBLY SUMMARY ;+ ;COND ; MT$UN (1) number of units supported ; 1-8 valid range ; ; MT$FSM (0) File structured module used ; 0 NFS ; 1 FSM used ; ; MMG$T std conditional ; TIM$T std conditional (no code effects) ; ERL$G std conditional (no code effects) ;- .IIF NDF MT$FSM MT$FSM == 0 .SBTTL Edit History ;EDITS: ; FIXED PARITY ERROR PROBLEMS ;BD0 ; ; FIXED XM ERRBLK REPORTING ;BD1 ; ; FIXED CONTROL C ABORT CODE ;SD2 ; ; FIXED DEVICE IN USE FLAGS FOR SYSTEM TASKING ;SD2 ; ; Edit History: ; ; 001 31-Dec-79 15:18 Davis, Scott (75474) [240,92] ; ALLOW ABORT ENTRY EVEN IF NO SERVICE ENTRY ; IT IS POSSIBLE TO ENTER AT ABORT ENTRY EVEN IF WE NEVER ENTERED ; AT THE I/O ENTRY IF THE USER OPENS THE MT NFS, THEN ABORTS ; (001) ; 002 31-Dec-79 15:51 Davis, Scott (75474) [240,92] ; FIX CRASH AFTER INTERRUPT WITH NO CURRENT QUEUE ELEMENT ; (002) ; 003 29-Jan-80 13:54 Davis, Scott (75474) [240,92] ; Change an incorrect call to .DRFIN to an RTS. ; (003) ; 004 23-Apr-80 10:33 Davis, Scott H. [240,92] ; FIX XM BUFFER CLEARING ; (004) ; 005 16-Jun-80 02:49 PM Davis, Scott H. [240,92] ; FIX READ RECOVERY BUG ; (005) ; ; Edits following V5.2: ; ; 004 13-Sep-85 MBG More complete audit trail (hardware handler and ; file-structured module info), updated to using ; .DRSET macros, added CSR, VECTOR and RETRY SET ; commands, general code clean-up ; ; 005 23-Sep-85 MBG Change of reference to 176 to INSCSR ; ; Edit for V5.4B ; ; 006 23-Jan-87 RHH Fix CSR addressing in error handling code ; ; Test Edit for future release ; ; 007 30-Jun-88 RHH Treat PURGE like CLOSE, change unit number check ; ; 008 29-Jul-88 RHH Return blocks not skipped as POSITIVE in all monitors ; ; 009 10-Aug-88 RHH Adapt for UMR support ; ; 010 26-Jun-89 RHH Move XBUMP out of here, and into FSM .SBTTL TM11 Magtape Handler Abstract .ENABL LC ;+ ; ; TM11 Magnetic Tape Driver (handler) ; ; 1. This handler is designed to allow the RT-11 monitor to access DIGITAL ; TM11 type magtape controllers. These include the TM11, TMA11 and TMB11 ; (subsystem units supported include the TU10 and the TS03.) ; ; 2. Handler Input Formats ; ; The hardware handler accepts commands through a queue element which is ; passed to it by the system or the file structured module. The following ; table describes the queue element format and how the magtape handler ; interprets it. ; ; Word Mnemonic Purpose MT handler uses this for: ; ; 0 --- Link to next Not used. ; queue element ; ; 2 Q.CSW Pointer to MT handler reports status to monitor ; channel status by setting bit 13(EOF$) if an ; word end of file condition is detected or ; bit 0(HDERR$) if a hard error ; condition is detected. ; ; 4 Q.BLKN Starting block 1. .ENTER and .LOOKUP requests interpret ; number this argument as SEQNUM. ; 2. Negative codes use this as an address ; (ERRBLK) to report qualifying information. ; When zero no information is reported. ; 3. NFS .READx/.WRITx requests zero this ; word. ; ; 6(byte) Q.FUNC Special MT handler accepts the following codes: ; Function code ; 3 .LOOKUP (NFS) ; 1 .CLOSE ; 0 .READx/.WRITx (NFS) ; -1 Write EOF (tapemark) ; -2 Forward space ; -3 Backspace ; -4 Write with extended gap ; -5 Rewind ; -6 Offline and rewind ; -7 Write a block ; -8 Read a block ; -9 Stream at 100 ips (TS05 only) ; ; Any other codes detected will cause a hard ; error. ; ; 7(byte) Q.JNUM Job number The job number is used by lookup and abort ; <13:11> to determine whether a unit is being used by ; F/G. ; Unit number The unit number is used to select a tape unit ; <10:8> and also by lookup to determine whether a unit ; is busy. ; ; 10 Q.BUFF Buffer address Used by .LOOKUP as the address of the filename ; to be found. First word of filename must be ; zero. Used as buffer address by ; .READx/.WRITx, read, write and write extend. ; ; 12 Q.WCNT Word count Zeroed by .LOOKUP to indicate a non RT-11 file ; structured device. Used as a word count by ; .READx/.WRITx, read, write, and write extend. ; Used as a count for the number of blocks to ; space by forward space and backspace. ; ; 14 --- Completion Not used. ; Function ; ; 16 --- PAR1 register Not used. ; ; 20 --- --- Not used. ; ; 22 --- --- Not used. ; ; The following is a description of the action taken by the handler for a ; given code. ; ; Code Action ; 3 .LOOKUP The filename at Q.BUFF is checked for zero (meaning a non ; file structured .LOOKUP.) Next the INUSE byte is examined to see ; whether another channel is using this unit. Finally, the SEQNUM ; argument (passed through Q.BLKN) is examined for a zero value ; which indicates that a rewind should be performed. ; ; 1 .CLOSE The unit is marked unused. ; ; 0 .READx/.WRITx These requests read or write blocks of data on the ; tape currently mounted. .WRITx will report end of file when it ; sees the EOT marker. .READx will report end of file only when it ; reads a tape mark (TM). It will ignore the EOT marker. ; ; -1 Write a tapemark. ; ; -2 Forward space n blocks (n specified in Q.WCNT) until n is ; satisfied, EOT marker is sensed, or a TM is read. ; ; -3 Backspace n blocks (n specified in Q.WCNT) until n is satisfied, ; BOT is sensed, or a TM is read. ; ; -4 Erase 3 inches of tape and write a block to tape (write with ; extended gap.) ; ; -5 Rewind the tape to BOT. ; ; -6 Turn tape unit offline and rewind. ; ; -7 Write a block to tape. ; ; -8 Read a block from tape. ; ; -9 Stream at 100 ips (TS05 only) This code will be ignored by the ; MT and MM handlers, as well as MS when it is running a TS11 ; ; Other input to the magtape handler comes when the handler is entered at the ; abort entry point. R4 must contain the job number of the job being ; aborted. ; ; 3. Handler conditionals. ; ; When the MT$FSM conditional is defined it creates an object module which ; must be linked with the file structure module (FSM.OBJ or FSMX.OBJ). This ; enables code which allows the handler to be called (at $MT) with a queue ; element (possibly created by FSM) and the handler will execute the ; command in the queue element and will return to either FSMDON or FSMERR ; depending on whether an exception condition (end of file or hard error) ; was detected during the operation. In addition, the handler provides the ; $DONE entry point for ending queue element processing (it exits to the ; monitor.) The legal codes which the FSM may issue to the handler are ; defined in the previous section. ; ; 4. Handler structure ; ; The handler is divided into 3 main parts. ; ; 1. The command dispatcher transforms a queue element into a command, ; initiates the command and then exits to the monitor while the unit ; is performing the command. ; ; 2. When the command completes the interrupt handler is entered. The ; interrupt handler is subdivided into 3 sections. ; ; 1. The exception condition evaluation section looks at the ; status of the controller to determine the result of the last ; operation. It can reach one of 3 conclusions. ; ; 1. The operation succeeded. ; ; 2. The operation failed but may be recoverable. ; ; 3. The operation failed and is unrecoverable. A ; hard error is issued and the handler goes to the ; monitor. ; ; 2. The recovery section is entered if a recoverable error is ; being processed. ; ; 3. The status checking and reporting section determines ; whether there are conditions such as TM, EOT and record ; length error to report. ; ; 3. The Data area stores information about which tape units are busy ; and what the recovery status is if an operation is being recovered. ; ;- .SBTTL DEFINITIONS ; PSECT ordering .PSECT MSDVR,I,LCL,CON ; This handler .PSECT MTDVR,I,LCL,CON ; FSM code .PSECT NONRES,I,LCL,CON ; Non-resident LOAD/UNLOAD code ; RT Macros .MCALL .ADDR .ASSUME .BR .DRDEF .SYNCH .LIBRARY "SRC:SYSTEM.MLB" .MCALL .ERMDF .ERRDF .FIXDF .SFMDF .SYCDF .UBVDF .USSDF .ERMDF ; Define magtape errors .ERRDF ; Define system errors .FIXDF ; Define Fixed Offsets .SFMDF ; Define magtape SPFUNs .SYCDF ; Define System Communication Area .UBVDF ; Define UB Vectors .USSDF ; Define USR Function Codes ; Local Macros .MACRO ...... .ENDM ; Define the device handler .IF EQ MMG$T .DRDEF MT,11,,0,172520,224,DMA=NO .IFF; EQ MMG$T NUMRS = MT$FSM .DRDEF MT,11,,0,172520,224,DMA=YES,PERMUMR=NUMRS,SERIAL=YES .ENDC; EQ MMG$T .DRPTR LOAD=LOAD,FETCH=LOAD,UNLOAD=UNLOAD,RELEASE=UNLOAD .IF EQ MT$FSM .DREST CLASS=DVC.MT,MOD=DVM.NS ; device is NFS MAGTAPE .IFF; EQ MT$FSM .DREST CLASS=DVC.MT ; device is a MAGTAPE .ENDC; EQ MT$FSM .DRSPF SF.MTM ; Write TAPE MARK .DRSPF SF.MFS ; Forward Space .DRSPF SF.MBS ; Backspace .DRSPF SF.MWE ; Write with Extended Gap .DRSPF SF.MRE ; Rewind .DRSPF SF.MOR ; Rewind Offline .DRSPF SF.MWR ; Write .DRSPF SF.MRD ; Read .DRSPF SF.MST ; Enable/Disable Streaming Mode .IIF NE MT$FSM .DRSPF SF.USR ; Async file operations .IF NE MMG$T .DRSPF +SPFTAB ; Pointer to SPFUN table for UMRs .ENDC; NE MMG$T .IIF NDF MT$UN, MT$UN == 1 ; Define the audit trail .IIF EQ MT$FSM .FSM = 100000 .AUDIT .TM ;Hardware handler .AUDIT .FSM ;File-structured module ; Control and Status register bit definitions ILC = 100000 ;ILLEGAL COMMAND EOF = 040000 ;END OF FILE CRE = 020000 ;CRC ERROR PAE = 010000 ;PARITY ERROR BGL = 004000 ;BUS GRANT LATE EOT = 002000 ;END OF TAPE MARKER SENSED IN FWD DIR. RLE = 001000 ;RECORD LENGTH ERROR BTEOPI = 000400 ;BAD TAPE/OPERATION INCOMPLETE ERRORS NXM = 000200 ;NON EXISTANT MEMORY ACCESSED SELR = 000100 ;SELECTED UNIT READY BOT = 000040 ;BEGINNING OF TAPE MARKER SENSED CH7 = 000020 ;7 CHANNEL DRIVE SELECTED SDWN = 000010 ;TAPE UNIT SLOWING DOWN WRL = 000004 ;TAPE UNIT WRITE LOCKED RWS = 000002 ;TAPE REWINDING TUR = 000001 ;TAPE UNIT READY ; Command register bit definitions ERR = 100000 ;ERROR IN MTS<15:7> ; DENSITY MTC<14:13> D7$200 = 000000 ;7 CHANNEL 200 BPI D7$556 = 020000 ;7 CHANNEL 556 BPI D7$800 = 040000 ;7 CHANNEL 800 BPI D7$CORE = 060000 ;7 CHANNEL 800 BPI ; CORE DUMP MODE(CH7=1) D9$800 = 060000 ;9 CHANNEL 800 BPI PWRCLR = 010000 ;CLEAR CONTROLLER AND DRIVES PEVN = 004000 ;PARITY IS EVEN ; UNIT SELECT MTC<10:8> UNIT = 003400 ;3 BITS FOR UNIT MASK CURDY = 000200 ;CONTROLLER READY INTENB = 000100 ;INTERRUPT ENABLE ; EXTENDED ADDRESS BITS MTC<3:1> FOFF = 000000 ;OFFLINE AND REWIND FREAD = 000002 ;READ FWRITE = 000004 ;WRITE FWRTTM = 000006 ;WRITE TAPE MARK FSPFOR = 000010 ;FORWARD SPACE FSPBAK = 000012 ;BACKSPACE FWRTEXT = 000014 ;WRITE WITH EXTEND INTERBLOCK GAP FREWIND = 000016 ;REWIND GO = 000001 ;EXECUTE FUNCTION CODE ; TMA11 Read line register bit definitions GPSDN = 010000 ;GAP SHUT DOWN .SBTTL SOFTWARE DEFINITIONS ; SPECIAL FUNCTIONS WRTEOF = -1 ;WRITE TAPE MARK FWDSPC = -2 ;FORWARD SPACE BKSPC = -3 ;BACKSPACE WRTXTD = -4 ;WRITE WITH EXTENDED INTERBLOCK GAP REWIND = -5 ;REWIND OFFLINE = -6 ;OFFLINE AND REWIND WRITEPHY= -7 ;WRITE PHYSICAL READF = -8. ;READ PHYSICAL ; STR100 = -9. ;STREAM AT 100 IPS (TS05 ONLY) ;NOTE: if you add an SPFUN code here, also add it to .DRSPF FN = 8. ;NUMBER OF FUNCTIONS ERRGAPS = -101. ;NUMBER OF 3" GAPS ALLOWED BETWEEN BLOCKS ; MISCELLANEOUS UNITMK = 007 ;Unit number mask (Q$UNIT) NRETRY = 8. ;Default maximum retry count .SBTTL INSTALLATION CHECKS .DRINS MT .ENABL LSB NOP ;SKIP NON-SYSTEM ENTRY MOV INSCSR,R0 ;POINT TO THE CONTROLLER TSTB 2(R0) ;IS THE SUBSYSTEM (OR CONTROLLER) READY? BPL 1$ ;NO, DON'T DO THE CHECK, JUST SUCCEED MOV #1000,2(R0) ;TRY TO SET UNIT SELECT 2 BIT BIT #1000,2(R0) ;DID IT COME ON? BNE 1$ ;YES, IT'S A TM11, RETURN SUCCESS SEC ;NO, WE JUST TRIED TO SET TS11 BA17, NOT TM11 1$: RETURN ;DON'T INSTALL IF TS11 .DSABL LSB .SBTTL SET COMMANDS ;+ ; ; THE MAGTAPE HANDLER ACCEPTS 4 SET COMMANDS. ; ; 1. SET MT DENSE=N SETS THE DENSITY AT WHICH THE TAPE DRIVES RUN AT. ; LEGAL DENSITIES ARE: ; ; 200 200 BPI FOR 7 TRACK DRIVE ; 556 556 BPI FOR 7 TRACK DRIVE ; 800 SYNONYM FOR 809 ; 807 800 BPI FOR 7 TRACK DRIVE ; 809 800 BPI FOR 9 TRACK DRIVE. ; ; 2. SET MT DUMP SETS THE HANDLER IN CORE DUMP MODE 800 BPI FOR A ; 7 TRACK DRIVE. CORE DUMP MODE WRITES 2 FRAMES OF DATA FOR ; EACH PDP-11 BYTE THUS ALLOWING A FULL 8 BITS OF DATA TO BE READ AND ; WRITTEN. THE FSM REQUIRES THAT CORE DUMP MODE BE SET IF FILE ; OPERATIONS ARE TO BE PERFORMED. THIS COMMAND OVERRIDES ANY PREVIOUS ; SET DENSE COMMANDS. IF A NO OPTION IS SPECIFIED THEN THE COMMAND ; RETURNS AN ERROR. ; ; 3. SET MT [NO] ODDPAR SETS THE HANDLER IN OR OUT OF ODD PARITY RECORDING. ; THE NO OPTION WILL SET EVEN PARITY RECORDING. IT IS RECOMMENDED THAT ; TAPES BE WRITTEN WITH ODD PARITY. WHEN THE PARITY IS EVEN AND NULL ; CHARACTERS ARE SENT TO THE TAPE UNIT THE CONTROLLER WILL CONVERT ; THESE NULLS TO OCTAL 20 CHARACTERS AND THIS IS WHAT WILL BE READ. ; ; 4. SET MT DEFALT=[7] OR [9] ; ; THIS COMMAND IS A GENERAL RESET THE OTHER OPTIONS. ; ; 7 SETS UP 800 BPI CORE DUMP ODD PARITY FOR A 7 TRACK DRIVE. ; 9 SETS UP 800 BPI ODD PARITY FOR A 9 TRACK DRIVE. ; ;- .DRSET DENSE, NOP, O.DENS, NUM .DRSET DUMP, NOP, O.DUMP, NO .DRSET ODDPAR, PEVN, O.PAR, NO .DRSET DEFALT, NOP, O.DFLT, NUM .DRSET CSR, 160000, O.CSR, OCT .DRSET VECTOR, 500, O.VEC, OCT .DRSET RETRY, 127., O.RTRY, NUM ; SET MT DENSE={200|556|800|807|809} O.DENS: CLR R3 CMP #200.,R0 ;IS TAPE 200BPI? BEQ DENS1 ;YES CMP #556.,R0 ;NO-IS TAPE 556BPI? BEQ 1$ ;YES CMP #807.,R0 ;NO-IS TAPE 800BPI FOR A SEVEN TRACK DRIVE? BEQ 2$ ;YES CMP #809.,R0 ;NO-IS TAPE 800BPI FOR A NINE TRACK DRIVE? BEQ 3$ ;YES CMP #800.,R0 ;NO-IS TAPE 800BPI FOR A NINE TRACK DRIVE? BEQ 3$ ;YES SEC RETURN 1$: BIS #D7$556,R3 ;SET FORMAT FOR SEVEN TRACK 556BPI BR DENS1 2$: BIS #D7$800,R3 ;SET FORMAT FOR SEVEN TRACK 800BPI BR DENS1 3$: BIS #D9$800,R3 ;SET FORMAT FOR 800BPI FOR A NINE TRACK DRIVE DENS1: BIC #D9$800,DENSE ;CLEAR OUT OLD BITS BIS R3,DENSE ;NOW CHANGE THE HANDLER DENS3: CLC ;NO ERRORS HERE RETURN ; SET MT [NO]DUMP O.DUMP: CLR R3 BR 1$ BR DFLT1 1$: BIS #D7$CORE,R3 ;7 TRACK CORE DUMP MODE BR DENS1 ; SET MT [NO]ODDPAR O.PAR: BR ODD ;R3=PEVN BIT NOP BIS R3,DENSE ;EVEN PARITY BR DENS3 ODD: BIC R3,DENSE BR DENS3 ; SET MT DEFALT={7|9} .ENABL LSB O.DFLT: CMP #7,R0 ;7 TRACK DRIVE BEQ 7$ CMP #9.,R0 ;CHECK FOR NINE TRACK DRIVE BEQ 9$ ;YES DFLT1: SEC RETURN 9$: MOV #D9$800,DENSE ;9 TRACK DRIVE BR DENS3 7$: MOV #D7$CORE,DENSE ;7 TRACK DRIVE,ODD PARITY BR DENS3 .DSABL LSB ; SET MT CSR=octal_address O.CSR: CMP R0,R3 ;Valid CSR address? BLO O.BAD ;Nope, reject it MOV R0,INSCSR ;Set the install-time MOV R0,DISCSR ; and display-time CSR's .ADDR #MTS,R1 ;R1 -> Device CSR table MOV #NREGS,R2 ;R2 = Count of registers to set 10$: MOV R0,(R1)+ ;Set a CSR address ADD #2,R0 ;Bump the address DEC R2 ;More table to fill? BGT 10$ ;Yep... O.GOOD: TST (PC)+ O.BAD: SEC RETURN ; SET MT VECTOR=octal_address O.VEC: CMP R0,R3 ;Valid vector address? BHIS O.BAD ;Nope, reject it MOV R0,MTSTRT ;Yes, inform the handler BR O.GOOD ; SET MT RETRY=n O.RTRY: CMP R0,R3 ;Test retry limits BHI O.BAD ;Branch if out of bounds MOV R0,RTRYCT ;Set the retry count BEQ O.BAD ;Zero retries not allowed BR O.GOOD .Assume . LE 1000,<;SET area overflow> .SBTTL Handler Entry Point .IF NE MT$FSM ;define globals to FSM ; EXTERNAL GLOBAL SYMBOLS .GLOBL FSMDIS FSMABT FSMDON .GLOBL FSMERR RESTOR CODE .GLOBL DVTBL FSMSIZ ; INTERNAL GLOBAL SYMBOLS .GLOBL MTCQE ; MTCQE IS THE FIFTH WORD OF THE HANDLER. WHENEVER THE HANDLER IS ; CALLED IT CONTAINS THE ADDRESS OF A QUEUE ELEMENT. ; ; MTCQ CONTAINS THE ADDRESS OF A QUEUE ELEMENT WHEN THE HARDWARE ; HANDLER IS CALLED FROM THE FILE STRUCTURED MODULE. ; ; $DONE IS THE ENTRY POINT WHERE THE FSM JUMPS WHEN QUEUE ELEMENT PROCESSING ; IS DONE. IT RELEASES THE QUEUE ELEMENT BY CALLING OR JUMPING TO I/O ; COMPLETE IN THE MONITOR AND IF THE GLOBAL VARIABLE SINK IS NON ZERO IT WILL ; DO A .SYNCH AND REPORT ERRORS (MEMORY MANAGEMENT ONLY). ; ; $MT IS THE ENTRY POINT PROVIDED FOR FSM TO CALL THE HARDWARE HANDLER TO ; PERFORM A FUNCTION IN A QUEUE ELEMENT WHOSE ADDRESS IS IN MTCQ AND R3. .IF NE MMG$T ; EXTERNAL GLOBAL SYMBOLS FOR MEMORY MANAGEMENT .GLOBL OLDBA EXTADR .GLOBL JOBNM SYNBLK TEMP .GLOBL SINK ERBSAV .ENDC ;NE MMG$T .ENDC ;NE MT$FSM .IF EQ MMG$T .DRBEG MT .IFF; EQ MMG$T .DRBEG MT,SPFUN=SPFTAB .ENDC; EQ MMG$T MTBASE =: MTSTRT + 6 ; MTLQE address BR MT ;Bypass some data space MTS: .WORD MT$CSR ;Control and Status register MTC: .WORD MT$CSR+2 ;Command register MTBRC: .WORD MT$CSR+4 ;Byte XOR record(block) counter MTCMA: .WORD MT$CSR+6 ;Current memory address register MTD: .WORD MT$CSR+10 ;Data buffer register MTRD: .WORD MT$CSR+12 ;TMA11 read lines register NREGS = <.-MTS>/2 ;Number of CSRs .Assume . LE MTSTRT+1000,<;SET object not in block 1> RTRYCT: .WORD NRETRY ;Retry count .Assume . LE MTSTRT+1000,<;SET object not in block 1> .IF NE MMG$T .SBTTL SPFTAB - SPFUN table for UMR/DMA operations SPFTAB: .DRSPF -,<370>,TYPE=R .DRSPF -,<371,374>,TYPE=W .WORD 0 .ENDC; NE MMG$T ; THIS CODE GETS AN 18 BIT PHYSICAL ADDRESS FROM THE MONITOR AND STORES ; IT IN THE OLDBA AND EXTADR VARIABLES. ; ; BITS 6-9 FROM $MPPHY ARE USED TO DELIVER BITS 19-22 FOR 22 BIT ; MACHINES. BECAUSE MT IS A UNIBUS DEVICE, THESE BITS MUST BE 0 .ENABL LSB MT: .IF NE MMG$T MOV MTCQE,R5 ;MAKE 18 BIT ADDRESS CMP (R5)+,(R5)+ ;POINT TO Q$BUFF CALL @$MPPTR ;GET AN 18 BIT ADDRESS MOV (SP)+,OLDBA ;SAVE LOW ORDER 16 BITS OF ADDRESS ; BIT #1700,@SP ;BITS 6-9 SET? ; BEQ 5$ ;IF NOT, BRANCH ; TST (SP)+ ;POP STACK FOR NEATNESS ; BR HDERR 5$: .REPT 4 ASR @SP ; Move extended bits from <4:5> to <0:1> .ENDR MOV (SP)+,EXTADR ;SAVE HIGH ORDER BITS .ENDC ;NE MMG$T ; THIS CODE LOADS THE ADDRESS OF THE QUEUE ELEMENT IN R3. ; ; IF MT$FSM IS DEFINED THE CODE CALLS FSM AND THIS ($MT) IS THE ENTRY ; POINT FOR THE FSM TO PASS REQUESTS TO THE HARDWARE HANDLER. .IF EQ MT$FSM MOV MTCQE,R3 ;GET ADDRESS OF BLOCK NUMBER IN R3 .IFF; EQ MT$FSM JMP FSMDIS ;CALL THE FILE STRUCTURED MODULE $MT:: ;R3 IS ASSUMED TO CONTAIN THE ADDRESS OF A QUEUE ELEMENT ;ENTER HERE TO PERFORM A FUNCTION WHEN FSM IS PRESENT .ENDC ;EQ MT$FSM ; THIS CODE GETS THE UNIT # FROM THE QUEUE ELEMENT AND SELECTS THE DRIVE. ; THIS CODE IS DELIBERATELY EXECUTED EARLY SO THAT THE CONTROLLER HAS TIME ; TO ACTUALLY COMPLETE THE SELECT OPERATION (FOR THE TMA11 THIS 28 ; MICROSECONDS). ; THE CODE FROM THE QUEUE ELEMENT IS ALSO EXTRACTED. TST (R3)+ ;R3 POINTS TO CODE,UNIT,AND JOB# MOV @R3,R0 ;GET THE CODE AND UNIT NUMBER MOVB R0,R4 ;R4=FUNCTION CODE BIC #^C,R0 ;R0=TAPE UNIT # MOV R0,R1 ;SAVE THE UNIT # SWAB R1 ;PUT THE UNIT # IN BOTTOM OF R1 .IF EQ MT$FSM .IF GT ;MULTIPLE UNIT HANDLERS CMP R1,#MT$UN ;VALID UNIT NUMBER? BLT 7$ .IFF; GT ;SINGLE UNIT HANDLERS BEQ 7$ .ENDC; GT CMPB R4,#LOOK.. ;INVALID UNIT. FUNCTION = LOOKUP? BNE HDERR MOV #ER.IUN,R0 BR USRERR ;RETURN ERROR TO USR .ENDC; EQ MT$FSM 7$: BIS (PC)+,R0 ;OR IN THE DENSITY DENSE: .WORD D9$800 ;DEFAULT DENSITY IS 800 BPI,9TRK,NRZI .Assume . LE MTSTRT+1000,<;SET object not in block 1> MOV R0,@MTC ;SELECT THE DRIVE ; THIS INITIALIZES A FLAG MARKING NO NON FILE STRUCTURED .READX DONE. CLR NFSREAD ;INITIALIZE NON FILESTRUCTURED READ DONE FLAG ; LET R0 POINT TO MANY OF THE VARIABLES USED DURING THE I/O INITIALIZATION ; CYCLE. IT BEGINS POINTING TO "RECOVE", AND WANDERS DOWN THROUGH MANY ; OTHERS. .ADDR #RECOVE,R0 ;R0=POINTER TO INUSE WORD ; PROCESS A LOOKUP. CHECK FOR A ZERO FILENAME AND GIVE HARD ERROR IF NOT. ; CHECK TO SEE IF OTHER CHANNELS ARE USING THE UNIT AND IF NOT ALLOCATE IT. ; IF BUSY IT ISSUES A CODE 2 ERROR. ; THEN THE SEQNUM (BLOCK #) ARGUMENT IS EXAMINED. IF ZERO THE TAPE IS ; REWOUND. IF -1, THE ROUTINE EXITS. OTHERWISE AN ILLEGAL ARGUMENT ; ERROR IS ISSUED VIA $SPUSR. MOV R1,R5 ;GET UNIT # ADD PC,R5 ;POINT TO TABLE ;SD2 ADD #$TBL-.,R5 ;POINT TO TABLE ;SD2 MOV @R3,R2 ;GET JOB # ;SD2 SWAB R2 ;PUT IT IN LOW BYTE ;SD2 ASR R2 ;SHIFT ;SD2 ASR R2 ;SHIFT ;SD2 ASR R2 ;SHIFT ;SD2 BIC #177760,R2 ;R2 = JOB # ;RHH .IF NE MMG$T MOVB R2,JOBNM ;STORE THE JOB NUMBER IN JOBNM .ENDC; NE MMG$T CMPB R4,#LOOK.. ;IS THIS COMMAND A LOOKUP? BNE 60$ ;NO HWXM = 0 .IF NE MMG$T .IF EQ MT$FSM HWXM = 1 MOV MTCQE,R4 ;POINT TO QUEUE ELEMENT CALL @$GTBYT ;GET HALF OF 1ST FILENAME WORD TSTB (SP)+ ;ZERO (NFS LOOKUP?) BNE 40$ ;SHOULD'VE BEEN CALL @$GTBYT ;GET OTHER HALF TSTB (SP)+ ;ZERO? BNE 40$ ;NO .ENDC; EQ MT$FSM .ENDC; NE MMG$T .IF EQ HWXM TST @2(R3) ;YES-IS THIS A NFS LOOKUP? BNE 110$ ;NO .ENDC; EQ HWXM CMPB #-1,@R5 ;UNIT TAKEN? ;SD2 BEQ 20$ ;NO .IF EQ MT$FSM MOV #ER.SHR,R0 ;UNIT ALREADY IN USE USRERR: 10$: MOV @#$SYPTR,R1 ;POINT TO RMON MOV R0,$SPUSR(R1) ;GIVE ERROR BR 120$ .IFF; NE MT$FSM MOV @#$SYPTR,R1 ;YES-GIVE AN ERROR MESSAGE MOV #ER.SHR,$SPUSR(R1) ;UNIT ALREADY IN USE CALL RESTOR JMP $DONE ;IMMEDIATE ABORT ...... .ENDC ;EQ MT$FSM HDERR: MOV MTCQE,R5 ;POINT TO Q ELEMENT BIS #HDERR$,@-(R5) ;SET HARD ERROR IN CSW JMP MTDONE ;GO OUT ...... 20$: CLR 4(R3) ;NFS DEVICE(RETURN ZERO IN WORD COUNT) MOVB R2,@R5 ;MARK UNIT BUSY IN TABLE ;SD2 .IF NE MT$FSM BR 120$ ;LET FSM TELL US WHAT'S NEXT ;SD2 ...... .IFF; NE MT$FSM 30$: MOV -2(R3),R1 ;GET SEQNUM ARGUMENT(Q$BLKN) BEQ 50$ ;DO A REWIND BGT 40$ ;POSITIVE NUMBER-GIVE ERROR INC R1 ;SEQNUM=-1? BEQ 120$ ;YES 40$: MOVB #-1,@R5 ;MARK UNIT VACANT ;SD2 MOV #ER.ISN,R0 ;ILLEGAL ARGUMENT BR 10$ ...... 50$: MOVB #SF.MRE,R4 ;SET UP FOR A REWIND BR 80$ .ENDC; NE MT$FSM ; THIS CODE CLEARS OUT THE UNIT BITS IN THE INUSE AND FGCHAN WORDS TO ; MARK THE UNIT NOT BUSY. 60$: CMPB R4,#PURG.. ;IS COMMAND A PURGE? ;007 BEQ 70$ ;BRANCH IF YES ;007 CMPB R4,#CLOS.. ;THIS COMMAND A CLOSE? BNE 80$ ;NO 70$: MOVB #-1,@R5 ;MARK UNIT VACANT ;SD2 BR 120$ ; THIS CODE INITIALIZES THE RECOVERY AND TAPE LEN VARIABLES AND LEAVES R0 ; POINTING AT LASTCOM. 80$: MOV (PC)+,(R0)+ ;NUMBER OF 3" GAPS TO ALLOW .BYTE -1,ERRGAPS ;INITIALIZE RECOVERY AND TAPELEN TST (R0)+ ;POINT R0 TO LASTCOM VARIABLE ; THIS CHECKS THE QUEUE ELEMENT CODE. ; 1. IF IN THE RANGE -1 TO -8 THEN IT'S A LEGAL SPFUN. ; 2. IF ZERO THEN IT WILL BE CONVERTED TO A -7 (WRITE) OR -8 (READ) ; DEPENDING ON THE SIGN OF THE WORD COUNT (+ MEANS READ). ; 3. IF NONE OF THE ABOVE THEN IGNORE IT AND RETURN ; ; THE ONLY EXCEPTION IS FOR CODE -9. ; -9 IS VALID ONLY FOR A TS05. IF THE DRIVE IS ANYTHING ; ELSE, -9 WILL PASS THROUGH THE HANDLER WITHOUT DOING ; ANYTHING. ; CMPB R4,#SF.MST ;TS05 SPFUN? ; BEQ 120$ ;IF YES, BRANCH .ASSUME SF.MRD EQ 370 CMPB R4,#SF.MRD ;IS THE FUNCTION CODE A LEGAL CODE? BHIS 130$ ;YES TSTB R4 ;.READ/.WRITE? BNE 120$ ;NO - Ignore other functions ; CONVERT .READ/.WRITE REQUESTS TO .SPFUN I/O MOV R3,R1 ;GET ADDRESS OF Q$FUNC CLR -2(R1) ;CLEAR Q$BLKN (ERRBLK) ARGUMENT ;TO PREVENT ERROR REPORTING CMP (R1)+,(R1)+ ;POINT TO Q$WCNT MOVB #SF.MRD,R4 ;ASSUME .READ TST @R1 ;.READ OR .WRITE? BPL 90$ ;.READ NEG @R1 ;.WRITE-MAKE WORD COUNT POSITIVE .ASSUME SF.MWR EQ INC R4 ;CHANGE CODE TO WRITEPHY BR 100$ 90$: COM NFSREAD ;MARK A NONFILESTRUCTURED READ BEING DONE 100$: .IF NE MT$FSM MOV R4,CODE ;REMEMBER CODE OF NEW REQUEST .ENDC ;NE MT$FSM BR 130$ ; THIS ISSUES A HARD ERROR. IF FILE SUPPORT IS PRESENT THEN R0-R3 MUST BE ; RESTORED BECAUSE WE MAY BE RUNNING AT .INTEN LEVEL. 110$: TST -(R3) ;POINT TO BLOCK # BIS #HDERR$,@-(R3) ;SET HARD ERROR BIT IN THE CSW 120$: .IF NE MT$FSM CALL RESTOR ;RESTORE THE REGISTERS .ENDC ;NE MT$FSM JMP MTDONE ; THIS CODE TRANSFORMS A CODE INTO A COMMAND AND LOADS IT INTO THE DEVICE ; REGISTER. NOTE THAT THE OLDBA VARIABLE IS NOT LOADED HERE IF MMG$T IS ; NOT EQUAL TO ZERO. 130$: ADD #FUNTAB-TABLE,R4 ;MAKE THE CODE POSITIVE MOV R4,(R0)+ ;SAVE THE LASTCOM (R0 -> OLDBA) .IF NE MMG$T MOV 4(R3),R1 ;GET WORD COUNT MOV R1,4(R0) ;SAVE WORD COUNT IN OLDWC .IFF TST (R3)+ ;POINT TO THE BUFFER MOV (R3)+,(R0)+ ;SAVE BUFFER ADDRESS IN OLDBA MOV @R3,@R0 ;SAVE WORD COUNT(R3-PTR TO WORDCOUNT) IN OLDWC MOV @R3,R1 ;LOAD WC INTO R1 .ENDC ;NE MMG$T NEG R1 ;NEEDS NEGATION CALL DISPAT ;GO DO COMMAND ...... .DSABL LSB TABLE: .BYTE REDEF-TABLE .BYTE RIGHT-TABLE .BYTE AWFLINE-TABLE .BYTE REWHINED-TABLE .BYTE RIGHTX-TABLE .BYTE BAKSPA-TABLE .BYTE FORSPA-TABLE .BYTE RIGHTM-TABLE FUNTAB: .BYTE FREAD+INTENB+GO ;READ .BYTE FWRITE+INTENB+GO ;WRITE .BYTE FOFF+INTENB+GO ;OFFLINE AND REWIND .BYTE FREWIND+INTENB+GO ;REWIND .BYTE FWRTEXT+INTENB+GO ;WRITE WITH EXTENDED INTERBLOCK GAP .BYTE FSPBAK+INTENB+GO ;BACKSPACE .BYTE FSPFOR+INTENB+GO ;FORWARD SPACE .BYTE FWRTTM+INTENB+GO ;WRITE TAPEMARK REDEF: RIGHTX: RIGHT: .IF NE MMG$T MOV (R0)+,@MTCMA ; load OLDBA into MTCMA MOV @R0,-(SP) ; Get EXTADR .REPT 4 ; rotate it up to where ASL @SP ; the controller wants it .ENDR BIS (SP)+,R5 ; Combine EXTENDED BITS with COMMAND .IFF MOV -(R3),@MTCMA ;PUT IN THE BUFFER ADDRESS .ENDC ;NE MMG$T ASL R1 ;TURN WORD COUNT INTO BYTE COUNT FORSPA: BAKSPA: MOV R1,@MTBRC ;PUT IN BYTE COUNT (OR BLOCK SPACE COUNT) AWFLINE: REWHINED: RIGHTM: MOVB R5,@MTC ;GO! .IF NE MT$FSM CALL RESTOR .ENDC; NE MT$FSM RETURN .SBTTL INTERRUPT HANDLER AND ABORT ENTRY POINTS ; ABORT ENTRY POINT. THIS CODE HALTS ANY OPERATION IN PROGRESS AND UPDATES ; THE INUSE TABLE. MTABRT: MOVB #-1,$FLG ;DEFAULT TO NOT CALLING COMPLETION ROUTINE ; IN THE MONITOR ;SD2 MOV R3,-(SP) ;SAVE R3 ;SD2 MOV PC,R5 ;-> TABLE ;SD2 ADD #$TBL-.,R5 ;-> TABLE ;SD2 MOV MTCQE,R3 ;-> QUEUE ELEMENT ;SD2 BEQ 7$ ;IF EQ NO ACTIVE Q ELEMENT ;SD2 MOVB Q$JNUM(R3),-(SP);GET JOB NUMBER ;SD2 MOVB (SP)+,R3 ;R3 = JNUN WORD BYTE IN Q ELEM ;SD2 ASR R3 ;SHIFT ;SD2 ASR R3 ;SHIFT ;SD2 ASR R3 ;SHIFT ;SD2 BIC #177760,R3 ;R3 = JOB NUM ;SD2 CMP R3,R4 ;IS ABORTING JOB ACTIVE? ;SD2 BNE 7$ ;IF NE NO ;SD2 CLRB $FLG ;CALL COMPLETE ;SD2 MOV #PWRCLR,@MTC ;DO A CONTROLLER RESET 5$: .IF NE MT$FSM MOV R0,-(SP) ;SAVE R0 MOV DVTBL,R0 ;POINT TO DEVICE TABLE BEQ 6$ ;IF EQ NOT INITIALIZED YET ;001 MOV #-1,(R0)+ ;MARK TAPE POSITION LOST MOV #-1,@R0 ;MARK CURRENT BLOCK NUMBER LOST 6$: MOV (SP)+,R0 ;RESTORE R0 ;001 .ENDC ;NE MT$FSM 7$: CMPB R4,@R5 ;DOES THIS UNIT BELONG TO THIS JOB? ;SD2 BNE 10$ ;IF NE NO ;SD2 MOVB #-1,@R5 ;MARK EMPTY ;SD2 10$: CMPB #-2,(R5)+ ;END OF TABLE? ;SD2 BNE 7$ ;IF NE NO ;SD2 MOV (SP)+,R3 ;RESTORE R3 ;SD2 JMP $DONE ;EXIT ;SD2 .SBTTL INTERRUPT ENTRY POINT ; ALL MAGTAPE INTERRUPTS COME THROUGH HERE. THE .DRAST MACRO GENERATES A ; PIC .INTEN CALL FOR PRIORITY LEVEL 5 AND ALSO GENERATES A BRANCH TO THE ; ABORT ENTRY POINT. ; THE INTERRUPT ROUTINE ONLY USES R4 AND R5. IF THESE REGISTERS ARE TO BE ; USED IN FUTURE MODIFICATIONS TO THE MAGTAPE HANDLER THEY MUST BE SAVED AND ; RESTORED. THE STACK IS USED ONLY LOCALLY AND FUTURE MODIFICATIONS SHOULD ; KEEP TO THIS CONSTRAINT BECAUSE THE HANDLER AT INTERRUPT LEVEL USES THE ; SYSTEM STACK. .DRAST MT,5,MTABRT .SBTTL ERROR-ERROR ROUTINE DISPATCHER ; THE ERROR ROUTINE IS ALWAYS ENTERED AND DOES ONE OF 2 THINGS. ; 1. DETECTS AN ABORTABLE CONDITION. IN THIS CASE THE PROPER ERROR CODE ; IS PUT IN R4 AND THE ABORT AND REPORT ROUTINE IS TRANSFERRED TO AND ; THE CONDITION IS REPORTED. EXECUTION OF THE INTERRUPT HANDLER IS ; ABORTED. ; 2. REPORTS THAT NO ERROR OCCURRED OR THAT A RECOVERABLE ERROR OCCURRED. ; IN THIS CASE THE VARIABLE ERRSUM (ERROR SUMMARY) IS LOADED WITH ; EITHER 0(NO ERROR) OR -1(RECOVERABLE ERROR). EXECUTION OF THE ; INTERRUPT HANDLER CONTINUES. ; THE BASIC PHILOSOPHY BEHIND THIS ERROR ROUTINE IS TO ASSUME THE ; OPERATION GUILTY UNLESS IT CAN BE SHOWN TO BE INNOCENT. ; THE ERROR ROUTINE DISPATCHER DOES THE FOLLOWING: ; -CHECKS FOR THE ERR BIT. IF NOT FOUND THEN ERRSUM IS CLEARED. ; -CHECKS FOR ILC SET AND SELR CLEAR. IF FOUND THEN A DRIVE NOT ; AVAILABLE CONDITION IS REPORTED TO THE ABORT ROUTINE. ; -GETS THE LAST COMMAND ISSUED AND DISPATCHES TO A ROUTINE WHICH ; CORRESPONDS TO THE VALUE OF THE LAST COMMAND. TST MTCQE ;QUEUE ELEMENT? ;002 BNE 114$ ;IF NE YES ;002 JMP $RTS ;DISMISS INTERRUPT WITH NO CHECKS ;003 114$: TST @MTC ;CHECK FOR ERR BIT SET BMI 1$ ;IT IS .IF NE MMG$T JMP NOERR ;NO EXCEPTION CONDITIONS .IFF BR NOERR ;NO EXCEPTION CONDITIONS .ENDC ;NE MMG$T 1$: MOV @MTS,R4 ;GET MTS AND CHECK ILLEGAL COMMAND BIT BPL 2$ ;NOT FOUND BIT #SELR,R4 ;FOUND-IS DRIVE SELECTED? BNE 2$ ;YES-SOMETHING ELSE IS WRONG MOV #EM.OFL,R4 ;NO-DRIVE IS NOT AVAILABLE BR ABORT 2$: MOV LASTCOM,R4 ;GO DO ERROR DECODING CALL DISPAT TABLEE: .BYTE ERREAD-TABLEE .BYTE ERWRIT-TABLEE .BYTE EROFFL-TABLEE .BYTE ERREWD-TABLEE .BYTE ERWRTX-TABLEE .BYTE ERBKSP-TABLEE .BYTE ERFWSP-TABLEE .BYTE ERWRTM-TABLEE .SBTTL ERROR-WRITE OR WRITE/GAP WAS ISSUED AND ERR BIT WAS SET ; THIS ROUTINE DETERMINES WHAT WENT WRONG IF ANYTHING WITH THE LAST WRITE ; COMMAND. IT ISSUES AN ABORT IF THE WRL BIT IS SET. IT CALLS ABOCHK ; AND SAVES THE RECOVERABLE ERRORS CHECK IN ERRSUM. IF EOT IS DETECTED THEN ; NO ERROR OCCURRED. IF NONE OF THE ABOVE CHECKS ARE FOUND THEN A HARD ERROR ; IS ISSUED. .ENABL LSB ERWRIT: ERWRTX: BIT #WRL,@MTS ;CHECK FOR WRITE LOCK ERROR BEQ 1$ ;NOT FOUND ERWRI1: MOV #EM.WLK,R4 ;ISSUE WRITE LOCK ABORT BR ABORT 1$: CALL ABOCHK ;GO CHECK SOME ERRORS MOV R5,ERRSUM ;SAVE RESULT OF ABOCHK AND TEST IT BNE CONT ;RECOVERABLE ERRORS DETECTED BIT #EOT,R4 ;IF EOT THEN NO ERROR BNE NOERR BR NQUAL ;CATCH OTHER ERRORS HERE .DSABL LSB .SBTTL ERROR-WRITE TM,FORWARD SPACE, OR BACKSPACE COMMAND GIVEN LAST AND ERR BIT SET ; WRITE TM CHECKS FOR WRITE LOCKED CONDITION ERWRTM: BIT #WRL,@MTS ;IS DRIVE WRITE LOCKED? BNE ERWRI1 ;YES-GO ISSUE ABORT ERBKSP: ERFWSP: CALL ABOCHK ;GO CHECK FOR THE COMMON ABORTS BIT #EOF+EOT,R4 ;IGNORE THESE CONDITIONS BNE NOERR BR NQUAL ;DON'T KNOW WHATS WRONG .SBTTL ERROR-READ COMMAND WAS ISSUED LAST AND ERR BIT WAS SET. ; THIS ROUTINE CHECKS FOR ABORTS WITH ABOCHK THEN CHECKS FOR RLE ; AND/OR EOT AND/OR EOF. IF FOUND THEN ERRSUM IS CLEARED. ; A HARD ERROR IS ISSUED IF THE ABOVE CONDITIONS WERE NOT FOUND. ERREAD: CALL ABOCHK ;CHECK FOR VARIOUS ERRORS MOV R5,ERRSUM ;SAVE RESULT OF ABOCHK AND TEST IT BNE CONT ;RECOVERABLE ERRORS DETECTED BIT #RLE+EOT+EOF,R4 ;NONE OF THESE CONDITIONS ARE ERRORS BNE NOERR BR NQUAL ;CATCH OTHER ERRORS HERE .SBTTL ERROR-ABORT CHECK SUBROUTINE ; THIS SUBROUTINE CHECKS FOR BAD TAPE/OPERATION INCOMPLETE ERRORS AND ; NON EXISTANT MEMORY ERRORS. IF THESE ARE FOUND THEN AN ABORT EXIT IS ; CALLED. ; NEXT PARITY ERRORS ARE CHECKED FOR. IF FOUND THEN R5 IS SET TO -1 ; ELSE IT IS CLEARED. THIS ALLOWS THE READ/WRITE/WRITE EXTENDED GAP ROUTINES ; TO MARK A RECOVERY IN PROGRESS AND INSURES THAT NO OTHER COMMANDS CAN ; INITIATE A RECOVERY SEQUENCE. ; EXIT: R4 CONTAINS THE MTS REGISTER ; R5 = -1 IF PAE AND/OR CRE AND/OR BGL WERE SET ; R5 = 0 IF PAE AND CRE AND BGL WERE CLEAR ; ALL OTHER REGISTERS UNAFFECTED. ABOCHK: MOV @MTS,R4 ;GET THE STATUS REGISTER BIT #BTEOPI,R4 ;CHECK FOR BAD TAPE OR OPERATION INCOMPLETE BEQ 1$ ;NOT FOUND MOV #EM.POS,R4 ;FOUND-POSITION ERROR BR 4$ ;BD0 1$: BIT #NXM,R4 ;CHECK FOR A NON EXISTANT MEMORY ERROR BEQ 2$ ;NOT FOUND MOV #EM.NXM,R4 ;FOUND-MEMORY ERROR 4$: TST (SP)+ ;CLEAN THE STACK ;BD0 BR ABORT 2$: CLR R5 ;MARK NO ERRORS FOUND BIT #CRE+PAE+BGL,R4 ;CHECK FOR PARITY ERRORS BEQ 3$ ;NOT FOUND COM R5 ;MARK PARITY ERRORS FOUND 3$: RETURN .SBTTL ERROR-ABORT OPERATION IN PROGRESS ERREWD: ;REWINDS DON'T GIVE RECOVERABLE OR IGNORABLE ERRORS EROFFL: NQUAL: CLR R4 ;HARD ERROR HAS OCCURRED ABORT: MOV #PWRCLR,@MTC ;DO CONTROLLER RESET MOV #HDERR$,-(SP) ;HARD ERROR HAS OCCURRED ; EXCEPTION REPORTING ROUTINE ; R4 CONTAINS ERROR QUALIFICATION CODE ; CSW BIT TO SET IS ON THE STACK EXCEP: .IF NE MT$FSM MOV (SP)+,R5 ;PUT CSW BIT IN R5 JMP FSMERR ;TELL FSM THAT OPERATION HAD AN EXCEPTION .IFF MOV MTCQE,R5 ;POINT TO QUEUE ELEMENT BIS (SP)+,@Q$CSW(R5) ;SET BIT IN CSW TST @R5 ;DON'T SET ERRBLK IF ADDRESS IS ZERO BEQ MTDONE .IF NE MMG$T COM SINK ;SET .SYNCH WILL BE DONE FLAG MOV @R5,ERBSAV MOV R4,TEMP ;THIS VALUE COMES BACK IN R0 AFTER .SYNCH MOVB Q$JNUM(R5),R5 ;GET THE JOB NUMBER IN <5:3> ASR R5 ;PUT IT IN <2:0> ;BD1+ ASR R5 ASR R5 ;BD1- MOV R5,JOBNM ;STORE IT IN SYNCH BLOCK .IFF MOV R4,@(R5)+ ;MOVE CODE TO ERRBLK .ENDC ;NE MMG$T .IFTF ; MTDONE IS THE ROUTINE WHERE THE HARDWARE HANDLER COMES WHEN IT IS DONE WITH ; AN OPERATION WHICH COMPLETED WITH NO EXCEPTION CONDITIONS. WHEN THE FSM IS ; PRESENT THE HARDWARE HANDLER JUMPS TO FSMDON WHICH INDICATES THAT THE ; OPERATION COMPLETED WITH NO EXCEPTION CONDITIONS. ; WHEN FSM IS NOT PRESENT THE HANDLER EXITS TO THE I/O COMPLETE ROUTINE IN THE ; MONITOR. ; WHEN EXTENDED MEMORY SUPPORT IS INCLUDED THE HANDLER WILL DECIDE WHETHER TO ; DO A SYNCH SO THAT ERRORS CAN BE REPORTED TO THE USER'S ERRBLK ADDRESS. MTDONE: .IFT; NE MT$FSM JMP FSMDON ;TELL FSM THAT OPERATION IS DONE ; FSM COMES HERE WHEN IT IS DONE ALL ITS PROCESSING. .ENDC ;NE MT$FSM $DONE:: TSTB $FLG ;CALL COMPLETE? ;SD2 BNE $RTS ;IF NE NO ;SD2 .IF NE MMG$T TST SINK ;SHOULD A JSR OR JMP BE DONE? BNE 10$ ;JSR .ADDR #MTCQE,R4 ;POINT TO MTCQE MOV @#$SYPTR,R5 ;GET BASE OF RMON JMP @$QCOMP(R5) ;ALL DONE ...... 10$: CLR SINK ; Reset .SYNCH HAS BEEN DONE flag .ADDR #SYNBLK,R4 ; point to global SYNCH block .SYNCH BR BADSYN ; From here down to the RETURN, we are a completion routine running for ; the job in job-context. MOV ERBSAV,R1 ; point to job's ERRBLK BIS #30000,@#177776 ; USER mode to previous MOV R0,-(SP) ; put exception code on stack MTPD (R1)+ ; store for user MOV ERRBL2,-(SP) ; 2nd word (typically a count) MTPD (R1)+ ; store for user ; DRFIN the queue element. We are in kernel mode, running as a completion ; routine in job-context. Only R0 and R1 are free, so save the other ; registers. MOV R2,-(SP) ; Save registers MOV R3,-(SP) ; that COMPLT MOV R4,-(SP) ; might use MOV R5,-(SP) .ADDR #MTCQE,R4 ; point to queue element, MOV @#$SYPTR,R5 ; get base of RMON, CALL @$QCOMP(R5) ; CALL COMPLT in RMON MOV (SP)+,R5 MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 BADSYN: .BR $RTS .IFF .DRFIN MT ...... .ENDC ;NE MMG$T $RTS: CLRB $FLG ;CLEAR FOR FUTURE USE ;SD2 RETURN ;RETURN FROM INTERUPT ;SD2 ...... .SBTTL STATUS REPORT COME HERE IF NO ABORTS ISSUED NOERR: CLR ERRSUM ;MARK NO ERRORS CONDITION ; CHECK FOR RECOVERY IN PROGRESS CONT: TSTB RECOVERY ;IF NEGATIVE NO RECOVERY HAPPENING BPL RECOVR ;GO PROCESS RECOVERY ; CHECK FOR A RECOVERABLE ERROR PTCH: MOV @MTS,R4 ;R4= STATUS REGISTER ;005 MOV LASTCOM,R5 ;GET THE LAST COMMAND ;**-1 TST ERRSUM ;IF ZERO THEN NO RECOVERABLE ERROR HAPPENED BEQ NEXT0 ;NOT FOUND ; A RECOVERABLE ERROR HAS HAPPENED CMP #FN+READF,R5 ;WAS LAST COMMAND A READ? BNE 1$ ;NO-MUST BE A WRITE MOVB #5,BACK1 ;INITIALIZE RETRY COUNTERS MOVB RTRYCT,BACK5 ;Re-issue retrys BR 2$ 1$: MOV #FN+WRTXTD,R5 ;WRITE AND WRITEX RECOVER WITH WRITE EXT-GAP 2$: MOVB R5,RECOVERY ;MARK THE TYPE OF RECOVERY IN PROGRESS JMP REEDF1 ;THIS WILL DO A BACKSPACE 1 BLOCK ; CHECK FOR THE FIRST REWIND INTERRUPT ; THE REWIND COMMAND GENERATES 2 INTERRUPTS. THE FIRST WHEN THE CONTROLLER ; HAS BEGUN MOVING THE TAPE. THE SECOND COMES WHEN THE BOT MARKER IS ; REACHED. ; WHEN BOT IS NOT SEEN IN THE STATUS REGISTER THEN THE TAPE IS STILL ; REWINDING AND THE HANDLER WILL MARK A REWIND RECOVERY IN PROGRESS. ; WHEN BOT IS NOT SEEN IN THE STATUS REGISTER THEN THE TAPE IS DONE AND THE ; OPERATION IS DONE. NEXT0: CMP #FN+REWIND,R5 ;REWIND? BNE NEXT1 ;NO BIT #BOT,R4 ;NO-ARE WE ALREADY AT BOT? BNE REWHYN ;YES MOVB R5,RECOVERY ;NO-WAIT FOR THE SECOND INTERRUPT RETURN ; LENGTH ERROR CHECK FOR READ ; THIS ROUTINE CHECKS FOR DATA LENGTH ERRORS. THERE ARE TWO WHICH CAN OCCUR. ; 1. RECORD (BLOCK) LENGTH ERROR (RLE) OCCURS WHEN THE BLOCK ON TAPE WAS ; LARGER THAN THE WORD COUNT SPECIFIED. THE TM11 DOES NOT REPORT HOW ; MUCH DATA WAS NOT READ THEREFORE ERRBLK+2 IS NOT CHANGED. CODE 5 ; IS RETURNED. ; 2. BLOCK IS SMALLER THAN SPECIFIED WORD COUNT. THE RESIDUAL COUNT IN THE ; MTBRC IS CHANGED TO A WORD COUNT AND REPORTED IN ERRBLK+2. CODE 6 ; IS RETURNED. ; RECOVERED ERRORS COME HERE NEXT1: CMP #FN+READF,LASTCOM ;WAS READ LAST COMMAND BNE NEXT2 ;NO BIT #EOF,R4 ;WAS A TM READ? BNE NEXT3 ;YES BIT #RLE,R4 ;CHECK FOR RECORD LENGTH ERROR BEQ 1$ ;NOT FOUND MOV #EM.BIG,R4 ;FOUND BR ABORT 1$: MOV @MTBRC,R5 ;CHECK FOR SMALL RECORD ERROR BEQ NEXT2 ;NOT FOUND ASR R5 ;CONVERT TO WORDS NEG R5 ;MAKE DIFFERENCE POSITIVE .IF NE MMG$T MOV R5,ERRBL2 ;SAVE EXTRA WORDS TO REPORT FOR LATER .IFF .IF NE MT$FSM MOV @MTCQ,R4 ;GET THE ADDRESS OF ERRBLK .IFF MOV @MTCQE,R4 ;GET THE ADDRESS OF ERRBLK .ENDC ;NE MT$FSM BEQ 2$ ;IF ZERO THEN DON'T REPORT DIFFERENCE MOV R5,2(R4) ;REPORT TO ERRBLK+2 .ENDC ;NE MMG$T 2$: MOV #EM.SML,R4 ;SMALL RECORD ERROR .IF NE MMG$T JMP ABORT .IFF BR ABORT .ENDC ;NE MMG$T ...... ; THIS ROUTINE CHECKS TO SEE WHETHER A SPACING COMMAND COMPLETED CORRECTLY ; OR WHETHER IT TERMINATED WITHOUT HAVING SPACED THE NUMBER OF BLOCKS ASKED ; FOR. ; WHEN A SPACING COMMAND TERMINATED WITHOUT HAVING SPACED THE CORRECT ; NUMBER OF BLOCKS THEN THE NUMBER OF BLOCKS NOT SPACED IS MADE POSITIVE ; AND REPORTED TO ERRBLK+2. NEXT2: CMP #FN+FWDSPC,LASTCOM BEQ 1$ ;FORWARD SPACE CMP #FN+BKSPC,LASTCOM BNE NEXT3 ;NOT A SPACING COMMAND ; SPACING COMMAND 1$: MOV @MTBRC,R4 ;GET THE NUMBER OF BLOCKS NOT SPACED BEQ NEXT3 ;SPACE COMPLETED NEG R4 ;MAKE POSITIVE RH008 .IF NE MMG$T MOV R4,ERRBL2 ;SAVE BLOCKS NOT SPACED .IFF .IF NE MT$FSM MOV @MTCQ,R5 ;GET ERRBLK ADDRESS .IFF MOV @MTCQE,R5 ;GET ERRBLK ADDRESS .ENDC ;NE MT$FSM BEQ 2$ ;IF 0 THEN DON'T WRITE TO ERRBLK MOV R4,2(R5) ;REPORT NUMBER OF BLOCKS NOT SPACED .ENDC ;NE MMG$T 2$: ; SET EOF/EOT/BOT CODES IF ANY .ENABL LSB NEXT3: MOV @MTS,R5 ;THIS HAS BOT,EOF,EOT INDICATORS CLR R4 ;THIS IS WHERE THE CODES GO BIT #BOT,R5 ;BOT? BNE 40$ ;Yes BIT #EOF,R5 ;TAPEMARK SET? BEQ 10$ ;NO CMP #FN+WRTEOF,LASTCOM BEQ 10$ ;WRITE TM DOESN'T REPORT EOF INC R4 ;SET BIT 0 10$: BIT #EOT,R5 ;END OF TAPE? BEQ 20$ ;NO TST NFSREAD ;YES-WAS NFS READ DONE? BNE 20$ ;YES-IGNORE THE EOT CONDITION CMPB (R4)+,(R4)+ ;NO-SET BIT 1 20$: TST R4 ;EOF DETECTED? BEQ MTD1 ;NO-GOTO MTDONE 30$: MOV #EOF$,-(SP) ;YES-MARK IT IN CSW JMP EXCEP ...... 40$: CMP #FN+REWIND,LASTCOM BEQ MTD1 ;REWIND DOESN'T REPORT BOT CMP #FN+OFFLINE,LASTCOM BEQ MTD1 ;OFFLINE/REWIND DOESN'T REPORT BOT CMP (R4)+,(R4)+ ;MARK BOT FOUND BR 30$ ;GO SET EOF BIT MTD1: JMP MTDONE ;Return queue element to RMON ...... .DSABL LSB .SBTTL RECOVERY IN PROGRESS DISPATCHER ; RECOVERY IN INITIATED FOR READ, WRITE, OR WRITE WITH EXTENDED GAP COMMANDS ; WHICH DETECT CRC ERROR, PARITY ERROR OR BUS GRANT LATE. THE ALGORITHMS USED ; ARE AS FOLLOWS. NOTE THAT IF AN ERROR IS DETECTED ON ANY OF THE SPACING ; COMMANDS IT TERMINATES THE RECOVERY ATTEMPT AND CAUSES A HARD ERROR. ; READ RECOVERY ; 1. BACKSPACE 1 BLOCK AND RE-READ, IF ERROR PERSISTS, REPEAT 4 MORE TIMES. ; 2. BACKSPACE 5 BLOCKS (OR TO BOT WHICHEVER COMES FIRST), SPACE FORWARD ; 4 BLOCKS, THEN RE-READ. ; 3. THIS ENTIRE SEQUENCE (STEPS 1 AND 2) SHOULD BE REPEATED 8 TIMES. WHEN ; ERROR STILL PERSISTS THEN THE RECOVERY IS DEEMED UNSUCCESSFUL AND A ; HARD ERROR IS GIVEN. ; WRITE RECOVERY ; 1. BACKSPACE OVER BLOCK. ; 2. ERASE THREE INCHES OF TAPE AND REWRITE THE BLOCK. ; 3. WHEN ERROR PERSISTS AND THE TOTAL LENGTH OF THE GAP WRITTEN IS LESS ; THAN 25 FEET (TAPELEN BYTE IS NOT ZERO YET) THEN PERFORM SEQUENCE ; AGAIN. RECOVR: MOV LASTCOM,R4 CALL DISPAT ...... TABLER: .BYTE REEDF-TABLER .BYTE RITE-TABLER .BYTE 0 .BYTE REWHYN-TABLER .BYTE RITEX-TABLER .BYTE BACH-TABLER .BYTE FORE-TABLER .BYTE 0 .SBTTL RECOVERY-WRITE WAS LAST COMMAND RITEX: RITE: TST ERRSUM ;RECOVERY COMPLETED? BEQ NEXT1 ;YES INCB TAPELEN ;ANOTHER 3" GAP WRITTEN BEQ NQ2 ;TOO MANY-ABORT WRITE RECOVERY BIT #EOT,@MTS ;EOT DETECTED? BEQ REEDF1 ;NO-BACKUP 1 BLOCK NQ2: JMP NQUAL ;YES-ABORT WRITE RECOVERY .SBTTL RECOVERY-REWIND WAS THE LAST COMMAND ; A CONTROLLER RESET MUST BE PERFORMED TO AVOID CONFUSING THE CONTROLLER. ; WHEN THIS IS NOT DONE THE CONTROLLER WILL "LOSE" THE REWIND COMPLETE ; INTERRUPT AND THE MAGTAPE HANDLER WILL HANG. REWHYN: MOV #PWRCLR,@MTC ;DO A CONTROLLER RESET BR MTD1 .SBTTL RECOVERY-READ WAS THE LAST COMMAND ISSUED .ENABL LSB REEDF: TST ERRSUM ;RECOVERY COMPLETE BEQ FOO ;IF EQ YES ;005 DECB BACK1 ;DECREMENT 1ST COUNTER ;**-1 BEQ 2$ ;IF EQ,TIME TO BACKSPACE 5 ;BD0+ BGT REEDF1 ;IF GT,KEEP BACKSPACE AT 1 ;ELSE TIME TO DECREMENT 2ND COUNTER ;AND RESET THE 1ST COUNTER MOVB #5,BACK1 ;RESET BACK1 COUNTER ;BD0- DECB BACK5 ;BACK5 COUNTER DONE? BEQ NQ2 ;YES-ABORT RECOVERY(LINK TO NQUAL) ; ENTER HERE TO ISSUE A BACKSPACE 1 BLOCK COMMAND. REEDF1: MOV #-1,R5 ;BD0+ BR 3$ ;BD0- 2$: MOV #-5,R5 ;GO BACK 5 BLOCKS 3$: MOV R5,@MTBRC ;SET NUMBER OF BLOCKS TO BACKSPACE BR BACH2 FOO: JMP PTCH ;BR OUT OF RANGE FIX ;005 ;005 .DSABL LSB .SBTTL RECOVERY-FORWARD SPACE WAS THE LAST COMMAND ; ENTER HERE TO REISSUE A READ COMMAND. FORE: MOV @MTBRC,R5 ;FORWARD SPACING ALL DONE? BNE BACH1 ;NO-ISSUE ANOTHER FORWARD SPACE COMMAND FORE1: MOV MTCMA,R5 ;R5 POINTS TO TM11 DEVICE REGISTER ;006 MOV OLDBA,@R5 ;PUT IN BUFFER ADDRESS MOV OLDWC,-(R5) ;PUT IN WORD COUNT ASL @R5 ;CONVERT TO BYTES NEG @R5 ;NEGATE THE BYTE COUNT ;BD0 MOV #FN+READF,R4 ;SAVE LAST COMMAND MOVB FUNTAB,R5 ;GO! BR BACH3 .SBTTL RECOVERY-BACKSPACE WAS LAST COMMAND ; WHEN BACKSPACE WAS THE LAST COMMAND ONE OF FOLLOWING ACTIONS IS TAKEN. ; 1. WHEN WRITE RECOVERY IS BEING PERFORMED A WRITE WITH EXTENDED GAP ; COMMAND IS ISSUED. ; 2. WHEN READ RECOVERY IS BEING DONE AND THE BACKSPACE COMPLETED A CHECK ; IS MADE AS TO WHETHER OR NOT THE BACKSPACE WAS PART OF 1 BLOCK OR ; 5 BLOCK SPACE. WHEN A 1 BLOCK BACKSPACE HAS COMPLETED A REREAD IS ; ISSUED. WHEN A 5 BLOCK BACKSPACE HAS COMPLETED A FORWARD SPACE TO BAD ; BLOCK IS PERFORMED. ; 3. WHEN READ RECOVERY IS BEING DONE AND THE BACKSPACE DID NOT COMPLETE THE ; ROUTINE CHECKS FOR BOT. WHEN BOT IS FOUND THEN THE HANDLER ISSUES A ; FORWARD SPACE COMMAND WHICH WILL POSITION IT IN FRONT OF THE BAD BLOCK. ; OTHERWISE A TM HAS BEEN ENCOUNTERED (OR EOT) AND THE BACKSPACE COMMAND ; IS REISSUED. .ENABL LSB BACH: CMPB #FN+READF,RECOVERY ;READ OR WRITE RECOVERY? BEQ 1$ ;READ ; ERASE AND REWRITE MOV OLDWC,R4 ;GET THE OLD WORDCOUNT ASL R4 ;MAKE IT A BYTE COUNT NEG R4 ;MT NEEDS TWO'S COMPLEMENT MOV R4,@MTBRC ;STICK IT IN THE REG. MOV OLDBA,@MTCMA ;GET THE OLD DATA ADDRESS MOV #FN+WRTXTD,R4 ;THIS IS THE LASTCOM MOVB FUNTAB+4,R5 ;THIS IS THE COMMAND BR 4$ ;GO EXECUTE THE COMMAND ; READ RECOVERY 1$: MOV @MTBRC,R5 ;DONE WITH BACKING UP? BEQ 6$ ;YES BIT #BOT,@MTS ;NO-BOT DETECTED? BEQ 5$ ;NO 2$: ADD #4,R5 ;YES-CALCULATE NUMBER OF BLOCKS TO FORWARD SPACE BEQ FORE1 ;GO READ IF NO SPACING REQUIRED ;BD0 3$: NEG R5 ;MAKE IT NEGATIVE BACH1: MOV R5,@MTBRC ;PUT IN NUMBER OF BLOCKS TO SPACE MOV #FN+FWDSPC,R4 ;THIS IS THE LASTCOM MOVB FUNTAB+6,R5 ;THIS IS THE COMMAND ; SET LASTCOM AND EXECUTE ; ENTER HERE TO EXECUTE A COMMAND. ; R4 = CODE TO STORE IN LASTCOM ; R5 = COMMAND TO MOVE TO MTC BACH3: 4$: MOV R4,LASTCOM ;REMEMBER LASTCOM .IF NE MMG$T MOV EXTADR,-(SP) .REPT 4 ASL @SP ;shift to where controller wants them .ENDR BIS (SP)+,R5 ;LOAD EXTENDED ADDRESS BITS .ENDC; NE MMG$T MOVB R5,@MTC ;GO! RETURN BACH2: 5$: MOV #FN+BKSPC,R4 ;THIS IS THE LASTCOM MOVB FUNTAB+5,R5 ;THIS IS THE COMMAND BR 4$ ; BACKUP DONE 6$: TSTB BACK1 ;ARE WE IN MIDDLE OF BACKING UP 5 BLOCKS ;BD0 BEQ 2$ ;YES BR FORE1 ;GO ISSUE READ .DSABL LSB .SBTTL DISPATCH SUBROUTINE ; THIS IS A DISPATCHING ROUTINE. FOR INPUT IT GETS AN INDEX IN R4 ; WHICH CORRESPONDS TO A BYTE IN A BYTE TABLE WHICH FOLLOWS THE CALLING ; JSR PC,DISPAT INSTRUCTION. IT ALSO GETS THE ADDRESS OF THAT TABLE ON ; THE STACK FROM THE JSR INSTRUCTION. ; THE ROUTINE ADDS THE TABLE ADDRESS TO THE INDEX TO GET AN ADDRESS IN R4 ; WHICH POINTS TO THE CORRECT TABLE ENTRY. NEXT A MOVB INSTRUCTION USES ; THIS ADDRESS TO FETCH A BYTE FROM A SECOND TABLE WHICH MAY DIRECTLY ; FOLLOW THE FIRST TABLE(THE SECOND TABLE IS OPTIONAL IN WHICH CASE ; R5 SHOULD BE IGNORED. IN ANY CASE R5 IS CHANGED). THE ROUTINE ; THEN FETCHES THE OFFSET BYTE INTO R4. NOW THE RETURN ADDRESS ON THE ; STACK IS ADDED TO THE VALUE IN R4 TO GET THE ADDRESS OF THE ROUTINE TO GO TO ; (INCIDENTALLY THE ADDITION POPS THE STACK). R4 NOW CONTAINS THE ADDRESS OF ; THE PROPER ROUTINE AND IT IS JUMPED TO. DISPAT: ADD @SP,R4 ;CALC ADDRESS OF OFFSET BYTE MOVB FUNTAB-TABLE(R4),R5 ;GET BYTE FROM SECOND TABLE MOVB @R4,R4 ;GET OFFSET BYTE ADD (SP)+,R4 ;CALC ADDRESS OF ROUTINE AND FIX STACK JMP @R4 ;GO THERE .SBTTL MAGTAPE DATA AREA ; RECOVERY BYTE - THIS BYTE IS USED TO INDICATE WHETHER OR NOT A MAGTAPE ; RECOVERY IS IN PROGRESS. IF THIS BYTE IS NEGATIVE THEN THERE IS NO RECOVERY ; IN PROGRESS. IF POSITIVE THEN IT CONTAINS A VALUE WHICH CORRESPONDS TO THE ; COMMAND BEING RECOVERED FROM. ; TAPELEN BYTE - THIS BYTE IS USED TO KEEP TRACK OF THE # OF INCHES OF ; CONSECUTIVE GAP WHICH HAS BEEN WRITTEN BY THE WRITE ERROR RECOVERY ROUTINE. ; THE DEC STANDARD SPECIFIES THAT A GAP OF GREATER THAN 300 INCHES IS ILLEGAL ; AND THE ERROR RECOVERY CODE WILL ISSUE A HARD ERROR IF IT INCREMENTS ; TAPELEN PAST 0. EACH INCREMENT REPRESENTS ONE 3 INCH GAP WRITTEN. ; BACK5 AND BACK1 BYTES - THESE ARE COUNTERS USED BY THE READ ERROR RECOVERY ; CODE. THERE ARE TWO TYPES OF READ ERROR RECOVERY. ONE IS SIMPLY TO ; BACKSPACE AND REREAD. WHENEVER THE ERROR RECOVERY ALGORITHM DOES THIS ; IT DECREMENTS BACK1. ANOTHER READ RECOVERY IS TO BACKSPACE 5 BLOCKS THEN ; FORWARD SPACE 4 AND REREAD. WHENEVER THE ERROR RECOVERY ALGORITHM DOES THIS ; IT DECREMENTS BACK5. ; LASTCOM CONTAINS A VALUE WHICH CORRESPONS TO THE LAST TAPE MOVEMENT COMMAND ; ISSUED TO THE TAPE UNIT CONTROLLER. THIS VALUE IS CALCULATED BY ADDING 8 TO ; THE CORRESPONDING SPFUN CODE. VALUES ARE: ; OPERATION CODE (IN LISTING) ; 7 WRITE A TAPE MARK FN+WRTEOF ; 6 FORWARD SPACE N BLOCKS FN+FWDSPC ; 5 BACKSPACE N BLOCKS FN+BKSPC ; 4 ERASE 3" OF TAPE AND WRITE FN+WRTXTD ; 3 REWIND THE TAPE FN+REWIND ; 2 GO OFFLINE AND REWIND THE TAPE FN+OFFLINE ; 1 WRITE A BLOCK FN+WRITEPHY ; 0 READ A BLOCK IN FORWARD DIRECTION FN+READF ; OLDBA WORD - THIS WORD CONTAINS THE BUFFER ADDRESS FOR THE LAST READ OR ; WRITE COMMAND. IT IS SAVED SO THAT THE ERROR RECOVERY CODE CAN REISSUE ; THE COMMAND WHICH IS BEING RECOVERED. IF THE HANDLER IS CONDITIONALIZED ; FOR EXTENDED MEMORY THEN OLDBA CONTAINS THE LOW 16 BITS OF A PHYSICAL ; ADDRESS. THIS WORD IS A GLOBAL WHICH CAN BE ACCESSED BY FSM. ; EXTADR WORD - THIS WORD IS ONLY IN A HANDLER CONDITIONALIZED FOR EXTENDED ; MEMORY. IT CONTAINS THE 2 HIGH ORDER BITS OF A PHYSICAL ADDRESS. ; THIS WORD IS A GLOBAL WHICH IS ACCESSED BY FSM. ; OLDWC WORD - THIS WORD CONTAINS THE WORD COUNT FOR THE LAST COMMAND. ; THIS IS USED BY THE ERROR RECOVERY CODE. ; ERRSUM WORD - AFTER ANY INTERRUPT THE TAPE CONTROLLER REGISTERS ARE ; EXAMINED FOR STATUS AND ERROR CONDITIONS TO DETERMINE WHICH OF THE ; FOLLOWING STATES THE MAGTAPE OPERATION IS IN. THIS RESULT IS SUMMARIZED ; IN THIS WORD. THE STATES ARE: ; VALUE ; HARD ERROR NOT SPECIFIED, OPERATION IS ABORTED ; RECOVERABLE ERROR NON ZERO ; NO ERROR ZERO ; NFSREAD WORD - THIS WORD IS IN SPECIAL CASE THE PROBLEM OF HOW TO ; REMEMBER THAT THE READ OEPRATION BEING DONE STARTED LIFE AS A .READ ON ; A CHANNEL OPENED WITH A NON FILE STRUCTURED .LOOPUP. WHEN THE EOT ; MARKER IS DETECTED AND THIS WORD IS NON ZERO THEN THE CONDITION IS IGNORED. ; .SYNCH REQUEST BLOCK [ONLY IN HANDLER CONDITIONALIZED FOR EXTENDED MEMORY] ; SYNBLK IS THE ADDRESS OF THE BLOCK. JOBNUM IS THE CURRENT JOB NUMBER FOR ; REQUEST BEING SERVICED. TEMP IS VARIABLE WHICH WILL BE USED TO ; LOAD R0 ON RETURN FROM THE .SYNCH. ; SINK WORD - THIS WORD IS SET TO INDICATE THAT THERE ARE ERRORS TO REPORT TO ; THE CALLING PROGRAM. WHEN ALL PROCESSING FOR THE CURRENT QUEUE ELEMENT IS ; DONE THIS WORD IS CHECKED FOR A NON ZERO VALUE. IF NOT FOUND THE HANDLER ; JUMPS TO THE I/O COMPLETE SUBROUTINE. IF SINK IS NON ZERO THEN THE HANDLER ; DOES A JSR TO THE I/O COMPLETE SUBROUTINE IN ORDER TO FREE UP THE QUEUE ; ELEMENT AND GET OUT OF INTEN LEVEL (SET WHEN INTERRUPT HANDLER WAS ENTERED). ; THEN THE HANDLER DOES A .SYNCH TO GET THE CONTEXT OF THE JOB WHICH WANTED ; THE INFORMATION REPORTED AND THEN USES THE INFORMATION STORED IN ERBSAV TO ; POINT INTO THE USERS AREA. THEN R0 (LOADED FROM TEMP IN .SYNCH BLOCK) ; AND ERRBC2 ARE STORED IN ERRBLK AND ERRBLK+2 RESPECTIVELY. ; DO NOT CHANGE THE ORDER OF THE FOLLOWING VARIABLES $TBL: .REPT MT$UN ;SD2 .BYTE -1 ;SD2 .ENDR ;SD2 .BYTE -2 ;SD2 $FLG: .BYTE 0 ;SD2 .EVEN RECOVE: .BYTE -1 TAPELE: .BYTE ERRGAPS BACK5: .BYTE 0 BACK1: .BYTE 0 LASTCO: .WORD 0 OLDBA: .WORD 0 .IF NE MMG$T EXTADR: .WORD 0 ; HIGH ORDER BITS FOR 18 BIT ADDRESS .ENDC; NE MMG$T OLDWC: .WORD 0 ERRSUM: .WORD 0 ; SUMMARIZE ERRORS HERE NFSREA: .WORD 0 ; THIS WORD IS SET TO -1 IF A ; NON FILESTRUCTURED READ WAS JUST DONE ; ELSE IT IS ZERO. IF SET THE EOT CONDITION ; WILL BE IGNORED. .EVEN .IF NE MMG$T ; .SYNCH REQUEST BLOCK SYNBLK: .WORD 0 ;RESERVED FOR SYSTEM USE JOBNM: .WORD 0 ;JOB NUMBER GOES HERE .WORD 0,0 ;UNUSED TEMP: .WORD 0 ;THIS WORD IS LOADED IN R0 AFTER SUCCESSFUL ;COMPLETION OF THE .SYNCH REQUEST .WORD -1,0 ;LEAVE THESE ALONE SINK: .WORD 0 ;IF ZERO, SYNCH WAS NOT DONE AND DON'T JSR ;TO COMPLETE. IF NON-ZERO, A SYNCH WAS DONE ; AND REGISTERS NEED TO BE RESTORED ;ON RETURN FROM COMPLETE. ERBSAV: .WORD 0 ;SAVE THE ADDRESS OF ERRBLK HERE ERRBL2: .WORD 0 ;THIS CONTAINS THE VALUE TO GO TO ERRBLK + 2 .ENDC ;NE MMG$T .IF NE MT$FSM MTCQ:: .WORD 0 ;FAKE AN MTCQE FOR FILE SUPPORT DRIVEN==MT$UN DVINFO::.REPT DRIVEN .WORD -1 ;D.CFSN - FILE SEQ NUMBER .WORD -1 ;D.CBLK - CURRENT BLOCK NUMBER .WORD -1 ;D.HBLK - HIGHEST BLOCK WRITTEN .BYTE 0 ;D.FTYPE - FILE TYPE, 0=LOOKUP,1=ENTER .BYTE 0 ;D.EOT - POSITIONED PAST EOT FLAG .WORD 0,0,0 ;D.FNAM - RAD50 FILENAME .ENDR .ENDC ;NE MT$FSM .IF EQ MT$FSM .DREND MT .IFF .GLOBL $FKPTR,$INPTR .IIF NE MMG$T, .GLOBL $RLPTR,$MPPTR,$GTBYT,$PTBYT,$PTWRD .IIF NE ERL$G, .GLOBL $ELPTR .IIF NE TIM$IT, .GLOBL $TIMIT .ENDC ;EQ MT$FSM SIZE=. SIZED=SIZE-MTSTRT/2 .SBTTL LOAD code ;+ ; LOAD/FETCH code ; ; Entry environment: ; ; R0 = Starting address of handler service routine ; R1 = Address of GETVEC routine (PRO only) ; R2 = $SLOT*2 value (length of $PNAME table in bytes) ; R3 = type of entry ; R4 = address of SY read routine (not used) ; R5 = $ENTRY entry address for this handler ;- .PSECT NONRES,I .ENABL LSB LOAD: .IF NE ; Allocate one UMR for MTX handler when built with FSM. MOV @#$SYPTR,R0 ; RMON base MOV $H2UB(R0),R3 ; R3 = UBVECT pointer MOV @R5,R1 ; Point to handler base MOV R1,-(SP) ; save it for later MOV #NUMRS,R0 ; this many UMRs needed ADD #,R1 ; point to FSM's HDR1 label area MOV R5,R4 ; $ENTRY entry address SUB R2,R4 ; $PNAME entry address CLR R2 ; high bits of FSM buffer CALL UB.ALL(R3) ; Allocate the UMR for FSM MOV (SP)+,R3 ; restore handler base in R3 BCS 10$ ; NO LOAD on failure from ALLUMR MOV R1,(R3) ; low 16 bits of UB adrs of HDR1LB MOV R2,(R3) ; high 2 bits of UB adrs of HDR1LB ADD #,R1 ; calculate effective UNIBUS address ADC R2 ; of LABLIO in FSM MOV R1,(R3) ; low 16 bits of UB adrs of LABLIO MOV R2,(R3) ; high 2 bits of UB adrs of LABLIO .ENDC; NE CLC ; Indicate successful LOAD 10$: RETURN .DSABL LSB .SBTTL UNLOAD code ;+ ; UNLOAD/RELEASE code ;- UNLOAD: .IF NE MOV R5,R1 ; Point to $ENTRY entry SUB R2,R1 ; Point to $PNAME entry MOV @#$SYPTR,R4 ; RMON base MOV $H2UB(R4),R5 ; Get H2UB vector entry CALL UB.RLS(R5) ; Release UMR .ENDC; NE CLR R0 ; Ensure clean UNLOAD RETURN .END