.TITLE MTED MULTI-TERMINAL ENABLE-DISABLE PROGRAM .IDENT /V01.10/ .ENABL LC .NLIST CND ; ; PURPOSE: To provide the user with the capability of dynamically ; redefining the use of monitor generated multi-terminal ports. ; ; COMMANDS: DISABLE, ENABLE, HELP, LIST ; ; This program will accept input from either the console ; terminal or an indirect command file. Errors in ; command input to MTED cause appropriate codes to be ; set in the monitor's user error byte. Thus this ; program responds properly to RT-11 "SET ERROR" conditions. ; ; Author: S.C. CRIBBS APRIL 14,1981 ; Added NHD support (RT-11 V5.1) June 1984 ; ATOMIC ENERGY OF CANADA LIMITED ; PINAWA, MANITOBA ; CANADA R0E 1L0 ; ; MONITOR DATABASE REFERENCE SYMBOLS MONPTR = 54 ; BASE OF MONITOR SYSGEN = 372 ; SYSTEM GENERATION WORD MTTY = 2000 ; MULTI-TERMINAL FEATURE BIT SYERRB = 52 ; SYSTEM ERROR BYTE USERRB = 53 ; USER JOB ERROR BYTE WARN$ = 2 ; "WARNING" EROR CONDITION CODE SEVER$ = 10 ; "FATAL" ERROR CONDITION CODE JSW = 44 ; JOB STATUS WORD RE$EN = 2000 ; REENTER BIT IN "JSW" ; TERMINAL CONTROL BLOCK SYMBOL DEFINITONS MAXTTY = 17. ; MAXIMUM NUMBER OF TERMINALS IN RT-11 T.OWNR = 12 ; OWNER OFFSET IN TERMINAL CONTROL BLOCK(TCB) T.STAT = 14 ; TERMINAL STATUS WORD T.CSR = 16 ; OFFSET TO FIRST CONTROL & STATUS REGISTER T.VEC = 20 ; OFFSET TO VECTOR IN "TCB" T.JOB = 24 ; (BYTE) OWNER JOB NUMBER IN "TCB" T$CNSL = 100000 ; SHARED OR PRIVATE CONSOLE BIT IN "T.STAT" NHD = 1 ;Assume processor has EIS instructions ; Set NHD = 1 if not .IIF NE NHD, .MCALL SOB ;Simulate SOB (RT-11 V5.1) .MCALL .MTSTAT,.PRINT,.EXIT,.LOOKUP,.GTLIN,.READW,.WRITW,.SCCA .PAGE NOP ; REENTER = START START: BIS #RE$EN,@#JSW ; ALLOW REENTER MOV @#MONPTR,R2 ; CREATE A POINTER TO MONITOR DATABASE BIT #MTTY,SYSGEN(R2) ; DOES MONITOR HAVE MULTI-TERMINAL FEATURE? BNE 1$ ; JUMP IF SO MOV #NOMTT,R0 ; POINT TO ERROR MESSAGE BR SERROR ; TELL USER 1$: .MTSTAT #EMT,#MTSTAT ; READ MULTI-TERMINAL STATUS BLOCK BCC 2$ ; JUMP IF NO ERROR MOV #XMERR,R0 ; GOT "XM" PROBLEMS BR SERROR ; TELL USER 2$: MOV #MTSTAT+10,R0 ; POINT JUST PAST RELEVENT INFORMATION MOV -(R0),R3 ; GET SIZE OF TCBS (BYTES) INC -(R0) ; ADJUST HIGHEST TCB NUMBER TO GET MOV @R0,R1 ; NUMBER OF TCBS SYSGENED ADD R2,-(R0) ; MAKE A POINTER TO JOB'S CONSOLE TCB ADD -(R0),R2 ; NOW MAKE A POINTER TO FIRST TCB MOV #TCBPTR,R0 ; AND TO BEGINNING OF "TCB" TABLE 3$: MOV R2,(R0)+ ; SAVE ADDRESS OF "TCB" ADD R3,R2 ; ADDING SIZE UPDATES "TCB" POINTER SOB R1,3$ ; LOOP UNTIL TABLE FILLED .LOOKUP #EMT,#0,#FNAME ; OPEN A PATH TO "MTED" DATABASE BCC CMDLUP ; ON SUCCESS, START COMMAND SCANNING MOV #NOFIL,R0 ; GET ADDRESS OF ERROR MESSAGE SERROR: BISB #SEVER$,@#USERRB ; SET FATAL ERROR STATUS .PRINT ; TYPE ERROR MESSAGE CLR R0 ; HARD EXIT .EXIT ; CALL BACK MONITOR .PAGE ; THIS COMMAND DECODER WOULD NOT PROPERLY HANDLE ; AMBIGUOUS ABBREVIATIONS. CMDLUP: MOV #LBUF,R5 ; CREATE A POINTER TO LINE BUFFER .GTLIN R5,#PROMPT ; REQUEST & ACCEPT USER'S COMMAND MOV #COMAND,R0 ; POINT TO SPACE FOR COMMAND OPERATOR MOV #6,R4 ; MAX. OF SIX CHARS. IN COMMAND MOV R4,R3 ; NEED A WORKING COPY MOV #CMDTBL,R1 ; CREATE A POINTER TO COMMAND TABLE 1$: MOVB (R5)+,(R0)+ ; COPY OPERATOR CHAR. TO COMMAND SPACE BEQ 2$ ; DONE IF NULL COPIED CMPB #40,-1(R5) ; WAS IT A SPACE? BEQ 2$ ; IF SO, COMMAND SCAN COMPLETE SOB R3,1$ ; ELSE LOOP FOR SIX CHARS. 2$: TSTB -(R5) ; ROLL BACK ONE CHAR. SUB R3,R4 ; CALCULATE # CHARS IN OPERATOR BNE 3$ ; JUMP IF NOT ZERO .PRINT #VERSN ; TYPE PROGRAM VERSION # BR CMDLUP ; GO LOOK FOR NEXT COMMAND 3$: MOV (R1)+,R0 ; GET ADDRESS OF NEXT COMMAND IN TABLE BNE 4$ ; JUMP IF NOT PAST END OF LIST .PRINT #UNREC ; TELL USER - UNRECOGNIZED COMMAND BR CMDLUP ; GO LOOK FOR NEXT COMMAND 4$: MOV R4,R2 ; GET WORKING COPY OF # CHARS. MOV #COMAND,R3 ; POINT TO COMMAND OPERATOR 5$: CMPB (R0)+,(R3)+ ; COMPARE CHARACTERS BNE 3$ ; QUIT ON FIRST MISMATCH SOB R2,5$ ; TEST ALL CHARS. IN OPERATOR TST -(R1) ; MATCH FOUND, ROLL BACK TABLE POINTER SUB #CMDTBL,R1 ; DETERMINE OFFSET FROM START OF TABLE CALL @DISPAT(R1) ; EXECUTE COMMAND BR CMDLUP ; GO LOOK FOR NEXT COMMAND .PAGE DISABL: JSR PC,GTARGS ; ANALYZE & DECODE ARGUMENT LIST TST R5 ; CHECK RETURNED ARG. COUNT BEQ 7$ ; DO NOTHING IF ZERO JSR PC,RDBASE ; READ DATA BASE 1$: MOV (SP)+,R4 ; GET TERMINAL# & ARG. POSITION MOVB R4,R3 ; ISOLATE TERMINAL NUMBER ASL R3 ; MAKE INTO TABLE OFFSET MOV TCBPTR(R3),R0 ; BUILD A POINTER TO IT'S "TCB" TST T.CSR(R0) ; CHECK "CSR" WORD IN "TCB" BNE 2$ ; "ENABLED" IF NOT ZERO MOV #NOTENB,R0 ; TELL USER YOU JSR PC,WERROR ; CAN'T DISABLE A DISABLED TERMINAL BR 6$ ; GO SERVICE NEXT ARGUMENT 2$: BIT #T$CNSL,T.STAT(R0) ; IS IT OUR CONSOLE? BNE 3$ ; ERROR IF SO TST T.OWNR(R0) ; CHECK "OWNER" WORD IN "TCB" BEQ 4$ ; OK TO DISABLE IF NOT OWNED 3$: MOV #INUSE,R0 ; CAN'T MODIFY SOMEONE ELSE'S TERMINAL JSR PC,WERROR ; PRINT MESSAGE & SET FLAG BR 6$ ; GO SERVICE NEXT ARGUMENT 4$: MOV R3,R4 ; CALCULATE THE OFFSET TO THE ASL R3 ; FIVE WORD STORAGE AREA ASL R3 ; IN THE DATABASE ADD R4,R3 ; FOR THIS TERMINAL ADD DBASE,R3 ; NOW POINT TO IT MOV T.CSR(R0),R1 ; GET ADDRESS OF "CSR" CLR @R1 ; DISABLE INPUT INTERRUPTS CLR T.CSR(R0) ; DISABLE MONITOR SUPPORT OF TERMINAL MOV R1,(R3)+ ; SAVE "CSR" ADDRESS IN DATABASE MOV #4,R2 ; NUMBER OF VECTOR WORDS TO MOVE MOV T.VEC(R0),R1 ; POINT TO FIRST VECTOR ADDRESS 5$: MOV (R1),(R3)+ ; COPY TO DATABASE CLR (R1)+ ; NOW ZERO VECTOR (PROTECT MONITOR FROM USER) SOB R2,5$ ; COPY & ZERO FOUR WORDS 6$: SOB R5,1$ ; LOOP THRU ARGUMENT LIST JSR PC,WDBASE ; WRITE OUT DATABASE 7$: RETURN ; RETURN TO COMMAND SCANNER .PAGE ENABLE: JSR PC,GTARGS ; ANALYZE & DECODE ARGUMENT LIST TST R5 ; CHECK RETURNED ARG. COUNT BEQ 5$ ; DO NOTHING IF ZERO JSR PC,RDBASE ; READ DATA BASE 1$: MOV (SP)+,R4 ; GET A TERMINAL# & ARG. POSITION MOVB R4,R3 ; ISOLATE TERMINAL NUMBER ASL R3 ; MAKE INTO TABLE OFFSET MOV TCBPTR(R3),R0 ; BUILD A POINTER TO IT'S "TCB" TST T.CSR(R0) ; CHECK "CSR" WORD IN "TCB" BEQ 2$ ; "DISABLED" IF NON-ZERO MOV #NOTDIS,R0 ; TELL USER "ALREADY ENABLED" JSR PC,WERROR ; PRINT ON CONSOLE BR 4$ ; GO SERVICE NEXT ARGUMENT 2$: MOV R3,R4 ; CALCULATE THE OFFSET TO THE ASL R3 ; FIVE WORD STORAGE AREA ASL R3 ; IN THE DATABASE ADD R4,R3 ; FOR THIS TERMINAL ADD DBASE,R3 ; NOW POINT TO IT MOV (R3)+,R4 ; GET "CSR" ADDRESS FROM DATABASE CLR @R4 ; BE SURE TERMINAL IS DORMANT CLR 4(R4) ; DISABLE INTERRUPTS OF BOTH "RCSR" & "XCSR" MOV T.VEC(R0),R1 ; GET VECTOR ADDRESS FROM "TCB" MOV #4,R2 ; NUMBER OF WORDS TO MOVE 3$: MOV (R3)+,(R1)+ ; RE-INSTALL VECTOR VALUES SOB R2,3$ ; COPY FOUR WORDS MOV R4,T.CSR(R0) ; INSTALL "CSR" ADDRESS IN "TCB" BIS #100,(R4)+ ; RE-ENABLE "RCSR" INTERRUPTS 4$: SOB R5,1$ ; LOOP THRU ARG. LIST JSR PC,WDBASE ; WRITE OUT DATABASE 5$: RETURN ; RETURN TO COMMAND SCANNER HELP: .PRINT #VERSN ; IDENTIFY PROGRAM .PRINT #HLPNTE ; DISPLAY HELP THAT'S AVAILABLE RETURN ; RETURN TO COMMAND SCANNER .PAGE LIST: .PRINT #LHDR ; TYPE HEADER LINE JSR PC,GTARGS ; ANALYZE & DECODE ARGUMENT LIST MOV #40,R3 ; GET CODE FOR A SPACE CHAR. MOV R5,R4 ; ANY ARGUMENTS? BNE 2$ ; JUMP IF SO MOV MTSTAT+4,R4 ; GET MAX# OF TERMINALS MOV R4,R0 ; NEED A WORKING COPY 1$: DEC R0 ; SPEAK IN COMPUTER VERNACULAR MOV R0,-(SP) ; LOAD TERMINAL NUMBERS ON STACK BNE 1$ ; THUS CREATE AN ARTIFICIAL ARG. LIST 2$: MOV #LBUF,R5 ; POINT TO ASCII BUFFER MOVB (SP)+,R0 ; GET LUN# JSR R5,OCNUM ; ENCODE AS OCTAL NUMBER .WORD 3 ; MAXIMUM OF TWO DIGITS & ONE SPACE .REPT 5 ; INSTALL FIVE SPACES MOVB R3,(R5)+ .ENDR ASL R0 ; CONVERT LUN INTO TABLE OFFSET MOV TCBPTR(R0),R1 ; MAKE POINTER TO "TCB" MOV T.CSR(R1),R0 ; GET THE "CSR" ADDRESS BNE 3$ ; JUMP IF NOT ZERO MOV #DSABLD,R0 ; POINT TO EXPLANATION BR 4$ ; INSTALL IN LINE 3$: JSR R5,OCNUM ; ENCODE AS OCTAL NUMBER .WORD 6 ; ALWAYS SIX DIGITS .REPT 7 ; INSTALL SEVEN SPACES MOVB R3,(R5)+ .ENDR MOV T.VEC(R1),R0 ; GET THE VECTOR ADDRESS JSR R5,OCNUM ; ENCODE AS OCTAL NUMBER .WORD 3 ; ALWAYS THREE DIGITS .REPT 8. ; INSTALL EIGHT SPACES MOVB R3,(R5)+ .ENDR BIT #T$CNSL,T.STAT(R1) ; IS IT A JOB CONSOLE? BEQ 5$ ; JUMP IF NOT CMP MTSTAT+2,R1 ; IS THIS, THIS JOB'S CONSOLE? BNE 6$ ; LINE COMPLETE IF NOT MOV #CONSOL,R0 ; POINT TO ASCII STRING CMPB -(R5),-(R5) ; ROLL BACK TWO SPACES 4$: MOVB (R0)+,(R5)+ ; PUT THE CHARACTERS IN THE BUFFER BNE 4$ ; LOOP TILL NULL MOVED BR 6$ ; COMPLETED ASCII LINE 5$: TST T.OWNR(R1) ; IS TERMINAL ATTACHED TO A JOB? BEQ 6$ ; IF NO, ASCII LINE COMPLETE MOVB T.JOB(R1),R0 ; NOPE, LOAD OWNER'S JOB# JSR R5,OCNUM ; ENCODE AS AN OCTAL NUMBER .WORD 2 ; MAXIMUM OF TWO DIGITS 6$: CLRB (R5)+ ; GUARRANTEE A NULL TERMINATOR .PRINT #LBUF ; TYPE THE ASCII LINE 7$: DEC R4 ; REACHED END OF ARG. LIST? BEQ 8$ ; COMMAND COMPLETE IF SO JMP 2$ ; ELSE PROCESS ANOTHER TERMINAL NUMBER 8$: RETURN ; RETURN TO CALLER .PAGE GTARGS: MOV (SP)+,RTNADR ; PRESERVE RETURN ADDRESS CLR R4 ; ASSUME ZERO ARGS. 1$: MOVB (R5)+,R0 ; COPY A CHAR. FROM ARG. LIST BEQ DECODE ; IF NULL BEFORE SPACE; NO ARGS. CMPB #40,R0 ; IS THE CHARACTER A SPACE? BNE 1$ ; LOOP UNTIL A SPACE FOUND MOV #LBUF,R3 ; STORE ASCII NAMES IN LINE BUFFER 2$: MOV #2,R1 ; ALLOW TWO CHARS. PER TERMINAL NAME INC R4 ; ADD ONE TO ARGUMENT COUNT 3$: MOVB (R5)+,R0 ; GET THE NEXT CHARACTER BEQ 5$ ; ALL DONE WHEN NULL FOUND CMPB #'0,R0 ; COMPARE WITH ASCII ZERO BGT 4$ ; MAYBE ITS A SEPERATOR CMPB #'9,R0 ; COMPARE WITH ASCII NINE BLT ARGERR ; ANY LARGER: ERROR MOVB R0,(R3)+ ; STORE THE CODE IN BUFFER DEC R1 ; ONE CHAR. LESS TO BE FOUND BR 3$ ; LOOP UNTIL A SEPERATOR FOUND 4$: CMPB #40,R0 ; IS THE CHAR. A SPACE? BEQ 5$ ; VALID SEPERATOR CMPB #',,R0 ; IS THE CHAR. A COMMA? BNE ARGERR ; ELSE ERROR 5$: TST R1 ; CHECK COUNT OF CHARS. RECEIVED BMI ARGERR ; CAN'T BE GREATER THAN TWO BEQ 6$ ; TWO IS OK DEC R1 ; IS IT ONE? BNE ARGERR ; IF NOT, ERROR CLRB (R3)+ ; ON SINGLE CHAR. NAMES, INSTALL TRAILING NULL 6$: TSTB R0 ; ARE WE HERE BECAUSE A NULL FOUND? BEQ DECODE ; IF SO, REACHED END OF LIST BR 2$ ; IF NOT, LOOK FOR NEXT ARGUMENT ARGERR: MOV #BADARG,R0 ; SOMETHING FUNNY WITH THIS ARGUMENT ERROR: BISB #WARN$,@#USERRB ; DEFINE ERROR BYTE .PRINT ; TYPE THE ERROR MESSAGE RTS PC ; RETURN TO CALLER'S CALLER .PAGE DECODE: MOV R4,R5 ; STORE ARG. COUNT TO RETURN BEQ 6$ ; IF ZERO, JUST RETURN 1$: CLR R0 ; ZERO WORKING REGISTER MOV -(R3),R2 ; BACKWARDS UP LIST OF NAMES BIC #170360,R2 ; STRIP ASCII CODE FROM BOTH BYTES SWAB R2 ; GET H.O. DIGIT IN LOW BYTE BEQ 2$ ; JUMP IF H.O. IS ZERO BISB R2,R0 ; GET LOW BYTE INTO WORKING REGISTER ASL R0 ; MULTIPLY BY MOV R0,R1 ; TEN TO ASL R0 ; ACCOMODATE ASL R0 ; TWO DECIMAL DIGIT ADD R1,R0 ; NUMBERS 2$: SWAB R2 ; GET L.O. DIGIT BACK IN LOW BYTE BISB R2,R0 ; ADD INTO NUMBER UNDER CONSTRUCTION CMP MTSTAT+4,R0 ; COMPARE WITH NUMBER OF TERMINALS ON SYSTEM BGT 5$ ; MUST FALL IN THAT RANGE 3$: CMP R4,R5 ; ANY ARGS. LEFT ON STACK BEQ 4$ ; NONE IF EQUAL TST (SP)+ ; UNLOAD AN ARGUMENT SOB R5,3$ ; LOOP TILL STACK CLEANED 4$: MOV #TOHIGH,R0 ; TELL USER: NUMBER TOO LARGE BR ERROR ; PRINT MESSAGE ON CONSOLE 5$: MOV R0,-(SP) ; STORE NUMBER ON STACK DEC R4 ; COUNT DOWN NUMBER OF ARGUMENTS LEFT MOVB R4,1(SP) ; STORE IN HIGH BYTE OF ARG. VALUE BNE 1$ ; LOOP UNTIL ALL ARGS. PROCESSED 6$: JMP @RTNADR ; RETURN TO CALLING ROUTINE RTNADR: .BLKW 1 ; STORAGE FOR RETURN ADDRESS .PAGE WERROR: .PRINT ; PUBLISH MESSAGE (ADDRESS IN "R0") CLRB R4 ; TWO STEPS NECESSARY SWAB R4 ; TO INSTALL ARG# ASL R4 ; MAKE INTO WORD OFFSET MOV LBUF(R4),EMT ; GET ASCII TERMINAL NAME CLRB EMT+3 ; DELIMIT WITH A NULL .PRINT #EMT ; ADD ON TO END OF MESSAGE BISB #WARN$,@#USERRB ; SET ERROR STATUS RTS PC ; RETURN TO CALLER RDBASE: .READW #RWEMT,#0 ; READ IN BLOCK ZERO OF THIS FILE BCS RWERR ; JUMP IF ERROR .SCCA #EMT,#SCCA ; DISABLE CONTROL "C" SERVICE RTS PC ; RETURN TO CALLER WDBASE: .WRITW #RWEMT,#0 ; WRITE OUT DATABASE TO BLOCK ZERO BCS RWERR ; JUMP IF ERROR .SCCA #EMT,#0 ; REENABLE CONTROL "C" TRAPS RTS PC ; RETURN TO CALLER RWERR: MOVB @#SYERRB,R0 ; GET SYSTEM ERROR CODE DEC R0 ; DECREMENT TO FACILITATE TESTING BEQ 1$ ; HARDWARE ERROR IF EQUAL TO ONE BPL 2$ ; LOST CHANNEL IF TWO MOV #RWEOF,R0 ; SOMEHOW GOT TO END-OF-FILE BR 3$ ; GO TELL USER 1$: MOV #HRDERR,R0 ; GET POINTER TO HARDWARE ERROR MESSAGE BR 3$ ; USER MUST BE TOLD 2$: MOV #NOCHAN,R0 ; LOST CHANNEL MESSAGE 3$: JMP SERROR ; VERY SERIOUS CONDITION! .PAGE ; DATA & VARIABLE STORAGE ; EMT: .BLKW 5 ; MONITOR WORK SPACE RWEMT: .WORD 0 ; + READ-WRITE "EMT" SPACE .WORD 0 ; + READ & WRITE BLOCK ZERO .WORD BLOCK0 ; + POINTER TO DATA BUFFER .WORD 256. ; + NUMBER OF WORDS .WORD 0 ; + SPECIFIES WAIT MODE MTSTAT: .BLKW 8. ; MULTI-TERMINAL STATUS TABLE COMAND: .BLKW 3 ; SPACE FOR COMAND STRING STORAGE TCBPTR: .BLKW MAXTTY ; ADDRESSS OF "TCB" BLOCKS IN MONITOR SCCA: .BLKW 1 ; "^C" TRAP SPACE DBASE: .WORD BLOCK0+400 ; POINTER TO DATABASE IN BLOCK ZERO BLOCK0: .BLKW 256. ; STORAGE SPACE FOR BLOCK ZERO .NLIST BEX FNAME: .RAD50 /SY MTED SAV/ CMDTBL: .WORD CMD1,CMD2,CMD3,CMD4 DISPAT: .WORD DISABL,ENABLE,HELP,LIST LBUF: .BLKB 81. ; LINE BUFFER SPACE (ALIGN ON WORD BOUNDARY) PROMPT: .ASCII/*/<200> ; COMMAND PROMPT STRING VERSN: .ASCIZ / MTED V01.10/<12> CMD1: .ASCII /DISABL/ CMD2: .ASCII /ENABLE/ CMD3: .ASCII /HELP / CMD4: .ASCII /LIST / NOMTT: .ASCIZ /?MTED-F-monitor not generated with multi-terminal feature/ XMERR: .ASCIZ /?MTED-F-"XM" status block not in valid user space/ NOFIL: .ASCIZ /?MTED-F-unable to access database file/ RWEOF: .ASCIZ ;?MTED-F-database I/O found END-OF-FILE; HRDERR: .ASCIZ ;?MTED-F-DATABASE I/O HARDWARE ERROR; NOCHAN: .ASCIZ ;?MTED-F-database I/O channel lost; UNREC: .ASCIZ /?MTED-W-unrecognized command/ NOTENB: .ASCII /?MTED-W-already disabled: TERMINAL #/<200> INUSE: .ASCII /?MTED-W-inuse: TERMINAL #/<200> NOTDIS: .ASCII /?MTED-W-already enabled: TERMINAL #/<200> BADARG: .ASCIZ /?MTED-W-illegal character in argument list/ TOHIGH: .ASCIZ /?MTED-W-terminal number too large/ LHDR: .ASCIZ / LUN CSR VECTOR OWNER/ CONSOL: .ASCIZ /CONSOLE/ DSABLD: .ASCIZ /DISABLED/ HLPNTE: .ASCII / PURPOSE:/<11>/To provide the user with the capability of dynamically/ .BYTE 15,12 .ASCII <11><11>/redefining the use of monitor generated multi-terminal ports./ .ASCII <15><12><12>/ COMMANDS:/<11>/DISABLE, ENABLE, HELP, LIST/<15><12><12> .ASCII <11><11>/This program will accept input from either the console/ .BYTE 15,12 .ASCII <11><11>/terminal or an indirect command file. Errors in/<15><12> .ASCII <11><11>/command input to MTED cause appropriate codes to be/ .BYTE 15,12 .ASCII <11><11>/set in the monitor's user error byte. Thus this/<15><12> .ASCII <11><11>/program responds properly to RT-11 "SET ERROR" conditions./ .BYTE 15,12,12,0 .EVEN ; ; OCNUM converts an octal number input in R0 into an ASCII string ; pointed to by R5. The word immediately following the call to OCNUM ; contains the number of characters you wish returned (1<=n=<6). ; OCNUM inserts a trailing null after the string it builds and R5 will ; point to the null on return. The numeric value will be right justified ; in the returned string, padded on the left with spaces. The least ; significant byte in the string will always be numeric. R0 is preserved. ; Called by: ; MOV #number,R0 ;Load number to be encoded ; MOV #buffer,R5 ;Point to ASCII buffer ; JSR R5,OCNUM ;R5 call sequence ; .WORD 5 ;Length of string wanted ; OCNUM: MOV R0,-(SP) ;Preserve R0 MOV R1,-(SP) ;Preserve R1 SUB #10,SP ;Create 8 byte workspace MOV SP,R1 ;Point to workspace MOVB #30,@R1 ;+ SEC ;+ 1$: ROL R0 ;+ ROLB (R1)+ ;+ MOVB #206,@R1 ;+ Pinched from RTMON.MAC 2$: ASL R0 ;+ BEQ 3$ ;+ ROLB @R1 ;+ BCS 2$ ;+ BR 1$ ;+ 3$: CLRB @R1 ;Install a trailing NULL SUB (R5)+,R1 ;Point to "wanted" string MOV 14(SP),R0 ;Point to user's buffer CLC ;Be sure CARRY is clear 4$: BCS 5$ ;Skip once non ASCII zero found CMPB #60,@R1 ;Is this ASCII zero? BNE 5$ ;If not CARRY will be set MOVB #40,@R1 ;Substitute a space character 5$: MOVB (R1)+,(R0)+ ;Copy the characters BNE 4$ ;Loop till exhausted ADD #10,SP ;Return workspace MOV (SP)+,R1 ;Restore R1 DEC R0 ;Point to trailing null MOV R0,2(SP) ;Return pointer to free space BISB #20,-(R0) ;Atleast LSD must be numeric MOV (SP)+,R0 ;Restore R0 RTS R5 .END START