.TITLE MT ; ;COPYRIGHT 1973,1974 DIGITAL EQUIPMENT CORP., MAYNARD, MASS. ; ;VERSION V007A ; ;MAGTAPE DRIVER FOR RSX11C/B ;THIS DRIVER IS MODIFIED FROM THE DOS-11 VERSION ; ; .GLOBL MT .GLOBL STRG .GLOBL MTDDB .GLOBL SY.RTN .GLOBL S.CDQ .GLOBL SRTI .GLOBL SY.TO .GLOBL SY.SCB .GLOBL DV.A2 .GLOBL DV.STS .GLOBL SY.QLK .GLOBL S.CDB .GLOBL SY.DPR .GLOBL SY.DWN .GLOBL SY.DFL .GLOBL SY.LOC .IFNDF MT.DSC MT.DSC=1 .ENDC ; .CSECT R0=%0 ;DDB PTR R1=%1 ;LCMMD PTR R2=%2 ;CMMD REG R3=%3 ;SP FUNC BLOCK PTR R4=%4 ; R5=%5 ;SCRATCH SP=%6 PC=%7 ; ; ; MTS=172520 ;TM11 STATUS MTC=172522 ;TM11 COMMAND MTBRC=172524 ;TM11 BYTE/RECORD COUNTER MTCMA=172526 ;TM11 CORE MEMORY ADDRESS MTD=172530 ;TM11 DATA BUFFER MTRD=172532 ;TM11 READ LINES ; PS=177776 ;PROCESSOR STATUS ; ; ;MTS BITS ; ILC=100000 EOF=40000 CRE=20000 PAE=10000 BGL=4000 EOT=2000 RLE=1000 BTE=400 NXM=200 SELR=100 BOT=40 CH79=20 SDWN=10 WRL=4 RWS=2 TUR=1 DENB=140 PARB=10 ; ;MTC BITS ; ERR=100000 DEN=60000 POWR=10000 PAR=4000 UNIT=3400 CUR=200 INT=100 ADEX=60 CMMD=16 GOB=1 ; ;MTRD BIT ; GAPSDN=10000 ; ;COMMANDS ; RWU=0 READ=1 WRITE=2 EOFM=3 RWD=4 SKPR=5 BSPR=6 ; ; ; ;THIS IS THE DEVICE DRIVER FOR THE TM11/TU10 ; MT: .WORD 0 ;BUSY INDICATOR .WORD 121177 ;FACILITIES WORD .BYTE 20 ;BUFFER SIZE = 512 BYTES .BYTE INTJ-MT ;INTERRUPT HANDLER LEVEL: .BYTE 240+MT.DSC-1 ;PRIORITY FOR INTERRUPT SERVICE .BYTE 0 ;NO OPEN ENTRY .BYTE TRANZ-MT ;TRANSFER ENTRY .BYTE CLOSJ-MT ;CLOSE ENTRY .BYTE SPECJ-MT ;SPECIAL FUNCTION ENTRY .BYTE MT.TB-MT ;MISCELLANEOUS TABLE ENTRY MT.NAM: .RAD50 /MT / ; OPNFLG: .BYTE 0,0,0,0,0,0,0,0 ;SET BY OPEN ROUTINE,CLEARED BY CLOSE LCMMD: .BYTE -1,-1,-1,-1,-1,-1,-1,-1 ;1 BYTE FOR EACH DEVICE .BYTE 0,0,0,0,0,0,0,0 ;DEN/PAR FOR EACH DEVICE OFFSET=GTABLE-LCMMD GTABLE: .BYTE 0,0,0,0,0,0,0,0 ;UNIT REWIND GOVERNING INTRET: .WORD 0 ;ADDR FOR RET FROM INT HANDLER TCMMD: .BYTE 0 ;LAST CMMD SAVE LOCN FOR ERR RECOVERY ERRSW: .BYTE 0 ;SET BY ERR RECOVERY IF NOT RECOVERED RETRY: .WORD 0 ;RETRY COUNT FOR ERROR RECOVERY TRYCNT: .WORD -15. ;INITIAL RETRY COUNT LASTAT: .WORD 0 ;ADDR IN LCMMD VECTOR FOR INT HANDLER CMA: .WORD 0 BRC: .WORD 0 INTENB: .BYTE 0 ; .EVEN ;MISCELLANEOUS TABLE ENTRY MT.TB: 0 ;POWER FAILURE MT.TO ;TIME OUT MT.CO ;CONTINUE MT.CA ;CANCEL ; TRANZ: JMP TRANS ;INTERMEDIATE TRANS ENTRY ; ;CONTINUE ENTRY MT.CO: MOVB SY.QLK-1(R0),R1 ;SET ENTRY TO PROLOGUE TABLE JMP S.CDB ;GO QUEUE THE REQUEST ; ;TIMEOUT ENTRY MT.TO: CLR SY.TO(R0) ;DISABLE TIMEOUT COUNT MOVB LEVEL,PS ;SET STATUS TO DRIVER LEVEL BIS #10000,12(R0) ;SET UNRECOVERABLE ERROR MOV MTBRC,16(R0) ;STORE UNTRANSFERRED BYTE COUNT ASR 16(R0) ;CONVERT BYTES TO WORDS JMP SIMCOM ;TAKE COMPLETION EXIT ; ;CANCEL ENTRY MT.CA: BITB #SY.DWN,SY.DFL(R0) ;IS DOWN BIT SET? BEQ MT.CAX ;BRANCH IF NOT BICB #SY.LOC+42,SY.DFL(R0) ;CLEAR LOCK AND DOWN MT.CAX: RTS PC ;EXIT ; INIT: MOV (SP)+,INITX+2 ;SAVE CALLER ADDR MOV 12(R0),R1 ;GET UNIT NUMBER BIC #174377,R1 ;CLR EXTRA BITS MOV @#MTC,-(SP) BIC #174377,(SP) CMP R1,(SP)+ BEQ INIT1 BIT @#MTS,#SELR ;LAST DRIVE OFF LINE? BEQ INIT1 ;IF SO DON'T TEST READY INIT0: BIT #TUR,@#MTS BEQ INIT0 INIT1: MOV R1,@#MTC SWAB R1 ADD PC,R1 ADD #LCMMD-.,R1 ;ADDR IN LAST CMMD VECTOR MOV R1,LASTAT ;SAVE FOR INT HANDLER JSR PC,READY ;CHECK IF UNIT READY TSTB (R1) ;CHECK IF DEVICE INITIALIZED BPL INITX ;BRANCH IF IS MOVB #DENB,10(R1) ;SET DEFAULT DEN=800,PAR=ODD CLRB (R1) ;CLEAR NON INIT STATE INITX: MOV (PC),PC ;RETURN TO CALLER .WORD 0 ;ADDR OF CALLER ; INTJ: JMP INTH SPECJ: JMP SPEC CLOSJ: JMP CLOSE ; ; ; ; ; GO: MOV (SP)+,INTRET ;SAVE INT RETURN ADDR GOA: MOV CMA,@#MTCMA MOV BRC,@#MTBRC CMPB (R1),#WRITE ;CHECK IF THIS IS A WRITE BNE GO2 ;BRANCH IF NOT GO1: BIT #WRL,@#MTS ;CHECK IF WRITE LOCK ON BEQ GO2 ;BRANCH IF NOT BR READY1 ;ISSUE ACTION MESSAGE AND EXIT ; TO DE-QUEUER BR GO1 ;GO TEST IF LOCK STILL ON GO2: JSR PC,READY ;CHECK IF DEVICE READY BISB 10(R1),@#MTC+1 ;SET DEN AND PAR MOVB R2,@#MTC ;ISSUE INSTRUCTION GO3: MOV #-200,SY.TO(R0) ;SET TIMEOUT CONTROL BIS #INT!GOB,@#MTC RTS PC ;RETURN TO SCHEDULER (SRTI) ; ; ;OUTPUT A002 MESSAGE READY1: MOVB SY.RTN(R0),SY.SCB+1(R0) ;MOVE TASK # FOR DV.A2 JSR R5,DV.A2 ;SET UP A002 MESSAGE NOP ;EXIT TO DE-QUEUER WHETHER... JMP S.CDQ ;...BACKGROUND OR NOT ; READY: ;JSR PC,READY MOV (SP)+,READYX+2 ;SAVE CALLER ADDR BIT #SELR,@#MTS ;TEST IF DEVICE READY BEQ READY1 ;BRANCH IF NOT BIT #GAPSDN,@#MTRD BNE READYX BIT #TUR!RWS!SDWN,@#MTS BEQ READY1 READYX: MOV (PC),PC ;RETURN TO CALLER .WORD 0 ;ADDR OF CALLER ; ; ; TRANS: JSR PC,INIT ;INIT CHECK DEVICE MOV 6(R0),CMA ;SET BUFF ADDR MOV 10(R0),BRC ;SET WORD COUNT ASL BRC ;CVT TO BYTE COUNT MOV 12(R0),R2 BIC #177773,R2 ;CLR ALL BUT READ AND ADDR EXT BITS BIT #4,R2 ;CHECK INPUT/OUTPUT BEQ TRANO ;BRANCH IF OUTPUT MOVB #READ,(R1) ;SET LAST CMMDSREAD SUB #2,R2 ;SET UP READ CMMD BR TRAN2 TRANO: BIT #EOT,@#MTS ;CHECK IF AT EOT BEQ TRAN1 ;BRANCH IF NOT MOV 10(R0),16(R0) ;RETURN WORD COUNT TRAN7: BR SIMCOM ;REJECT CMMD - EXIT TRAN1: MOVB #WRITE,(R1) ;SET LAST CMMD S WRITE ADD #4,R2 ;SET UP WRITE CMMD TRAN2: JSR PC,GO ;GO INITIATE I/O MOV @#MTBRC,R2 CMPB (R1),#READ ;COME HERE AFTER INT ERR CHK BNE TRAN6 ;BRANCH IF NOT READ BIT #EOF,@#MTS ;IF EOF, SET INIT CNT IN RESIDUE BEQ TRAN6 MOV BRC,R2 TRAN6: ASR R2 ;CHECK IF ODD BYTES SHORT REC BCC TRAN3 ;BRANCH IF NOT MOV @#MTCMA,R5 ;PUT NULL IN NEXT BUFF POS CLRB (R5) INC R2 ;ROUND UP WORD COUNT TRAN3: BEQ .+6 ;BRANCH IF NO RESIDUE BIS #100000,R2 ;INSURE NEG WORD COUNT BIT #RLE,@#MTS ;CHECK IF LENGTH ERROR BEQ TRAN4 ;BRANCH IF NOT INCB ERRSW TRAN4: MOV R2,16(R0) ;RETURN RESIDUE WORD COUNT TRANX: TSTB ERRSW ;BRANCH IF NO ERRORS BEQ TRAN5 BIS #100000,12(R0) ;SET ERR BIT TRAN5: BR TRAN7 ;TAKE DONE EXIT ; SIMCOM: CLRB ERRSW ;CLEAR ERROR SWITCH MTEXIT: CLRB INTENB JMP @14(R0) ;COMPLETION EXIT ; ; SPEC: JSR PC,INIT ;INIT CHECK DEVICE MOV 2(R0),R3 ;GET FUNC BLOCK ADDR MOVB (R3),R5 ;GET FUNC BYTE SUB #SPFST,R5 BMI TRAN5 ;BRANCH OUT IF NOT CMP #SPLST,R5 ;SUPPORTED FUNCTION BLO TRAN5 CMPB #3,1(R3) ;CHECK IF VALID FUNC BLOCK BHI ABORT ;ABORT IF NOT TST R5 ;CHECK IF OFF-LINE COMMAND BEQ SPEC2 ;IF EQ, BRANCH TO SET UP OFF-LINE SEQUENCE CMP R5,#5 ;IF THE FUNCTION CODE IS > 5 ... BLO SPEC1 SPEC2: JSR R5,DV.STS ;... FAKE AN INTERRUPT TO THE SYSTEM MOV 16(SP),R5 ;GET FUNCTION CODE BACK FROM STACK CLR -(SP) ;SET STACK FOR RE-ENTRY TO "SPC" HANDLER MOVB LEVEL,PS ;RESTORE DRIVER PRIOITY SPEC1: ASL R5 ADD PC,R5 ADD #SPECT-.,R5 JMP @R5 ;GO TO PROPER SP FUNC ROUTINE ; ; SPFST=1 SPLST=7 ; SPECT: BR OFFLIN BR WEOF BR RWND BR SKP BR BSP BR PARDEN BR TUSTAT BR TRAN5 ;8 UNIMPLEMENTED (RESERVED) ; ; ABORT: ;INVALID SPECIAL FUNCTION BLOCK MOV R3,-(SP) ;ADDR OF SPECIAL FUNCTION BLOCK MOV #1433,-(SP) ;F033 MOVB SY.RTN(R0),-(SP);TASK SLOT # IOT ;OUTPUT ERROR MESSAGE BIS #10000,12(R0) ;SET UNRECOVERABLE ERROR BIT BR SIMCOM ;TAKE COMPLETION EXIT ; ; OFFLIN: JSR PC,EOFCK ;WRITE EOF IF NECESSARY CLRB (R1) ;SET LAST COMMAND = OFF-LINE MOVB #1,@#MTC ;SET DRIVE TO OFF-LINE BR TUSTAT ;GET STAT AND EXIT RWND: JSR PC,EOFCK ;ISSUE WRITE EOF IF NECESSARY JSR PC,RWNDC ;ISSUE DISABLED RWD BR TUSTAT ;GET STATUS AND EXIT RWNDC: MOVB #RWD,(R1) ;SET LAST CMMD=RWD TSTB OFFSET(R1) ;REWINDS SUPPRESSED? BNE RWNDX ;YES MOV #16,R2 ;ISSUE RWD JMP GO RWNDX: RTS PC ; EOFCK: CMPB (R1),#WRITE ;IF LAST CMMD WAS WRITE BEQ EOFCK1 ;BRANCH RTS PC ;ELSE RETURN EOFCK1: MOV #6,R2 ;SET CMMD=WRITE EOF MOV (SP)+,INTRET ;SET INT RET ADDR JMP GO1 ;GO EXECUTE ; WEOF: MOVB #EOFM,(R1) ;SET LAST CMMD JSR PC,EOFCK1 ;GO EXECUTE WRITE EOF BR TUSTAT ;AT INT RET, GET STAT AND EXIT ; ; PARDEN: BIT #CH79,@#MTS ;IF 9 TRACK TAPE BEQ TUSTAT ;BRANCH (IGNORE NEW SETTINGS) MOV 4(R3),R5 ;GET NEW DEN/PAR BIC #176376,R5 ;CLR EXTRA BITS ASRB R5 ;SET INTO PROPER POSITION RORB R5 RORB R5 ROR R5 ROR R5 ROR R5 MOVB R5,10(R1) ;SET NEW DEN/PAR BR TUSTAT ; SKP: MOVB #SKPR,(R1) ;SET LAST CMMD=SKP MOV #8.,R2 ;SET CMMD BR SKPBSP ;GO SET COUNT AND EXEC BSP: MOVB #BSPR,(R1) ;SET LAST CMMD=BSP MOV #10.,R2 ;SET CMMD BIT #BOT!RWS,@#MTS ;TEST IF AT BOT BEQ SKPBSP ;BRANCH IF NOT MOV 4(R3),6(R3) ;REJECT CMMD RETURN REC COUNT BR TUSTAT ;SET STATUS AND EXIT SKPBSP: MOV 4(R3),BRC ;SET RECORD COUNT NEG BRC JSR PC,GO ;GO EXECUTE CMMD MOV @#MTBRC,6(R3) ;SET RESIDUE REC COUNT NEG 6(R3) ; TUSTAT: MOVB 10(R1),R2 ;GET DEN/PAR MOVB (R1),R1 ;GET LAST CMMD SWAB R2 BIS R2,R1 ;SET DEN AND PAR MOV @#MTS,R2 BIT #CRE!PAE!RLE,R2 ;TEST STATUS FOR ERROR BEQ STAT1 ;BRANCH IF NONE BIS #100000,R1 ;SET ERR BIT STAT1: BIT #EOT,R2 ;TEST IF EOT BEQ STAT2 ;BRANCH IF NOT BIS #1000,R1 ;SET EOT BIT STAT2: BIT #BOT,R2 ;TEST IF AT BOT BEQ STAT3 ;BRANCH IF NOT BIS #400,R1 ;SET BOT BIT STAT3: BIT #EOF,R2 ;TEST IF EOF BEQ STAT4 ;BRANCH IF NOT BIS #200,R1 ;SET EOF BIT STAT4: BIC #177753,R2 ;CLEAR ALL BUT WRL AND 79CH BITS SWAB R2 BIS R2,R1 ;SET WRL AND 7,9 TRACK MOV R1,2(R3) ;RETURN STATUS BR COMJ ;EXIT ; ; ; CLOSE: JSR PC,INIT ;INIT CHECK ON DEVICE CLRB -10(R1) ;CLEAR OPEN FLAG JSR PC,EOFCK ;IF LAST CMMD WAS WRITE, WRITE 3 EOFS JSR PC,EOFCK JSR PC,EOFCK TSTB OFFSET(R1) ;REWINDS SUPPRESSED? BEQ CLOSE3 ;NO ; ; ISSUE 2 BSPS INSTEAD OF RWD IF OUTPUT ; OR SKIP TO END OF FILE IF INPUT ; CMPB (R1),#WRITE ;IF LAST CMMD WAS WRITE BNE CLOSE1 MOV #10.,R2 ;ISSUE 2 BSPS MOV #-1,BRC MOVB #BSPR,(R1) ;THIS IS SOLELY FOR INT ERR CHK JSR PC,GO MOV #10.,R2 BR CLOSE2 ; CLOSE1: BIT #EOF,@#MTS ;SKIP TO EOF UNLESS ALREADY THERE BNE CLOSE3 MOV #8.,R2 CLR BRC MOVB #SKPR,(R1) CLOSE2: JSR PC,GO CLOSE3: JSR PC,RWNDC ;ISSUE DISABLED RWD COMJ: JMP SIMCOM ; ; ; ; ;INTERRUPTS ARRIVE HERE INTH: BIC #100,@#MTC ;DISABLE DEVICE INTERRUPTS JSR R5,STRG ;STORE REGISTERS MOV #SRTI,-(SP) ;GET RETURN ADDR MOV MT,R0 ;GET DDB ADDR CLR SY.TO(R0) ;CLEAR TIMEOUT FUNCTION MOVB LEVEL,PS ;SET STATUS TO DRIVER LEVEL ; MOV LASTAT,R1 ;GET LCMMD VECTOR ADDR MOV 2(R0),R3 ;GET SP FNC BLOCK ADDR MOV #MTC,R5 ;ADDR OF CMMD REG MOV @#MTS,R2 ;GET STATUS OF DEVICE INCB INTENB ;SET INT FLAG BIT #ILC!NXM,R2 ;CHECK ILLEGAL CMMD, NONEXIST CORE BEQ INT1 ;BRANCH IF NOT ;UNRECOVERABLE ERROR DETECTED SERVICING INTERRUPT INTF: MOV R2,-(SP) ;OUTPUT MAG TAPE STATUS MOV #1432,-(SP) ;F032 MOVB SY.RTN(R0),-(SP) ;TASK SLOT # IOT BIS #10000,12(R0) ;SET UNRECOVERABLE ERROR MOV MTBRC,16(R0) ;STORE UNTRANSFERRED BYTE COUNT ASR 16(R0) ;CONVERT BYTES TO WORDS JMP SIMCOM ;TAKE COMPLETION EXIT ; INT1: TSTB TCMMD ;CHECK IF THIS WAS A RETRY BEQ INT3 ;BRANCH IF NOT BMI INT2 ;BRANCH IF WAS NOT BSP OR RETRY CLR R2 BISB TCMMD,R2 ;GET CMMD NEGB TCMMD ;SET-NOT BSP JMP GOA ;GO TRY AGAIN ; INT2: BIT #BGL!BTE!CRE!PAE,R2 ;TEST IF ERROR THIS TIME BEQ INT7 ;BRANCH IF NOT INC RETRY BNE INT6 ;BRANCH IF TO TRY AGAIN BIT #BGL,R2 ;IF ERR=BUS GRANT LATE BNE INTF ;IS FATAL INCB ERRSW ;SET ERROR FLAG BIT #4,(R5) ;IF WRITE OR WEOF, ISSUE ACTION DIAG BEQ INT7 ;WRITE OR WEOF UNSUCCESSFUL AFTER 15 ATTEMPTS MOV R2,-(SP) ;MAG TAPE STATUS MOV #412,-(SP) ;A012 MESSAGE MOVB SY.RTN(R0),-(SP);TASK SLOT # IOT JMP S.CDQ ;EXIT TO DE-QUEUER ; INT3: BIT #BGL!BTE!PAE!CRE,R2;CHECK IF ERROR BEQ INT7 ;BRANCH IF NOT CMPB #SKPR,(R1) ;BRANCH IF SKIP OR BSP BEQ INT4 CMPB #BSPR,(R1) BEQ INT4 MOV TRYCNT,RETRY ;SET RETRY COUNT BIT #12,(R5) ;IF CMMD IS WRITE BNE INT6 BIS #10,(R5) ;TRY WRITE WITH LONG GAP INT6: MOVB (R5),TCMMD ;SAVE CMMD MOVB #10.,R2 ;SET UP BSP MOV #-1,@#MTBRC ;COUNT OF 1 JMP GO2 ;GO EXECUTE ; INT4: BIT #EOF!BOT,R2 ;IF EOF OR BOT BNE INT7 ;SKIP OR BSP IS DONE TST @#MTBRC ;IF COUNT EXHAUSTED BEQ INT7 ;IS DONE MOVB (R5),R2 ;ELSE SET UP CMMD JMP GO2 ;CONTINUE SKIP OR BSP ; INT7: CLRB TCMMD ;CLEAR RETRY INDICATORS CLRB RETRY MOV INTRET,PC ;GO TO SPECIFIC ROUTINE ; ; MTUNIT=0 ;UNIT # MTSPN=60 ;SUSPEND # MTDDB=.+14 .REPT MT.DSC ;BEGINNING OF DDB 0,0 ;QUEUE OF ACTIVE DDB'S 0 ;MONITOR DDB CHAIN LINK 0,0 ;LEVEL COUNTS MT ;DRIVER ADDR 0 ;MTDDB 0 ;ADDR OF TRAN OF SPEC BLOCK 0 ;BLOCK # (0 ALWAYS FOR MT) 0 ;CORE ADDR OF TRAN 0 ;# WORDS .BYTE 0 ;FUNCTION .BYTE MTUNIT ;UNIT # 0 ;COMPLETION RETURN 0 ;UNTRANSFERRED WORD COUNT 0,0,0,0 .BYTE 0 .BYTE MTSPN ;SUSPEND # 0,0,0,0,0 .BYTE 0 ;TASK # .BYTE SY.DPR ;PERMANENT DDB 0,0 .BYTE 0 ;TIMEOUT COUNT .BYTE 0 ; MTUNIT=MTUNIT+1 MTSPN=MTSPN+1 .ENDR .END