MCALL   .MODULE
MODULE  CONSOL,RELEASE=X05,VERSION=01,COMMENT=<RT-11 Consoler Switcher>,AUDIT=YES

;       Copyright (c) 1982, 1989 by Megan Gentry, All rights reserved.
;
; This software is provided for personal use only and only with
; the inclusion of the above copyright notice.
;
; The author assumes no responsibility or liability for the use
; or reliability of this software

       .SBTTL  Abstract and Edit History

;+
;
; CONSOL
;
;       The purpose of this program is to allow an RT-11 user to
;       switch the console terminal from one terminal to another
;       (if both terminals are attached via DL-type interfaces).
;       This is accomplished by altering the in-core copy of the
;       RT-11 monitor. The CTY can not be moved if the GT scroller
;       is active or if the monitor supports multi-terminals.
;
;       This program is pre-coded for the appropriate terminal
;       interfaces of a PDT-11.
;
; Build procedure:
;
;       Following the existing definition for default console,
;       use the DEFTTY macro to define additional terminals to
;       match system configuration of local DL interfaces.
;
;       .R MACRO
;       *CONSOL=CONSOL
;       *^C
;       .R LINK
;       *CONSOL=CONSOL
;       *^C
;
; Edit History:
;
; X05 (000) dd-mmm-yy   Initial coding
;       MBG
;
; X05 (001) 28-Jun-89   Use of .MODULE, fixed copyright, added edit
;       MBG             history.
;
;-

       .SBTTL  DEFINITIONS

; RT-11 MACROS TO BE USED

       .MCALL  .GTLIN
       .MCALL  .PRINT, .EXIT
       .MCALL  .CSISP, .TTYOU

; SYSCOM LOCATIONS

       USERRB  = 53                    ;USER ERROR REPORTING BYTE
       SYSPTR  = 54                    ;->START OF RMON

; RMON FIXED OFFSETS

       SCROLL  = 302                   ;->GT SCROLLER
       TTKS    = 304                   ;KEYBOARD CSR
       LOWMAP  = 326                   ;LOW CORE BIT MAP
       SYSGEN  = 372                   ;SYSGEN FEATURES WORD
               MTTY$   =  20000 ;MULTI-TERMINAL SUPPORT

; CHARACTERS

       TAB     = 11
       LF      = 12
       CR      = 15

