.TITLE RSXMSG - REPORT RSX-11M ERROR MESSAGE .IDENT /3.4/ .ENABL LC ;+ ; ; Free software BY ; Project Software & Development, Inc. ; ; This software is furnished for free and may be used and copied as ; desired. This software or any other copies thereof may be provided ; or otherwise made available to any other person. No title to and ; ownership of the software is hereby transferred or allowed. ; ; The information in this software is subject to change without notice ; and should not be construed as a commitment by PROJECT SOFTWARE ; AND DEVELOPMENT, INC. ; ; PROJECT SOFTWARE assumes no responsibility for the use or reliability ; of this software on any equipment whatsoever. ; ; Project Software & Development, Inc. ; 14 Story St. ; Cambridge, Ma. 02138 ; 617-661-1444 ; ; ; Title: RSXMSG ; Author: Robin Miller ; Date: November 10, 1981 ; ; Description: ; ; This module contains a complete list of all the RSX-11M error ; codes (both I/O and Directive error codes). It will either return ; the error (or success) messsage to a specified buffer, or will write ; the message to the terminal. In either case, control is returned ; to the user program for further processing. ; ;- .ENABL AMA .MCALL ALUN$S, DIR$, QIOW$, QIOW$S .MCALL FILIO$, NMBLK$, IOERR$ FILIO$ ; DEFINE THE I/O FUNCTIONS IOERR$ ; DEFINE I/O ERROR CODES ;+ ; ; Modification History: ; ; June 7, 1984 by Robin Miller ; Use logical name ER0: for alternate message directory device. ; ; September 14, 1983 by Robin Miller ; Add support for alternate message directory. ; ; September 2, 1983 by Robin Miller ; Pass back the message byte count when there is no error message ; file instead of bad status. ; ; August 30, 1982 by Robin Miller ; Fix bug with checking offsets in the error message block. ; ; May 14, 1982 by Robin Miller ; Add offset for alternate message facility to support BASIC ; error messages. ; ; February 19, 1984 by Robin Miller ; Use the message output LUN assigned by TKB (.MOLUN) for the error ; message file and terminal output LUN and event flag. ; ; February 17, 1984 by Robin Miller ; Always assign TOLUN to TI0: and MSGLUN to LB0: to avoid unassigned ; LUN errors and wrong device assigned by TKB defaults. ; ; February 16, 1982 by Robin Miller ; Add word ALTOFF to the error message block. This word is used to ; specify an alternate message facility such as RMS. This word ; should be -1 to use Directive/FCS errors. ; ; February 15, 1982 by Robin Miller ; Moved directive and I/O error messages to message file ; (LB:[1,2]RSX11M.MSG). Allow terminal output LUN (TOLUN) and ; message file LUN (MSGLUN) to be defined at TKB time using the GBLDEF ; option. These symbols can also be defined within the users program ; by using a double equals (==) to define the symbols as global ; (TKB will do the rest). ; ; January 21, 1982 by Robin Miller ; Change first character in messages to lowercase to be compatable ; with VAX/VMS. ; ; December 30, 1981 by Robin Miller ; Add severity level to messages. ; ;- ; Globals for debugging with DDT (comment out when not using DDT). ; .GLOBL DIRFNB, BASFNB, RSXFNB, MSGDPB, MSGSB, BLKBUF ; .GLOBL WNOMSG, NOMFIL, CHKMSG, GERMSG, FNDMSG, FIND, DOQIO ; ; Local equates. ; ; Maximum error codes in the message file (alter if messages added). MAXFCS = 90. ; MAXIMUM FCS ERROR CODE MAXDIR = 99. ; MAXIMUM DIRECTIVE ERROR CODE MAXSUC = 10. ; MAXIMUM SUCCESS RETURN CODE MAXRMS = 00. ; MAXIMUM RMS ERROR CODE MAXBAS = 74. ; MAXIMUM BASIC ERROR CODE ; Offsets into error message block. ERROFF = 2 ; ERROR CODE OFFSET BUFOFF = 4 ; OUTPUT BUFFER OFFSET FLGOFF = 6 ; MESSAGE FLAGS OFFSET FACOFF = 10 ; FACILITY NAME OFFSET STAOFF = 12 ; STATUS RETURN OFFSET ALTOFF = 14 ; ALTERNATE FACILITY OFFSET ; Bit definitions for message flags word. TXTBIT = 1 ; INCLUDE TEXT OF MESSAGE MIDBIT = 2 ; INCLUDE MESSAGE ID SEVBIT = 4 ; INCLUDE SEVERITY LEVEL FACBIT = 10 ; INCLUDE FACILTY NAME ; Offsets into alternate error messages table (value passed in ALTOFF). DIRMSG = 0 ; DIRECTIVE ERROR MESSAGES FCSMSG = 1 ; FILE CONTROL SYSTEM MESSAGES SUCMSG = 2 ; SUCCESSFUL RETURN MESSAGES RMSMSG = 3 ; RECORD MANAGEMENT SYSTEM BASMSG = 4 ; BASIC INTERPRETER ERRORS MAXMSG = BASMSG + 1 ; MAXIMUM MESSAGE ENTRYS +1 ; Table of offsets into message file for above messages. ; Format: (maximum code) , (offset into message file) MSGTBL: .WORD MAXDIR,0,RSXFNB ; DIRECTIVE MESSAGES (128.) MSGSIZ = .-MSGTBL ; SIZE OF EACH ENTRY .WORD MAXFCS,128.,RSXFNB ; FCS ERROR MESSAGES (128.) .WORD MAXSUC,256.,RSXFNB ; SUCCESS MESSAGES ( 20.) .WORD MAXRMS,276.,RSXFNB ; RMS ERROR MESSAGES (???.) .WORD MAXBAS,0,BASFNB ; BASIC ERROR MESSAGES(100.) ; ; Local storage. ; .NLIST BEX TOTTY: .WORD 0 ; PUT MESSAGE TO TTY FLAG -1 = TRUE TIOSB: .BLKW 2 ; TERMINAL I/O STATUS BLOCK .MOLUN::.WORD 0 ; MESSAGE OUTPUT LUN FILLED IN BY TKB ; Format of error message block (Fortran compatible). ERRBLK: .BYTE 6,0 ; ARGUMENT COUNT (CURRENTLY IGNORED) .WORD ERRCOD ; ADDRESS OF ERROR CODE .WORD OUTBUF ; ADDRESS OF OUTPUT BUFFER (-1 = PUT TO TTY) .WORD DEFFLG ; ADDRESS OF MESSAGE FLAGS (-1 = USE DEFAULT) .WORD FACNAM ; ADDRESS OF FACILITY NAME (-1 = USE DEFAULT) .WORD STATUS ; ADDRESS OF STATUS RETURN (-1 = NO STATUS) .WORD -1 ; ADDRESS OF ALTERNATE FACILITY (-1 = DISABLED) ERRCOD: .WORD 0 ; ERROR CODE OUTBUF: .BLKW 50. ; OUTPUT BUFFER DEFFLG: .WORD TXTBIT!MIDBIT!SEVBIT!FACBIT ; DEFAULT MESSAGE FLAGS FACNAM: .ASCIZ %SYSTEM% ; DEFAULT FACILITY NAME .EVEN STATUS: .WORD 0 ; RETURN STATUS .SBTTL DIRECTIVE PARAMETER BLOCKS DIRFNB: NMBLK$ 001002,DIR,,LB,0 ; FNB FOR LB:[0,0]001002.DIR .=DIRFNB+N.DID .WORD 4,4 ; SET DIRECTORY ID FOR MFD (000000.DIR) .=DIRFNB+S.FNB MSGPTR: .WORD RSXFNB ; POINTER TO FILE NAME BLOCK RSXFNB: NMBLK$ RSX11M,MSG ; FNB FOR RSX11M MESSAGE FILE BASFNB: NMBLK$ BASIC,MSG ; FNB FOR BASIC MESSAGE FILE MSGDPB: QIOW$ ,,,,MSGSB,,<,,,,,> MSGSB: .BLKW 2 ; MESSAGE I/O STATUS BLOCK BLKBUF: .BLKB 512. ; BUFFER FOR VIRTUAL BLOCK .SBTTL SUCTBL - SUCCESSFUL RETURN TABLE ; ; Successful return table. ; ; Although a message is usually not output on success, this table is ; included for completness. It may also be useful in debugging. ; ; Some of the success returns are duplicated such as IS.CLR and IS.PND. ; Because of this, it is impossible to know which message to return. ; Since many of our programs do terminal I/O, the terminal driver returns ; are used in this table. ; SUCTBL: .WORD IS.PND,1 ; OPERATION IS PENDING .WORD IS.SUC,2 ; SUCCESSFUL OPERATION .WORD IS.TMO,3 ; REQUEST TIMED OUT .WORD IS.CC,4 ; TERMINATED BY CTRL/C .WORD IS.EOT,5 ; TERMINATED BY EOT (BLOCK MODE INPUT) .WORD IS.TAB,6 ; TERMINATED BY TAB (FORMS MODE INPUT) .WORD IS.CR,7 ; TERMINATED BY CARRIAGE RETURN .WORD IS.ESC,8. ; TERMINATED BY ESCAPE .WORD IS.ESQ,9. ; TERMINATED BY ESCAPE SEQUENCE .WORD IS.PES,10. ; TERMINATED BY PARTIAL ESCAPE SEQUENCE .WORD 0,0 ; END OF TABLE ; ; Other error messages. ; .NLIST BEX NOMSG: .ASCII %F% .ASCIZ %NOMSG% .ASCII %no such message, code = % CODE: .BLKB 10. MSGFIL: .ASCII %F% .ASCIZ %MSGFIL% .ASCII %message file error % CODE1: .ASCII % % .ASCII %actual error % CODE2: .ASCII % % .EVEN .SBTTL SIGNAL - SIGNAL ERROR AT TERMINAL ;+ ; ; SIGNAL - Signal error message at the terminal. ; ; Inputs: ; R5 = Pointer to argument list (Fortran convention): ; ; R5 -->> .BYTE 1,0 ; ARGUMENT COUNT ; .WORD ERRCOD ; ADDRESS OF ERROR CODE ; ; Outputs: ; R5 is destroyed. ;- SIGNAL:: MOV @2(R5),ERRCOD ; COPY THE ERROR CODE MOV #ERRBLK,R5 ; SETUP THE ERROR BLOCK BR PUTMSG ; PROCESS LIKE PUT MESSAGE .SBTTL GETMSG - GET AN ERROR MESSAGE FOR THE USER .SBTTL PUTMSG - PUT AN ERROR MESSAGE TO THE TERMINAL ;+ ; ; GETMSG - Get (return) an error message to the user. ; PUTMSG - Put an error message to the terminal (TTY). ; ; This routine is used to report or return an error message. The ; error code will normally be F.ERR of the FDB or the first word ; from an I/O status block. If the high byte is minus, a Directive ; error will be returned instead of an I/O error (FCS convention). ; ; Inputs: ; R5 = Points to error message block (Fortran standard): ; ; .BYTE 5,0 ; ARGUMENT COUNT ; .WORD ERRCOD ; ADDRESS OF ERROR CODE ; .WORD OUTBUF ; ADDRESS OF OUTPUT BUFFER (-1 = PUT TO TTY) ; .WORD DEFFLG ; ADDRESS OF MESSAGE FLAGS (-1 = USE DEFAULT) ; .WORD FACNAM ; ADDRESS OF FACILITY NAME (-1 = USE DEFAULT) ; .WORD STATUS ; ADDRESS OF STATUS RETURN (-1 = NO STATUS) ; ; Outputs: ; Initializes STATUS word to 0 (Success). ; R2 = Error message address. ; ;- GETMSG:: CLR TOTTY ; PRESUME TO TTY CMP BUFOFF(R5),#-1 ; SPECIFY A BUFFER ? BNE ERROR ; IF NE, YES ; ELSE, FALL THROUGH TO PUTMSG PUTMSG:: MOV #-1,TOTTY ; ALWAYS WRITE TO TTY ERROR: CALL $SAVAL ; SAVE R0 - R5 CMP STAOFF(R5),#-1 ; ADDRESS FOR STATUS ? BEQ 10$ ; IF EQ, NO CLR @STAOFF(R5) ; PRESUME GOOD RETURN ; Check for alternate message facility (i.e., RMS or BASIC). 10$: CMP ALTOFF(R5),#-1 ; SPECIFY AN ALTERNATE MESSAGE ? BEQ 15$ ; IF EQ, NO MOV @ALTOFF(R5),R3 ; YES, COPY THE VALUE CMP R3,#MAXMSG ; IS VALUE WITHIN TABLE RANGE ? BLT 20$ ; IF LT, YES (ELSE FALL THROUGH) ; Determine type of status (SUCCESS / DIRECTIVE / FCS). 15$: TSTB @ERROFF(R5) ; SUCCESS RETURN CODE ? BMI 17$ ; IF MI, NO (ERROR) JMP SUCESS ; YES, RETURN MESSAGE 17$: MOV #DIRMSG,R3 ; PRESUME DIRECTIVE MESSAGE TST @ERROFF(R5) ; IS IT A DIRECTIVE ERROR ? BMI 20$ ; IF MI, YES MOV #FCSMSG,R3 ; NO, SET FOR FCS MESSAGE 20$: MUL #MSGSIZ,R3 ; CALCULATE OFFSET INTO TABLE ADD #MSGTBL,R3 ; ADD IN START OF TABLE MOV 2(R3),R4 ; COPY OFFSET TO FIRST MESSAGE MOV 4(R3),MSGPTR ; POINTER TO FILE NAME BLOCK MOV (R3),R3 ; COPY MAXIMUM MESSAGE CODE MOVB @ERROFF(R5),R1 ; GET ERROR CODE (SIGN EXTEND) BPL 25$ ; IF PL, POSITIVE CODE NEG R1 ; MAKE IT POSITIVE 25$: CMP R1,R3 ; EXCEED # OF ENTRIES ? BGT WNOMSG ; IF GT, YES (NO MESSAGE) ; Now get the error message from the message file. 30$: MOV R1,R0 ; COPY THE ERROR NUMBER ADD R4,R0 ; OFFSET INTO ERROR FILE CALL GERMSG ; GET THE ERROR MESSAGE BCS NOMFIL ; IF CS, UNABLE TO GET IT JMP CHKMSG ; CHECK WHERE TO PUT IT .SBTTL WNOMSG - WRITE/RETURN "NO SUCH MESSAGE" ;+ ; ; WNOMSG - Write/return "No such message". ; ; This routine is entered whenever a unknown error/success code is ; encountered to return the code to the user. ; ; Inputs: ; R1 = illegal message code number. ; ; Outputs: ; Sets STATUS word in argument block to -1 (failure). ; ; Presumes registers were previously saved. ; ;- WNOMSG: MOV #CODE,R0 ; OUTPUT BUFFER CALL BADMSG ; CONVERT THE NUMBER MOV #NOMSG,R2 ; ADDRESS OF MESSAGE JMP CHKMSG ; CHECK WHERE TO PUT IT ; Entry for error accessing error message file. NOMFIL: MOV #CODE1,R0 ; OUTPUT BUFFER MOV $DSW,R1 ; COPY THE DSW BMI 10$ ; IF MI, GOT ERROR MOVB MSGSB,R1 ; COPY THE I/O ERROR BMI 10$ ; IF MI, GOT ERROR MOVB @ERROFF(R5),R1 ; COPY THE ERROR # BR WNOMSG ; PRESUME NO MESSAGE 10$: CALL BADMSG ; FILL IN ERROR NUMBER MOVB #',,(R0) ; REPLACE NULL WITH COMMA MOVB @ERROFF(R5),R1 ; COPY THE ERROR # MOV #CODE2,R0 ; AND STROE IT HERE CALL BADMSG ; FILL IN ACTUAL ERROR MOV #MSGFIL,R2 ; ADDRESS OF MESSAGE JMP CHKMSG ; CHECK WHERE TO PUT IT ; Common code to convert error number to signed decimal ASCII. ; R0 = output buffer, R1 = binary number. BADMSG: CLR R2 ; ZERO SUPPRESSION CALL $CBDSG ; CONVERT TO DECIMAL MOVB #'.,(R0)+ ; SHOW DECIMAL NUMBER CLRB (R0) ; SET THE TERMINATOR CMP STAOFF(R5),#-1 ; ADDRESS FOR STATUS ? BEQ 10$ ; IF EQ, NO MOV #-1,@STAOFF(R5) ; SET BAD STATUS CODE 10$: RETURN .SBTTL SUCESS - RETURN SUCCESS MESSAGE ;+ ; ; SUCESS - Return a successful return message. ; ; This routine is called whenever a successful return code ; (positive number in low byte) is passed to GETMSG or PUTMSG. ; ; See GETMSG/PUTMSG for description of inputs. ; ; Outputs: ; R1 = Success code. ; R2 = Message address. ; ;- SUCESS: MOV @ERROFF(R5),R1 ; COPY SUCCESS CODE MOV #SUCTBL,R0 ; TABLE OF SUCCESS RETURNS 10$: CMP R1,(R0)+ ; IS THIS THE CODE ? BEQ 20$ ; IF EQ, YES TST (R0)+ ; POINT TO NEXT ENTRY BNE 10$ ; IF NE, MORE TO GO BR WNOMSG ; ELSE, RETURN BAD MESSAGE 20$: MOV (R0),R0 ; GET ERROR MESSAGE OFFSET MOV #SUCMSG,R3 ; SET FOR SUCCESS MESSAGES MUL #MSGSIZ,R3 ; CALCULATE OFFSET INTO TABLE ADD #MSGTBL,R3 ; ADD IN START OF TABLE ADD 2(R3),R0 ; ADD OFFSET INTO MESSAGE FILE MOV 4(R3),MSGPTR ; POINTER TO FILE NAME BLOCK CALL GERMSG ; GET THE ERROR MESSAGE BCS NOMFIL ; IF CS, UNABLE TO GET IT BR CHKMSG ; CHECK WHERE TO PUT IT .SBTTL CHKMSG - CHECK WHERE TO PUT MESSAGE ;+ ; ; CHKMSG - Check where to put message. ; ; This routine checks where the message should be put. It checks ; the message flags to determine which portions of the message ; should be returned/output. ; ; Message flag bits (VAX/VMS equivalent): ; ; Bit 0 = 1 - Include text of message. ; 0 Do not include text of message ; ; Bit 1 = 1 - Include message identifier. ; 0 Do not include message identifier. ; ; Bit 2 = 1 - Include severity level indicator. ; 0 - Do not include severity level indicator. ; ; Bit 3 = 1 - Include facility name. ; 0 - Do not include facility name. ; ; Bits 4-15 are unused and should be zero. ; ; Inputs: ; R2 = Message address. ; R5 = Pointer to error message block. ; ;- CHKMSG: CMP FLGOFF(R5),#-1 ; SPECIFY A FLAG WORD ? BEQ 5$ ; IF EQ, NO MOV @FLGOFF(R5),R3 ; COPY FLAG BITS BIT DEFFLG,R3 ; SPECIFY ANY BITS ? BNE 10$ ; IF NE, YES 5$: MOV DEFFLG,R3 ; NO, USE DEFAULT BITS 10$: MOV BUFOFF(R5),R1 ; GET MESSAGE BUFFER CMP R1,#-1 ; IS THERE A BUFFER ? BNE 20$ ; IF NE, YES MOV #OUTBUF,R1 ; ELSE GO TO TERMINAL MOV #-1,TOTTY ; SHOW GOING TO TTY ; ; Register usage: ; R0 = scratch area. ; R1 = address of output buffer. ; R2 = address of severity level/message id/error message text. ; R3 = message flag bits. ; R4 = current output buffer address. ; R5 = address of error message block. ; ; Copy the facility name. 20$: MOV R1,R4 ; COPY MESSAGE BUFFER MOV FACOFF(R5),R0 ; ADDRESS OF FACILITY NAME CMP R0,#-1 ; IS THERE AN ADDRESS ? BNE 30$ ; IF NE, YES MOV #FACNAM,R0 ; SET DEFAULT FACILITY NAME 30$: BIT #FACBIT,R3 ; OUTPUT FACILITY NAME ? BEQ 50$ ; IF EQ, NO MOVB #'%,(R4)+ ; MOVE IN PERCENT SIGN 40$: MOVB (R0)+,(R4)+ ; NOW THE FACILITY NAME BNE 40$ ; IF NE, MORE TO GO DEC R4 ; POINT TO THE NULL MOVB #'-,(R4)+ ; MOVE IN DELIMITER ; Copy the severity level. 50$: BIT #SEVBIT,R3 ; OUTPUT SEVERITY LEVEL ? BEQ 55$ ; IF EQ, NO MOVB (R2),(R4)+ ; YEP, MOVE IT (1 BYTE) MOVB #'-,(R4)+ ; AND THE DELIMITER ; Copy the message ID. 55$: INC R2 ; POINT PAST SEVERITY BIT #MIDBIT,R3 ; OUTPUT MESSAGE ID ? BEQ 70$ ; IF EQ, NO 60$: MOVB (R2)+,(R4)+ ; MOVE MESSAGE ID BNE 60$ ; IF NE, MORE TO GO DEC R4 ; POINT TO THE NULL MOVB #',,(R4)+ ; MOVE IN A COMMA MOVB #' ,(R4)+ ; AND A SPACE BR 80$ ; BR TO CONTINUE ... 70$: TSTB (R2)+ ; SKIP PAST MESSAGE ID BNE 70$ ; IF NE, MORE TO GO ; Copy text of the message. 80$: BIT #TXTBIT,R3 ; WANT TEXT OF MESSAGE ? BEQ 100$ ; IF EQ, NO MOV R4,R0 ; SAVE START OF MESSAGE 90$: MOVB (R2)+,(R4)+ ; MOVE IN MESSAGE TEXT BNE 90$ ; IF NE, MORE TO GO DEC R4 ; POINT AT THE NULL BIT #MIDBIT!SEVBIT!FACBIT,R3 ; REQUESTING TEXT ONLY ? BNE 100$ ; IF NE, NO BICB #40,(R0) ; MAKE 1ST BYTE UPPERCASE 100$: TST TOTTY ; PUT TO THE TERMINAL ? BNE 200$ ; IF NE, YES CMP STAOFF(R5),#-1 ; ADDRESS FOR STATUS ? BEQ 110$ ; IF EQ, NO ;*** TST @STAOFF(R5) ; PASSING BACK BAD STATUS ? ;*** BMI 110$ ; IF MI, YES (DON'T ALTER) SUB R1,R4 ; CALCULATE BYTE COUNT MOV R4,@STAOFF(R5) ; PASS IT BACK AS STATUS 110$: RETURN ; ELSE RETURN TO USER ; Write the message to the terminal. 200$: SUB R1,R4 ; CALCULATE BYTE COUNT 210$: ALUN$S .MOLUN,#"TI,#0 ; ASSIGN LUN TO TI0: QIOW$S #IO.WVB!TF.CCO,.MOLUN,.MOLUN,,#TIOSB,, BCS 999$ ; IF CS, ERROR TSTB TIOSB ; ANY I/O ERRORS ? BMI 999$ ; IF MI, YES RETURN ; If we receive a Directive or I/O error, put the error codes ; into the general purpose registers and dump via an IOT. 999$: MOV $DSW,R0 ; DIRECTIVE CODE MOVB TIOSB,R1 ; I/O STATUS CODE MOVB @ERROFF(R5),R3 ; COPY ORIGINAL CODE IOT ; DUMP THE REGISTERS .SBTTL GERMSG - GET ERROR MESSAGE FROM FILE ;+ ; ; GERMSG - Get error message from file. ; ; Inputs: ; R0 = Record number within message file. ; ; Outputs: ; C clear/set = success/failure. ; R2 = Points to the error message text. ; All other registers are preserved. ; ;- GERMSG: CALL $SAVAL ; SAVE ALL REGISTERS MOV .MOLUN,MSGDPB+Q.IOLU ; SETUP THE MESSAGE LUN MOV .MOLUN,MSGDPB+Q.IOEF ; AND THE EVENT FLAG ; Try to find the default message directory first (LB:[1,2]). MOV MSGPTR,R1 ; Set address of message FNB. MOV #DIRFNB,R4 ; Set the directory FNB address. CALL FNDMSG ; Try to find the message directory. BCC 30$ ; If CC, we found it. ; Try to find the alternate message directory (ER0:[MILLER]). MOV #^RMIL,N.FNAM(R4) ; Set the directory file MOV #^RLER,N.FNAM+2(R4) ; name to [MILLER]. MOV #"ER,N.DVNM(R4) ; Set the device name to ER. ; CLR N.UNIT(R4) ; Set the unit number to zero. ; ; *** Already zero from LB0: *** CLR (R4) ; Clear the file ID and the CLR N.DID(R1) ; directory ID to force FIND. CALL FNDMSG ; Try to find the message directory. BCS 90$ ; If CS, directory or file not found. ; Access the message file for read only. 30$: MOV #IO.ACR,MSGDPB+Q.IOFN ; SET ACCESS I/O FUNCTION CALL CLIOPL ; CLEAR THE QIO PARAMETER LIST MOV R1,(R5) ; ADDRESS OF FILE ID POINTER (FNB) MOV #100000,8.(R5) ; ENABLE ACCESS BIT CALL DOQIO ; ISSUE THE ACCESS QIO BCS 90$ ; IF CS, FAILED TO ACCESS ; Calculate the Virtual Block Number (VBN) to read. MOV R0,R4 ; COPY THE RECORD NUMBER DEC R4 ; BIAS IT BY -1 CLC ; CLEAR THE CARRY BIT ROR R4 ; SHIFT ASR R4 ; RIGHT ASR R4 ; 3 BITS INC R4 ; BUMP, VBN'S START AT 1 ; Read the virtual block with the desired error message record. MOV #IO.RVB,MSGDPB+Q.IOFN ; SET THE READ I/O FUNCTION CALL CLIOPL ; CLEAR THE QIO PARAMETER LIST MOV #BLKBUF,(R5)+ ; SET THE BUFFER ADDRESS MOV #512.,(R5)+ ; AND THE BYTE COUNT CMP (R5)+,(R5)+ ; SKIP TO PARAMETER #5 MOV R4,(R5) ; STORE VBN TO READ CALL DOQIO ; ISSUE THE READ QIO ROR R4 ; SAVE THE CARRY BIT ; Deaccess the message file even if we had a read error. MOV #IO.DAC,MSGDPB+Q.IOFN ; SET DEACCESS I/O FUNCTION CALL CLIOPL ; CLEAR THE QIO PARAMETER LIST MOV R1,(R5) ; SET FILE ID TO DEACCESS CALL DOQIO ; ISSUE THE DEACCESS QIO BCS 90$ ; IF CS, COULDN'T DEACCESS ROL R4 ; RESTORE CARRY BIT FROM READ BCS 90$ ; IF CS, READ FAILED ; Now calculate the record number within the block. MOV R0,R2 ; COPY THE RECORD NUMBER DEC R2 ; BIAS IT BY -1 BIC #177770,R2 ; CALCULATE RECORD # WITHIN BLOCK ASH #6,R2 ; SHIFT LEFT 6 BITS (64. BYTES) ADD #BLKBUF,R2 ; POINT TO RECORD WITHIN BLOCK TSTB (R2) ; IS THERE A MESSAGE HERE ? BEQ 90$ ; IF EQ, NO (RETURN FAILURE) MOV R2,6(SP) ; STORE IN SAVED R2 ON STACK RETURN 90$: SEC ; SHOW FAILURE RETURN .SBTTL FNDMSG - Find the message directory. ;+ ; ; FNDMSG - Find the message directory. ; ; This routine assigns the message lun and then looks up the directory ; in the Master File Directory (MFD). If the directory is found, then ; the message file is looked up in that directory. ; ; Inputs: ; R4 = The directory FNB address. ; N.DVNM = The ASCII device name. ; N.UNIT = The device unit number. ; ; Outputs: ; C bit clear/set = success/failure. ; ; All registers are preserved. ; ;- FNDMSG: CALL $SAVAL ; Save all registers, ALUN$S .MOLUN,N.DVNM(R4),N.UNIT(R4) ; Assign the message LUN. BCS 90$ ; IF CS, FAILURE MOV MSGPTR,R1 ; POINTER TO MESSAGE FNB TST N.DID(R1) ; IS THE DIRECTORY ID SET ? BNE 20$ ; IF NE, YES ; Find the directory file if the file ID is not set. TST (R4) ; IS THE FILE ID SET ? BNE 10$ ; IF NE, YES (SKIP FIND) CALL FIND ; FIND THE DIRECTORY ID BCS 90$ ; IF CS, NO MESSAGE FILE 10$: MOV (R4)+,N.DID(R1) ; COPY THE DIECTORY ID MOV (R4)+,N.DID+2(R1) ; AND THE SECOND WORD MOV (R4)+,N.DID+4(R1) ; AND THE THIRD WORD ; Find the message file if the ID is not set. 20$: TST (R1) ; IS FILE ID ALREADY PRESENT ? BNE 90$ ; If NE, yes (skip the FIND). MOV R1,R4 ; COPY MESSAGE FNB CALL FIND ; FIND THE MESSAGE FILE ;*** BCS 90$ ; IF CS, NO MESSAGE FILE 90$: RETURN .SBTTL UTILITY SUBROUTINES ;+ ; ; FIND - Issue a find QIO. ; ; Inputs: ; R4 = Address of the File Name Block (FNB). ; ; Outputs: ; C clear/set = success/failure. ; R5 points to start of QIO parameter list (Q.IOPL). ; R0 - R4 preserved. ; ;- FIND: MOV #IO.FNA,MSGDPB+Q.IOFN ; SET FIND I/O FUNCTION CALL CLIOPL ; CLEAR THE PARAMETER LIST MOV R4,10.(R5) ; STORE THE FNB ADDRESS CALL DOQIO ; ISSUE THE FIND QIO RETURN ;+ ; ; CLIOPL - Clear the message QIO parameter list (6 WORDS). ; ; Inputs: ; None. ; ; Outputs: ; R0-R4 Preserved. ; R5 points to start of QIO parameter list (Q.IOPL). ; ;- CLIOPL: MOV #MSGDPB+24.,R5 ; POINT TO END OF QIO LIST MOV R0,-(SP) ; SAVE R0 MOV #6,R0 ; NUMBER OF WORDS TO CLEAR 10$: CLR -(R5) ; CLEAR THE NEXT WORD SOB R0,10$ ; LOOP UNTIL DONE MOV (SP)+,R0 ; RESTORE R0 RETURN ;+ ; ; DOQIO - Issue the QIO. ; ; Inputs: ; The directive parameter block is set up. ; ; Outputs: ; C clear/set = success/failure. ; ;- DOQIO: DIR$ #MSGDPB ; ISSUE THE DIRECTIVE BCS 10$ ; IF CS, DIRECTIVE FAILED TSTB MSGSB ; ANY I/O ERRORS ? BPL 10$ ; IF PL, NO SEC ; YES, SHOW FAILURE 10$: RETURN .END