From the Wizzards Book of RSX MAGIC D. B. Curtis SCIENCE APPLICATIONS, INC. Oak Brook, IL This is the second RSX MAGIC article. Due to my time limitations, it may be the last unless the wizards out there pitch in and help. This article describes processes that, if misused, may cause the destruction of your operating system. These methods should not be lightly used, they are provided to help solve applications where normal RSX methods will not work. As with all magic, mistakes are dreadful! (Remember the sorcerer's apprentice.) The last article described a method of sending ASTs to specified tasks. This method was initially used in an error logging task. That error logger task is presented in this article. I have not had time to rework the code that sends ASTs so you get to see the original item. This task provides a very efficient, general purpose, error display task. There is only a six word memory overhead at each error occurrence. Essentially this is done by dynamically adding an error directive to the executive. The technique indicates how to expand the functionality of the RSX-11M executive without modification to the executive source. This particular version of the error task was written for an RSX-11S system. Therefore, I did not use disk resident error messages. However, it would be simple to add that capability. An example of the use of the error processor is shown below: MRKT$S #1,#1,#1 BCC 1$ ERROR MKTERR,-1,0,0 1$: In this example you see an attempt to execute a mark time directive. If the directive fails, you want an error message and some attempt to recover from the error. The recovery may be as simple as aborting the task. The error macro definition follows: Page 2 .MACRO ERROR,P1,P2,P3,P4 ; ; MACRO TO SET UP INSTRUCTION BLOCK FOR ERROR MESSAGES ; ; ERROR KEY,TYPE,PRAM1,PRAM2 ; ; KEY <= 6 RAD50 CHARACTERS ; TYPE = -1 FATAL ERROR ; = -2 FOR DELAYED RECOVERY ; = -3 FOR JUMP RECOVERY ; = 0 FOR MESSAGE ONLY ; SEE DESCRIPTION IN ERRDIS MODULE ; .WORD 210 ; ERROR HANDLING INSTRUCTION .NCHR TEMPN,P1 .IIF LT 6-TEMPN .ERROR ; RAD50 NAME > 6 CHARACTERS .IF LT 3-TEMPN .RAD50 /P1/ .IFF .RAD50 /P1/ .RAD50 / / .ENDC .WORD P2,P3,P4 .ENDM ERROR .MACRO SAVRG JSR R5,$SAVRG .ENDM The error control block looks like: ----------------------------------------- | OP CODE (210) | |---------------------------------------| | FIRST 3 CHAR. OF RAD50 KEY | |---------------------------------------| | SECOND 3 CHAR. OF RAD50 KEY | |---------------------------------------| | FIRST PARAMETER | |---------------------------------------| | SECOND PARAMETER | |---------------------------------------| | THIRD PARAMETER | ----------------------------------------- where: 1. The two word key is used to both identify the error, and as a key into an expanded message table. If a match is found in the message table, the message is printed in addition to the normal information. Page 3 2. The first parameter specifies the type of error recovery to perform. This parameter takes the following values: 1. 0 -- Message only. The task continues execution after the error control block. The second and third parameter contain data to be printed. If the second parameter is 0, R0 will be printed. If the third parameter is 0, R5 will be printed. 2. -1 -- Fatal error. The message is printed, and the erroring task is aborted. The second and third parameters are treated as in the message only case. 3. -2 -- Recoverable error. The message is printed and the task continues processing at the location specified in the second parameter. The first byte of the third parameter is the number of seconds to wait before continuing, and the last byte of the third parameter is the event flag to use while waiting. If the seconds are zero, it will default to 1, if the event flag is zero, it will default to 1. 4. -3 -- Recoverable error. The message is printed and the task continues processing at the location specified in the second parameter. If parameter 3 is 0, R5 will be printed. 5. If some other value than the ones listed above, the error is printed, and the offending task is aborted. For example, you would use -2 for an error that required operator intervention and -3 for an error exit from the routine. The error printout has the following form: 'TSKNAM' PS = XXXXXX, PC = XXXXXX, DSW = XXXXXX ERROR 'KEYNAM', PRAMS = XXXXXX XXXXXX Where the XXXXXXs are octal numbers for the values of the erroring task. KEYNAM is the keyword for the error and TSKNAM is the name of the task where the error occurred. If a message is associated with the error, the message line is printed before the standard display. Again, this could be easily modified for your special needs. 1.0 DESCRIPTION OF THE CODE This section provides an overview of the operation of the error logging task. Page 4 The basic concept of the error logger is to allow any active task to display an error without extra code in the task. The error task is invoked by the execution of a PDP-11 reserved instruction. The error logging task intercepts the system illegal instruction processing and checks if the instruction is the one specific to the error logging system. If the instruction is not the error logging instruction, the instruction is handled in the normal manner, otherwise, the error logger is invoked. To install the illegal instruction intercept, the error task does a Connect-To-Interrupt directive to an unused vector. At this time, some PIC code is inserted into the system pool, and the illegal instruction vector is pointed to the new code. This code examines the illegal instruction and if it is the instruction specific to the error logger, will cause a transfer to the error logger via the vector specified by the connect to interrupt. The code in the error logging task is simplified as the task is built as /PR:5. Information about the erroring task is gathered and a call to $FORK2 transfers the task from interrupt level to system state. Here, information about the error is placed in an AST block which is sent to the error logging task to be processed. 2.0 DISCUSSION OF THE CODE The complete listing of the error routine follows this description. Here I describe sections of the code. 2.1 Initialization And Self Test The following is the initialization and self test sections of the error logging task. The task initializes itself and then suspends. If the task is resumed, it generates a sequence of test error messages. Page 5 CINT: CINT$ ERRVEC,120000,ERRINT,ERRINI,PR7,ASTAD START: DIR$ #CINT ; CONNECT TO THE VECTOR, BCC 10$ ; AND INIT IT, IF ERROR IOT ; JUST CRASH 10$: SPND$S ; ELSE SUSPEND FOREVER ; ; IF THIS TASK IS RESUMED, IT WILL SELF TEST ; ERROR AAAAA,0,1,2 ; PRINT ERROR MESSAGE WITH ; DEFAULT PARAMETERS MOV #3,R0 MOV #4,R5 ERROR BBBBB,0,0,0 ; PRINT ERROR MESSAGE BR 30$ ; NEXT MESSAGE SHOULD BE DDDDD 20$: ERROR CCCCC,-3,40$,6 ; NEXT MESSAGE WILL BE ; A DELAY MESSAGE 30$: ERROR DDDDD,-3,20$,5 ; CCCCC IS NEXT MESSAGE 40$: ERROR EEEEE,-2,50$,<<15*400>+5> ; CHECK FOR 5 SECOND DELAY 50$: ERROR FFFFF,-2,60$,<<0*400>+0> ; CHECK DEFAULT DELAY ; AND EVENT FLAG 60$: ERROR DONE,-3,10$,0 ; ALL DONE Note that the interrupt priority is 7 and that the base address of the connect code is at the start of the task (120000). 2.2 AST Handler The next section of code is the AST routine that displays the errors. This routine is easily modified for your special needs. One nice enhancement would be to send the erroring tasks TI terminal number to the AST routine so that the error would also be displayed on that terminal. Page 6 ; ; INPUTS: ; INFORMATION IS ON THE STACK, ALL REGISTERS MUST BE SAVED ; THE INFORMATION ON THE STACK IS: ; 2 WORDS OF RAD50 TASK NAME ISSUING THE INSTRUCTION ; PS OF THAT TASK ; PC OF THAT TASK ; DSW OF THAT TASK ; 2 WORDS OF RAD50 ERROR KEYWORD ; FIRST PARAMETER ; SECOND PARAMETER ; ; ; EQUATED SYMBOLS ; BEL = 7 ; ASCII CODE FOR BELL .ASECT . = 0 ; STACK PARAMETERS REGS: .BLKW 6 ; R5-R0 R5 IS FIRST ERTNM: .BLKW 2 ; 2 WORDS OF RAD50 TASK NAME FROM ERROR ETPS: .BLKW 1 ; ERRORING TASKS PS ETPC: .BLKW 1 ; ERRORING TASKS PC ETDSW: .BLKW 1 ; ERRORING TASKS DSW EKEY: .BLKW 2 ; 2 RAD50 WORDS WITH KEY NAME ETP1: .BLKW 1 ; FIRST PARAMETER ETP2: .BLKW 1 ; SECOND PARAMETER .PSECT .ENABL LSB ASTAD: .IRPC REG,<012345> ; SAVE THE REGISTERS MOV R'REG,-(SP) .ENDM ; ; GET THE INFORMATION FROM THE INTERRUPT PART AND DISPLAY IT ; MOV SP,R0 ; GET THE ADDR OF THE ERROR DATA BLOCK MOV EKEY(R0),R1 ; GET THE FIRST WORD OF THE KEY MOV #MSGKYS,R2 ; AND THE ADDRESS OF THE KEYS 10$: CMP R1,(R2) ; IS THE FIRST PART OF THE KEY THE SAME? BNE 20$ ; HERE THE FIRST PART OF THE KEY MATCHES CMP EKEY+2(R0),2(R2) ; DOES THE SECOND PART MATCH? BNE 20$ ; IF NE NO, SO CONTINUE BR 50$ 20$: ADD #6,R2 ; ADVANCE TO NEXT KEY TST (R2) ; CHECK NOT END OF KEYS BNE 10$ ; KEY NOT FOUND, => NO MESSAGE OTHER Page 7 ; OTHER THEN KEY ITSELF ; ; HERE, CONVERT KEY TO ASCII, AND PRINT IT AND OTHER VARIABLES ; .PSECT MESFMT,RO,D .NLIST BEX MG1: .ASCII /'%2R' PS = %P, PC = %P, DSW = %P%N/ .ASCIZ /ERROR '%2R', PRAMS = %2P%N/ .LIST BEX .PSECT 30$: MOV SP,R2 ; SAVE POINTER TO PARAMETERS ADD #ERTNM,R2 SUB #200.,SP ; SAVE SPACE FOR LINE ON STACK MOV SP,R0 MOV SP,R5 MOV #MG1,R1 ; POINT TO FORMAT INFORMATION CALL $EDMSG ; FORMAT IT CMP #200.,R1 ; CHECK STACK DIDN'T GET WIPED BGE 40$ IOT 40$: QIOW$S #IO.WBT,#TTLUN,#TTEV,,,, ADD #200.,SP ; CLEAN UP STACK BR 60$ ; ; HERE PRINT MESSAGE, AND VARIABLES ; 50$: MOV 4(R2),R1 ; GET ADDRESS OF MESSAGE MOVB (R1)+,R2 ; GET SIZE OF MESSAGE QIO$S #IO.WBT,#TTLUN,,,,, BR 30$ 60$: .IRPC REG,<543210> ; RESTORE THE REGISTERS MOV (SP)+,R'REG .ENDM ADD #2*NUMPRM,SP ; CLEAN OFF PARAMETERS ASTX$S .DSABL LSB There isn't much magical about this routine, it is just a normal AST receiver. Well, almost normal as the number of parameters on the stack isn't a standard number, but if you read the last article you will not be surprised by that. Page 8 2.3 Intercepting The Illegal Instruction Trap The next routine is called when the connect to interrupt directive is executed. This routine is responsible for inserting some code into the system pool space and intercepting the illegal instruction trap. The format of the intercept code in the pool follows the form that was described by a paper in the DECUS proceedings<1>. The error logger could just as well be inserted into the system with the ISF task as described in that paper. However this task was developed for a stand alone RSX-11S task and needed to insert the code itself. ------------------------------------ <1> Extending RSX-11M by Use of the Illegal Instruction Trap DECUS _________ _______ __ ___ __ ___ _______ ___________ ____ PROCEEDINGS Vol 6, No. 2, Pg. 467. This paper describes a means of inserting code into the system pool. It is good background reading for parts of this article Page 9 ;+ ; **-ERRINI-CONNECT TO INTERRUPT ENABLE/DISABLE ROUTINE ; ; THIS ROUTINE ENABLES/DISABLES THE ILLEGAL INSTRUCTION INTERCEPT ; IF CARRY IS CLEAR, IT ENABLES, IF SET, IT DISABLES ; THIS MODULE ALLOCATES SOME POOL MEMORY, PLACES THE ILLEGAL INSTRUCTION ; INTERCEPT CODE INTO THE POOL AREA, MODIFIES XDT TO NOT PLAY WITH THE ; ILLEGAL INSTRUCTION TRAP VECTOR (ONLY IF XDT IS PRESENT) AND RETURNS. ; ; THE DISABLE OF THIS OPERATION UNDOES ALL OF THE ABOVE ; ; INPUTS: ; CARRY SET TO DETACH FROM VECTOR, CLEAR TO ATTACH TO VECTOR ; ; OUTPUTS: ; NONE ; ; SIDE EFFECTS: ; ; MODIFIED EXTERNALS ; ; OTHER SIDE EFFECTS ; POLADD,POLSIZ ARE SET TO THE ADDRESS OF THE POOL AREA, AND ITS SIZE ; THE ILLEGAL INSTRUCTION TRAP VECTOR IS INTERCEPTED. ; ; REGISTER USAGE: ; R1,R4,R5 ARE SAVED ; ;- ERRINI: BCC 10$ ;; CONNECT TO ILLEGAL INSTRUCTION VEC JMP ABOPRO ;; IF CARRY SET, DISCONNECT 10$: MOV R5,-(SP) ;; SAVE REGISTERS MOV R4,-(SP) MOV R1,-(SP) MOV #EPOLCD-POOLCD,R1 ;; NEED TO ALLOCATE POOL SPACE TO PUT CALL $ALOCB ;; TRAP INTERCEPT CODE BCC 20$ IOT ;; IF NO POOL SPACE, CRASH SYSTEM 20$: MOV R0,POLADD ;; SAVE ADDRESS OF ALLOCATED BLOCK MOV R1,POLSIZ ;; AND SIZE OF ALLOCATED BLOCK MOV $TKTCB,MYTCBA ;; AND WHILE AT IT, SET MY TCB ADDRESS MOV #/2,R2 ;; GET THE NUMBER OF BYTES TO COPY MOV #POOLCD,R3 ;; AND THE ADDRESS OF CODE TO MOVE ;; TOO THE POOL 30$: MOV (R3)+,(R0)+ ;; DO THE MOVE SOB R2,30$ ;; UNTIL FULLY COPIED MOV POLADD,R0 ;; GET THE START ADDRESS OF POOL CODE ADD #2,R0 ;; BUMP PAST THE "ILL" MOV POLSIZ,(R0)+ ;; SAVE THE NUMBER OF BYTES IN CODE Page 10 MOV @#ILLVEC,(R0)+ ;; SAVE THE ORIGINAL VECTOR MOV #NOP,(R0) ;; TURN ON THE CODE MOV #$XDT,R2 ;; CHECK IF XDT IS AVAILABLE BEQ 40$ ;; IF EQ NO SUB #XDTFIX,R2 ;; CHECK IF XDT IS CONSISTENT CMP @#ILLVEC,(R2) BNE 40$ MOV R0,(R2) ;; ADJUST XDT 40$: MOV R0,@#ILLVEC ;; POINT ILLEGAL INSTRUCTION TRAP TO ;; THIS NEW CODE MOV (SP)+,R1 ;; RESTORE REGISTERS MOV (SP)+,R4 MOV (SP)+,R5 RETURN ;; AND RETURN TO TASK This code inserts the PIC code that starts at POOLCD into the system pool. It modifies XDT to allow executive debugging with this code inserted<2>. The code that is inserted into the system pool examines the instruction that caused the illegal instruction trap. If the instruction is recognised by the error system, this code simulates an interrupt via the unused interrupt vector that the error task connected to. Otherwise, the illegal instruction is passed to the original illegal instruction trap handler. ------------------------------------ <2> XDT resets the illegal instruction vector whenever it proceeds from a breakpoint. Thus resetting our intercept. The modification causes XDT to bypass resetting the illegal instruction vector. Page 11 ; ; CODE THAT GETS LOADED INTO THE POOL ; >>>>>> THIS CODE MUST BE PIC <<<<< ; POOLCD: .RAD50 /ILL/ ;;; SHOW THIS CODE IS ATTACHED TO THE .WORD 0,0 ;;; ILLEGAL INSTRUCTION VECTOR RTI ;;; INITIALLY, TURN OFF CODE EP: MOV R5,-(SP) ;;; SAVE R5 MOV 2(SP),R5 ;;; AND GET TASK PC FROM STACK MFPI -(R5) ;;; GET THE INSTRUCTION THAT CAUSED THE TRAP CMP (SP),#210 ;;; IS IT OUR INSTRUCTION? BEQ 100$ ADD #2,SP ;;; NO! SO CLEAR THE STACK MOV (SP)+,R5 ;;; RESTORE R5 JMP @EP-4 ;;; AND PROCESS NORMALLY ; ; HERE IT IS OUR ILLEGAL INSTRUCTION ; 100$: ADD #2,SP ;;; CLEAN THE STACK MOV (SP)+,R5 ;;; RESTORE R5 MOV @#ERRVEC,-(SP) ;;; AND JUMP VIA THE VECTOR WE ARE CONNECTED TO JMP @(SP)+ ;;; POSITION INDEPENDENT INDIRECT JUMP EPOLCD: ;;; END OF THE CODE INSERTED INTO THE POOL The illegal instruction trap vector points to EP-2. EP-4 contains the address of the original service routine. If the error logging task exits, the modifications to XDT must be removed along with the intercept code from the system pool. Page 12 ABOPRO: MOV R1,-(SP) ;; SAVE ITB POINTER MOV @#ILLVEC,R0 ;; GET CURRENT VECTOR TO FIND OUR CODE MOV -2(R0),@#ILLVEC ;; RESET THE ILLEGAL INSTRUCTION VEC MOV #$XDT,R2 ;; RESET XDT BEQ 1$ SUB #XDTFIX,R2 MOV -2(R0),(R2) 1$: MOV POLADD,R0 ;; GET THE ADDRESS OF THE POOL CODE MOV POLSIZ,R1 ;; AND THE SIZE CALL $DEACB MOV (SP)+,R1 ;; RESTORE ITB POINTER RETURN The next routine contains a large amount of magic. It copies the error parameter block from the user task and, if required, adjusts the issuing tasks program counter. After entering system state by a call to $FORK2, other actions on the issuing task are performed. These actions are aborting or delaying execution of the issuing task. Finally an AST is sent to the error logging task. Page 13 ;+ ; **-ERRINT-PROCESSES ERROR INTERRUPTS ; ; THIS MODULE RECEIVES THE 210 INSTRUCTION CODE. ; IT SAVES THE ERROR BLOCK PARAMETERS, DOES ANY PROCESSING OF THE ; PARAMETERS (CHECKS WHAT TO DO WITH THE ISSUING TASKS PC). ; FORKS AND PLACES THE TASK IN THE APPROPRIATE STATE ; ; INPUTS: ; R5 POINTS TO THE ITB ; R4 IS SAVED AND MAY BE USED ; ; OUTPUTS: ; NONE ; ; SIDE EFFECTS: ; ; MODIFIED EXTERNALS ; ; OTHER SIDE EFFECTS ; MANY, TASK MAY BE ABORTED, MADE TO MARK TIME, TASKS PC MAY BE ; MOVED AS DIRECTED BY THE PARAMETERS ETC. ; ; REGISTER USAGE: ; ; R5 POINTS TO ITB ; R4 IS SAVED AND MAY BE USED, ALL OTHER REGISTERS MUST BE SAVED AND ; RESTORED ; ;- ; ; LOCAL DATA ; ERL1: .WORD 0 ERL2: .WORD 0 PER1: .WORD 0 PER2: .WORD 0 PER3: .WORD 0 ERRINT: ;;; HERE IF ILLEGAL INSTRUCTION ;;; FIRST 2 WORDS ARE RAD50 REP ;;; OF NAME OF ERROR MOV 10(SP),R4 ;;; GET PC OF TASK MFPI (R4)+ ;;; GET FIRST WORD OF RAD50 ERROR MOV (SP)+,ERL1 ;;; MFPI (R4)+ ;;; MOV (SP)+,ERL2 ;;; MFPI (R4)+ ;;; MOV (SP)+,PER1 ;;; MFPI (R4)+ ;;; MOV (SP)+,PER2 ;;; MFPI (R4)+ ;;; MOV (SP)+,PER3 ;;; Page 14 TST PER1 ;;; CHECK IF MESSAGE ONLY BMI 20$ ;;; IF MI NO MOV R4,10(SP) ;;; SET NEW PC AS ONLY MESSAGE IS REQUIRED 10$: CALL @#$FORK2 ;;; CLR (R3) ;; CLEAR THE FORK BLOCK CALLR SNDMSG ;; AND SEND AST TO TASK STATE 20$: CMP #-1,PER1 ;;; CHECK IF TO ABORT TASK BNE 40$ ;;; NE NO 30$: CALL @#$FORK2 ;;; CLR (R3) ;; CLEAR THE FORK BLOCK 32$: MOV #S.CABO,R0 ;; ABORTING FROM ILLEGAL INSTRUCTION CALL $ABCTK ;; ABORT THE CURRENT TASK CALLR SNDMSG ;; AND SEND AST TO TASK STATE 40$: CMP #-2,PER1 ;;; CHECK IF OFFSET JMP BNE 50$ MOV PER2,10(SP) ;;; ADJUST PC CALL @#$FORK2 ;;; CLR (R3) ;; CLEAR FORK BLOCK MOV #2,-(SP) ;; SET THE UNITS TO SECONDS MOVB PER3,-(SP) ;; GET THE NUMBER OF SECONDS TO WAIT BNE 41$ ;; CHECK SPECIFIED INC (SP) ;; DEFAULT IS 1 41$: CLRB 1(SP) ;; MAX 255 MOV SP,R3 ;; POINT R3 TO BLOCK CALL $CVRTM ;; AND CONVERT THE TIME MOV R0,2(SP) MOV R1,(SP) 42$: MOVB PER3+1,R0 ;; GET THE EVENT FLAG TO USE BNE 43$ ;; EVENT FLAG OF 0 IMPLIES DEFAULT INCB PER3+1 BR 42$ 43$: MOV $TKTCB,R5 ;; AND THE TCB OF THE CURRENT TASK CALL $CEFI ;; AND CONVERT TO MASK WORD AND ADDRESS BCC 45$ 44$: ADD #4,SP ;; CLEAN UP STACK BR 32$ 45$: CMPB PER3,#64. ;; CHECK IF GLOBAL EVENT FLAG BHI 44$ ;; IF SO GO TO 44 AND ABORT BIC R0,(R1) ;; CLEAR THE EVENT FLAG MOV R0,-(SP) ;; SAVE EVENT FLAG MASK WORD MOV R1,-(SP) ;; AND THE EVENT FLAG MASK ADDRESS MOV T.PCB(R5),R4 ;; GENERATE POINTER TO TASK HEADER MOV P.HDR(R4),R4 INC T.ST2(R5) ;; PUT TASK IN WAIT FOR STATE MOV 2(SP),H.EFLM(R4) ;; SAVE WAIT FLAG MOV (SP),H.EFLM+2(R4) CALL $SETRT ;; SET SCHEDULE REQUEST MOV #C.MRKT,R4 ;; MAKE CLOCK BLOCK A MARK TIME BLOCK Page 15 CALL $ALCLK ;; ALLOCATE A CLOCK BLOCK MOVB PER3+1,C.EFN(R0) ;; SAVE MARK TIME EVENT FLAG CLR C.AST(R0) ;; CLEAR THE AST ADDRESS MOV (SP)+,C.DST(R0) ;; SET THE EVENT FLAG DESTINATION MOV (SP)+,C.SRC(R0) ;; AND THE VALUE TO BE SET MOV (SP)+,R2 ;; GET THE TIME TO WAIT MOV (SP)+,R1 CALL $CLINS ;; AND INSERT THE MARK TIME BLOCK IN THE CALLR SNDMSG ;; CLOCK QUEUE, AND SEND AST TO TASK STATE 50$: CMP #-3,PER1 ;;; CHECK IF ABSOLUTE JMP BNE 30$ ;;; MOV PER2,10(SP) ;;; BR 10$ ;;; The call to SNDMSG just sends an AST to the user mode part of the task. Starting at label 40$ is the code that causes the task to delay for a time. One caution here, this method can only be used with an executing task that is in memory. We are sure of that condition in this example, however other cases may not be as simple. The next routine just sends the error information to the AST part of this task. The method has already been explained in the last multi tasker. Page 16 ;+ ; **-SNDMSG-SEND MESSAGE (VIA AST) ; ; THIS MODULE SENDS AN AST BLOCK TO THIS TASK. ; THE AST PARAMETERS ARE DESCRIBED IN THE AST RECEIVER MODULE ; ; INPUTS: ; ERL1-PER3 -- INFORMATION FROM THE AST ; ; OUTPUTS: ; GENERATES AN AST BLOCK WHICH IS QUEUED TO THE TASK ; ; SIDE EFFECTS: ; ; MODIFIED EXTERNALS ; ; OTHER SIDE EFFECTS ; ; REGISTER USAGE: ; ALL REGISTERS ARE FREE TO BE USED ; ;- SNDMSG: MOV #<5+NUMPRM>*2,R1 ;; ALLOCATE AN AST BLOCK FOR ERRLOG CALL $ALOCB ;; ALLOCATE SOME POOL BCC 10$ IOT ;; CRASH SYSTEM 10$: MOV R0,R2 ;; COPY ADDRESS OF BLOCK MOV R0,ASTADD ;; SAVE ADDRESS OF BLOCK CLR (R2)+ ;; CLEAR THE LINK MOV R1,(R2)+ ;; SET IN SIZE OF BLOCK MOV #<7+NUMPRM>*2,(R2)+ ;; SET NUMBER OF BYTES FOR STACK MOV #ASTAD,(R2)+ MOV #NUMPRM,(R2)+ ;; SPECIFY THE NUMBER OF PARAMETERS ; ; LOAD STANDARD PARAMETERS ; MOV $TKTCB,R0 ;; GET THE POINTER TO THE TCB MOV T.NAM(R0),(R2)+ ;; GET THE TASK NAME MOV T.NAM+2(R0),(R2)+ MOV 22(SP),(R2)+ ;; GET THE TASK PS MOV 20(SP),(R2)+ ;; GET THE TASK NEW PC MFPI @#$DSW ;; GET THE USER DSW MOV (SP)+,(R2)+ MOV ERL1,(R2)+ ;; SAVE ERROR LABEL MOV ERL2,(R2)+ TST PER1 ;; CHECK FOR TYPE OF INFO TO TASK BNE 50$ ; ; HERE FOR NORMAL MESSAGE NO TASK AFFECT ; 20$: MOV PER2,(R2)+ ;; GET THE FIRST PARAMETER BNE 30$ ;; IF DEFAULT USE Page 17 MOV 4(SP),-2(R2) ;; R0 AS PARAMETER 30$: MOV PER3,(R2) ;; GET THE SECOND PARAMETER BNE 40$ ;; IF DEFAULT USE MOV 16(SP),(R2) ;; R5 AS PARAMETER 40$: BR 70$ 50$: CMP PER1,#-1 ;; CHECK FOR FATAL ERROR BEQ 20$ ;; TREAT AS NORMAL ERROR CMP PER1,#-2 ;; CHECK FOR RECOVERABLE ERROR BNE 60$ CLR (R2)+ ;; IF RECOVERABLE ERROR, NO PARAMETER CLR (R2) BR 70$ 60$: CMP PER1,#-3 ;; CHECK FOR RECOVERABLE ERROR BNE 20$ CLR (R2)+ ;; IF RECOVERABLE, NO PARAMETER 1 BR 30$ 70$: MOV MYTCBA,R0 ;; GET TASK ERRDIS TASK TCB MOV ASTADD,R1 ;; GET AST BLOCK ADDRESS CALLR @#$QASTT ;; AND PLACE ON AST QUEUE All that is left is to see how the table of extra error information lines is generated. However, this is only the method I used for the RSX-11S system. A unified error file is quite possible and is recommended. Page 18 ;+ ; FILE DESCRIPTION ; ; THIS FILE CONTAINS ERROR MESSAGES ; ; THE MESSAGES ARE STORED UNSORTED IN THE FOLLOWING MANNER: ; ; PSECT MSGKEY CONTAINS THE FOLLOWING STRUCTURE ; FIRST 3 CHARACTERS OF KEY ; SECOND 3 CHARACTERS OF KEY ; POINTER TO MESSAGE IN PSECT MSGMSG ; ; THE KEYS ARE TERMINATED BY A KEY WITH SPACES AS THE ; FIRST 3 CHARACTERS = IE 0 ; ; PSECT MSGMSG CONTAINS THE FOLLOWING STRUCTURE ; MESSAGE SIZE, MESSAGE ; ;- ; ; .MACRO MAKMSG KEY,MES .PSECT MSGMSG .NCHR TEMSZ, TEMP = . .BYTE TEMSZ .ASCII /MES/ .PSECT MSGKEY .RAD50 /KEY/ .WORD TEMP .PSECT .ENDM MAKMSG .PSECT MSGKEY,RO,D MSGKYS:: .PSECT MSGMSG,RO,D MSG:: .PSECT MAKMSG AAAAA, MAKMSG < >, .PSECT MSGMSG .EVEN .PSECT MSGKEY .EVEN .PSECT .END Page 19 The entire listing of the program, data file, build and assembly files follow. ; ; PREFIX FILE -- DEFF.MAC ; .MACRO ERROR,P1,P2,P3,P4 ; ; MACRO TO SET UP INSTRUCTION BLOCK FOR ERROR MESSAGES ; ; ERROR KEY,TYPE,PRAM1,PRAM2 ; ; KEY <= 6 RAD50 CHARACTERS ; TYPE = -1 FATAL ERROR ; = -2 FOR DELAYED RECOVERY ; = -3 FOR JUMP RECOVERY ; = 0 FOR MESSAGE ONLY ; SEE DESCRIPTION IN ERRDIS MODULE ; .WORD 210 ; ERROR HANDLING INSTRUCTION .NCHR TEMPN,P1 .IIF LT 6-TEMPN .ERROR ; RAD50 NAME > 6 CHARACTERS .IF LT 3-TEMPN .RAD50 /P1/ .IFF .RAD50 /P1/ .RAD50 / / .ENDC .WORD P2,P3,P4 .ENDM ERROR .MACRO SAVRG JSR R5,$SAVRG .ENDM .TITLE ERRDIS .IDENT /X1.0/ ; ; ; WRITTEN BY D.B.CURTIS ; SCIENCE APPLICATIONS, INC. ; 14-JUL-81 ; ARGONNE NATIONAL LAB ; ; ; VERSION 01 ; EDIT NUMBER = 0003 ; FILE = ERRDIS.MAC ; EDITED BY: D.B.CURTIS 19 AUG 81 11:25 ; ; ; MODIFICATIONS: ; ;+ ; FILE DESCRIPTION ; ; THIS TASK IS AN ERROR LOGGING TASK ; IT CAN BE USED WITH MOST OTHER RSX11-M/S FACILITIES IF THE ERROR ; MESSAGES AND KEYS ARE CHANGED. THIS TASK INTERCEPTS THE ILLEGAL ; INSTRUCTION TRAP AND IS INVOKED BY THE 210 OP CODE. ; ; INFORMATION FOLLOWS THAT OPCODE. THIS INFORMATION DETERMINES HOW ; THIS TASK PROCESSES THE ERROR. ; ; THE MAIN PURPOSE OF THIS TASK IS TO DISPLAY ERRORS. ITS SECONDARY ; PURPOSE IS TO HELP RECOVER FROM THE ERRORS. THIS MEANS THAT SOME ; CONTROL OPERATIONS ARE PROVIDED. ; ; THE ERROR CONTROL BLOCK LOOKS LIKE: ; ; ----------------------------------------- ; | OP CODE (210) | ; |---------------------------------------| ; | FIRST 3 CHAR. OF RAD50 KEY | ; |---------------------------------------| ; | SECOND 3 CHAR. OF RAD50 KEY | ; |---------------------------------------| ; | FIRST PARAMETER | ; |---------------------------------------| ; | SECOND PARAMETER | ; |---------------------------------------| ; | THIRD PARAMETER | ; ----------------------------------------- ; ; WHERE THE RAD50 KEY MUST MATCH WITH THE KEYS IN THE ERROR MESSAGE ; TABLE. IF NO MATCH IS FOUND, THE KEY IS PRINTED. ; ; THE FIRST PARAMETER SPECIFIES THE ACTION THIS TASK TAKES ON THE ; ISSUING TASK. THIS PARAMETER TAKES THE FOLLOWING VALUES: ; ; 0 = MESSAGE ONLY, PROCESSING CONTINUES AFTER THE DATA BLOCK ; THE SECOND AND THIRD PARAMETER CONTAIN DATA TO BE PRINTED ; IF THE SECOND PARAMETER IS 0 R0 WILL BE PRINTED INSTEAD ; IF THE THIRD PARAMETER IS 0, R5 WILL BE PRINTED INSTEAD ; ; -1 = FATAL ERROR, THE MESSAGE IS PRINTED, AND ; THE TASK IS ABORTED. THE SECOND AND THIRD PARAMETERS ARE ; TREATED AS IN THE 0 CASE ; ; -2 = RECOVERABLE ERROR, THE MESSAGE IS PRINTED. THE SECOND ; PARAMETER CONTAINS THE ADDRESS TO SET THE PC TO. ; THE FIRST BYTE OF THE THIRD PARAMETER IS THE NUMBER ; OF SECONDS TO WAIT, AND THE LAST BYTE OF THE THIRD ; PARAMETER IS THE EVENT FLAG TO USE WHILE WAITING. ; IF THE SECONDS ARE ZERO, IT WILL DEFAULT TO 1, IF THE EVENT ; FLAG IS ZERO, IT WILL DEFAULT TO 1. ; ; -3 = RECOVERABLE ERROR, THE MESSAGE IS PRINTED. THE SECOND ; PARAMETER CONTAINS THE ADDRESS TO SET THE PC TO. ; IF PARAMETER 3 IS 0, R5 WILL BE USED AS AN ARGUMENT. ; ; IF ANOTHER VALUE THE THE ONES LISTED ABOVE, THE ERROR IS PRINTED, ; AN ERROR MESSAGE FROM THIS TASK IS PRINTED, AND THE OFFENDING ; TASK IS ABORTED ; ; YOU WOULD USE -2 FOR AN ERROR THAT REQUIRED OPERATOR INTERVENTION ; YOU WOULD USE -3 FOR AN ERROR THAT COULD NOT BE TRIED AGAIN, ; AND JUMP TO AN ERROR EXIT ; ; ; ;- .MCALL QIOW$S,CINT$,QIOW$,DIR$,ASTX$S,SPND$S,TCBDF$,ABODF$,HWDDF$ .MCALL QIO$S,CLKDF$,PCBDF$,HDRDF$ ABODF$ TCBDF$ HWDDF$ CLKDF$ HDRDF$ PCBDF$ ; ; NUMBER OF PARAMETERS IN AST ; NUMPRM = 9. CINT: CINT$ ERRVEC,120000,ERRINT,ERRINI,PR7,ASTAD POLADD: .WORD 0 POLSIZ: .WORD 0 MYTCBA: .WORD 0 ASTADD: .WORD 0 START: DIR$ #CINT ; CONNECT TO THE VECTOR, AND INIT IT BCC 10$ ; IF ERROR JUST IOT ; CRASH 10$: SPND$S ; ELSE SUSPEND FOREVER ; ; IF THIS TASK IS RESUMED, IT WILL SELF TEST ; ERROR AAAAA,0,1,2 ; PRINT ERROR MESSAGE WITH DEFAULT PARAMETERS MOV #3,R0 MOV #4,R5 ERROR BBBBB,0,0,0 ; PRINT ERROR MESSAGE WITH R0,R5 PARAM BR 30$ ; NEXT MESSAGE SHOULD BE DDDDD 20$: ERROR CCCCC,-3,40$,6 ; NEXT MESSAGE WILL BE A DELAY MESSAGE 30$: ERROR DDDDD,-3,20$,5 ; CCCCC IS NEXT MESSAGE 40$: ERROR EEEEE,-2,50$,<<15*400>+5> ; CHECK FOR 5 SECOND DELAY 50$: ERROR FFFFF,-2,60$,<<0*400>+0> ; CHECK DEFAULT DELAY AND EVENT FLAG 60$: ERROR DONE,-3,10$,0 ; ALL DONE ;+ ; **-ASTAD-AST RECEIVER/ERROR DISPLAY MODULE ; ; THIS MODULE RECEIVES THE AST BLOCK FROM THE FORK CODE. ; IT TAKES THAT INFORMATION, SEARCHES FOR A MATCHING KEY IN THE ; EXPANDED MESSAGE DATA AREA AND IF ONE IS FOUND THE EXPANDED MESSAGE ; IS WRITTEN OUT. REGARDLESS OF WEITHER THE EXPANDED MESSAGE IS ; FOUND, THE PARAMETERS IN THE AST BLOCK ARE WRITTEN OUT AS: ; ; 'TSKNAM' PS = XXXXXX, PC = XXXXXX, DSW = XXXXXX ; ERROR 'KEYNAM', PRAMS = XXXXXX XXXXXX ; ; ; INPUTS: ; INFORMATION IS ON THE STACK, ALL REGISTERS MUST BE SAVED ; THE INFORMATION ON THE STACK IS: ; 2 WORDS OF RAD50 TASK NAME ISSUING THE INSTRUCTION ; PS OF THAT TASK ; PC OF THAT TASK ; DSW OF THAT TASK ; 2 WORDS OF RAD50 ERROR KEYWORD ; FIRST PARAMETER ; SECOND PARAMETER ; ; OUTPUTS: ; NONE ; ; SIDE EFFECTS: ; ; MODIFIED EXTERNALS ; ; OTHER SIDE EFFECTS ; STACK IS CLEANED, MESSAGE IS PRINTED ; ; REGISTER USAGE: ; ALL REGISTERS SAVED ; ;- ; ; REFERENCED GLOBALS ; .GLOBL $EDMSG ; EDIT MESSAGE ( SYSTEM LIBRARY ROUTINES MANUAL) .GLOBL MSGKYS ; ADDRESS OF THE ERROR KEY TABLE .GLOBL TTLUN ; LUN OF THE TERMINAL I/O .GLOBL TTEV ; EVENT FLAG FOR TERMINAL OPERATIONS ; ; EQUATED SYMBOLS ; BEL = 7 ; ASCII CODE FOR BELL .ASECT . = 0 REGS: .BLKW 6 ; R5-R0 R5 IS FIRST ERTNM: .BLKW 2 ; 2 WORDS OF RAD50 TASK NAME FROM ERROR ETPS: .BLKW 1 ; ERRORING TASKS PS ETPC: .BLKW 1 ; ERRORING TASKS PC ETDSW: .BLKW 1 ; ERRORING TASKS DSW EKEY: .BLKW 2 ; 2 RAD50 WORDS WITH KEY NAME ETP1: .BLKW 1 ; FIRST PARAMETER ETP2: .BLKW 1 ; SECOND PARAMETER .PSECT .ENABL LSB ASTAD: .IRPC REG,<012345> ; SAVE THE REGISTERS MOV R'REG,-(SP) .ENDM ; ; GET THE INFORMATION FROM THE INTERRUPT PART AND DISPLAY IT ; MOV SP,R0 ; GET THE ADDR OF THE ERROR DATA BLOCK MOV EKEY(R0),R1 ; GET THE FIRST WORD OF THE KEY MOV #MSGKYS,R2 ; AND THE ADDRESS OF THE KEYS 10$: CMP R1,(R2) ; IS THE FIRST PART OF THE KEY THE SAME? BNE 20$ ; HERE THE FIRST PART OF THE KEY MATCHES CMP EKEY+2(R0),2(R2) ; DOES THE SECOND PART MATCH? BNE 20$ ; IF NE NO, SO CONTINUE BR 50$ 20$: ADD #6,R2 ; ADVANCE TO NEXT KEY TST (R2) ; CHECK NOT END OF KEYS BNE 10$ ; KEY NOT FOUND, => NO MESSAGE OTHER ; OTHER THEN KEY EITHER ; ; HERE, CONVERT KEY TO ASCII, AND PRINT IT AND OTHER VARIABLES ; .PSECT MESFMT,RO,D .NLIST BEX MG1: .ASCII /'%2R' PS = %P, PC = %P, DSW = %P%N/ .ASCIZ /ERROR '%2R', PRAMS = %2P%N/ .LIST BEX .PSECT 30$: MOV SP,R2 ; SAVE POINTER TO PARAMETERS ADD #ERTNM,R2 SUB #200.,SP ; SAVE SPACE FOR LINE ON STACK MOV SP,R0 MOV SP,R5 MOV #MG1,R1 ; POINT TO FORMAT INFORMATION CALL $EDMSG ; FORMAT IT CMP #200.,R1 ; CHECK STACK DIDN'T GET WIPED BGE 40$ IOT 40$: QIOW$S #IO.WBT,#TTLUN,#TTEV,,,, ADD #200.,SP ; CLEAN UP STACK BR 60$ ; ; HERE PRINT MESSAGE, AND VARIABLES ; 50$: MOV 4(R2),R1 ; GET ADDRESS OF MESSAGE MOVB (R1)+,R2 ; GET SIZE OF MESSAGE QIO$S #IO.WBT,#TTLUN,,,,, BR 30$ 60$: .IRPC REG,<543210> ; RESTORE THE REGISTERS MOV (SP)+,R'REG .ENDM ADD #2*NUMPRM,SP ; CLEAN OFF PARAMETERS ASTX$S .DSABL LSB ;+ ; **-ERRINI-CONNECT TO INTERRUPT ENABLE/DISABLE ROUTINE ; ; THIS ROUTINE ENABLES/DISABLES THE ILLEGAL INSTRUCTION INTERCEPT ; IF CARRY IS CLEAR, IT ENABLES, IF SET, IT DISABLES ; THIS MODULE ALLOCATES SOME POOL MEMORY, PLACES THE ILLEGAL INSTRUCTION ; INTERCEPT CODE INTO THE POOL AREA, MODIFIES XDT TO NOT PLAY WITH THE ; ILLEGAL INSTRUCTION TRAP VECTOR (ONLY IF XDT IS PRESENT) AND RETURNS. ; ; THE DISABLE OF THIS OPERATION UNDOES ALL OF THE ABOVE ; ; INPUTS: ; CARRY SET TO DETACH FROM VECTOR, CLEAR TO ATTACH TO VECTOR ; ; OUTPUTS: ; NONE ; ; SIDE EFFECTS: ; ; MODIFIED EXTERNALS ; ; OTHER SIDE EFFECTS ; POLADD,POLSIZ ARE SET TO THE ADDRESS OF THE POOL AREA, AND ITS SIZE ; THE ILLEGAL INSTRUCTION TRAP VECTOR IS INTERCEPTED. ; ; REGISTER USAGE: ; R1,R4,R5 ARE SAVED ; ;- ; ; REFERENCED GLOBALS ; .GLOBL $ALOCB ; ALLOCATE CORE BLOCK .GLOBL $TKTCB ; CURRENT TASK TCB ADDRESS .GLOBL $DEACB ; DEALLOCATE CORE BLOCK .GLOBL ERRVEC ; VECTOR TO SEND ERROR INSTRUCTION TOO .GLOBL XDTFIX ; OFFSET FROM $XDT TO PATCH XDT ILLEGAL ; INSTRUCTION VECTOR RESET .GLOBL $XDT ; ENTRY POINT TO XDT .GLOBL ILLVEC ; TRAP VECTOR ADDRESS FOR ILLEGAL INSTRUCTION ERRINI: BCC 10$ ;; CONNECT TO ILLEGAL INSTRUCTION VEC JMP ABOPRO ;; IF CARRY SET, DISCONNECT 10$: MOV R5,-(SP) ;; SAVE REGISTERS MOV R4,-(SP) MOV R1,-(SP) MOV #EPOLCD-POOLCD,R1 ;; NEED TO ALLOCATE POOL SPACE TO PUT CALL $ALOCB ;; TRAP INTERCEPT CODE BCC 20$ IOT ;; IF NO POOL SPACE, CRASH SYSTEM 20$: MOV R0,POLADD ;; SAVE ADDRESS OF ALLOCATED BLOCK MOV R1,POLSIZ ;; AND SIZE OF ALLOCATED BLOCK MOV $TKTCB,MYTCBA ;; AND WHILE AT IT, SET MY TCB ADDRESS MOV #/2,R2 ;; GET THE NUMBER OF BYTES TO COPY MOV #POOLCD,R3 ;; AND THE ADDRESS OF CODE TO MOVE ;; TOO THE POOL 30$: MOV (R3)+,(R0)+ ;; DO THE MOVE SOB R2,30$ ;; UNTIL FULLY COPIED MOV POLADD,R0 ;; GET THE START ADDRESS OF POOL CODE ADD #2,R0 ;; BUMP PAST THE "ILL" MOV POLSIZ,(R0)+ ;; SAVE THE NUMBER OF BYTES IN CODE MOV @#ILLVEC,(R0)+ ;; SAVE THE ORIGINAL VECTOR MOV #NOP,(R0) ;; TURN ON THE CODE MOV #$XDT,R2 ;; CHECK IF XDT IS AVAILABLE BEQ 40$ ;; IF EQ NO SUB #XDTFIX,R2 ;; CHECK IF XDT IS CONSISTENT CMP @#ILLVEC,(R2) BNE 40$ MOV R0,(R2) ;; ADJUST XDT 40$: MOV R0,@#ILLVEC ;; POINT ILLEGAL INSTRUCTION TRAP TO ;; THIS NEW CODE MOV (SP)+,R1 ;; RESTORE REGISTERS MOV (SP)+,R4 MOV (SP)+,R5 RETURN ;; AND RETURN TO TASK ; ; CODE THAT GETS LOADED INTO THE POOL ; >>>>>> THIS CODE MUST BE PIC <<<<< ; POOLCD: .RAD50 /ILL/ ;;; SHOW THIS CODE IS ATTACHED TO THE .WORD 0,0 ;;; ILLEGAL INSTRUCTION VECTOR RTI ;;; INITIALLY, TURN OFF CODE EP: MOV R5,-(SP) ;;; SAVE R5 MOV 2(SP),R5 ;;; AND GET TASK PC FROM STACK MFPI -(R5) ;;; GET THE INSTRUCTION THAT CAUSED THE TRAP CMP (SP),#210 ;;; IS IT OUR INSTRUCTION? BEQ 100$ ADD #2,SP ;;; NO! SO CLEAR THE STACK MOV (SP)+,R5 ;;; RESTORE R5 JMP @EP-4 ;;; AND PROCESS NORMALLY ; ; HERE IT IS OUR ILLEGAL INSTRUCTION ; 100$: ADD #2,SP ;;; CLEAN THE STACK MOV (SP)+,R5 ;;; RESTORE R5 MOV @#ERRVEC,-(SP) ;;; AND JUMP VIA THE VECTOR WE ARE CONNECTED TO JMP @(SP)+ ;;; POSITION INDEPENDENT INDIRECT JUMP EPOLCD: ;;; END OF THE CODE INSERTED INTO THE POOL ABOPRO: MOV R1,-(SP) ;; SAVE ITB POINTER MOV @#ILLVEC,R0 ;; GET CURRENT VECTOR TO FIND OUR CODE MOV -2(R0),@#ILLVEC ;; RESET THE ILLEGAL INSTRUCTION VEC MOV #$XDT,R2 ;; RESET XDT BR 1$ ;; IF IT IS IN THE SYSTEM SUB #XDTFIX,R2 MOV -2(R0),(R2) 1$: MOV POLADD,R0 ;; GET THE ADDRESS OF THE POOL CODE MOV POLSIZ,R1 ;; AND THE SIZE CALL $DEACB MOV (SP)+,R1 ;; RESTORE ITB POINTER RETURN ;+ ; **-ERRINT-PROCESSES ERROR INTERRUPTS ; ; THIS MODULE RECEIVES THE 210 INSTRUCTION CODE. ; IT SAVES THE ERROR BLOCK PARAMETERS, DOES ANY PROCESSING OF THE ; PARAMETERS (CHECKS WHAT TO DO WITH THE ISSUING TASKS PC). ; FORKS AND PLACES THE TASK IN THE APPROPRIATE STATE ; ; INPUTS: ; R5 POINTS TO THE ITB ; R4 IS SAVED AND MAY BE USED ; ; OUTPUTS: ; NONE ; ; SIDE EFFECTS: ; ; MODIFIED EXTERNALS ; ; OTHER SIDE EFFECTS ; MANY, TASK MAY BE ABORTED, MADE TO MARK TIME, TASKS PC MAY BE ; MOVED AS DIRECTED BY THE PARAMETERS ETC. ; ; REGISTER USAGE: ; ; R5 POINTS TO ITB ; R4 IS SAVED AND MAY BE USED, ALL OTHER REGISTERS MUST BE SAVED AND ; RESTORED ; ;- ; ; REFERENCED GLOBALS ; .GLOBL $FORK2 ; ; LOCAL DATA ; ERL1: .WORD 0 ; TEMP STORAGE FOR ERROR KEY AND PARAMETERS ERL2: .WORD 0 PER1: .WORD 0 PER2: .WORD 0 PER3: .WORD 0 ERRINT: ;;; HERE IF ILLEGAL INSTRUCTION ;;; FIRST 2 WORDS ARE RAD50 REP OF NAME OF ERROR MOV 10(SP),R4 ;;; GET PC OF TASK MFPI (R4)+ ;;; GET FIRST WORD OF RAD50 ERROR MOV (SP)+,ERL1 ;;; MFPI (R4)+ ;;; MOV (SP)+,ERL2 ;;; MFPI (R4)+ ;;; MOV (SP)+,PER1 ;;; MFPI (R4)+ ;;; MOV (SP)+,PER2 ;;; MFPI (R4)+ ;;; MOV (SP)+,PER3 ;;; TST PER1 ;;; CHECK IF MESSAGE ONLY BMI 20$ ;;; IF MI NO MOV R4,10(SP) ;;; SET NEW PC AS ONLY MESSAGE IS REQUIRED 10$: CALL @#$FORK2 ;;; CLR (R3) ;; CLEAR THE FORK BLOCK CALLR SNDMSG ;; AND SEND AST TO TASK STATE 20$: CMP #-1,PER1 ;;; CHECK IF TO ABORT TASK BNE 40$ ;;; NE NO 30$: CALL @#$FORK2 ;;; CLR (R3) ;; CLEAR THE FORK BLOCK 32$: MOV #S.CABO,R0 ;; ABORTING FROM ILLEGAL INSTRUCTION CALL $ABCTK ;; ABORT THE CURRENT TASK CALLR SNDMSG ;; AND SEND AST TO TASK STATE 40$: CMP #-2,PER1 ;;; CHECK IF OFFSET JMP BNE 50$ MOV PER2,10(SP) ;;; ADJUST PC CALL @#$FORK2 ;;; CLR (R3) ;; CLEAR FORK BLOCK MOV #2,-(SP) ;; SET THE UNITS TO SECONDS MOVB PER3,-(SP) ;; GET THE NUMBER OF SECONDS TO WAIT BNE 41$ ;; CHECK SPECIFIED INC (SP) ;; DEFAULT IS 1 41$: CLRB 1(SP) ;; MAX 255 MOV SP,R3 ;; POINT R3 TO BLOCK CALL $CVRTM ;; AND CONVERT THE TIME MOV R0,2(SP) MOV R1,(SP) 42$: MOVB PER3+1,R0 ;; GET THE EVENT FLAG TO USE BNE 43$ ;; EVENT FLAG OF 0 IMPLIES DEFAULT INCB PER3+1 BR 42$ 43$: MOV $TKTCB,R5 ;; AND THE TCB OF THE CURRENT TASK CALL $CEFI ;; AND CONVERT TO MASK WORD AND ADDRESS BCC 45$ 44$: ADD #4,SP ;; CLEAN UP STACK BR 32$ 45$: CMPB PER3,#64. ;; CHECK IF GLOBAL EVENT FLAG BHI 44$ ;; IF SO GO TO 44 AND ABORT BIC R0,(R1) ;; CLEAR THE EVENT FLAG MOV R0,-(SP) ;; SAVE EVENT FLAG MASK WORD MOV R1,-(SP) ;; AND THE EVENT FLAG MASK ADDRESS MOV T.PCB(R5),R4 ;; GENERATE POINTER TO TASK HEADER MOV P.HDR(R4),R4 INC T.ST2(R5) ;; PUT TASK IN WAIT FOR STATE MOV 2(SP),H.EFLM(R4) ;; SAVE WAIT FLAG MOV (SP),H.EFLM+2(R4) CALL $SETRT ;; SET SCHEDIUAL REQUEST MOV #C.MRKT,R4 ;; MAKE CLOCK BLOCK A MARK TIME BLOCK CALL $ALCLK ;; ALLOCATE A CLOCK BLOCK MOVB PER3+1,C.EFN(R0) ;; SAVE MARK TIME EVENT FLAG CLR C.AST(R0) ;; CLEAR THE AST ADDRESS MOV (SP)+,C.DST(R0) ;; SET THE EVENT FLAG DESTINATION MOV (SP)+,C.SRC(R0) ;; AND THE VALUE TO BE SET MOV (SP)+,R2 ;; GET THE TIME TO WAIT MOV (SP)+,R1 CALL $CLINS ;; AND INSERT THE MARK TIME BLOCK IN THE CALLR SNDMSG ;; CLOCK QUEUE, AND SEND AST TO TASK STATE 50$: CMP #-3,PER1 ;;; CHECK IF ABSOLUTE JMP BNE 30$ ;;; MOV PER2,10(SP) ;;; BR 10$ ;;; ;+ ; **-SNDMSG-SEND MESSAGE (VIA AST) ; ; THIS MODULE SENDS AN AST BLOCK TO THIS TASK. ; THE AST PARAMETERS ARE DESCRIBED IN THE AST RECEIVER MODULE ; ; INPUTS: ; ERL1-PER3 -- INFORMATION FROM THE AST ; ; OUTPUTS: ; GENERATES AN AST BLOCK WHICH IS QUEUED TO THE TASK ; ; SIDE EFFECTS: ; ; MODIFIED EXTERNALS ; ; OTHER SIDE EFFECTS ; ; REGISTER USAGE: ; ALL REGISTERS ARE FREE TO BE USED ; ;- ; ; REFERENCED GLOBALS ; .GLOBL $QASTT ; QUEUE AST TO TASK SNDMSG: MOV #<5+NUMPRM>*2,R1 ;; ALLOCATE AN AST BLOCK FOR ERRLOG CALL $ALOCB ;; ALLOCATE SOME POOL BCC 10$ IOT ;; CRASH SYSTEM 10$: MOV R0,R2 ;; COPY ADDRESS OF BLOCK MOV R0,ASTADD ;; SAVE ADDRESS OF BLOCK CLR (R2)+ ;; CLEAR THE LINK MOV R1,(R2)+ ;; SET IN SIZE OF BLOCK MOV #<7+NUMPRM>*2,(R2)+ ;; SET NUMBER OF BYTES FOR STACK MOV #ASTAD,(R2)+ MOV #NUMPRM,(R2)+ ;; SPECIFY THE NUMBER OF PARAMETERS ; ; LOAD STANDARD PARAMETERS ; MOV $TKTCB,R0 ;; GET THE POINTER TO THE TCB MOV T.NAM(R0),(R2)+ ;; GET THE TASK NAME MOV T.NAM+2(R0),(R2)+ MOV 22(SP),(R2)+ ;; GET THE TASK PS MOV 20(SP),(R2)+ ;; GET THE TASK NEW PC MFPI @#$DSW ;; GET THE USER DSW MOV (SP)+,(R2)+ MOV ERL1,(R2)+ ;; SAVE ERROR LABEL MOV ERL2,(R2)+ TST PER1 ;; CHECK FOR TYPE OF INFO TO TASK BNE 50$ ; ; HERE FOR NORMAL MESSAGE NO TASK AFFECT ; 20$: MOV PER2,(R2)+ ;; GET THE FIRST PARAMETER BNE 30$ ;; IF DEFAULT USE MOV 4(SP),-2(R2) ;; R0 AS PARAMETER 30$: MOV PER3,(R2) ;; GET THE SECOND PARAMETER BNE 40$ ;; IF DEFAULT USE MOV 16(SP),(R2) ;; R5 AS PARAMETER 40$: BR 70$ 50$: CMP PER1,#-1 ;; CHECK FOR FATAL ERROR BEQ 20$ ;; TREAT AS NORMAL ERROR CMP PER1,#-2 ;; CHECK FOR RECOVERABLE ERROR BNE 60$ CLR (R2)+ ;; IF RECOVERABLE ERROR, NO PARAMETERS CLR (R2) BR 70$ 60$: CMP PER1,#-3 ;; CHECK FOR RECOVERABLE ERROR BNE 20$ CLR (R2)+ ;; IF RECOVERABLE, NO PARAMETER 1 BR 30$ 70$: MOV MYTCBA,R0 ;; GET TASK ERRDIS TASK TCB MOV ASTADD,R1 ;; GET AST BLOCK ADDRESS CALLR @#$QASTT ;; AND PLACE ON AST QUEUE .END START .TITLE ERRDAT - ERROR DISPLAY DATA/MESSAGES .IDENT /X1.0/ ; ; ; WRITTEN BY D.B.CURTIS ; SCIENCE APPLICATIONS, INC. ; 14-JUL-81 ; ARGONNE NATIONAL LAB ; ; ; VERSION 01 ; EDIT NUMBER = 0001 ; FILE = ERRDISDAT.MAC ; EDITED BY: D.B.CURTIS 14-JUL-81 10:11:46 ; ; ; MODIFICATIONS: ; ;+ ; FILE DESCRIPTION ; ; THIS FILE CONTAINS ERROR MESSAGES ; ; THE MESSAGES ARE STORED UNSORTED IN THE FOLLOWING MANNER: ; ; PSECT MSGKEY CONTAINS THE FOLLOWING STRUCTURE ; FIRST 3 CHARACTERS OF KEY ; SECOND 3 CHARACTERS OF KEY ; POINTER TO MESSAGE IN PSECT MSGMSG ; ; THE KEYS ARE TERMINATED BY A KEY WITH SPACES AS THE ; FIRST 3 CHARACTERS = IE 0 ; ; PSECT MSGMSG CONTAINS THE FOLLOWING STRUCTURE ; MESSAGE SIZE, MESSAGE ; ;- ; ; .MACRO MAKMSG KEY,MES .PSECT MSGMSG .NCHR TEMSZ, TEMP = . .BYTE TEMSZ .ASCII /MES/ .PSECT MSGKEY .RAD50 /KEY/ .WORD TEMP .PSECT .ENDM MAKMSG .PSECT MSGKEY,RO,D MSGKYS:: .PSECT MSGMSG,RO,D MSG:: .PSECT MAKMSG AAAAA, MAKMSG < >, .PSECT MSGMSG .EVEN .PSECT MSGKEY .EVEN .PSECT .END ; ; ERRDATASM.CMD ; COMMAND FILE TO ASSEMBLE ERRDIS AND ERRDAT MODULES ; ERRDIS,ERRDIS=LB:[1,1]EXEMC/ML,[11,10]RSXMC,SY:[125,5]DEFF,ERRDIS ERRDAT,ERRDAT=LB:[1,1]EXEMC/ML,[11,10]RSXMC,SY:[125,5]DEFF,ERRDAT ; ; ERRDISBLD.CMD ; COMMAND FILE TO BUILD ERROR DISPLAY TASK ; ; YOU MAY GET A UNDEFINED SYMBOLE '$XDT' IF XDT ISN'T IN THE SYSTEM. ; THIS IS EXPECTED AND SHOULD NOT BE FIXED! (IT DEFAULTS TO 0) ; ERRDIS/PR:5/-DA, = ERRDIS,ERRDAT LB:[1,54]RSX11M.STB/SS / TASK = ERRDIS ; ; SET UP TERMINAL INTERACTION USE LUN4 AND EVENT FLAG 4 ; ASG = TI:4 GBLDEF = TTLUN:4 GBLDEF = TTEV:4 ; ; OFFSET IN XDT TO INITIALLIZATION TABLE ; GBLDEF = XDTFIX:300 ; ; ILLEGAL INSTRUCTION TRAP VECTOR ; GBLDEF= ILLVEC:10 ; ; UNUSED VECTOR TO CONNECT TO ; GBLDEF = ERRVEC:774 //