; ERROR REPORTING MACRO

       .MACRO  ERR.    PREFIX,MESSAG,CR=YES
       ..MASK = 0
       ..FLAG = 0
       .IRPC   X,<IWEFU>
        .IF EQ ..FLAG
         .IF IDN PREFIX,X
               ..FLAG = 1
         .IFF
          .IIF EQ ..MASK ..MASK = 1
               ..MASK = ..MASK*2
         .ENDC
        .ENDC
       .ENDR
       .IF NE ..FLAG
        .SAVE
        .PSECT .TEXT.
        ... = .
               .BYTE   ..MASK
               .ASCII  |'PREFIX'MESSAG|
        .IF IDN CR,YES
               .BYTE   0
        .IFF
               .BYTE   200
        .ENDC
        .RESTORE
               MOV     #...,R0
               JSR     PC,ERRPRO
        .IFF
               .ERROR  ;ILLEGAL SEVERITY '''PREFIX
        .ENDC
       .ENDM

       .SBTTL  PROGRAM START

       .PSECT  .CODE.

       .ENABL  LSB

CONSOL: MOV     @#SYSPTR,R5             ;R5->RMON
       TST     SCROLL(R5)              ;LINKED TO SCROLLER?
       BEQ     10$                     ;NOPE...
       ERR.    U,<GT Scroller active, cannot move CTY>
EXIT:   .EXIT

10$:    BIT     #MTTY$,SYSGEN(R5)       ;MONITOR HAS MULTI-TERMINAL SUPPORT?
       BEQ     COMAND                  ;NOPE...
MTTY:   ERR.    W,<Monitor supports multi-terminal, use SET TT CONSOL>
       BR      COMAND

       .DSABL  LSB

       .SBTTL  ERRPRO  - ERROR PROCESSOR

ERRPRO: BISB    (R0)+,@#USERRB          ;SET THE USER ERROR BYTE
       MOVB    (R0)+,M.SEV             ;SET THE SEVERITY
       MOV     R0,-(SP)                ;SAVE POINTER TO MESSAGE
       .PRINT  #M.PFX                  ;PRINT THE PREFIX
       .PRINT  (SP)+                   ;AND THE MESSAGE
       RTS     PC

       .SBTTL  COMAND  - COMMAND INPUT AND OPTION RESET

CSIERR: ERR.    F,<Invalid syntax>      ;FOR CSI ERRORS
COMAND: MOV     #CONSOL,SP              ;SET UP (OR FIX) STACK
       .GTLIN  #COMBUF,#M.PROM         ;PROMPT FOR AND GET AN OPTION STRING
       TSTB    COMBUF                  ;ANY RESPONSE?
       BNE     10$                     ;YEP, PARSE IT
       .PRINT  #M.VER
       .PRINT  #M.CRLF
       BR      COMAND

10$:    .CSISP  #FILSPC,#DEFEXT,#COMBUF ;PARSE THE RESPONSE
       BCS     CSIERR
       MOV     #SWTTAB,R4              ;R4->OPTION TABLE
       MOV     R4,R0                   ;SET TO RESET OPTION TABLE
20$:    TSTB    (R0)+                   ;END OF TABLE?
       BEQ     30$                     ;YES...
       CLRB    (R0)+                   ;NOPE...RESET USE BYTE
       MOV     #-1,(R0)+               ;AND VALUE
       TST     (R0)+                   ;ON TO NEXT ENTRY
       BR      20$

30$:    MOV     (SP)+,(PC)+             ;SET OPTION COUNT
SWTCNT:  .BLKW
       BEQ     COMAND                  ;NONE...GET ANOTHER OPTION STRING

       .SBTTL  SWTSCN  - OPTION SCANNER

       .ENABL  LSB

SWTSCN: MOV     R4,R0                   ;R0->OPTION TABLE
10$:    TSTB    (R0)                    ;END OF TABLE?
       BNE     20$                     ;NOPE...
       ERR.    E,<Invalid option: />,CR=NO
15$:    MOVB    (SP),E.CHR              ;GET INVALID OPTION CHARACTER
       .PRINT  #E.CHR                  ;AND PRINT IT (WITH <CR><LF>)
       BR      COMAND

20$:    CMPB    (SP),(R0)+              ;OPTIONS MATCH?
       BEQ     30$                     ;YEP...
       ADD     #5,R0                   ;NOPE...TRY NEXT ENTRY
       BR      10$

30$:    BITB    #2,(R0)                 ;OPTION ALREADY SELECTED?
       BEQ     35$                     ;NOPE...
       ERR.    E,<Duplicate option: />,CR=NO
       BR      15$

35$:    BISB    #2,(R0)+                ;SET USE BIT
       TST     (SP)+                   ;OPTION HAS VALUE?
       BPL     40$                     ;NOPE...
       MOV     (SP)+,(R0)              ;YES...GET IT
       BISB    #1,-(R0)                ;SET OPTION BIT
40$:    DEC     SWTCNT                  ;ANY MORE OPTIONS?
       BGT     SWTSCN                  ;YEP...
;;;     BR      EXEC                    ;NOPE...START OPERATING ON OPTIONS

       .DSABL  LSB

       .SBTTL  EXEC    - OPTION EXECUTE

EXEC:   TSTB    (R4)+                   ;END OF TABLE?
       BEQ     COMAND                  ;YEP...
       BITB    #2,(R4)+                ;WAS OPTION USED?
       BEQ     10$                     ;NOPE...
       JSR     PC,@2(R4)               ;YES...DO ROUTINE
10$:    ADD     #4,R4                   ;ON TO NEXT ENTRY
       BR      EXEC

       .SBTTL  OPTION TABLE

       .MACRO  SWTDEF  CHAR,LOC
               .BYTE   ''CHAR
               .BYTE   0
               .WORD   0,LOC
       .ENDM

; Following are ordered for priority in executing options

SWTTAB: SWTDEF  H,HELP
       SWTDEF  L,LIST
       SWTDEF  C,MOVE
       SWTDEF  E,EXIT

; End of ordering

       .WORD   0                       ;TABLE STOPPER

       .SBTTL  HELP    - USER HELP ROUTINE

HELP:   .PRINT  #M.HLPH                 ;PRINT HELP HEADER
       .PRINT  #M.VER                  ;PROGRAM VERSION
       .PRINT  #M.CRLF
       .PRINT  #M.CRLF
       .PRINT  #M.HLP                  ;AND REMAINDER OF HELP
       BR      COMAND

       .SBTTL  LIST    - CONFIGURATION TABLE LIST

LIST:   MOV     #-1,LSTFLG              ;RESET HEADER FLAG
       MOV     (R4),R1                 ;DOES OPTION HAVE VALUE?
       BMI     20$                     ;NOPE...
       CMP     R1,#TTY-1               ;IS IT IN RANGE?
       BHI     SWTERR                  ;NOPE...
       ASL     R1                      ;YES...MAKE IT A BYTE OFFSET
       JSR     PC,LSTOUT               ;PRINT INFO
10$:    BR      COMAND

20$:    CLR     R1
30$:    JSR     PC,LSTOUT               ;LIST A TERMINAL
       BCS     10$                     ;NO MORE TO GO
       TST     (R1)+                   ;BUMP OFFSET
       BR      30$                     ;AND DO IT AGAIN

LSTOUT: INC     (PC)+                   ;SHOULD WE PRINT HEADER?
LSTFLG:  .BLKW
       BNE     10$                     ;NOPE...
       .PRINT  #M.HEAD                 ;YES...
10$:    TST     TTCSR(R1)               ;IS THERE AN ENTRY?
       BEQ     40$                     ;NOPE..TAKE ERROR RETURN
20$:    MOV     R1,R0                   ;GET OFFSET
       ASR     R0                      ;SHIFT FOR TERMINAL NUMBER
       JSR     PC,OCTOUT               ;PRINT THE NUMBER
       CMP     TTCSR(R1),TTKS(R5)      ;LISTING THE TTY WE'RE CURRENTLY ON?
       BNE     30$                     ;NOPE...
       .TTYOU  #'*
30$:    .TTYOU  #11
       MOV     TTCSR(R1),R0            ;R0=TTY CSR
       JSR     PC,OCTOUT
       .TTYOU  #11
       MOV     TTVEC(R1),R0            ;R0=INTERRUPT VECTOR
       JSR     PC,OCTOUT
       .TTYOU  #11
       MOV     TTOFF(R1),R0            ;R0=BITMAP OFFSET
       JSR     PC,OCTOUT
       .TTYOU  #11
       MOV     TTMSK(R1),R0            ;R0=BITMAP MASK
       JSR     PC,OCTOUT
       .TTYOU  #11
       MOV     TTPTR(R1),R0            ;PRINT NOTE
       .PRINT
       TST     (PC)+                   ;GOOD RETURN (CARRY CLEAR)
40$:    SEC                             ;ERROR RETURN (CARRY SET)
       RTS     PC

       .SBTTL  MOVE    - CTY MOVE ROUTINE

       .ENABL  LSB

MOVE:   BIT     #MTTY$,SYSGEN(R5)       ;MULTI-TERMINAL SUPPORT?
       BEQ     5$                      ;NOPE...
       JMP     MTTY                    ;YES, CAN'T DO A SWITCH

5$:     MOV     (R4),R1                 ;GET OPTION VALUE
       BPL     10$                     ;SO FAR SO GOOD...
SWTERR: ERR.    E,<Argument missing or invalid>
       JMP     COMAND

10$:    CMP     R1,#TTY-1               ;IS TTY NUMBER IN RANGE?
       BHI     SWTERR                  ;NOPE...
       ASL     R1                      ;SHIFT FOR BYTE OFFSET
       MOV     #TTCSR,R0               ;R0->TTY CSR TABLE
20$:    CMP     TTKS(R5),(R0)           ;IS CURRENT CTY IN TTY TABLE?
       BEQ     40$                     ;YES...
       TST     (R0)+                   ;AT END OF TABLE?
       BNE     20$                     ;NOPE...
       ERR.    E,<Current CTY not in known configuration>
30$:    JMP     COMAND

40$:    SUB     #TTCSR,R0               ;R0=OFFSET FOR CURRENT CTY
       CMP     R0,R1                   ;ARE WE ALREADY THERE?
       BEQ     30$                     ;YES...
       MOV     R5,R2
       ADD     #TTKS,R2
       MOV     TTCSR(R1),(R2)          ;LET MONITOR KNOW ABOUT NEW CTY
       MOV     #3,R3
50$:    MOV     (R2)+,(R2)
       ADD     #2,(R2)
       DEC     R3
       BGT     50$
       MOV     TTVEC(R0),R2            ;R2->CURRENT CTY'S VECTORS
       MOV     TTVEC(R1),R3            ;R3->NEW CTY'S VECTORS
       MOV     #4,-(SP)
60$:    MOV     (R2),(R3)+
       CLR     (R2)+
       DEC     (SP)
       BGT     60$
       MOV     TTCSR(R0),R2            ;R2->CURRENT CTY'S CSR'S
       MOV     TTCSR(R1),R3            ;R3->NEW CTY'S CSR'S
       MOV     #4,(SP)
70$:    MOV     (R2),(R3)+
       CLR     (R2)+
       DEC     (SP)
       BGT     70$
       MOV     R5,R2                   ;UNPROTECT OLD CTY'S VECTORS
       ADD     TTOFF(R0),R2
       BICB    TTMSK(R0),(R2)
       MOV     R5,R2
       ADD     TTOFF(R1),R2            ;PROTECT NEW CTY'S VECTORS
       BISB    TTMSK(R1),(R2)
       .PRINT  TTPTR(R1)               ;LET USER KNOW WHERE WE ARE NOW
       TST     (SP)+
       RTS     PC

       .DSABL  LSB

       .SBTTL  OCTOUT  - OCTAL OUTPUT ROUTINE

OCTOUT: MOV     R0,-(SP)                ;MAKE A COPY OF THE NUMBER
       BIC     #177770,(SP)            ;DISCARD TO BITS <2:0>
       ADD     #60,(SP)                ;MAKE IT PRINTABLE
       ROR     R0                      ;SHIFT FOR NEXT DIGIT
       ASR     R0
       ASR     R0
       BEQ     10$                     ;IF ZERO...START PRINTING
       JSR     PC,OCTOUT               ;OTHERWISE...RECURSE...
10$:    .TTYOU  (SP)+
       RTS     PC

       .SBTTL  MESSAGES

       .PSECT  .TEXT.

M.PROM: .ASCII  /*/<200>
M.PFX:  .NLCSI  TYPE=I,PART=PREFIX
M.SEV:  .ASCII  /x-/<200>

E.CHR:  .ASCII  /x/
M.CRLF: .BYTE   0

M.VER:  .NLCSI  TYPE=I,PART=ALL
       .BYTE   200

M.HLPH: .ASCII  <TAB>/Help for /<200>
M.HLP:  .ASCII  <TAB>\/C:n      Switch CTY to terminal n\<CR><LF>
       .ASCII  <TAB>\/H        This text\<CR><LF>
       .ASCII  <TAB>\/L[:n]    List terminal configuration table\<CR><LF>
       .ASCII  <TAB><TAB>/[or info on terminal n]/<CR><LF>
       .ASCIZ  <TAB>\/E        Exit to monitor\

M.HEAD: .ASCII  /TTY    CSR     VEC     OFFSET  MASK    NOTE/<CR><LF>
       .ASCIZ  /---    ---     ---     ------  ----    ----/

       .EVEN

       .SBTTL  DATA AREA

       .PSECT  .DATA.

COMBUF: .BLKB   134.

FILSPC: .BLKW   39.

DEFEXT: .WORD   0,0,0,0

       .SBTTL  TTY TABLES

; TTY TABLE BUILDING MACRO

       .MACRO  BLDTTY

       .MACRO  TTYBLD
       TTY     = 0
;               CSR     VEC     NOTE
;               ---     ---     ----
       DEFTTY  177560  60      <Hardware console>
       DEFTTY  176500  300     <PDT Cluster Port 1>
       DEFTTY  176510  310     <PDT Cluster Port 2>
       DEFTTY  176520  320     <PDT Cluster Port 3>
       DEFTTY  176610  330     <Asynchronous Modem Port>
       DEFTTY  176620  340     <Synchronous Modem Post>
       .ENDM

       .MACRO  DEFTTY  CSR,VEC,NOTE
       .IF EQ,TTY
TTCSR:
       .IFTF
               .WORD   CSR
       .ENDC
       TTY = TTY+1
       .ENDM

       TTYBLD

       .WORD   0

       .MACRO  DEFTTY  CSR,VEC,NOTE
       .IF EQ,TTY
TTVEC:
       .IFTF
               .WORD   VEC
       .ENDC
       TTY = TTY+1
       .ENDM

       TTYBLD

       .MACRO  DEFTTY  CSR,VEC,NOTE
       .IF EQ,TTY
TTOFF:
       .IFTF
               .WORD   LOWMAP+<VEC/20>
       .ENDC
       TTY = TTY+1
       .ENDM

       TTYBLD

       .MACRO  DEFTTY  CSR,VEC,NOTE
       ....B0 = 360
       .REPT   <VEC-<20*<VEC/20>>>/8.
       ....B0 = ....B0/16.
       .ENDR
       .IF EQ,TTY
TTMSK:
       .IFTF
               .WORD   ....B0
       .ENDC
       TTY = TTY+1
       .ENDM

       TTYBLD

       .MACRO  DEFTTY  CSR,VEC,NOTE
       .IF EQ,TTY
TTPTR:
       .IFTF
       .IRP    XXX,\TTY
               .WORD   TMSG'XXX
       .ENDR
       .ENDC
       TTY = TTY+1
       .ENDM

       TTYBLD

       .MACRO  DEFTTY  CSR,VEC,NOTE
       .IRP    XXX,\TTY
TMSG'XXX:       .ASCIZ  /'NOTE/
       .ENDR
       TTY = TTY+1
       .ENDM

       TTYBLD

       .ENDM   BLDTTY

; DEFINE THE TABLES!

       BLDTTY

       .END    CONSOL