.MCALL .MODULE .MODULE PIPMT,VERSION=12,COMMENT=,IDENT=NO ; 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 Edit History ;+ ; ; Edit History: ; ; CG04 Correct bootable magtape problem PIPMT EL10 PIP X07.00D ; ; 001 22-Jan-80 22:36 Guldenschuh, Chuck cpg [240,148] ; Correct 'file not found' with non-wildcard spec ; (001) ; 002 01-Feb-80 13:36 Parent, Les (75450) [240,95] ; Fix MT file-not-found fix !!! ; (002) ; 003 19-Feb-80 11:22 Fingerhut, David [240,134] ; QAR B177: PIP could not handle factoring from MT:. ; (003) ; 004 16-Jun-81 02:38 PM David Fingerhut [240,134] ; Convert date to RT format when input file is from MT ; (004) ; 005 30-Jun-81 10:48 AM David Fingerhut [240,134] ; copy in physical order when input from MT. ; (005) ; 006 9-Apr-87 Deb Sengupta ; Modified the bit pattern to test for tape_mark in routine ; "BSTM4" to account for TK70s, which does NOT return a tape_mark ; on hitting BOT (Action Item #6165). ; (006) ; 007 30-May-89 Rob Hamilton ; Change error message on magtape rewind failure from "Device ; in use" to "Directory read error." ; ; 010 02-Nov-1990 JFW ; bracket error messages in ;+/;ERROR/.../;- ; ; (011) 01-Aug-91 MBG Extended error checking for magtape operations. ; Added use of some system definitions from SYSTEM. ; Corrected earlier change for TK70 support, code ; should not have been doing bit tests, the errors ; returned have discrete codes. ; ; 012 13-Oct-1996 Tim Shoppa ; Check for HDR1 dates from 2000-2099, signaled by a '0' before ; the YYDDD field. Set epoch bits in resulting date. ; ;- .ENABL GBL,LC .SBTTL PSECT definitions ;+ ; The PSECT's are defined here to give them the desired ordering. ; Consider the ordering critical. Several of the PSECT's contain ; stoppers for lists in the previous PSECT. ;- PSECT IMPURE ;Impure data PSECT PIPMTR ;Routines to be pulled to the root PSECT PIPMT ;Main code psect PSECT PATCH ;Patch psect .BLKW 32. ;Root patch space .SBTTL System Definitions .LIBRARY "SRC:SYSTEM.MLB" .MCALL .ERMDF ;Magtape error conditions .ERMDF .MCALL .SFMDF ;Magtape special functions .SFMDF .SBTTL Local Data MT.DAY = 44. ;Offset to file creation date (Julian) MT.YER = 42. ;Offset to file creation year .PSECT IMPURE,D MONTAB: .WORD 31. ;JAN FEB: .WORD 28. ;FEB .WORD 31. ;MAR .WORD 30. ;APR .WORD 31. ;MAY .WORD 30. ;JUN .WORD 31. ;JUL .WORD 31. ;AUG .WORD 30. ;SEP .WORD 31. ;OCT .WORD 30. ;NOV .WORD 31. ;DEC .SBTTL NEXTMT - Get the next magtape directory entry ;+ ; NEXTMT ; This routine returns the filename of the next file on a magtape in a format ; similar to a disk directory entry. ; ; $NXTSG <> 0 => Do initial positioning. ; $DIRCH = channel number to read the directory on ; $DIRBF -> buffer to read directory into. 512. words. ; ; CALL NEXTMT ; ; C-bit = 0 => no error ; R0 <> 0 => R0 -> directory entry ; ; R0 = 0 => no more entries in directory ; ; C-bit = 1 => error ; R0 = error code ; ; Errors: ; DIE ; ILD ;- ORIGIN PIPMT .ENABL LSB NEXTMT:: TST OVRLOD ;Are we being loaded? BNE 10$ ;Branch if not INC OVRLOD ;Bump flag to indicate real entry next time RETURN ;Go home 10$: JSR R5,$SAVRG ;Save R3 - R5 MOV @R3,DEFEXT ;Set up device name MOV $DIRCH,R1 ;R1 = input channel number MOV $DIRBF,R3 ;R3 -> directory buffer TST $NXTSG ;Have we been entered before? BEQ 90$ ;Branch if so CLR $NXTSG ;Don't do this again JSR R5,MTNFS ;Do .LOOKUP non-file-structured with ; sequence number .WORD DEFEXT ;Dblk for .LOOKUP BCS 140$ ;Branch on error TST IFILNO ;File sequence number positive? BLT 70$ ;Branch if < 0 BEQ 40$ ;Branch if = 0 MOV #4,R2 ;Set up backspace count 20$: JSR R5,SPFUNM ;Do a backspace until count expires .BYTE 377,SF.MBS ; Backspace code BCC 30$ ;SHOULDN'T HAPPEN CMP MTERR,#EM.BOT ;Quit if we hit BOT BEQ 50$ ;Branch if we hit it 30$: SOB R2,20$ ;Loop CALL MTFS1 ;Space forward over tape mark BR 120$ ; 40$: JSR R5,SPFUN0 ;Rewind the magtape .BYTE 377,SF.MRE ; Rewind code BCC 50$ ;Branch if no error TSTB @#S$EERB ;What kind of error BEQ 140$ ;Branch if bad directory??? MOV #DEFEXT,R5 ;R5 -> filename block CLR 2(R5) ;Clear filename ;+ ;ERROR .ERR #ERAREA,#DIE,LEVEL=FATAL,RETURN=NO,FILE=R5 ; <-F-Directory input error DEV:> ;- ; ; At this point we're supposed to be at BOT ; 50$: CALL MTFS1 ;Space forward over VOL1 label 60$: CALL READMT ;Read a block from the magtape CMP #240,@R3 ;Is it a boot block? BEQ 60$ ;Branch if so. ;CG04 JSR R5,SPFUN1 ;Else it may be HDR1. Back up. .BYTE 377,SF.MBS ; Backspace code BR 130$ ;Go read label 70$: JSR R5,SPFUNM ;Backspace to tape mark .BYTE 377,SF.MBS ; Backspace code BCC 80$ ;Branch if no error CMP MTERR,#EM.BOT ;Did we hit BOT? BEQ 50$ ;Branch if so. 80$: CALL MTFSM ;Space forward past tape mark CALL READMT ;Read in buffer load (hopefully EOF1 or HDR1) CMP @R3,#EOF1 ;Is it an EOF label? BEQ 110$ ;Branch if so JSR R5,SPFUNM ;Else backspace again .BYTE 377,SF.MBS ; Backspace code BR 70$ ;and try again 90$: BR 110$ ;always get more files ;;; BIT #FLG.WD,@SAVSTS ;Was the spec wildcarded? ;;; BNE 110$ ;Branch if so ;;; TST MATFLG ;Did we find anything last time thru? ;;; BEQ 100$ ;Branch if not. We'll keep on truckin' ;;; JMP MTDONE ;Else quit. We found the file. 100$: CALL MTFSM ;Space forward to EOF1 110$: CALL MTFSM ;Space forward to HDR1 120$: CALL READMT ;Read a block (SHOULD be HDR1) 130$: CMP @R3,#EOF1 ;EOF label? BEQ 110$ ;Branch if so. Try again CMP @R3,#HDR1 ;HDR1 label? BEQ 150$ ;Branch if so. TSTB @R3 ;Is it a 0 byte? ;preV3 BEQ 100$ ;Branch if so. Deleted file ;preV3 CMPB @R3,#RUBOUT ;How about rubout? ;preV3 BEQ 100$ ;Yep. That's one also. ;preV3 ;+ ;ERROR 140$: MOV #ILD,R0 ;Set the error code ; <-F-Illegal directory DEV:> ;- SEC ;Flag the error BR 160$ ; 150$: CALL MTFSM ;Skip the next tapemark CALL CVTMT ;Convert the label to a proper (disk) entry CLR $EXTBY ;No extra bytes 160$: RETURN .DSABL LSB .SBTTL Magtape Support Routines .SBTTL Overlay Support Routines .SBTTL MTFSM - Space forward to tape mark .ENABL LSB MTFSM:: JSR R5,SPFUNM ;Space forward to tape mark .BYTE 377,SF.MFS ; Space forward code BR 10$ MTFS1:: JSR R5,SPFUN1 ;Space forward record .BYTE 377,SF.MFS ; Space forward code 10$: BCC 50$ ;Branch if no error TSTB @#S$EERB ;EOF (tape mark) encountered? BEQ 30$ ;Branch if so ;+ ;ERROR 20$: MOV #DIE,R0 ;Set the error code ; <-F-Directory input error DEV:> ;- TST (SP)+ ;Clean of return address SEC ;Set C-bit BR 50$ ; .SBTTL READMT - Read a Block From Magtape READMT:: .SPFUN #IOAREA,R1,#SF.MRD,R3,#256.,#MTERR,#0 BCC 50$ ;Branch if no error TSTB @#S$EERB ;What kind of error BEQ 40$ ;Branch if EOF CMP MTERR,#EM.BIG ;Short or long read? BGE 50$ ;Branch if so BR 20$ ;Else input error 30$: DEC MTERR ;Only tape mark (not physical EOT) BEQ 50$ ;Branch if so 40$: TST (SP)+ ;Clean the stack MTDONE: CLR R0 ;Flag no more entries 50$: RETURN .DSABL LSB .SBTTL CVTMT - Convert a Magtape Label to a Disk Directory Entry ;+ ; CVTMT ; This routine turns the magtape label into a pseudo-directory entry. ; ; R3 -> HDR1 label ; ; CALL CVTMT ; ; R0 -> entry ; R1, R2, and CMDBF1 modified ;- CVTMT:: JSR R5,$SAVRG ;Save R3 - R5 MOV R3,R5 ;R5 -> label ADD #512.,R5 ;Point to second half of directory buffer MOV R3,R0 ;R0 -> HDR1 label ADD #MT.FID,R0 ;R0 -> file ID MOV #CMDBF1,R1 ;R1 -> temp area for ASCII to RAD50 convert MOV R1,R4 ;Save it MOV #11,R2 ;Number of characters in the filename 10$: MOVB #BLANK,(R1)+ ;Blank fill it SOB R2,10$ ; MOV #6,R2 ;Number of characters in name MOV R4,R1 ;Point to temp area again 20$: CMPB @R0,#'. ;Hit the dot? BEQ 30$ ;Branch if so MOVB (R0)+,(R1)+ ;Put in the character SOB R2,20$ ; 30$: MOV R4,R1 ;Point to the start ADD #6,R1 ;Point to the filetype MOV #3,R2 ;Length of filetype CMPB @R0,#'. ;Pointing to the "."? BNE 40$ ;Branch if not TSTB (R0)+ ;Else skip it 40$: CMPB @R0,#'. ;Hit a "."? BEQ 50$ ;Branch if so MOVB (R0)+,(R1)+ ;Store the character SOB R2,40$ ; 50$: MOV R5,R2 ;R2 -> directory entry MOV R4,R1 ;R1 -> ASCII filename MOV #3,R3 ;Convert 3 words MOV #DS.PRM,(R2)+ ;Make the file permanent 60$: CALL $ASCR5 ;Convert ASCII to RAD50 MOV R0,(R2)+ ;Store a word SOB R3,60$ ; MOV R5,R0 ;R0 -> entry MOV #-1,DE.LEN(R0) ;The length is large SUB #512.,R5 ;R5 -> HDR1 label CALL MTDATE ;Convert date to RT format ; MOV DATE,DE.DAT(R0) ;Set the date CLR $STBLK ;Starts at block 0 RETURN .SBTTL MTDATE- Convert a magtape date to RT-11 format ;+ ; MTDATE ; ; This routine converts the date on a magtape label to RT-11 ; format. The magtape date is of the form: ; yyddd ; where 'yy' is the year mod 100, and ddd is the Julian date ; ; R5 -> Magtape header label (HDR1) ; R0 -> RT-11 directory entry ; ; JSR PC,MTDATE ; ; MTDATE fills in DE.DAT(R0) with the date in RT format ;- MTDATE:: JSR PC,$SAVAL ;Save all registers MOV R5,R1 ;R1 -> Magtape header label MOV R5,R2 ;R2 -> Magtape header label MOV R0,R5 ;R5 -> RT directory entry ADD #MT.DAY,R1 ;Point to day of creation CLRB 3(R1) ;Mark the end of the field CALL GETNUM ;Convert the number to binary ; (returned in R3) MOV R2,R0 ;Point to label ADD #MT.YER,R0 ;Point to year of creation CALL GETNM ;Go convert it to binary CMPB (R2),#'0 ;is it a 20xx year? ;012 BNE 4$ ;Branch if no ;012 ADD #100.,R0 ;Else add another 100. ;012 4$: TST R0 ;Got a date? BEQ 10$ ;Branch if no SUB #72.,R0 ;Else put it in RT-11 format 10$: MOV #28.,FEB ;Default is 28 days in FEB BIT #3,R0 ;Is it a leap year? BNE 20$ ;Branch if not INC FEB ;Bump number of days in FEB 20$: MOV #MONTAB,R1 ;Point to the month table 30$: CMP @R1,R3 ;Will it fit? BGE 40$ ;Branch if not. We've found the month SUB (R1)+,R3 ;Subtract this month's days, bump pointer BR 30$ ;Try again 40$: SUB #MONTAB,R1 ;R1 now = Month *2 +2 TST (R1)+ ;Month *2 TST R3 ;Is there a day? BNE 50$ ;Branch if so CLR R1 ;Else clear the month 50$: ASL R1 ;Make room for the day ASL R1 ; ... ASL R1 ; ... ASL R1 ; ... ADD R3,R1 ;Add in the day ASL R1 ;Now make room for the year ASL R1 ; ... ASL R1 ; ... ASL R1 ; ... ASL R1 ; ... MOV R0,R3 ;Now we put the age bits into R3 ;012 ASL R3 ;Put them in the right place ;012 SWAB R3 ; ;012 BIC #^c<140000>,R3 ;clear all but age bits in R3 ;012 BIC #^c<000037>,R0 ;clear all but year bits in R0 ;012 ADD R3,R1 ;Add in epoch*32 ;012 ADD R0,R1 ;Add in the year MOV R1,DE.DAT(R5) ;Save the date RETURN .SBTTL GETNM- Convert 2 ASCII characters to a binary number ;+ ; GETNM ; This routine converts two ASCII characters to a binary number. It ; assumes that the characters really represent a number and does no ; checking. ; ; INPUTS: ; R0 -> ASCII characters ; ; OUTPUTS: ; R0 = Binary number ;- GETNM:: MOV R1,-(SP) ;Save R1 MOVB (R0)+,R1 ;Get the first char SUB #60,R1 ;Make it binary MOV R1,-(SP) ;Save it momentarily ASL R1 ;*2 ASL R1 ;*4 ADD (SP)+,R1 ;*5 ASL R1 ;*10 MOVB @R0,R0 ;Get the next char ADD R1,R0 ;Add in the 1st value SUB #60,R0 ;Take care of the ASCII'ness MOV (SP)+,R1 ;Restore R1 RETURN .SBTTL GETNUM - Convert ASCII to binary, decimal ;+ ; ; GETNUM ; Converts a string of ASCII digits to their binary ; representation. ; ; Call: ; R1 -> String ; ; Return: ; R1 -> Beyond character which caused error in conversion ; R3 = Binary ; ; Notes: ; o No checking done for overflow ; o R0 is used ; ;- GETNUM:: CLR R3 ;Reset result 10$: MOVB (R1)+,R0 ;Get a character SUB #'0,R0 ;De-ASCIIfy it... BMI 20$ ;It isn't numeric... CMP #9.,R0 ;Check upper limit BLO 20$ ;It isn't numeric ASL R3 ;Multiple MOV R3,-(SP) ; current ASL R3 ; result ASL R3 ; by ADD (SP)+,R3 ; ten ADD R0,R3 ;Add new digit BR 10$ ; and loop for another character 20$: RETURN .SBTTL Root Segment Routines ;+ ; The following routines are in a global PSECT to get them pulled ; into the root. They are used by the execution or directory scan ; routines. ;- ORIGIN PIPMTR .SBTTL MTNFS - Do a non-file-structured .LOOKUP to magtape ;+ ; MTNFS ; ; R1 = channel number ; ; JSR R5,MTNFS ; .WORD dblk ; ; C-bit = 1 => error ; error code in S$EERB ;- MTNFS:: MOV R2,-(SP) ;Save R2 MOV (R5)+,R2 ;R2 -> device block CLR 2(R2) ;Make sure it's NFS .LOOKUP #IOAREA,R1,R2,#-1 MOV (SP)+,R2 ;Restore R2 RTS R5 .SBTTL BSTMn - Magtape backspace to tape mark BSTM4:: JSR PC,@PC ;Call do it twice and fall into it BSTM2:: JSR PC,@PC ;Call do it once and fall into it BSTM1:: JSR R5,SPFUNM ;Do a .SPFUN with -1 word count .BYTE 377,SF.MBS ; Backspace code BCS 10$ ;Return error indication CMP MTERR,#EM.EOF ;Hit a tape mark? BEQ 10$ ;Yep... CMP MTERR,#EM.BOT ;Nope, was it BOT (for TK70)? BNE BSTM1 ;Nope, try another backspace 10$: RETURN .SBTTL SPFUNx - Do a .SPFUN to magtape SPFUNM:: MOV #-1,-(SP) ;Word count of -1 BR SPFUN SPFUN1:: MOV #1,-(SP) ;Word count of 1 BR SPFUN SPFUN0:: CLR -(SP) ;Word count of 0 .BR SPFUN SPFUN:: MOV #IOAREA,R0 ;R0 -> EMT area block MOV (SP)+,6(R0) ;Set up the word count MOV (R5)+,10(R0) ; and the function code .SPFUN ,R1,,#0,,#MTERR,#0,CODE=SET ;Do it RTS R5 .SBTTL WRTnTM - Write tape marks ;+ ; WRTnTM ; The following routines write tape marks to magtape. The ; different entry points cause a different number of tape ; marks to be written. ; ; R1 = channel number ; ; CALL WRTnTM ;- WRT3TM:: ;3 tape mark entry point CALL WRT1TM ;Write 1 tape mark WRT2TM:: ;2 tape mark entry point JSR PC,@PC ;Write 2 tape marks WRT1TM:: ;1 tape mark entry point .SPFUN #IOAREA,R1,#SF.MTM,#0,#0,#0,#0 ;Write a tape mark RETURN .END