.MCALL .MODULE .MODULE FSM,VERSION=24,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 CONDITIONAL ASSEMBLY SUMMARY .ENABL LC ;+ ;COND ; MMG$T std conditional ; TIM$T std conditional (no code effects) ; ERL$G std conditional (no code effects) ; ; FSM$PU .PURGE support ;- .IIF NDF FSM$PU FSM$PU = 1 ; Default to .PURGE support ; ; Edit History: ; ; Fix FSN LOOKUPs (FNDLOC and GETFIL) when at EOT ; ; FIXED .ENTER (READ AFTER WRITING PROBLEM) ;BD0 ; ; POSITIONING INFINITE LOOPED FIXED ;BD1 ; ; FIXED FSN POSITIONING BUG ;SHD01 ; ; 001 31-Dec-79 16:54 Davis, Scott (75474) [240,92] ; FIX VARIOUS XM BUGS ; (001) ; ; 25-Feb-83 Banche, Linda (98515) [240,124] ; Finally fixed for V5 ; ; 10-Jan-86 Clogher, Bill (x-8105) [240,105] ; Fix backup over just written tape mark for TK50. ; ; 004 15-Jul-87 Rob Hamilton for V5.5 ; 005 12-Jun-88 - add .PURGE code ; 006 09-Aug-88 - add code for UB compatibility ; 007 12-Oct-88 - change HDR1/EOF1 label format ; to squeeze out embedded blanks in filenames. ; Both old and new formats are allowed on read ; 008 26-May-89 Use names in SYSTEM.MLB ; 009 26-Jun-89 Put XBUMP here in FSM - not global anymore ; 010 11-Oct-89 Fix re-LOOKUP with both name and seq no. ; ; 022 13-Jun-91 WFG Eliminate overlap between NQE: and MONTAB: ; 023 24-Aug-92 RHS Fix GETFIL to force FNDPOS if FSN <= 0 ; 024 10-Oct-1996 Tim Shoppa Allow for years .GE. 2000 in HDR1 .SBTTL FSM INFORMATION ; File-structure support module for RT-11 magtape. ; 1. This module can be linked with an appropriate hardware handler to provide ; a file structure for magtapes. The format is compatible with the DEC ; Magnetic Tape Labels and File Structure Standard (tapes written in ; conformance to this standard will also conform to ANSI X3.27-1969 ; revision 1975.) ; 2. Handler input formats ; A file-structure-handler accepts commands through a queue element which is ; passed to it by the system as an address in MTCQE. The following table ; describes the queue element format and how the file-structure magtape ; handler interprets it. ; Word Mnemonic Purpose Handler uses this for ; 0 --- Link to next Not used. ; queue element ; 2 Q.CSW Pointer to Handler reports status to monitor by setting ; channel status bit 13 (20000-CSWEOF) when an end of file ; condition is detected or bit 0 (1-CSWHERR) ; when a hard error condition is detected. ; 4 Q.BLK Starting block 1. File structured .READx/.WRITx requests use ; number this as a block number. ; 2. .ENTER and .LOOKUP interpret this number ; as a SEQNUM argument. ; 3. Special function requests (.SPFUN negative ; code in Q.FUNC) use this as an address ; (ERRBLK) to report qualifying information on ; the operation which has just occurred. ; 4. NFS .READx/.WRITx requests zero this word ; to force no error reporting. ; 6(BYTE)Q.FUNC Special Handler accepts the following codes. ; function ; Code ; 6 .PURGE ; 5 .RENAME (returns invalid op code) ; 4 .ENTER ; 3 .LOOKUP ; 2 .DELETE (returns invalid op code) ; 1 .CLOSE ; 0 .READx/.WRITx ; -1 Write EOF (tape mark) ; -2 Forward space ; -3 Backspace ; -4 Write with extended gap ; -5 Rewind ; -6 Offline and rewind ; -7 Write ; -8. Read ; -9. Stream at 100 ips (TS05 only) ; -20. Asynchronous directory operation ; When 5(.RENAME), 2(.DELETE), or any other ; code is detected an illegal function ; error is given. ; ; 7(BYTE)Q.JNUM Job number The job number is used by NFS lookup to ; <13:11> determine whether a unit is being used by ; F/G. ; Unit number The unit number is used to select a tape unit ; and by NFS lookup to determine whether a unit ; is busy. ; 10 Q.BUF Buffer address 1. Used by .LOOKUP and .ENTER as the address ; of the filename to be found. ; 2. Used by the asynchronous directory ; operations request as the address of a command ; block containing the filename, function code, ; and the SEQNUM argument. ; 3. Used as a buffer address by .READx/.WRITx, ; read, write, and write with extended gap. ; 12 Q.WCNT Word count 1. Zeroed by .LOOKUP to indicate the file size ; of the .LOOKUPed file is not available. ; 2. Used as a word count for .READx/.WRITx, ; read, write, and write with extended gap. ; 3. Used as a block count by forward space and ; backspace. ; 14 Q.COMP Completion Not used. ; function ; 16 Q.PAR PAR1 register For XM, contains DMA-compatible PAR1 ; or UMR relocation bias. Updated by XBUMP. ; 20 Q.MEM PAR1 register For XM, contains PAR1 relocation bias. ; Updated by XBUMP. ; 22 --- --- Not used. ; The following is a description of the action taken by the handler for a ; given code. ; Code Action ; 4 .ENTER The handler marks the drive busy. The SEQNUM argument ; (Q.BLK) is interpreted as follows. ; -2 The tape is rewound and then searched until the ; filename or logical end of tape (LEOT) is found. ; The file is entered whichever is found. When ; the file is not entered at LEOT then any succeeding ; files are lost. ; -1 The tape is positioned at LEOT and the file is ; entered. ; 0 The tape is rewound and then searched until the ; filename or LEOT is found. When the filename is ; found a file exists error is issued. When LEOT is ; found the file is entered. ; positive The tape is positioned via the algorithm described ; number described for the GETFILE routine at the file ; sequence number given and the file is entered over ; the previous file. Any succeeding files on the tape ; are lost. ; Any other SEQNUM arguments or a null filename (first word is ; zero) will generate an illegal arguments error. ; 3 .LOOKUP The handler marks the unit busy. The first word of the ; filename is checked. When zero is detected the SEQNUM ; argument is interpreted as follows. ; SEQNUM Action ; -1 Do a non-file-structured lookup and do not ; rewind the tape. ; 0 Do a non-file-structured lookup and rewind ; the tape. ; positive number The tape is positioned via the algorithm ; described for the GETFILE routien at the ; file sequence number given and the file is ; lookuped. The filename is not checked. ; When the first word of the filename is not zero the SEQNUM ; argument is interpreted as follows. ; SEQNUM Action ; -1 Search the tape from the current position ; on the tape (do not rewind) and lookup the ; file when found. ; 0 Rewind the tpae and search for filename. ; Lookup the file when found. ; positive number The tape is positioned via the algorithm ; described for the GETFILE routine at the ; file sequence number given and the file ; is lookuped. The filename is checked ; and an error message is given if it does ; not match. ; 1 .CLOSE This request is interpreted in one of three different ways ; depending on how the channel and/or file was opened. ; Channel was Action ; opened by: ; Non-file-structured The channel is marked not busy. ; .LOOKUP The tape is not moved. ; File-structured The channel is marked not busy and ; .LOOKUP the tape is positioned past the ; tapemark following the EOF label ; group. ; File-structured The channel is marked not busy and ; .ENTER the handler writes a tapemark, a ; EOF1 label and 3 tapemarks then spaces ; back 2 tapemarks. ; Non-file-structured When the asynchronous request was ; .LOOKUP and non-file-structured, the channel is ; asynchronous lookup closed the same as a close for a ; request NFS .LOOKUP. When the request was ; file-structured the channel is ; closed the same as a file-structured ; .LOOKUP. ; Asynchronous .ENTER The channel is closed the same as for ; request an .ENTER request. ; 0 .READx/.WRITx .READx has a positive word count (Q.WCNT) and .WRITx ; has a negative word count. ; When a channel and a file are open these requests are ; interpreted as follows. ; 1. .WRITx expects 256. words/block on the tape and will ; issue multiple reads of 256. words to exhaust the word ; count. ; 2. .WRITx will write only 256. words/block on the tape. ; When the word count is a multiple of 256. the request will ; issue several writes to exhaust the word count. When the ; word count is not a multiple of 256. then the last block ; will contain the number of extra words needed to write a ; block of 256. words. ; When the channel is opened non-file-structured these ; requests read or write blocks of data whose physical size ; is given by Q.WCNT. .WRITx will report end of file when ; it sees the EOT marker. .READx will report end of file ; only when it reads a TM. It will ignore the EOT marker. ; -1 Write a TM(tapemark). ; -2 Forward space n blocks (n specified in Q.WCNT) until n is ; satisfied, EOT marker is sensed, or a TM is read. When EOT or TM ; are sensed, the number of blocks not spaced is reported in the ; second word of ERRBLK. ; -3 Backspace n blocks (n specified in Q.WCNT) until n is satisfied, ; BOT is sensed, or a TM is read. When BOT or TM are sensed, the ; number of blocks not spaced is reported in the second word of ; ERRBLK. ; -4 Erase 3 inches of tape and write a block to tape (write with ; extended gap.) ; -5 Rewind the tape to BOT. ; -6 Turn the tape unit offline and rewind. ; -7 Write a block to tape. ; -8. Read a block from tape. When there is less data in the block than ; in the word count for the request the number of words not read is ; reported in the second word of ERRBLK. ; For the MM handler only. When there is more data in the block than ; in the word count the number of words not read is reported in the ; second word of ERRBLK. ; -9. Stream at 100 ips (TS05 only) This code will be ignored by the ; MT, MM, and MU handlers, as well as MS when it is running ; anything besides a TS05. ; -16. TMSCP bypass (MU only). This issues an MSCP command directly ; without going through the handler ; -20. Asynchronous lookup and enter. This request is provided so that ; a program can do lookup or enter operations which require long ; search times and not lock the USR or hold up program execution. ; The channel to the unit is opened with a non-file-structured ; .LOOKUP request which is immediately followed by a .SPFUN call ; with a -20. code. This call uses the buffer address argument to ; point to a command block which appears in the following format. ; Word Purpose ; 0,2,4 Filename is 3 Radix 50 words. ; 6 Command. 3 means lookup, 4 means enter. ; 10 SEQNUM argument. ; 12,14 Reserved for future use. ; 3. Handler Conditionals ; When MMG$T is not equal to zero the file structure module will be ; assembled to know about extended memory support. This means that ; requests which read and write labels access the OLDBA and EXTADR ; globals will clear EXTADR because the address is in the low 28k. ; It also changes the way qualifying information is reported. ; When DRIVEN is defined in the range of 1 through 7 the handler will ; create a DVINFO table which will support that many drives. This will ; save approximately 7 words per unspecified unit. Note that this ; restricts the set of unit numbers which the handler will accept to ; DRIVEN - 1 (for example, when DRIVEN is specified as 2 the highest ; unit number which the handler will accept is 1. Any number greater ; than that will cause a hard error.) ; 4. FSM Structure ; The file-structure-module is divided into six major sections. ; 1. The first section gets the function from the queue element, ; determines whether the function is file structured or not, does ; whatever initialization and/or set up is needed and then passes ; control to a routine which will do the function. ; When the function is an asynchronous ENTER or LOOKUP this routine ; shuffles arguments and sets flags around so that the .ENTER or ; .LOOKUP routines can be used unchanged. ; When the function is negative and not an asynchronous request the ; routine just passes control to the hardware handler. ; When the function is positive the routine passes control to one of ; the file oriented routines in the next section. ; 2. The second section is divided into four routines, one each for ; .LOOKUP (LOOK), .ENTER (ENT), .CLOSE (CLO), and .READx/.WRITx (RW). ; 3. The third section consists of two routines. The EXECHH routine ; sets up a queue element, pulls all FSM generated data off the stack, ; restores R0-R3, and jumps to the hardware handler. The hardware ; handler performs the requested operation then returns to the ; FSMDON/FSMERR routine. ; The FSMDON entry point is transferred to when no exception conditions ; were detected. The FSMERR entry point is transferred to when there ; were exception conditions detected. The stack is restored to what is ; looked like when the EXECHH routine was called and the results of the ; operation are returned in the registers. ; When FSMDON/FSMERR is transferred to and the function being performed ; was not file oriented, the results of the operation are returned to ; the user and the handler exits to the monitor. ; 4. The fourth section is the set of subroutines used by the file ; oriented operations. ; Subroutine Purpose ; GETFIL Searches the tape for a given filename or file sequence ; number. ; FNDPOS Called by GETFIL when the position of the magtape is ; unknown by the FSM. ; MATCH Routine which will match a filename from HDR1 label with a ; filename specified to the handler. This routine knows ; about RSX-11 filenames and also RT-11 V02 filenames. ; R50ASC Converts 3 words of Radix 50 to a six byte filename, a ; dot, and a three byte extension. ; DECBIN Converts a decimal number to binary. ; BINDEC Converts a binary number to decimal. ; DATE Converts an RT-11 date word to an ANSI date in the form ; ' YYDDD' where YY is a year and DDD is the day. ;024 ; For years .GE. 2000 the space becomes a '0'. ;024 ; BACKTM Backspaces the tape until a TM is detected. ; FORWTM Forward spaces the tape until a TM is detected. ; GETLA Reads 80 bytes to the label buffer and ignores record ; length errors. ; BACKU1 Backspaces the tape one block. ; REW Rewinds the tape and initializes the current file sequence ; number variable for that unit. ; READLA Reads a label and returns a value depending on what label ; it read. This subroutine knows about VOL1 and that a boot ; block and/or other labels can come between it and the ; first HDR1. ; WRITLA Writes a label to tape. ; WRTTM Writes a tapemark. ; 5. There are many different ways of reporting error conditions from the ; File Structure Module. They are all grouped together in this section ; because they can share a lot of code. ; 6. The sixth section is the data area. It contains variables, a ; prototype label, a label buffer, and a device information table which ; stores unit dependent information. .SBTTL DEFINITIONS .IIF NDF TIM$IT, TIM$IT = 0 ;NO TIMEOUT SUPPORT .IIF NDF MMG$T, MMG$T = 0 ;NO MEMORY MANAGEMENT SUPPORT .IIF NDF ERL$G, ERL$G = 0 ;NO ERROR LOGGING SUPPORT .IIF NDF FSM$MX, FSM$MX = 0 ;No high memory FSM unless defined .SBTTL ...Local Macros .MACRO ...... .ENDM .SBTTL ...RT-11 SYSMAC Macros .IIF EQ MMG$T, .MCALL SOB ; Bring in SOB macro ONLY in non-XM .MCALL .ADDR, .ASSUME, .BR .MCALL .DREND .MCALL .QELDF .QELDF .SBTTL ...RT-11 SYSTEM Definitions .LIBRARY "SRC:SYSTEM.MLB" .MCALL .CF2DF, .CSWDF, .ERMDF, .ERRDF, .FIXDF .MCALL .SFMDF, .SYCDF, .UBVDF, .USSDF .CF2DF ; Config word 2 bits .CSWDF ; CSW offsets .ERMDF ; Magtape error codes .ERRDF ; Error codes .FIXDF ; Fixed Offsets .SFMDF ; Magtape SPFUNs .SYCDF ; System Communication Area .USSDF ; USR functions .SBTTL ...DVINFO table offsets .IF NDF D.CFSN D.CFSN =: 0 ; CURRENT FILE SEQUENCE NUMBER D.CBLK =: 2 ; CURRENT BLOCK NUMBER D.HBLK =: 4 ; HIGHEST BLOCK WRITTEN D.FTYPE =: 6 ; FILE TYPE ; 0=LOOKUPED ;-1=ENTERED D.EOT =: 7 ; POSITION IS PAST EOT MARKER FLAG D.FNAM =: 8. ; RAD50 FILE NAME .ENDC; NDF D.CFSN .SBTTL ...Miscellaneous UNITLM =: 7 ; MASK FOR UNIT NUMBER SPACE =: 40 ; SPACE CHARACTER LBLSIZ =: 40. ;Label size in words (when written) .SBTTL FSM Interface to Hardware Handler ; EXTERNAL GLOBAL SYMBOLS - These symbols serve to interface the FSM with ; a hardware magtape handler. .GLOBL $DONE $MT ; Code entries in Hdwr Hdlr .GLOBL FSMDIS FSMDON FSMERR FSMABT ; FSM entries accessed by HH .GLOBL DRIVEN DVINFO MTCQE MTCQ ; Global data in HH .GLOBL DVTBL CODE ; Global data in FSM .IF NE MMG$T ; GLOBALS FOR MEMORY MANAGEMENT VERSION .GLOBL OLDBA EXTADR SYNBLK JOBNM ; Data .GLOBL TEMP SINK ERBSAV .ENDC; NE MMG$T .SBTTL FSMDIS entry point .IF EQ FSM$MX .PSECT MTDVR .ENDC; EQ FSM$MX .ENABL LSB FSMDIS::MOV SP,SPSAV ;remember stack pointer for later MOV MTCQE,R3 ;point to queue element MOVB Q$FUNC(R3),R0 ;get code for this request MOVB Q$JNUM(R3),R1 ;get job number/unit number byte BIC #^C,R1 ;isolate unit number MOV #ER.IUN,R2 ;Potential error code for USR CMP R1,#DRIVEN ;Is unit number valid? BLO 16$ ;branch if it is. ; An error of some sort has been discovered. It is either an invalid ; function, or an invalid unit. 10$: TSTB R0 ;Error; USR function? BLE 18$ ;Branch if not. MOV R2,R0 ;Get error code for USR BR SPER2 ; Send it. ...... ; Get the address of this unit's Device Info Table entry 16$: MOV R1,-(SP) ;THIS IS A MULTIPLY BY 7 ROUTINE ASL R1 ;X2 ASL R1 ;X4 ASL R1 ;X8 SUB (SP)+,R1 ;X7 ASL R1 ;THIS IS FOR A WORD TABLE .ADDR #DVINFO,R1,ADD ;POINT INTO DVINFO TABLE MOV R1,DVTBL ;SAVE THIS ADDRESS FOR LATER CLR SEEKYN ;Initialize SEEK IN PROGRESS flag ; Determine what kind of function is to be performed TSTB R0 ;Look at code for this request... BGT 70$ ; Branch if USR function BEQ 20$ ; Branch if .READ or .WRITE ; It is an .SPFUN CMPB R0,#SF.MST ;SPFUN - is it for the HH? BHIS 30$ ; Branch if so CMPB R0,#SF.BYP ;IS IT MU BYPASS? BEQ 30$ ;IF YES, BRANCH CMPB R0,#SF.USR ;NO-IS IT A SEEK? BEQ 90$ ;YES 18$: BIS #HDERR$,@-(R3) ;No. Set the HARD_ERROR bit in the CSW BR 60$ ...... 20$: CMPB #1,D.FTYPE(R1) ;WAS FILE OPENED WITH A NFS LOOKUP? BNE 100$ ;NO ; A Hardware Handler SPFUN code is to be processed. ; FSM will increment the block number if it's not invalid ; (equal to -1) and the code is for a WRITE. .ASSUME D.CFSN EQ 0 30$: MOV R0,CODE ;CODE FOR THE HH CMPB R0,#SF.MWR ;WRITE PHYSICAL BLOCK? BNE 40$ ;NO INC D.CBLK(R1) ;Count the WRITE BNE 50$ ; unless it was already -1. 40$: MOV #-1,@R1 ;FLAG D.CFSN NOT KNOWN MOV @R1,D.CBLK(R1) ;FLAG BLOCK NUMBER NOT KNOWN (-1) 50$: CALL ADJSP ;GO DO THE FUNCTION 60$: JMP DONE ...... ; FSM function but not SEEK - make sure code is legal 70$: CMPB R0,#DELE.. ;DELETE is illegal BEQ 80$ CMPB R0,#RENM.. ;RENAME is also illegal .IF NE FSM$PU BEQ 80$ .ASSUME PURG.. GT DELE.. .ASSUME PURG.. GT RENM.. CMPB R0,#PURG.. ;PURGE and the rest below it are OK BLOS 100$ .IFF; NE FSM$PU BNE 100$ ;Request appears ok. .ENDC; NE FSM$PU 80$: MOV #ER.OPE,R0 ;YES-OR MAYBE SOMETHING ELSE SPER2: JMP SPERRF ;GO ISSUE SPECIAL DEV USR ERROR ($SPUSR) ...... ; PROCESS AN ASYNCHRONOUS .ENTER OR .LOOKUP ; THE ASYNCHRONOUS REQUESTS ARE IMPLEMENTED BY MOVING THE ARGUMENTS TO MATCH ; WAY THE MONITOR WOULD PASS THEM TO FSM AND FAKE OUT THE ENTER AND LOOKUP ; ROUTINES WHICH FOLLOW. 90$: DEC SEEKYN ;SET SEEK IN PROGRESS FLAG CLR CODE ;INSURE CODE IS NOT NEGATIVE MOVB #CLOS..,Q$FUNC(R3) ;MAKE THE DRIVE LOOK LIKE ITS AVAILABLE CALL ADJSP ;CALL HARDWARE HANDLER MOV MTCQE,R3 ;PUT THIS BACK IN PLACE MOV @R3,SEEKER ;SAVE THE ADDRESS OF WHERE TO PUT SEEK ERRORS .IF NE MMG$T MOV R3,R4 ;GET ADDRESS OF QUEUE ELEMENT CMP (R3)+,(R3)+ ;POINT TO Q$BUFF MOV @R3,R1 ;SAVE OLD Q$BUFF ADD #6,@R3 ;POINT TO CODE AND SEQNUM MOV $GTBYT,R5 ;ADDRESS OF MONITOR SUBROUTINE CALL @R5 ;$GTBYT MOVB (SP)+,R0 ;PUT CODE IN R0 INC @R3 ;IGNORE HIGH BYTE CALL @R5 ;$GTBYT MOV (SP)+,@R4 ;GET LOW BYTE OF SEQNUM CALL @R5 ;$GTBYT MOVB (SP)+,1(R4) ;GET HIGH BYTE OF SEQNUM MOV R1,@R3 ;RESTORE OLD Q$BUFF MOV R4,R3 ;RESTORE R3 .IFF; NE MMG$T MOV Q$BUFF(R3),R4 ;GET ADDRESS OF FILENAME ADD #6,R4 ;POINT PAST FILENAME TO ASYNCH COMMAND MOV (R4)+,R0 ;PUT THE CODE IN R0(COMMAND=CODE) MOV @R4,@R3 ;REPLACE ERRBLK ADDRESS WITH SEQNUM ARG .ENDC; NE MMG$T CMPB R0,#ENTR.. ;IS THIS AN ENTER? BEQ 100$ ;YES CMPB R0,#LOOK.. ;IS THIS A LOOKUP? BNE 10$ ;NO-GIVE ERROR ; THE FOLLOWING CODE DOES SOME WORK COMMON FOR ALL FILE STRUCTURED REQUESTS. ; THE FSM SETS UP A FAKE QUEUE ELEMENT HERE. 100$: .ADDR #LABLIO,R1 ;GET ADDRESS OF LABEL BUFFER MOV R1,LABINP ;THIS IS WHERE TO READ LABELS MOV R0,CODE ;FSM FUNCTION-STORE THE CODE .ADDR #NQE,R4 ;GET ADDRESS OF FAKE QUEUE ELEMENT MOV R4,NQ ;SAVE IT FOR LATER MOV Q$CSW(R3),-2(R4) ;PUT CSW POINTER INTO FAKE Q ELEM CLR (R4)+ ;MAKE BLOCK NUMBER 0 SO THAT NQ.BUF CAN ; POINT TO ZERO WORD TST (R3)+ ;POINT TO NEXT WORD MOV (R3)+,(R4)+ ;MOVE CODE,JOB NUMBER,UNIT NUMBER .IF NE FSM$PU CMPB R0,#PURG.. ;Is code PURGE? BEQ 130$ ; Go do it now if so. .ENDC; NE FSM$PU CMPB R0,#DELE.. ;IS CODE LOOKUP or ENTER? BLOS 110$ ;Branch if READ, WRITE or CLOSE ; Do a NFS LOOKUP on the Hardware Handler to reserve drive on this ; file-structured LOOKUP call. MOVB #LOOK..,R0 ;THEN CALL HH TO SET THE DRIVE BUSY BIT(INUSE) MOV NQ,R1 ;R1 BECOMES THE ADDRESS OF A NULL FILENAME MOV #-1,@R1 ;DON'T REWIND FOR NFS LOOKUP ADD #Q$WCNT,R1 ;POINT R1 TO WCNT WHICH ISN'T USED ; AND USE IT FOR A NULL FILENAME .IF NE MMG$T MOV R1,NQ.BUF ;POINT TO ZERO WORD .ENDC; NE MMG$T CLR R2 ;USE WCNT AS A NULL FILENAME CALL EXECHH ;GO CALL HH AT $MT 110$: .IF NE FSM$PU CMP CODE,#PURG.. ;if PURGE, follow CLOSE BEQ 130$ .ENDC; NE FSM$PU CMP CODE,#CLOS.. ;If READ/WRITE or CLOSE code BLE 130$ ;Don't get the filename into DVINFO ; Get the filename of this LOOKUP or ENTER, and store it in the ; device info table. .IF NE MMG$T MOV MTCQE,R4 ;POINT TO QUEUE ELEMENT MOV DVTBL,R5 ;POINT TO DVINFO TABLE ADD #D.FNAM,R5 ;POINT TO RAD50 FILENAME STORAGE PLACE MOV #6,R3 ;DO SIX $GTBYT'S 120$: CALL @$GTBYT ;GET A BYTE FROM USER MAPPING MOVB (SP)+,(R5)+ ;SAVE IT SOB R3,120$ ;COUNTDOWN MOV R5,R4 ;SET UP R4 FOR CALL TO R50ASC .IFF; NE MMG$T MOV MTCQE,R5 ;BUFFER ADDRESS POINTS TO RAD50 NAME MOV Q$BUFF(R5),R5 MOV DVTBL,R4 ;ADDRESS OF DVINFO TABLE ADD #D.FNAM,R4 ;POINT TO FILENAME MOV (R5)+,(R4)+ ;MOVE THE FILENAME MOV (R5)+,(R4)+ ;MOVE THE FILENAME MOV (R5)+,(R4)+ ;MOVE THE EXTENSION AND POINT PAST IT .ENDC; NE MMG$T CALL R50ASC ;SO WE CAN CALL THE RAD50 CONVERTER ; Dispatch to the requested file-structure routine. 130$: MOV CODE,R5 ;USE FUNCTION CODE AS AN OFFSET INTO THE TABLE ASL R5 ;MULTIPLY BY 2 ADD PC,R5 ;CALCULATE ADDRESS OF DISPATCH TABLE ADD #TABL1-.,R5 ADD @R5,PC ;GO TO THE PROPER ROUTINE TABL1: .WORD .ASSUME CLOS.. EQ 1 .WORD .ASSUME DELE.. EQ 2 .WORD <80$-TABL1> .ASSUME LOOK.. EQ 3 .WORD .ASSUME ENTR.. EQ 4 .WORD .IF NE FSM$PU .ASSUME RENM.. EQ 5 .WORD <80$-TABL1> .ASSUME PURG.. EQ 6 .WORD .ENDC; NE FSM$PU .EVEN .DSABL LSB .SBTTL LOOKUP ROUTINE ; THERE ARE 2 TYPES OF LOOKUP'S PROCESSED HERE. ; 1. A NON-FILE-STRUCTURED LOOKUP REQUIRES ONLY THAT THE FILE POSITION ; INFORMATION BE ERASED. ; 2. A FILE-STRUCTURED LOOKUP SEARCHES FOR THE FILE WITH THE GETFIL ; SUBROUTINE. ; WHEN THE SEQNUM ARGUMENT IS 0 OR -1 THE FILENAME IN LNAME IS SEARCHED FOR. ; WHEN THE SEQNUM ARGUMENT IS A POSITIVE NON ZERO NUMBER THEN THAT ; FILE-SEQUENCE NUMBER IS SEARCHED FOR. ; WHEN THE FILE IS FOUND THE TAPE SPACES PAST THE TM DELIMITING THE HEADER ; LABEL AREA LEAVING IT POINTED AT THE BEGINNING OF THE DATA. ; FILE STRUCTURED LOOKUP INITIALIZES THE CURRENT BLOCK NUMBER (D.CBLK) AND ; SETS THE FSN POSITION (D.CFSN). ; ERRORS: ; FILE NOT FOUND (1) ERROR IS REPORTED WHEN GETFILE REPORTS THE FILE NOT ; FOUND. THE TAPE IS POSITIONED AFTER THE LAST TM OF THE LAST FILE. ; WHEN A SEQNUM ARGUMENT IS NEGATIVE AND NOT -1 THEN AN ILLEGAL ARGUMENT (5) ; ERROR IS REPORTED. .ENABL LSB LOOK: MOV DVTBL,R5 ;POINT TO DVINFO TABLE MOV MTCQE,R3 ;GET THE QUEUE ELEMENT POINTER ;BD1+ CLR Q$WCNT(R3) ;ZERO THE WORD COUNT MOV @R3,R3 ;GET SEQNUM ARGUMENT-FSN LOOKUP? ;BD1- BGT 30$ ;YES TST D.FNAM(R5) ;NO-NULL FILENAME SPECIFIED? BNE 10$ ;NO ; NON FILE STRUCTURED LOOKUP BEING DONE MOVB #1,D.FTYPE(R5) ;MARK A NON FILE STRUCTURED LOOKUP IN PROGRESS TST R3 ;SHOULD A REWIND BE PERFORMED? BNE 50$ ;NO MOV #-1,(R5)+ ;YES-MARK D.CFSN NOT KNOWN MOV #-1,@R5 ;MARK D.CBLK NOT MEANINGFUL CALL REW ;DO A REWIND BR 50$ ; FILENAME .LOOKUP - CHECK SEQNUM 10$: TST R3 ;SEQNUM=0? BEQ 30$ ;YES INC R3 ;SEQNUM=-1? BNE ENT1 ;NO-ILLEGAL ARGUMENT 20$: COM R3 ;REMEMBER -1 30$: CALL GETFIL ;TRY AND FIND THE FILE ;R0=0 FILE FOUND ;R0=1 FILE NOT FOUND MOV @MTCQE,R3 ;GET SEQNUM-FSN SEARCH? BLE 60$ ;NO ; FSN LOOKUP - CHECK FOR FILE FOUND AND VERIFY FILENAME IF NECESSARY MOV DVTBL,R5 ;POINT TO DVINFO TABLE TST D.FNAM(R5) ;NULL FILENAME? BEQ 60$ ;YES TST R0 ;WAS FSN FOUND? BNE 70$ ;NO MOV LABINP,R1 ;YES-VERIFY FILE NAME-GET ADDR OF LABEL BUFFER CMP (R1)+,(R1)+ ;POINT TO FILE IDENTIFIER CALL MATCH ;FILENAME MATCHES? BCS 70$ ;NO-GO GIVE FILE NOT FOUND ; DO A LOOKUP 40$: CALL FORWTM ;SPACE PAST LABEL GROUP TO POINT TO DATA MOV DVTBL,R5 ;POINT TO DVINFO TABLE CLR D.CBLK(R5) ;MARK BLOCK NUMBER AT ZERO CLRB D.FTYPE(R5) ;FILE TYPE IS FILE STRUCTURED LOOKUP 50$: BR DONE01 ;ALL DONE ...... ; DON'T VERIFY FILENAME 60$: TST R0 ;FILE FOUND? BEQ 40$ ;YES-GO DO LOOKUP 70$: MOV #ER.FNF,-(SP) ;FILE NOT FOUND ERROR BR SPERB ...... .DSABL LSB .SBTTL ENTER A FILE ROUTINE ; THIS ROUTINE ENTERS A FILE ON MAGTAPE BY WRITING A HDR1 LABEL AND A TM. ; BY DEFINITION AN ENTERED FILE IS THE LAST FILE ON THE TAPE. LEGAL ; SEQNUM ARGUMENTS ARE DESCRIBED IN THE NOTES AT THE BEGINNING OF THE HANDLER. ; THE ENT ROUTINE INITIALIZES THE CURRENT BLOCK NUMBER TO ZERO(D.CBLK) AND ; SETS THE CURRENT FILE SEQUENCE NUMBER (D.CFSN) TO THE NUMBER OF THE FILE ; BEING ENTERED. ; THE HDR1 LABEL WRITTEN BY ENT IS AS FOLLOWS: ; CP FIELD NAME CONTENTS ; 1-3 LABEL IDENTIFIER "HDR" ; 4 LABEL NUMBER "1" RT-11 ONLY SUPPORTS HDR1 LABELS. HDR2 ; OR ANY OTHER HEADER LABELS ARE NOT ; SUPPORTED. ; 5-21 FILE IDENTIFIER 6 CHARACTER FILENAME (SPACES ARE USED TO ; PAD THE FILENAME TO 6 CHARACTERS), DOT, ; AND 3 CHARACTER FILE TYPE. EXAMPLES ARE ; FOO .FOO AND ABCDEF.GHI. ; 22-27 FILE-SET IDENTIFIER "RT11A " ; 28-31 FILE SECTION NUMBER "0001" ; 32-35 FILE SEQUENCE NUMBER THE FIRST FILE ON THE TAPE IS 0001. THIS ; NUMBER IS INCREMENTED BY 1 FOR EACH ; SUCCEEDING FILE. THE ONLY TIME WHEN THIS ; ISN'T TRUE IS FOR A NEWLY INITIALIZED TAPE. ; IN THIS CASE THE FILE SEQUENCE NUMBER IS ; ZERO SO THAT THE ENTER PROCESSER CAN WRITE ; OVER THE DUMMY FILE WHICH IS REQUIRED ON ; NEWLY INITIALIZED TAPES. ; 36-39 GENERATION NUMBER "0001" ; 40-41 GENERATION VERSION "00" ; 42-47 CREATION DATE " YYDDD" OR "0YYDDD" OR " 00000" ;024 ; WHERE YY REPRESENTS ;024 ; THE LAST 2 DIGITS OF THE YEAR, DDD REPRE-;024 ; SENTS THE NUMBER OF DAYS INTO THE YEAR, ;024 ; THE LEADING "0" IS PRESENT ONLY IF THE ;024 ; YEAR IS GREATER THAN 1999, AND ;024 ; " 00000" IS WHAT IS INSERTED WHEN THERE ;024 ; IS NOT SYSTEM DATE AVAILABLE. ;024 ; 48-53 EXPIRATION DATE " 00000" RT-11 DOESN'T SUPPORT EXPIRATION ; DATE PROCESSING. ; 54 ACCESSIBILITY " " RT-11 DOESN'T WRITE PRIVELEGED TAPES. ; 55-60 BLOCK COUNT "000000" ; 61-73 SYSTEM CODE "DECRT11A " PADDED OUT WITH SPACES ; 74-80 RESERVED PADDED WITH SPACES ; ERRORS: ; ILLEGAL ARGUMENT (5) ERROR IS REPORTED WHEN THE FILENAME BEING ENTERED ; STARTS WITH 3 BLANKS (THE RAD50 VALUE OF THE FIRST WORD IS 0.) ; DEVICE FULL (1) ERROR IS REPORTED WHEN THE ENTER ROUTINE ATTEMPTS TO ; WRITE PAST THE EOT MARKER. ; FILE SEQUENCE NUMBER NOT FOUND (4) ERROR IS REPORTED WHEN THE GETFIL ; ROUTINE SEARCHES FOR A FILE SEQUENCE NUMBER WHICH IS GREATER THAN THE ; NUMBER OF FILES ON THE TAPE. ; FILE FOUND (3) ERROR IS REPORTED WHEN THE SEQNUM ARGUMENT IS 0 (MEANING ; ENTER A UNIQUE FILENAME) AND THE GETFIL ROUTINE FINDS A FILE OF THE ; SAME NAME AS THE NAME OF THE FILE TO BE ENTERED. .ENABL LSB ENT: MOV @MTCQE,R3 ;GET SEQNUM ARGUMENT(FROM QUEUE ELEMENT) BPL 30$ ;LEAVE ARGUMENT ALONE IN R3 AND SEARCH INC R3 ;SEQNUM=-1? BNE 10$ ;NO MOV #77777,R3 ;YES-GUARANTEE LEOT WILL BE FOUND BY USING BR 30$ ;IMPOSSIBLY LARGE FSN FOR ARGUMENT TO GETFIL 10$: INC R3 ;SEQNUM=-2? BEQ 30$ ;YES=SEARCH FOR FILENAME 20$: ENT1: MOV #ER.ISN,-(SP) ;NO-ILLEGAL ARGUMENT FOUND BR SPER1 30$: MOV DVTBL,R5 ;POINT TO DVINFO TABLE TST D.FNAM(R5) ;NULL FILENAME? BEQ 20$ ;YES-GIVE ERROR CALL GETFIL ;TRY AND FIND A FILE ;R0=0 FOUND ;R0=1 NOT FOUND 40$: MOV DVTBL,R1 ;R1 -> DEVICE INFO TABLE TSTB D.EOT(R1) ;HAS THE END OF TAPE MARKER BEEN PASSED? BEQ 60$ ;NO 50$: MOV #ER.FUL,-(SP) ;YES-DON'T DO THE ENTER SPERB: CALL BACKU1 ;ASSUME STANDARD POSITION AFTER FILE SPER1: MOV #CLOS..,R0 ;REQUESTS DIDN'T SUCCEED SO CLOSE ;UP THE INUSE TABLE CALL EXECHH MOV (SP)+,R0 ;RESTORE THE ERROR CODE JMP SPERRF ...... 60$: MOV @MTCQE,R2 ;WHAT KIND OF ENTER IS IT? BGT 160$ ;GO CHECK FSN FOUND BNE 70$ ;Branch if FSN is negative ; FSN is 0. FILE NAME IS BEING SEARCHED TST R0 ;WAS FILENAME FOUND? BNE 80$ ;NO. That's good. MOV #ER.PRO,-(SP) ;FILE EXISTS, CANNOT BE DELETED ERROR DEC @DVTBL ;TAPE IS LEFT INFRONT OF HDR1 BR SPERB ...... 70$: INC R2 ;WHAT KIND OF NEGATIVE ENTER IS THIS? BEQ 80$ ;-1;ENTER AT LEOT TST R0 ;-2;WAS FILENAME FOUND? BEQ 110$ ;YES-DON'T INCREMENT FSN ; ENTER A FILE (WRITE THE LABEL) 80$: TST @R1 ;CHECK WHETHER AT FSN 0? BNE 100$ ;NO ; IF AT FSN 0 THEN WE'RE ON A NEWLY INITIALIZED TAPE AND ; THE ENTERED FILE SHOULD BE ENTERED OVER THE DUMMY FILE 90$: CALL REW ;GET TO BOT CALL READLA ;READ PAST VOL1 100$: INC @DVTBL ;MAKE FSN A LEGAL NUMBER 110$: CALL BACKU1 ;FILE NOT FOUND(LEOT) CALL SQBLNK ; Squeeze blanks from filename .ADDR #HDR1LB,R1 ; Get address of HDR1 data MOV #"HD,@R1 ; Store "HDR1" chars in label buffer MOV #"R1,2(R1) MOV @DVTBL,FSNTMP ;GET D.CFSN MOV R1,R4 ;ADDRESS OF LABEL ADD #FSNASC-HDR1LB,R4 ;POINT TO FSN CLR BLKTMP ; Let BLK = 0 CALL HDRCOM ; Format the FSN, BLK and DATE fields CALL WRITLA ;GO WRITE THE LABEL TST R5 ;ANY EXCEPTION CONDITIONS? BEQ 140$ ;NO ; EOT HAS BEEN FOUND 130$: CALL BACKU1 ;BACKUP OVER LABEL JUST WRITTEN CALL WRT2TM ;WRITE 2 TAPEMARKS CALL BACKU1 ;POSITION CORRECTLY ;bc01 BR 50$ ;DEVICE FULL ERROR ...... 140$: CALL WRTTM ;WRITE A TAPEMARK TO START THE DATA AREA TST R5 ;EOT CONDITION? BEQ 150$ ;NO CALL BACKU1 ;YES-BACKUP OVER TM JUST WRITTEN ;bc01 BR 130$ ;GO FINISH POSITIONING TAPE ...... 150$: MOV DVTBL,R5 ;POINT TO DVINFO TABLE TST (R5)+ ;SKIP OVER D.CFSN CLR (R5)+ ;INITIALIZE D.CBLK MOV #-1,(R5)+ ;INITIALIZE D.HBLK MOVB #-1,@R5 ;MARK FILE ENTERED IN D.FTYPE ; JMP DONE DONE01: BR DONE02 ;JMP DONE ...... ; FILE SEQUENCE NUMBER IS BEING SEARCHED 160$: TST R0 ;FSN FOUND? BEQ 110$ ;YES-GO WRITE A HDR1 LABEL TST @DVTBL ;IF D.CFSN=0 THEN WE'RE ON AN INITIALIZED TAPE BNE 170$ ;NO CMP #1,@MTCQE ;YES-ARE WE ENTERING AT FSN 1? BEQ 90$ ;YES-GO REPOSITION AT HDR1 170$: MOV #ER.NNF,-(SP) ;NO-ISSUE A FILE SEQUENCE NUMBER NOT FOUND BR SPERB ...... .DSABL LSB .SBTTL CLOSE ROUTINE ; THE CLOSE REQUEST CLOSES A CHANNEL IN A MANNER DEPENDENT ON HOW THE CHANNEL ; WAS OPENED. SEE THE FSM NOTES AT THE BEGINNING OF THE HANDLER FOR MORE ; DETAILS. ; CLO UPDATES THE CURRENT FILE SEQUENCE NUMBER (D.CFSN). ; WHEN CLO CLOSES AN ENTERED CHANNEL IT WRITES THE FOLLOWING LABEL. ; CP FIELD NAME CONTENTS ; 1-3 LABEL IDENTIFIER "EOF" ; 4 LABEL NUMBER "1" ; 5-21 FILE IDENTIFIER SAME AS IN HDR1 LABEL(SEE ENTER) ; 22-27 FILE-SET IDENTIFIER "RT11A " ; 28-31 FILE SECTION NUMBER "0001" ; 32-35 FILE SEQUENCE NUMBER SAME AS IN HDR1 LABEL(SEE ENTER) WHEN ; KNOWN. WHEN THE FILE SEQUENCE NUMBER ISN'T ; KNOWN A "0001" IS WRITTEN (THIS HAPPENS WHEN ; .SPFUN REQUEST WAS GIVEN) ; 36-39 GENERATION NUMBER "0001" ; 40-41 GENERATION VERSION "00" ; 42-47 CREATION DATE SAME AS IN HDR1 LABEL(SEE ENTER) ; 48-53 EXPIRATION DATE " 00000" ; 54 ACCESSIBILITY " " ; 55-60 BLOCK COUNT NUMBER OF BLOCKS WHICH HAVE BEEN WRITTEN ; OR ELSE ZERO WHEN THE BLOCK COUNT ISN'T ; KNOWN (THIS HAPPENS WHEN AN .SPFUN ; REQUEST WAS GIVEN) ; 61-73 SYSTEM CODE "DECRT11A " PADDED WITH SPACES ; 74-80 RESERVED PADDED WITH SPACES ; ERRORS: ; CLOSE DOESN'T REPORT ANY ERRORS. .ENABL LSB .IF NE FSM$PU PUR: MOV SP,(PC)+ ;Indicate PURGE PURCLO: .WORD 0 BR 10$ CLO: CLR PURCLO ;Indicate CLOSE .IFF; NE FSM$PU CLO: .ENDC; NE FSM$PU 10$: MOV DVTBL,R4 ;POINT TO DVINFO TABLE MOVB D.FTYPE(R4),R1 ;How was the file opened? BEQ 130$ ; Branch if File-Structured LOOKUP DEC R1 ;Was it an NFS LOOKUP? BEQ 140$ ; Do nothing if so. ; This is a CLOSE or PURGE after .ENTER .IF NE FSM$PU TST PURCLO ; .PURGE? BEQ 80$ ; Branch if .CLOSE ; Do a PURGE - Backspace the tape over the open file. Check for ; BOT. If not BOT, then write two tapemarks; otherwise, skip over ; the VOL1 label and write a ZEROED.ZZZ file to re-initialize. .ASSUME D.CFSN EQ 0 20$: DEC @DVTBL ; Decrease the FSN by 1 CALL BACKT2 ; back to end of HDR label(s) and ; to end of previous EOF ; Check for BOT - if so, we're purging the first file BIT #EM.BOT,R4 BNE 40$ ; Branch if we hit EOT ; Wipe out the .ENTER entry 30$: CALL FORWTM ; cross the prev file's final tapemark BR 120$ ; and write 2 more. 40$: CALL GETLA ; read the VOL1 label ; Set contents of HDR1 to ZEROED.ZZZ, FSN=0. .ADDR #HDR1LB+4,R1 ; point to label buffer name area .ADDR #ZEROED,R0 ; point to special non-file name MOV #10.,R5 ; 10 characters to move 60$: MOVB (R0)+,(R1)+ ; copy it in SOB R5,60$ ; count down ADD #18.,R1 ; point to FSN field MOV #4,R5 ; four zeroes needed 70$: MOVB #'0,(R1)+ ; here they go... SOB R5,70$ ; bing, bing, bing, bing... ; write HDR1, TM, TM, EOF1, TM, TM, TM CALL WRITLA ; write HDR1 CALL WRTTM ; write a tapemark, BR 110$ ; join common code below .ENDC; NE FSM$PU ; .CLOSE a new file .ASSUME D.CFSN EQ 0 80$: MOV (R4)+,FSNTMP ;GET D.CFSN for HDRCOM .ASSUME D.CBLK EQ 2 90$: MOV @R4,R0 ;GET D.CBLK INC R0 ;IS D.CBLK = -1? .ASSUME 0 EQ <-1+1> BEQ 100$ ;YES - DEFAULT TO 0 DEC R0 ;NO - LEAVE IT AS IT WAS 100$: MOV R0,BLKTMP ;Save block number for HDRCOM ADD #D.FNAM+4,R4 ;POINT TO END OF D.FNAM CALL R50ASC ;CONVERT FNAM TO ASCII CALL SQBLNK ;Squeeze out blanks MOV R5,R4 ;pointing to ASCII name ADD #,R4 ;POINT TO FSN CALL HDRCOM ;Do HDR1/EOF1 common stuff 110$: CALL WRTTM ;END THE DATA AREA .ADDR #HDR1LB,R1 ;Point to HDR1/EOF1 label area MOV #"EO,(R1)+ ; change HDR1 buf to EOF1 MOV #"F1,@R1 CALL WRITLA ;WRITE IT CALL WRTTM ;Write tapemark 120$: CALL WRT2TM ;Write 2 (more) tapemarks CALL BACKU2 ;Back over 2 tapemarks BR 140$ ...... ; FILE WAS OPENED WITH A LOOKUP 130$: CALL FORWT2 ;POINT AFTER EOF1 AND THE TM INC @DVTBL ;Indicate now pointing at next file. ; FILE WAS OPENED WITH A NFS LOOKUP 140$: MOV #CLOS..,R0 ;MARK THE DRIVE CLOSED TO THE HH CALL EXECHH DONE02: JMP DONE ; BR DONE03 ...... ; HDR1/EOF1 Common code - Format the File Sequence Number (FSN), ; the block number, and the date. On entry, R4 points to the ; HDR1 label buffer's FSN field. HDRCOM: MOV FSNTMP,R2 ;GET D.CFSN BPL 150$ ;NEGATIVE? MOV #1,R2 ;YES-DEFAULT TO 1 150$: MOV #2,R0 ;CONVERT 4 DIGITS CALL BINDEC ADD #>,R4 ;POINT TO BLOCK NUMBER MOV BLKTMP,R2 ;GET D.CBLK CLR R0 ;OUTPUT 5 DIGITS CALL BINDEC CALLR DATE ;MAKE ANSI DATE ; RETURN ...... .DSABL LSB .SBTTL READX/WRITX ROUTINE ; THIS ROUTINE WILL FORCE THE READING AND WRITING OF 512 BYTE BLOCKS ON ; MAGTAPE. WHEN THE D.CBLK VARIABLE IN THE DVINFO TABLE IS -1 THEN ; THE TAPE IS WRITTEN OR READ FROM WHEREVER IT IS POSITIONED (THIS HAPPENS ; AFTER AN .SPFUN REQUEST IS GIVEN.) WHEN THE D.CBLK VARIABLE IS POSITIVE ; THEN THE TAPE IS POSITIONED AT THE CORRECT BLOCK NUMBER PROVIDING THE ; BLOCK NUMBER IS NOT GREATER THAN THE HIGHEST BLOCK WRITTEN (ON ENTERED ; FILES). ; NOTE THAT READX WILL NOT RETURN AN ERROR WHEN THE BLOCKS IN THE FILE ARE ; GREATER THEN 512 BYTES/BLOCK, IT WILL JUST READ THE FIRST 512 BYTES. ; ERRORS: ; READX WILL RETURN A HARD (1) ERROR WHEN: ; IT TRIES TO READ A BLOCK WHICH IS SMALLER THAN THE WORD COUNT. ; THERE IS A HARD ERROR WHILE POSITIONING FOR THE READ OR WHILE ; DOING THE READ. ; READX WILL RETURN AN END OF FILE (0) CONDITION WHEN: ; IT READS A TM (NOTE THAT READING THE EOT MARKER DOESN'T CAUSE AN ; EOF ERROR.) ; WRITX WILL RETURN A HARD (1) ERROR WHEN: ; THE TAPE DRIVE IS WRITE LOCKED. ; THERE IS A HARD ERROR WHILE POSITIONING FOR THE WRITE OR WHILE ; DOING THE WRITE. ; WRITX WILL RETURN AN END OF FILE (0) CONDITION WHEN: ; IT WRITES PAST THE EOT MARKER. .ENABL LSB RW: MOV MTCQE,R4 ;POINT TO QUEUE ELEMENT MOV Q$WCNT(R4),-(SP);SAVE WORD COUNT ON STACK MOV DVTBL,R5 ;POINT TO DVINFO TABLE ENTRY CMP #-1,D.CBLK(R5) ;ARE WE DOING POSITIONING? BEQ 100$ ;NO ; CHECK FILE LIMITS MOV D.HBLK(R5),R0 ;YES-GET LAST BLOCK WRITTEN TSTB D.FTYPE(R5) ;ENTER WAS USED TO OPEN FILE? BMI 10$ ;YES-ENTER TST @SP ;NO-LOOKUP-WRITE COMMAND BEING DONE? BPL 60$ ;NO JMP HARDER ;WRITES AREN'T ALLOWED ON A LOOKUPED FILE 10$: MOV @SP,R1 ;READ OR WRITE? BMI 40$ ;WRITE ; CHECK WHETHER READ WILL EXCEED HBLK LIMIT TSTB R1 ;IS WORD COUNT A MULTIPLE OF 256? BEQ 20$ ;YES ADD #256.,R1 ;NO-ROUND UP TO NEXT 256. WORD BOUND 20$: CLRB R1 ;FUNNY DIVIDE BY 256. SWAB R1 ADD @R4,R1 ;ADD IN START OF REQUEST DEC R1 ;THIS IS THE LAST BLOCK WHICH WILL BE READ CMP R0,R1 ;DOES IT EXCEED HBLK? BHIS 60$ ;NO-CONTINUE 30$: JMP EOFERR ;YES-GIVE END OF FILE ; CHECK WHETHER READ OR WRITE TRYS TO EXCEED HBLK 40$: INC R0 ;WRITE CAN ACCESS ONE BLOCK PAST LAST BLOCK WRITTEN 50$: CMP R0,@R4 ;IS BLOCK NUMBER LARGER THAN HBLK? BLO 30$ ;YES-GIVE END OF FILE ; POSITIONING ROUTINE 60$: MOV @R4,R2 ;GET BLOCK NUMBER SUB D.CBLK(R5),R2 ;GET DIFFERENCE BETWEEN THE CURRENT POSITION ;OF THE TAPE AND THE BLOCK NUMBER REQUESTED BEQ 100$ ;TAPE IS POSITIONED CORRECTLY-DON'T MOVE TAPE BMI 70$ ;TAPE IS POSITIONED BEFORE THE REQUESTED BLOCK MOV #SF.MFS,R0 ;SET TO FORWARD SPACE TO REQUESTED BLOCK BR 80$ 70$: NEG R2 ;TAPE IS POSITIONED BEFORE THE REQUESTED BLOCK MOV #SF.MBS,R0 ;SET TO BACKSPACE TO REQUESTED BLOCK 80$: CALL EXECHH ;GO DO SPACING BEQ 90$ ;OPERATION OK JMP ERRR ;GO GIVE EXCEPTION INDICATION ; SET CBLK EQUAL TO BLK 90$: MOV MTCQE,R4 ;POINT TO QUEUE ELEMENT MOV DVTBL,R5 ;POINT TO DVINFO TABLE MOV @R4,D.CBLK(R5) ;CBLK=BLK ; DO THE READ/WRITE 100$: .IF EQ MMG$T MOV Q$BUFF(R4),XAREA2 ;GET THE BUFFER ADDRESS .IFTF 110$: .IFT MOV XAREA2,R1 ;GET THE BUFFER ADDRESS .ENDC; EQ MMG$T MOV @SP,R2 ;READ OR WRITE? AND GET WORD COUNT BMI 120$ ;WRITE BEQ 300$ ;SEEK ; READ ROUTINE MOV #SF.MRD,R0 ;READ CMP #256.,R2 ;IS WCNT > 256? BGE 140$ ;NO BR 130$ ;YES-CHANGE IT TO 256 ; WRITE ROUTINE 120$: MOV #SF.MWR,R0 ;WRITE 130$: MOV #256.,R2 ;WRITE ALWAYS WRITES 256. WORDS ; EXECUTE READ OR WRITE 140$: MOV DVTBL,R3 ;POINT TO DVINFO TABLE CMP #-1,D.CBLK(R3) ;IS THE BLOCK NUMBER SIGNIFICANT? BEQ 160$ ;NO-SKIP OVER IT TST @SP ;IS THIS A WRITE ? ;BD0+ BPL 150$ ;IF PL, NO SKIP UPDATE ;BD0- MOV D.CBLK(R3),D.HBLK(R3) ;UPDATE HIGHEST BLOCK NUMBER 150$: INC D.CBLK(R3) ;UPDATE CURRENT BLOCK NUMBER ;BD0 160$: CALL EXECHH ;GO DO IT! BEQ 270$ ;NO ERRORS DETECTED ; ERROR IN READ/WRITE MOV DVTBL,R3 ;POINT TO DVINFO TABLE TSTB R5 ;HARD ERROR? BNE 210$ ;YES BIT #EM.EOF,R4 ;TM MARKER REACHED? BNE 170$ ;YES TST @SP ;NO-.READ OR .WRITE REQUEST? BMI 260$ ;.WRITE-GO GIVE EOT;ELSE IGNORE EOT FOR .READ 170$: CMP #-1,D.CBLK(R3) ;IS BLOCK NUMBER SIGNIFICANT? BEQ 180$ ;NO DEC D.CBLK(R3) ;UPDATE CURRENT BLOCK NUMBER 180$: MOV MTCQE,R4 ;POINT TO QUEUE ELEMENT CMP Q$WCNT(R4),@SP ;HAVE WE READ MORE THAN ONE BLOCK? BEQ 200$ ;NO .IF NE MMG$T 190$: CLR -(SP) ;CLEAR A WORD CALL @$PTWRD ;PUT IT IN THE USERS BUFFER SPACE .IFF; NE MMG$T MOV XAREA2,R1 ;YES-ZERO OUT THE REST OF THE USER'S BUFFER 190$: CLR (R1)+ ;CLEAR A WORD .ENDC; NE MMG$T DEC @SP ;ARE WE DONE? BNE 190$ ;NO BR 250$ ;YES-LEAVE ZERO ON STACK SO CSW BIT ISN'T SET 200$: MOV R5,@SP ;SAVE CSW BIT BR 250$ ;GO BACKUP 1 BLOCK 210$: CMP #EM.POS,R4 ;POSITION ERROR? BNE 220$ ;NO MOV #-1,(R3)+ ;INITIALIZE D.CFSN MOV #-1,@R3 ;INITIALIZE D.CBLK 220$: TST @SP ;READ OR WRITE REQUEST? BMI 230$ ;WRITE CMP #EM.BIG,R4 ;IF MORE DATA IN BLOCK IGNORE ERROR BEQ 270$ ;YES-OPERATION WAS OK BR 260$ ;READ ERROR 230$: CMP #EM.POS,R4 ;IF POSITION ERROR BEQ 240$ ;YES TST R4 ;CHECK FOR NOQUAL ERROR BEQ 240$ ;YES CMP #EM.NXM,R4 ;CHECK FOR MEMORY ERROR BNE 260$ ;NO ; TRY AND SAVE WHAT'S WRITTEN 240$: MOV R5,-(SP) ;SAVE ERROR REGISTER CALL WRT3TM ;WRITE 3 TAPEMARKS 250$: CALL BACKU1 ;POSITION AFTER FILE MOV (SP)+,R5 ;RESTORE ERROR REGISTER 260$: JMP ERRR ;GO GIVE EXCEPTION INDICATION ; CHECK IF REQUEST DONE 270$: .IF NE MMG$T XBUMP: MOV MTCQE,R2 ;Point to Queue element ADD #10,Q$PAR(R2) ;bump the Q$PAR and Q$MEM entries ADD #10,Q$MEM(R2) ; by one block's worth of chunks ADD #1000,OLDBA ; and OLDBA/EXTADR ADC EXTADR ; by 512 bytes. .IFF; NE MMG$T ADD #1000,XAREA2 ;POINT NEXT BUFFER .ENDC; NE MMG$T MOV @SP,R2 ;READ OR WRITE REQUEST? BPL 280$ ;READ NEG R2 ;WRITE-MAKE A POSITIVE NUMBER 280$: SUB #256.,R2 ;ARE WE DONE? BLE 300$ ;YES TST @SP ;READ OR WRITE? BPL 290$ ;WRITE NEG R2 290$: MOV R2,@SP ;PUT WORD COUNT BACK BR 110$ ; END OF READ/WRITE 300$: TST (SP)+ ;FIX UP STACK JMP DONE ...... .DSABL LSB .SBTTL EXECUTION AND STACK ADJUSTER ROUTINES ;+ ; ROUTINE EXECHH ; ; ENTRY: ; R0=HARDWARE CODE ; R1=BUFFER ADDRESS(NOT USED IF MMG$T <>0) ; R2=WORD COUNT ; ; THIS ROUTINE BUILDS A FAKE QUEUE ELEMENT AND THEN PASSES IT TO THE ; HARDWARE HANDLER. ;- EXECHH: MOV NQ,R3 ;POINT TO FAKE Q ADDRESS MOVB R0,NQ.FUNC ;MOVE IN THE CODE .IF EQ MMG$T MOV R1,NQ.BUF ;MOVE IN THE BUFFER ADDRESS .ENDC; NE MMG$T MOV R2,NQ.WC ;MOVE IN THE WORD COUNT ;FALL THROUGH TO ADJSP ; ROUTINE ADJSP ; ; ENTRY: ; JUMP TO HARDWARE HANDLER -- ; THIS ROUTINE ASSUMES THAT THE RETURN ADDRESS IS ON THE STACK ; AND SAVES ALL THE DATA WHICH IS ON THE STACK IN ITS OWN ; DATA AREA ALONG WITH POINTERS TO HELP THE FSMDON AND FSMERR ; ROUTINES RESTORE THE STACK TO WHERE IT WAS. THIS MEANS THAT ; YOU CAN EXECUTE A HARDWARE FUNCTION WITHOUT WORRYING TOO MUCH ; ABOUT THE STACK. ; ; R3 MUST POINT TO THE BLOCK NUMBER IN A QUEUE ELEMENT ; (THE QUEUE ELEMENT CAN BE FAKED.) .ENABL LSB ADJSP: MOV R3,MTCQ ;FAKE QUEUE ELEMENT POINTER .ADDR #AREA,R5 ;Point to saving area MOV R5,AREMIN ;SAVE START OF AREA 10$: CMP SP,SPSAV ;SP ADJUSTMENT FINISHED? BEQ 20$ ;YES MOV (SP)+,(R5)+ ;NO BR 10$ 20$: MOV R5,AREMAX ;SAVE END OF SAVE AREA JMP $MT ;GO TO HARDWARE HANDLER .DSABL LSB .SBTTL FSMDON AND FSMERR ENTRY POINTS (FROM HARDWARE HANDLER) ; THESE ROUTINES WILL BE ENTERED FROM THE HARDWARE HANDLER FROM ; VARIOUS PLACES LIKE MTDONE(FSMDON) AND THE ERROR ROUTINE(FSMERR). ; THEY WILL DETERMINE AND REPORT ERRORS DETECTED AND WILL THEN RESTORE ; THE STACK TO WHERE IT WAS. .ENABL LSB .SBTTL ABORT ENTRY POINT FSMABT:: FSMDON::CLR R5 ;INDICATE NO ERRORS FSMERR::MOV SP,SPSAV ;JUST IN CASE SP HAS CHANGED TST CODE ;HH FUNCTION? BPL 20$ ;NO TST R5 ;YES-EXCEPTION CONDITION TO REPORT? BEQ 10$ ;NO ; HARDWARE HANDLER FUNCTION ERROR OCCURRED MOV R5,-(SP) ;YES-SAVE CSW BIT MOV MTCQE,R5 ;POINT TO BLOCK NUMBER IN QUEUE ELEMENT BIS (SP)+,@Q$CSW(R5) ;SET CSW BIT INTO CSW TST @R5 ;ERRBLK ARG EQUAL TO ZERO? BEQ 10$ ;YES-DON'T REPORT ERRORS .IF NE MMG$T COM SINK ;A .SYNCH WILL BE DONE MOV @MTCQE,ERBSAV ;REMEMBER ERRBLK ADDRESS FOR AFTER THE .SYNCH MOV R4,TEMP ;REMEMBER THE ERROR CODE .IFF; NE MMG$T MOV R4,@(R5)+ ;SET EXCEPTION CODE INTO ERRBLK .ENDC; NE MMG$T $DONEL: 10$: JMP $DONE ;GOTO HARDWARE HANDLER ; FSM FUNCTION 20$: MOV R0,(PC)+ ;SAVE R0 R0SAV: .WORD 0 MOV R1,(PC)+ ;SAVE R1 R1SAV: .WORD 0 MOV R2,(PC)+ ;SAVE R2 R2SAV: .WORD 0 MOV R3,(PC)+ ;SAVE R3 R3SAV: .WORD 0 BIT #EOF$,R5 ;WAS AN END OF FILE ISSUED? BEQ 30$ ;NO BIT #EM.EOT,R4 ;IS THE EOT BIT SET? BEQ 30$ ;NO MOV DVTBL,R3 ;POINT TO DVINFO TABLE MOVB #-1,D.EOT(R3) ;MARK EOT MARKER PASSED 30$: MOV AREMAX,R3 ;THIS IS WHERE STACK INFO STARTS 40$: CMP R3,AREMIN ;IS THE STACK RESTORED? BEQ 50$ ;YES MOV -(R3),-(SP) ;NO BR 40$ 50$: TST R5 ;TEST FOR ERRORS RETURN ;ON ERROR EXIT; R5=BIT 13 SET IF EOF ...... ;BIT 0 IF HARD ERROR ;R4=QUALIFYING INFORMATION CODE ;R5=0 IF NO EXCEPTION CONDITIONS ; AND Z BIT IS SET .DSABL LSB .SBTTL FIND A FILE ON MAGTAPE ; THIS ROUTINE WILL ACCEPT A VALUE IN R3 WHICH CORRESPONDS TO THE SEQNUM ; VALUE GIVEN IN THE .ENTER, .LOOKUP, AND .DELETE EMT REQUESTS. ; THIS ROUTINE USES THE D.CFSN VARIABLE IN THE DVINFO TABLE TO DETERMINE THE ; POSITION OF THE MAGTAPE SO THAT IT CAN KNOW WHICH WAY TO SEARCH THE TAPE. ; IF THE POSITION IS UNKNOWN (D.CFSN IS 0) THEN THE FNDPOS ROUTINE IS CALLED ; TO LOCATE THE POSITION OF THE MAGTAPE. GETFIL NEEDS D.CFSN TO BE ACCURATE ; IN ORDER TO WORK CORRECTLY. ; VALUE ACTION TAKEN ; NEGATIVE THE TAPE IS SEARCHED FOR THE FILENAME STARTING FROM ; -1 WHERE EVER THE TAPE IS POSITIONED. (REWIND IS ; SUPPRESSED). ; PLEASE NOTE THAT ALTHOUGH ANY NEGATIVE NUMBER MAY BE ; USED TO SUPPRESS REWIND -1 SHOULD BE USED AS THE REST ; OF THE NEGATIVE NUMBERS ARE RESERVED FOR FUTURE USE. ; ZERO THE TAPE IS REWOUND AND THEN SEARCHED FOR THE FIRST ; OCCURANCE OF THE SUPPLIED FILE NAME (IN LNAME). ; POSITIVE THIS IS DEFINED AS A FILE SEQUENCE NUMBER SEARCH. ; THE TAPE POSITION IN D.CFSN IS COMPARED TO THE VALUE ; AND IF GREATER THAN THE TAPE IS SEARCHED FROM ITS ; PRESENT POSITION UNTIL THE FILE IS FOUND. ; IF LESS THAN OR EQUAL THE DIFFERENCE IS COMPARED TO 2. ; IF THIS COMPARISON SHOWS THAT THE FILE REQUESTED IS ; MORE THAN 2 FILES AWAY THEN THE TAPE IS REWOUND AND ; SEARCHED FROM THE BEGINNING. ; IF THE REQUESTED FILE IS LESS THAN OR EQUAL TO 2 FILES ; THEN THE TAPE POSITION IS CHECKED TO SEE WHETHER IT IS ; AT THE FRONT OF THE TAPE AND IT WOULD BE FASTER TO ; REWIND ANYWAY. IF THE TAPE IS GREATER THAN 4 FILES ; FROM THE BOT THEN THE TAPE IS BACKSPACED TO THE FILE. ; EXIT: R0=0 IF THE FILE HAS BEEN FOUND ; R0=1 OF THE FILE WAS NOT FOUND ; ALL REGISTERS ARE DESTROYED BY THIS SUBROUTINE .ENABL LSB GETFIL: MOV #1,R2 ;assume pointing to HDR1 ;004 MOV R3,-(SP) ;SAVE FSN WHICH WE'RE LOOKING FOR BNE 20$ ;IF 0 THEN REWIND THE TAPE 10$: CALL REW ;REWIND THE TAPE 20$: TST @DVTBL ;DO WE KNOW WHERE WE ARE? BGT 30$ ;YES ;023 CALL FNDPOS ;NO 30$: MOV @SP,R0 ;FSN OR FILENAME BLE 50$ ;FILENAME SUB @DVTBL,R0 ;FSN-D.CFSN BNE 40$ ;branch if we must move somewhere ;004 TST R2 ;next record HDR1? ;004 BGT 50$ ; if so, go read it and be done. ;004 BR BAKFSN ; otherwise, back up to start of file ;004 40$: ;004 BLT BAKFSN ;BACKUP TO FIND THE FILE WE WANT ;SHD01 ; SEARCH FORWARDS TO FIND EITHER FSN OR FILENAME 50$: CALL READLA ;TRY TO READ HDR1 BNE 70$ ;BRANCH IF NOT A TM TST (SP) ; FSN or filename? ;005 BLE 60$ ;005 CMP @SP,@DVTBL ; FSN; Was that the end? ;005 BNE 60$ ; Return if not. ;005 CALL BACKU1 ; Maintain tape position ;005 BR BAKFSN ; back up to start of file. ;005 ; Report FILE NOT FOUND 60$: TST (SP)+ ;LEOT FOUND-FIX THE STACK MOV #1,R0 ;SET R0 AND THE CONDITION CODES RETURN 70$: BMI DIRER ;GO GIVE DIRECTORY ERROR 80$: TST @SP ;FSN OR FILENAME? BLE 100$ ;FILENAME CMP @SP,@DVTBL ;FSN FOUND? BNE 110$ ;NO 90$: TST (SP)+ ;FSN IS FOUND-FIX STACK AND CLEAR CARRY BIT CLR R0 ;CLEAR R0 AND SET CONDITION CODES RETURN 100$: CALL MATCH ;FILENAME IS BEING SEARCHED FOR BCC 90$ ;FOUND! 110$: CALL FORWT2 ;POINT TO DATA, THEN TO EOF1 CALL READLA ;CHECK FOR EOF/EOV BEQ DIRER ;TM FOUND BPL 80$ ;HDR1 FOUND CALL FORWTM ;POINT TO HDR1 BR 50$ ; SEARCH BACKWARDS FOR FILE ; R0 MUST CONTAIN THE DIFFERENCE BETWEEN FSN AND D.CFSN BAKFSN: CMP #-2,R0 ;GREATER THAN 2 FILES TO BACKUP? BGE 10$ ;YES-GO REWIND CMP #4,@DVTBL ;IF NEAR THE BOT THEN REWIND BGE 10$ ;YES-GO REWIND ; BACKUP 1 FILE 120$: CALL BACKT2 ;POINT TO END OF EOF LABEL AND DATA AREAS CALL FORWTM ;POINT TO EOF1 CALL READLA ;CHECK FOR EOF1 BGE DIRER CALL BACKT2 ;POINT TO END OF DATA THEN HDR LABEL CALL BACKTM ;POINT TO END OF EOF LABEL AREA 130$: CALL FORWTM ;POINT TO HDR1 CALL READLA ;CHECK FOR HDR1 BEQ DIRER BMI 130$ ;EOF1-SPACE FORWARD A LABEL CMP @SP,@DVTBL ;HAVE WE FOUND THE CORRECT FSN? BNE 120$ ;NO BR 90$ ;YES DIRER: JMP DIRERR ;GIVE DIRECTORY ERROR .DSABL LSB .SBTTL FIND POSITION ON MAGTAPE ; THIS ROUTINE WILL ATTEMPT TO DETERMINE THE POSITION OF THE MAGTAPE WHEN ; THE CURRENT FILE SEQUENCE NUMBER INDICATOR (D.CFSN IN DVINFO) SHOWS THAT THE ; MAGTAPE POSTION IS UNKNOWN. THE ROUTINE WILL LEAVE THE TAPE AT THE END ; OF A FILE, THAT IS AFTER THE TAPE MARK FOLLOWING THE EOF1 LABEL FOR THAT ; FILE. IF THE TAPE IS DETERMINED TO BE AT BOT THEN THE VOL1 LABEL IS READ ; AND THE TAPE IS LEFT POSITIONED AFTER THE VOL1 LABEL. THIS ROUTINE UPDATES ; D.CFSN. .ENABL LSB FNDPOS: MOV DVTBL,R3 ;POINT TO DVINFO TABLE CLRB D.EOT(R3) ;RESET THE EOT MARKER PASSED FLAG 10$: CALL BACKTM ;BACKUP TO SEE WHERE WE ARE 20$: CMP #EM.BOT,R4 ;ARE WE AT BOT? BNE 40$ ;NO 30$: CLR @DVTBL ;UPDATE D.CFSN RETURN ...... ; WE AREN'T AT BOT SO KEEP LOOKING 40$: CALL BACKTM CMP #EM.BOT,R4 ;ARE WE AT BOT? ;BD1 BEQ 30$ ;YES,GO INDICATE IT ;BD1 CALL FORWTM ;SPACE BACK OVER TM CALL GETLA ;TRY AND READ LABEL BIT #EM.EOF,R4 ;TM FOUND? BEQ 50$ ;NO-CHECK THE LABEL CALL BACKTM ;YES-WE WERE ON A DOUBLE TM BR 10$ ;GO BACKUP SOME MORE 50$: MOV LABINP,R1 ;CHECK FOR EOF1 CMP #"EO,(R1)+ BNE 10$ ;NO EOF1 CMP #"F1,(R1)+ BNE 10$ ;NO EOF1 ADD #FSNASC-LNAME,R1 ;POINT TO FILE SEQUENCE NUMBER FIELD MOV #4,R0 ;SET TO CONVERT 4 DIGITS CALL DECBIN MOV R0,@DVTBL ;SAVE FILE SEQUENCE NUMBER CALL FORWTM ;EOF1 FOUND - move across tape mark, CALL READLA ;Verify next LABEL or LEOT and update D.CFSN MOV R2,-(SP) ;save label indicator ;004 CALL BACKU1 ;KEEP THE POSITION CORRECT MOV (SP)+,R2 ;restore label indicator ;004 RETURN ...... .DSABL LSB .SBTTL MATCH A FILENAME SUBROUTINE ; ENTRY- R1 POINTS TO THE FILE IDENTIFIER IN A HDR1. ; EXIT- R0-R4 DESTROYED ; CARRY BIT SET IF FILE WAS NOT THE SAME AS THE FILENAME IN LNAME ; CARRY BIT CLEARED IF THE FILENAMES MATCHED ; XAREA2 IS USED AS A TEMPORARY WORK AREA(10 CHARACTERS) ; THIS ROUTINE WILL TRANSLATE THE FILENAME IN THE HDR1 INTO A FILENAME WHICH ; COULD BE MATCHED TO THE FILENAME TRANSLATED BY THE R50ASC ROUTINE. ; XXXXXX.XXX WHERE X CAN BE ANY ASCII LETTER OR DOLLAR SIGN($) ; AND THE DOT IS REQUIRED. ; THE ALGORITHM USED IS COMPATIBLE WITH THE DEC STANDARD AS WELL AS ALLOWING ; TAPES WRITTEN UNDER RT11 V02-V02C TO BE READ AND MATCHED(THESE TAPES DON'T ; HAVE A DOT TO SEPARATE THE FILENAME FROM THE EXTENSION. RT11 TAPES ; ARE DETECTED BY THE PRESENCE OF 'RT11' IN CP61-CP64 OF THE HDR1 LABEL. ; THE ALGORITHM IS AS FOLLOWS: ; 1. CLEAR THE CHARACTER COUNT(CC) ; 2. LOOK AT THE FIRST CHARACTER IN THE FILENAME, IF IT IS A DOT THEN DO THE ; FOLLOWING: ; 1.MARK A DOT FOUND ; 2.IF CC < 6 THEN INSERT SPACES AND INCREMENT THE CC UNTIL CC = 6 ; 3.IF CC > 6 THEN DELETE CHARACTERS AND DECREMENT THE CC UNTIL CC = 6 ; 3. IF CC = 6 AND IF 'RT11' IS FOUND IN CP61-CP64 OF THE SYSTEM CODE FIELD ; THEN INSERT A DOT IN THE TRANSLATED NAME, MARK THE DOT FOUND, AND ; INCREMENT CC. ; 4. MOVE THE CHARACTER INTO XAREA2 AND POINT TO THE NEXT CHARACTER. ; 5. INCREMENT THE CC. ; 6. IF CC < 9. GO BACK TO 2. ; 7. CHECK THE DOT FOUND INDICATOR AND IF A DOT WASN'T FOUND THEN BACKUP ; 4 CHARACTERS AND INSERT '.DAT' FOR THE EXTENSION. ; 8. NOW PERFORM A CHARACTER BY CHARACTER COMPARISON BETWEEN THE FILENAME ; BEING LOOKED FOR (IN LNAME) AND THE FILENAME WHICH WAS BUILT FROM THE ; FILENAME IN THE HDR1. IF THEY COMPARE THEN CLEAR THE CARRY BIT AND RETURN, ; ELSE SET THE CARRY BIT AND RETURN. .ENABL LSB MATCH: CLR R2 ;COUNT CHARACTERS HERE (CC) CLR R3 ;MARK NO DOT FOUND MOV R1,R4 ;SAVE POINTER INTO HDR1 ADD #SYSCOD-LNAME,R4 ;MAKE IT POINT TO SYSTEM CODE .ADDR #XAREA2,R0 ;Point to XAREA2 for building filename 10$: CMPB #'.,@R1 ;DOT FOUND? BNE 40$ ;NO INC R3 ;MARK DOT FOUND 20$: CMP #6,R2 ;IS CC < 6? BEQ 50$ ;CC IS EQUAL TO 6 BLT 30$ ;NO ; CC IS LESS THAN 6 AND A DOT HAS BEEN SPOTTED MOVB #' ,(R0)+ ;SPACE FILL TO 6 CHARACTERS INC R2 ;BUMP CC BR 20$ ;GO SEE IF WE'RE DONE ; CC IS GREATER THAN 6 AND A DOT HAS BEEN SPOTTED 30$: CMPB -(R2),-(R0) ;DECREMENT CC AND XAREA2 POINTER BR 20$ ;GO SEE IF WE'RE DONE ; CC IS EQUAL TO 6 40$: CMP #6,R2 ;IS CC = 6? BNE 50$ ;NO CMP #"RT,@R4 ;TRY AND SPOT RT11 IN THE SYSTEM CODE BNE 50$ ;NOT FOUND CMP #"11,2(R4) BNE 50$ ;NOT FOUND ; THIS IS A TAPE WRITTEN BY RT-11 V02 THROUGH V02C MOVB #'.,(R0)+ ;INSERT AN EXTRA DOT IN THE FILENAME CMPB (R2)+,(R3)+ ;INCREMENT CC AND DOT FOUND MARKER ; MOVE THE CHARACTER AND SEE WHETHER NAME HAS BEEN BUILT 50$: MOVB (R1)+,(R0)+ ;MOVE THE CHARACTER INC R2 ;INCREMENT CC CMP #9.,R2 ;IF CC < 9 THEN WE AREN'T DONE YET BGE 10$ ;NOT DONE TST R3 ;WAS DOT FOUND? BNE MATCH1 ;YES ; DOT NOT FOUND MOV #"AT,-(R0) ;DEFAULT TO .DAT EXTENSION MOV #".D,-(R0) CMP (R0)+,(R0)+ ;POINT BACK TO END OF BUILT NAME IN XAREA2 ; MATCH A FILENAME MATCH1: .ADDR #,R1 ; Point to end of LNAME filename 60$: CMPB -(R0),-(R1) ; Match? BNE 70$ ; No. SOB R2,60$ ; Loop until entire name compares TST (PC)+ ; filename found 70$: SEC RETURN .DSABL LSB .SBTTL CONVERT A FILENAME FROM RAD50 TO ASCII ; ENTRY: R4 POINTS TO THE WORD FOLLOWING THE RAD50 FILENAME. ; ; EXIT: R3 IS UNCHANGED ; R4 POINTS TO FNAM IN DTBL ; R5 POINTS TO ASCII NAME ; OTHER REGISTERS ARE DESTROYED .ENABL LSB R50ASC: MOV PC,R5 ADD #LNAME-.+10.,R5 ;GET UNPACKING AREA ADDRESS MOV #1,R2 ;3 WORDS TO CONVERT GET50: MOV -(R4),R0 ;GET A RAD50 WORD MOV #3,-(SP) ;3 CHARACTERS CNVLUP: CLR R1 ;CLEAR REMAINDER MOV #20,-(SP) ;16 BITS DIVLUP: ASL R0 ;SHIFT DIVIDEND-QUOTIENT REGISTER ROL R1 ;SHIFT REMAINDER CMP R1,#50 ;BIT ENUF TO SUBTRACT? BLO NOFIT ;NO SUB #50,R1 ;IF SO-SUBTRACT DIVISOR INC R0 ;SET CORRESPONDING BIT IN QUOTIENT NOFIT: DEC @SP ;ANY MORE BITS? BNE DIVLUP ;IF SO - CONTINUE DIVISION TST (SP)+ ;WHEN DONE-FIX SP TST R1 ;AND CONVERT R1 TO ASCII BEQ PSPACE ;=0 MEANS SPACE CMP R1,#32 ;LETTER (1-32)? BLE LETTER SUB #36,R1 ;DIGIT (36-47)? BCC DIGIT PSPACE: MOV #-40,R1 ;0,33,34,35 GIVE SPACE LETTER: ADD #20,R1 ;CONVERT (1-32) TO (101-132) DIGIT: ADD #60,R1 ;CONVERT (36-47) TO (60-71) MOVB R1,-(R5) ;INSERT CHARACTERS IN STORAGE DEC @SP ;DO 3 CHARACTERS BGT CNVLUP TST (SP)+ ;FIX STACK DEC R2 ;DO NEXT WORD BNE 10$ ;ZERO MEANS INSERT DOT MOVB #'.,-(R5) ;INSERT THE DOT 10$: CMP #-2,R2 ;ARE WE DONE? BNE GET50 20$: RETURN ...... .DSABL LSB .SBTTL SQBLNK - Squeeze blanks out of HDR1/EOF1 ;+ ; Squeeze blanks out of HDR1/EOF1 name area ;- .ENABL LSB SQBLNK: MOV #10.,R0 ; counter .ADDR #LNAME,R1 ; input pointer MOV R1,R2 ; output pointer 30$: MOVB @R1,@R2 CMPB (R1)+,#40 ; is char blank? BEQ 40$ TSTB (R2)+ ; if not, point to next out char 40$: SOB R0,30$ ; loop until done 50$: CMP R2,R1 ; all done? BEQ 70$ MOVB #40,(R2)+ ; work in a trailing blank BR 50$ .SBTTL DECIMAL TO BINARY SUBROUTINE ; ENTRY: R1=ADDRESS OF DECIMAL NUMBER ; R0=NUMBER OF DIGITS TO CONVERT ; ; EXIT: R0=NUMBER ; R2 IS DESTROYED DECBIN: CLR -(SP) ;FORM THE NUMBER HERE 60$: MOV @SP,R2 ;MULTIPLY BY 10 ROUTINE ASL @SP ;X2 ASL @SP ;X4 ADD R2,@SP ;X5 ASL @SP ;X10 MOVB (R1)+,R2 ;GET CHARACTER SUB #'0,R2 ;STRIP OFF ASCII BITS ADD R2,@SP ;ADD INTO NUMBER SOB R0,60$ ;DONE YET? MOV (SP)+,R0 ;YES-RETRIEVE NUMBER 70$: RETURN ...... .DSABL LSB .SBTTL BINARY TO DECIMAL SUBROUTINE ;+ ; BINARY TO DECIMAL SUBROUTINE ; ; ENTRY: R2=BINARY NUMBER TO CONVERT ; R4 POINTS TO OUTPUT STRING AREA ; R0=(5-NUMBER OF DIGITS TO OUTPUT)*2 [DECTBL DISPLACEMENT] ; ; EXIT: R4 POINTS PAST LAST CHARACTER WRITTEN ; R0, R1, R2, DESTROYED ; R3 AND R5 ARE PRESERVED ;- .ENABL LSB BINDEC: ADD PC,R0 ;POINT TO CORRECT PLACE IN DECTBL ADD #DECTBL-.,R0 10$: MOV #'0-1,R1 ;form character in r1 20$: INC R1 ;next digit... SUB @R0,R2 ;subtract power of ten BCC 20$ ;until underflow ADD (R0)+,R2 ;fix number and point to next power of ten MOVB R1,(R4)+ ;save this digit TST @R0 ;at end of table? BNE 10$ ;No - do next power RETURN ...... .DSABL LSB .SBTTL CONVERT AN RT-11 DATE TO YYDDD FORMAT ; CONVERT AN RT-11 DATE INTO YYDDD NOTATION FOR ANSI LABEL ; R0 THROUGH R4 ARE DESTROYED .ENABL LSB DATE: MOV @#$SYPTR,R2 ;GET SYSTEM DATE WORD MOV $DATE(R2),R2 MOV R2,R1 ;COPY DATE TO R1 ASR R1 ;MOVE MONTH RIGHT ONE SWAB R1 ;MONTH X 2 IN R1 ;024 MOV R1,-(SP) ;SAVE FOR EPOCH ;024 BIC #^c<17*2>,R1 ;GET MONTH BITS;R2= ;024 .ADDR #MONTAB,R4 ;Point to month table ADD R1,R4 MOV @R4,R3 ;R3=NUMBER OF DAYS TO FIRST OF MONTH CMP R1,#4 ;IS MONTH = JANUARY OR FEBRUARY? BLE 10$ ;YES - NO LEAP YEAR YET BIT #3,R2 ;IF BOTH BITS OF DATE=0 THEN LEAP YEAR BNE 10$ ;AND THERE IS EXTRA DAY AROUND INC R3 ;EXTRA DAY 10$: MOV R2,R1 ;DATE TO R1 ASR R1 ASR R1 ASR R1 ASR R1 ASR R1 ;DAYS INTO BITS<4:0> BIC #177740,R1 ;R1=DAY ADD R1,R3 ;TOTAL NUMBER OF DAYS THIS YEAR IN R3 BIC #177740,R2 ;LEAVE YEAR IN R2 MOV (SP)+,R0 ;GET BACK OUR SAVED EPOCH INFO ;024 BIC #^c140,R0 ;LEAVE EPOCH*32 IN R0 ;024 ADD R0,R2 ;R2=EPOCH*32+YEAR ;024 BEQ 20$ ;IF YEAR = 0 THEN NO YEAR ;024 ADD #72.,R2 ;R2=YEAR+1972 ;024 20$: MOV PC,R4 ;024 ADD #DAREA-.,R4 ;R4 POINTS TO DATE STRING ;024 MOVB #' ,(R4)+ ;Years before 2000 get a space ;024 CMP R2,#100. ;But years after 2000 ;024 BLT 30$ ; will ;024 MOVB #'0,-1(R4) ; get a '0' and need ;024 SUB #100.,R2 ; 100 taken off before conversion;024 30$: MOV #<10.-<2*2>>,R0 ;Advance into DECTBL(YEAR=2 CHARACTERS CALL BINDEC ;CONVERT YEAR TO ASCII MOV R3,R2 ;DAY TO R2 ;024 MOV #<10.-<3*2>>,R0 ;Advance INTO DECTBL(DAY=3 CHARACTERS) CALLR BINDEC ;CONVERT DAYS TO ASCII, AND RETURN ...... .DSABL LSB .SBTTL TAPE MANIPULATING SUBROUTINES .ENABL LSB ; Forward by Tape Marks FORWT2: CALL @PC ;FORWARD 2 TAPEMARKS FORWTM: MOV #SF.MFS,R0 ;SET FOR FORWARD SPACE CALL 10$ ;THIS GETS CONTROL BACK IF NO HARD ERRORS BIT #EM.EOF,R4 ;DID WE FIND A TAPEMARK? BNE 60$ ;YES WE DID BR FORWTM ;NO-REISSUE THE FORWTM UNTIL WE FIND ONE ...... ; Backspace blocks BACKU2: CALL @PC ;BACKSPACE 2 BLOCKS BACKU1: MOV #SF.MBS,R0 ;SET TO BACKSPACE MOV #1,R2 ;JUST ONE BLOCK BR 20$ ...... ; Rewind the tape REW: MOV DVTBL,R3 ;POINT TO DVINFO TABLE CLRB D.EOT(R3) ;RESET THE EOT MARKER PASSED FLAG CLR @R3 ;SET D.CFSN TO 0 MOV #SF.MRE,R0 ;SET FOR REWIND BR 30$ ...... ; Backspace by Tape Marks BACKT2: CALL @PC ;BACKSPACE 2 TAPEMARKS BACKTM: MOV #SF.MBS,R0 ;SET FOR BACKSPACE TAPEMARK .BR 10$ 10$: MOV #-1,R2 ;MAXIMUM NUMBER OF BLOCKS WHICH CAN BE SPACED 20$: .ADDR #,R1 ;MAKE SURE THAT EXTRA (ERRBLK+2) GETS UPDATED MOV R1,@NQ ;SO POINT NEW QUEUE ELEMENT TO ERRBLK EXHH1: 30$: CALL EXECHH ;EXECUTE THE FUNCTION BEQ 60$ ;EXCEPTION CONDITIONS? BIT #HDERR$,R5 ;YES-TEST HARDERROR BIT BEQ 60$ ;NOT SET BR ERRR ;SET ...... .SBTTL GETLA - Read a label ;+ ; Try to read a label. This routine will read 80 bytes. If no exception ; conditions occur or a length error occurs then R4 is cleared. If ; any other hard error occurs then the err routine is jumped to. If anything ; else, the routine just returns with R4 containing the code which was ; returned from the hardware handler. ;- GETLA: MOV #SF.MRD,R0 ; get the READ code .IF NE MMG$T MOV LRBUBL,OLDBA ; Point to LABEL READ buffer MOV LRBUBH,EXTADR ; UNIBUS-compatible .IFF; NE MMG$T MOV LABINP,R1 ; point to label input buffer .ENDC; NE MMG$T MOV #40.,R2 ;READ 80 BYTES .ADDR #,R4 ;Fake ERRBLK for HH MOV R4,@NQ CALL EXECHH ;Read a block BEQ 50$ ;Branch if no exception conditions BIT #HDERR$,R5 ;HARD ERROR? BEQ 60$ ;NO-MUST BE EOF AND/OR EOT CMP #EM.BIG,R4 ;IS IT A LENGTH ERROR? BHI ERRR ;NO-GO ISSUE ERROR 50$: CLR R4 ;MARK NO EOF/EOT DETECTED FOR READLA ROUTINE 60$: RETURN ...... .DSABL LSB .SBTTL READ/WRITE LABELS SUBROUTINES ;+ ; THIS SUBROUTINE WILL READ A LABEL FROM THE CURRENT POSITION OF THE TAPE AND ; WILL THEN TAKE THE FOLLOWING ACTIONS. ; 1. IF A HARD ERROR OCCURRED THEN THE ROUTINE WILL TEST FOR A RECORD ; LENGTH ERROR. IF A RECORD LENGTH ERROR THEN THE CONDITION IS IGNORED ; OTHERWISE A DIRECTORY ERROR IS GIVEN. ; ; 2. IF AN END OF FILE CONDITION OCCURRED THEN THE ROUTINE WILL CHECK TO ; SEE WHETHER A TAPE MARK CAUSED THE CONDITION. IF A TM CAUSED THE ; CONDITION THEN A ZERO IS MOVED TO R2 AND CONTROL RETURNED. ; ; 3. IF NO EXCEPTION CONDITIONS OCCURRED THEN THE ROUTINE CHECKS FOR ; A HDR1 LABEL. IF A HDR1 LABEL WAS READ THEN A 1 IS MOVED TO R2 AND ; AND CONTROL IS RETURNED. ; ; 4. IF NO HDR1 LABEL WAS FOUND THE ROUTINE CHECKS FOR EOF1 OR EOV1 ; LABELS. IF FOUND THEN A -1 IS MOVED TO R2 AND CONTROL IS RETURNED. ; ; 5. NEXT A VOL1 IS CHECKED FOR. IF A VOL1 IS FOUND THEN A FLAG IS SET ; IN XAREA2 WHICH WILL CAUSE READS TO BE PERFORMED UNTIL A LABEL IS ; FOUND. ; ; 6. IF NONE OF THE ABOVE LABELS HAVE BEEN FOUND AND THE HEADER SEARCH ; SEARCH FLAG ISN'T SET THEN THE ROUTINE WILL JUMP TO DIRERR. ; ; EXITS: ; R2 = 0 TAPE MARK FOUND ; R2 = 1 HDR1 FOUND ; R2 = -1 EOF1 OR EOV1 FOUND ; ; THE CONDITION CODES CAN BE TESTED FOR POSITIVE,NEGATIVE, OR ZERO ON ; RETURN FROM THIS ROUTINE. ; ; R1 POINTS TO FILENAME IN LABINP AREA. ;- .ENABL LSB READLA: CLR XAREA2 ;MARK NO LABEL SEARCH 10$: CALL GETLA ;GO GET A POSSIBLE LABEL BIT #EM.EOF,R4 ;YES-TAPEMARK FOUND? BEQ 20$ ;NO CLR R2 ;YES-MARK IT AND SET CC'S RETURN ; NO EXCEPTION CONDITIONS 20$: MOV LABINP,R1 ;POINT TO LABEL JUST READ CMP #"HD,(R1)+ ;CHECK FOR HDR1 BNE 30$ ;NO CMP #"R1,@R1 BNE 70$ MOV #1,-(SP) ;HDR1 FOUND BR 50$ 30$: CMP #"EO,-2(R1) ;CHECK FOR EOF OR EOV LABEL BNE 60$ ;NO CMP #"F1,@R1 ;EOF1? BEQ 40$ ;YES CMP #"V1,@R1 ;EOV1? BNE 70$ ;NO 40$: MOV #-1,-(SP) ;YES 50$: ADD #FSNASC-HDR1LB-2,R1 ;POINT TO FSN MOV #4,R0 ;CONVERT 4 CHARACTERS CALL DECBIN MOV R0,@DVTBL SUB #-LNAME,R1 ;POINT TO FILENAME MOV (SP)+,R2 ;SHOW WHAT LABEL IT IS RETURN 60$: CMP #"VO,-(R1) ;CHECK FOR VOL1 LABEL BNE 70$ ;NO CMP #"L1,2(R1) BNE 70$ COM XAREA2 ;SET LABEL SEARCH FLAG 70$: TST XAREA2 ;LABEL SEARCH IN PROGRESS? BMI 10$ ;YES BR DIRERR ;GIVE DIRECTORY ERROR ; WRITLA writes a HDR1 or EOF1 label, whose buffer is at HDR1LB WRITLA: .IF NE MMG$T MOV LWBUBL,OLDBA ;Point to LABEL WRITE buffer MOV LWBUBH,EXTADR ; UNIBUS-compatible .IFF; NE MMG$T .ADDR #HDR1LB,R1 ;Point to LABEL WRITE buffer .ENDC; NE MMG$T MOV #SF.MWR,R0 ;SET FOR WRITE MOV #LBLSIZ,R2 ;WRITE this many WORDS EXHH2: BR EXHH1 ;GO DO WRITE AND CHECK FOR HARDERROR ; WRITE TAPE MARKS WRT3TM: CALL WRTTM ;THREE TAPEMARKS WRT2TM: CALL @PC ;TWO TAPEMARKS WRTTM: MOV #SF.MTM,R0 ;SET FOR WRITE TAPEMARK BR EXHH2 .DSABL LSB .SBTTL ERROR EXITS .ENABL LSB ERRR: TST SEEKYN ; Is a SEEK going on? BEQ 40$ ; NO BR 10$ ; Yes - No qualifying info ;001A ...... ;**-5 ; EXIT AND PUT THE VALUE IN R0 INTO THE SPECIAL DEVICE ERROR WORD SPERRF: TST SEEKYN ; Is a SEEK going on? BNE 20$ ; Yes. ; JUST A REGULAR USR REQUEST IN PROGRESS MOV @#$SYPTR,R1 MOV R0,$SPUSR(R1) ; cause R0 to be put in byte 52 BR 50$ ; exit from handler ...... DIRERR: TST SEEKYN ; Is a SEEK going on? BEQ 30$ ; NO ; ASYNCHRONOUS REQUEST IN PROGRESS 10$: CLR R0 ; mystery error .BR 20$ ; go put code in error word ; ASYNCHRONOUS REQUEST IN PROGRESS .IF NE MMG$T 20$: CALL SYNCHB ; set up a .SYNCH block .IFF; NE MMG$T 20$: MOV R0,@SEEKER ; move code to ERRBLK .ENDC; NE MMG$T MOV DVTBL,R5 ; point to DVINFO block MOVB #1,D.FTYPE(R5) ; Say file opened with a NFS .LOOKUP ; USR REQUEST HARDER: 30$: MOV #HDERR$,R5 ; DIRECTORY ERROR - SET HARD ERROR BIT BR 40$ ; DURING A DIRECTORY OPERATION ...... EOFERR: MOV #EOF$,R5 ; MOVE IN EOF BIT 40$: MOV MTCQE,R3 ; POINT TO QUEUE ELEMENT BIS R5,@-(R3) ; SET THE BIT IN THE CSW 50$: MOV SPSAV,SP ; Restore the stack pointer DONE: CALL RESTOR ; RESTORE R0-R3 JMP $DONEL ; Go to Hardware Handler .SBTTL RESTOR - Restore R0-R3 ; Restore registers, saved ... ; This routine is called by BOTH FSM and the Hardware Handler RESTOR::MOV R0SAV,R0 ; RESTORE R0-R3 MOV R1SAV,R1 MOV R2SAV,R2 MOV R3SAV,R3 RETURN ...... .DSABL LSB .IF NE MMG$T .SBTTL SYNCHB - Set up a SYNCH block ; THIS SUBROUTINE SETS UP A .SYNCH BLOCK. ; ENTRY: R0 CONTAINS ERRBLK CODE ; EXIT: R0-R4 ARE PRESERVED, R5 IS DESTROYED. SYNCHB: MOV R0,TEMP ;SAVE R0; THIS VARIABLE COMES BACK ; IN R0 AFTER .SYNCH MOV MTCQE,R5 ;GET JOB NUMBER MOVB Q$JNUM(R5),R5 ASR R5 ASR R5 ASR R5 MOV R5,JOBNM ;STORE IN SYNCH BLOCK COM SINK ;MARK SYNCH WILL BE PERFORMED MOV SEEKER,ERBSAV ;POINT TO ERRBLK ADDRESS FOR HH ;001 RETURN .ENDC; NE MMG$T .NLIST BEX .SBTTL FSM Tables .SBTTL DECTBL - Powers of ten table DECTBL: .WORD 10000.,1000.,100.,10.,1,0 ; Powers of ten table .SBTTL MONTAB - DAYS PER MONTH TABLE ; MONTAB contains 12 entries one for each month each containing the total ; number of days in a non-leap year up till the start of that month. JAN = 0 ;0 DAYS UP TO JANUARY FEB = JAN + 31. MAR = FEB + 28. APR = MAR + 31. MAY = APR + 30. JUN = MAY + 31. JUL = JUN + 30. AUG = JUL + 31. SEP = AUG + 31. OCT = SEP + 30. NOV = OCT + 31. NOEL = NOV + 30. MONTAB: .WORD 0 ;IF NO DATE SPECIFIED, MONTH = 0 .WORD JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,NOEL .SBTTL FSM Variables CODE:: .WORD 0 ;THIS CONTAINS THE FUNCTION CODE WHICH IS ;BEING PERFORMED BY THE FSM EXCEPT WHEN AN ;ASYCHRONOUS REQUEST IS BEING DONE. DVTBL:: .WORD 0 ;ADDRESS OF DVINFO TABLE ENTRY FOR THIS DRIVE .IF NE MMG$T FSMNAM::.RAD50 /FS / ;Pseudo handler name for UB LRBUBL::.WORD 0 ;UNIBUS DMA Address of LABLIO, Bits 0-15 LRBUBH::.WORD 0 ;UNIBUS DMA Address of LABLIO, Bits 16-17 LWBUBL::.WORD 0 ;UNIBUS DMA Address of HDR1LB, Bits 0-15 LWBUBH::.WORD 0 ;UNIBUS DMA Address of HDR1LB, Bits 16-17 .ENDC; NE MMG$T SPSAV: .WORD 0 ;WHENEVER CONTROL IS PASSED FROM THE HH TO THE ;FSM THIS VARIABLE IS LOADED WITH THE VALUE ;THE STACK POINTER. AREMIN: .WORD 0 ;THESE VARIABLES ARE USED TO STORE AND RESTORE AREMAX: .WORD 0 ;VALUES WHICH FSM KEEPS ON THE STACK BUT WHICH ;CAN'T BE THERE WHEN HH IS PERFORMING A ;COMMAND. LABINP: .WORD 0 ;ADDRESS OF AREA TO READ A LABEL INTO NQ: .WORD 0 ;ADDRESS OF FAKE QUEUE ELEMENT ; THIS FLAG IS SO THAT ERROR ROUTINES CAN TELL WHETHER AN ASYNCHRONOUS ; REQUEST IS IN PROGRESS. SEEKYN: .WORD 0 ;SEEK? 0=NO, -1=YES SEEKER: .WORD 0 ;ADDRESS OF SEEK ERROR WORD(S) FSNTMP: .WORD 0 ; Temporary loc for File Seq No. BLKTMP: .WORD 0 ; Temporary loc for Block Seq No. ZEROED: .ASCII /ZEROED.ZZZ/ ; Initialized tape's dummy filename .EVEN .SBTTL FAKE QUEUE ELEMENT ; THESE VARIABLES ARE USED AS BY FSM TO PASS COMMANDS TO HH. NQ.CSW: .WORD 0 ;POINTER TO CSW NQE: NQ.BLK: .WORD 0 ;BLOCK NUMBER NQ.FUNC:.BYTE 0 ;CODE NQ.JNUN:.BYTE 0 ;JOB NUMBER/UNIT NUMBER NQ.BUF: .WORD 0 ;BUFFER ADDRESS NQ.WC: .WORD 0 ;WORD COUNT ; EXTRA IS USED AS THE SECOND WORD IN FSM'S ERRBLK. THE VALUES NORMALLY ; RETURNED IN THE FIRST WORD OF ERRBLK ARE PASSED BACK TO FSM IN REGISTERS ; (SEE FSMDON/FSMERR ROUTINES.) EXTRA CONTAINS VALUES LIKE THE NUMBER OF ; WORDS WHICH WEREN'T THERE ON A READ OR THE NUMBER OF BLOCKS WHICH WEREN'T ; SPACED ETC. ERRBLK = EXTRA-2 ;ADDRESS OF FSM'S ERRBLK (1ST WORD ISN'T USED) EXTRA: .WORD 0 ;NUMBER OF BLOCKS/WORDS NOT SPACED/READ .IF NE MMG$T ;If XM .WORD 0 ;PAR1 BIAS FOR FAKE QUEUE ELEMENT .WORD 0 ; (TWO EXTRA WORDS IN XM QUEUE ELEMENT) .WORD 0 ; .ENDC ;NE MMG$T XAREA2: .WORD 0 ;THIS WORD IS A TEMPORARY VARIABLE USED BY ;THE RW, READLA, SYNCH, AND MATCH ROUTINES. ; THIS AREA IS USED TO STORE THE VALUES FROM THE STACK WHILE HH IS DOING A ; COMMAND. AREA: .BLKW 8. .SBTTL LABEL BUFFERS and DATA ;+ ; ------------------------------------------------------------------- ; HDR1/EOF1 label data for making header and trailer labels. ; See ENT and LOOK routines for more information. ; ; Also, see ANSI X3.27-1987, and ISO 1001-1986 specifications ; ------------------------------------------------------------------- ;- HDR1LB::.ASCII /HDR1/ ; label identifier LNAME: .ASCII / / ; 9 Characters for RT-11 filename .ASCII / / ; 8 Characters are left blank .ASCII /RT11A / ; File Set Identifier .ASCII /0001/ ; File Section Number FSNASC: .ASCII /0000/ ; File Sequence Number .ASCII /0001/ ; Generation Number .ASCII /00/ ; Generation Version Number DAREA: .ASCII / / ; first character of Creation Date ;024 .ASCII /00000/ ; Creation Date (chars 2-6) ;024 .ASCII / 00000/ ; Expiration Date .ASCII / / ; File Accessibility .ASCII /0/ ; Block Count (first character) BLKASC: .ASCII /00000/ ; Block Count (chars 2-6) SYSCOD: .ASCII /DECRT11A / ; Implementation ID .ASCII / / ; reserved area .ASSUME . EQ ; ------------------------------------------------------------------- ; LABLIO is the area used to READ labels into. LABLIO::.BLKB 80. ; label buffer area .ASSUME LABLIO GT HDR1LB ; For Hardware Handler Load code FSMEND = . ; End of FSM .SBTTL DREND .IF NE FSM$MX .RESTORE ; Back to low memory PSECT for DREND .ENDC; NE FSM$MX .DREND MT FSMSIZ==FSMEND-FSMDIS ; For visibility in maps MMEND==MTEND ; For (RT-11/RTEM) MM driver MSEND==MTEND ; For (RT-11/RTEM) MS driver MFEND==MTEND ; For RTEM MF driver MUEND==MTEND ; For RTEM MU driver UMEND==MTEND ; For RT-11 MU driver .END