;***************************************************************************;
;                                                                           ;
;                               UltraStat 3.x                               ;
;                            COMMAND PROCESSING                             ;
;                                                                           ;
;***************************************************************************;
;Copyright (C) 1988 UltraSoft Corporation.  All Rights Reserved.
;
;Written by: David Pallmann
;
;All edit history for USTAT is in USYM.M68.

       ASMMSG  "== UltraStat 3.x (COMMAND) =="
       AUTOEXTERN

;--- Include files

       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  TRM
       COPY    DSKINF.CPY
       COPY    USYM/L

;--- Keystroke was entered by user - get it and respond to it

GET.COMMAND::
       TSTB    JOB.ARROW(MEM)
       BEQ     4$
       CURSOR  JOB.ARROW(MEM),ARROW.COL(MEM)
       TYPE    <   >
       CLRB    JOB.ARROW(MEM)
4$:     TIN                             ; get the character (into D1)
       UCS
       LEA     A0,COMMAND.TABLE
       MOV     #-2,D0
10$:    TSTB    @A0
       JEQ     HEADER.SCAN
       ADD     #2,D0
       CMMB    (A0)+,D1
       BNE     10$
       MOVW    JUMP.TABLE[~D0],D0
       JMP     JUMP.TABLE[~D0]

DEFINE  CASE    ADDR
       WORD    ADDR-JUMP.TABLE
       ENDM

JUMP.TABLE:
       CASE    FINISH                  ; ^C  - exit
       CASE    END                     ; ^E  - end of job list
       CASE    WIDTH.80                ; ^H  - narrow screen
       CASE    TAB                     ; TAB - advance to next screen
       CASE    JOB.DOWN                ; ^J  - move job down
       CASE    JOB.UP                  ; ^K  - move job up
       CASE    WIDTH.132               ; ^L  - wide screen
       CASE    PAGE.BACK               ; ^R  - page back
       CASE    PAGE.FORWARD            ; ^T  - page forward
       CASE    FINISH                  ; ESC - exit
       CASE    HOME                    ; ^^  - home
       CASE    HOLD                    ; SPC - hold
       CASE    STATS.ON                ; +   - statistics on
       CASE    STATS.OFF               ; -   - statistics off
       CASE    HELP                    ; ?   - help
       CASE    SET.DELAY               ; 0   - set delay time
       CASE    SET.DELAY               ; 1   - set delay time
       CASE    SET.DELAY               ; 2   - set delay time
       CASE    SET.DELAY               ; 3   - set delay time
       CASE    SET.DELAY               ; 4   - set delay time
       CASE    SET.DELAY               ; 5   - set delay time
       CASE    SET.DELAY               ; 6   - set delay time
       CASE    SET.DELAY               ; 7   - set delay time
       CASE    SET.DELAY               ; 8   - set delay time
       CASE    SET.DELAY               ; 9   - set delay time
       CASE    ATTACH                  ; A   - attach (operator mode)  [105]
       CASE    COLOR                   ; C   - set background color
       CASE    DEV.MODE                ; D   - device mode -or- detach (opr) [105]
       CASE    ERSATZ.ON.OFF           ; E   - ersatz on/off
       CASE    FORCE                   ; F   - force (operator mode)   [105]
       CASE    HELP                    ; H   - help
       CASE    JOB.MODE                ; J   - job mode
       CASE    KILL                    ; K   - kill (operator mode)    [105]
       CASE    LOG.ALERT               ; L   - log alert on/off
       CASE    WIDTH.80                ; N   - narrow width
       CASE    OPERATOR                ; O   - operator mode on/off
       CASE    PROG.ALERT              ; P   - prog alert on/off
       CASE    FINISH                  ; Q   - finish
       CASE    REFRESH                 ; R   - refresh display
       CASE    TERM.MODE               ; T   - terminal mode
       CASE    USER.ON.OFF             ; U   - user name display on/off
       CASE    WIDTH.132               ; W   - wide mode
       CASE    HEIGHT                  ; X   - change height           [120]
       CASE    HELP                    ; HLP - help key                [105]

COMMAND.TABLE:
       BYTE    'C-'@
       BYTE    'E-'@
       BYTE    'H-'@
       BYTE    'I-'@
       BYTE    'J-'@
       BYTE    'K-'@
       BYTE    'L-'@
       BYTE    'R-'@
       BYTE    'T-'@
       BYTE    ESC
       BYTE    '^-'@
       BYTE    40
       BYTE    '+
       BYTE    '-
       BYTE    '?
       BYTE    '0
       BYTE    '1
       BYTE    '2
       BYTE    '3
       BYTE    '4
       BYTE    '5
       BYTE    '6
       BYTE    '7
       BYTE    '8
       BYTE    '9
       BYTE    'A
       BYTE    'C                      ;
       BYTE    'D
       BYTE    'E
       BYTE    'F                      ;                               [105]
       BYTE    'H
       BYTE    'J
       BYTE    'K                      ;                               [105]
       BYTE    'L
       BYTE    'N
       BYTE    'O
       BYTE    'P
       BYTE    'Q                      ; QUIT same as ESC
       BYTE    'R
       BYTE    'T
       BYTE    'U
       BYTE    'W
       BYTE    'X                      ;                               [120]
       BYTE    271                     ; help key                      [105]
       BYTE    0
       EVEN

;--- go to end of current list

END:    MOV     #22.,D0                 ;                               [115]
       MOVBL   JOB.ROW(MEM),D1         ;                               [115]
       SUB     D1,D0                   ;                               [115]
       CMMW    HD.TBL+HD.ALC(MEM),D0   ;                               [105]
       JLOS    HEADER.SCAN
       MOVW    HD.TBL+HD.ALC(MEM),JOB.OFFSET(MEM) ;                    [105]
       SUBW    D0,JOB.OFFSET(MEM)
       DECB    JOB.ROW(MEM)
       OR      #F$UPDATE,FLAGS(MEM)    ; DEBUG DEBUG DEBUG
       JMP     TITLE

;--- log alert on/off

LOG.ALERT:
       BIT     #F$OPR,FLAGS(MEM)       ; are we in operator mode?
       JNE     ERROR                   ;  yes - ignore
       CURSOR  #1,#46.
       HIGH
       FRED
       XOR     #F$LOG,FLAGS(MEM)
       BIT     #F$LOG,FLAGS(MEM)
       BEQ     LOG.OFF
LOG.ON:
       TYPE    <LOG-ALERT>
       FCYAN
       JMP     HEADER.SCAN
LOG.OFF:
       TYPE    <         >
       FCYAN
       JMP     HEADER.SCAN

;--- operator mode on/off - only works if user is in [1,2]

OPERATOR:
       CMPW    MODE(MEM),#M$JOB        ; in job display mode?          [105]
       JNE     ERROR                   ;  no                           [105]
       JOBIDX                          ; A6 <- JCB                     [105]
       CMPW    JOBUSR(A6),#1_8.+2      ; in [1,2]?                     [105]
       JNE     ERROR                   ;  no - ignore command          [105]
       CALL    OPR.UNMARK              ;                               [105]
       AND     #^C<F$STATUS>,FLAGS(MEM); turn off status line flag     [105]
       XOR     #F$OPR,FLAGS(MEM)       ;                               [105]
       BIT     #F$OPR,FLAGS(MEM)       ;                               [105]
       BEQ     OPR.OFF                 ;                               [105]
OPR.ON: CURSOR  #1,#46.                 ;                               [105]
       HIGH                            ;                               [105]
       FRED
       TYPE    <SYSTEM OPERATOR MODE > ;                               [105]
       CLRB    OPR.MARKER(MEM)         ;                               [105]
       CALL    OPR.MARK                ;                               [105]
       CALL    LINE24                  ; update help line              [105]
       FCYAN
       JMP     HEADER.SCAN             ;                               [105]
OPR.OFF:                                ;                               [105]
       CURSOR  #1,#46.
       HIGH
       FWHITE
       TYPE    <                     > ;                               [105]
       CLRB    OPR.MARKER(MEM)         ;                               [105]
       CALL    LINE24                  ; update help line              [105]
       BIT     #F$PROG,FLAGS(MEM)      ;                               [105]
       BEQ     10$                     ;                               [105]
       CURSOR  #1,#57.                 ;                               [105]
       HIGH                            ;                               [105]
       TYPE    <PROG-ALERT>            ;                               [105]
10$:    BIT     #F$LOG,FLAGS(MEM)       ;                               [105]
       BEQ     20$                     ;                               [105]
       CURSOR  #1,#46.                 ;                               [105]
       HIGH                            ;                               [105]
       TYPE    <LOG-ALERT>             ;                               [105]
20$:    FCYAN
       JMP     HEADER.SCAN             ;                               [105]

;--- program alert on/off

PROG.ALERT:
       BIT     #F$OPR,FLAGS(MEM)       ; are we in operator mode?
       JNE     ERROR                   ;  yes - ignore
       CURSOR  #1,#57.
       HIGH
       FRED
       XOR     #F$PROG,FLAGS(MEM)
       BIT     #F$PROG,FLAGS(MEM)
       BEQ     PROG.OFF
PROG.ON:
       TYPE    <PROG-ALERT>
       FCYAN
       JMP     HEADER.SCAN
PROG.OFF:
       TYPE    <          >
       FCYAN
       JMP     HEADER.SCAN

;--- Attach (operator mode only)

ATTACH: BIT     #F$OPR,FLAGS(MEM)       ; operator mode?                [105]
       JEQ     ERROR                   ;  no                           [105]
       CMPW    MODE(MEM),#M$JOB        ; job display?                  [105]
       JNE     ERROR                   ;  no                           [105]
       SAVE    A0-A5,D0-D5
       MOVB    JOB.ROW(MEM),D0
       INCB    D0
       CURSOR  D0,#1
       CLREOS
       INCW    D0
       CURSOR  D0,#2
       HIGH
       TYPESP  Attach
       CALL    OPRJOB
       JNE     ATTSLF
       TYPESP  Enter name of terminal to attach:
       CALL    GET.FIELD               ; get name of terminal
       JNE     ATTRTN                  ;  aborted
       ADD     #2,D0
       CURSOR  D0,#1
       LEA     A1,TEMP+6(MEM)          ; convert
       LEA     A2,TEMP(MEM)            ;  name
       PACK                            ;   to RAD50
       PACK                            ; TRMDEF name is now in TEMP+6(MEM)
ATTSRC: MOV     TRMDFC,A0               ; point to start of term table
10$:    CMM     TEMP+6(MEM),4(A0)       ; name match?
       BEQ     ATTFND                  ;  yes
       TST     @A0                     ; end of table?
       JEQ     ATTERR                  ;  yes
       MOV     @A0,A0                  ; point to next entry
       BR      10$                     ;  and continue scanning
ATTFND: ADD     #10,A0                  ; point to the actual TCB
ATTDET: MOV     JOBTRM(A3),D7           ; get previous TCB
       BEQ     10$                     ;  none
       MOV     D7,A4
       CLR     JOBTRM(A3)              ; clear job link to terminal
       CLR     T.JLK(A4)               ; clear terminal link to job
       TYPE    < Job >
       OUTNM2  JOBNAM(A3)
       TYPE    < detached from Terminal >
       OUTNAM  -4(A4)
       CRLF
10$:
ATTDT2: MOV     T.JLK(A0),D7            ; get previous JOB
       BEQ     10$                     ;  none
       MOV     D7,A4
       CLR     T.JLK(A0)
       CLR     JOBTRM(A4)
       TYPE    < Terminal >
       OUTNM2  -4(A0)
       TYPE    < detached from Job >
       OUTNAM  JOBNAM(A4)
       CRLF
10$:
ATTATT: MOV     A0,JOBTRM(A3)           ; set job link to terminal
       MOV     A3,T.JLK(A0)            ; set terminal link to job
       TYPE    < Job >
       OUTNM2  JOBNAM(A3)
       TYPE    < attached to Terminal >
       OUTNAM  -4(A0)
       CRLF
       JMP     ATTRTN
ATTSLF: TTYI
       BYTE    7,0
       EVEN
       TYPE    <?You cannot attach your own job>
       BR      ATTRTN
ATTERR: ADD     #2,D0
       CURSOR  D0,#2
       TTYI
       BYTE    7,0
       EVEN
       TYPE    <?Specified terminal not found>
ATTRTN: REST    A0-A5,D0-D5
       JMP     ANYKEY

;--- point A3 to selected JCB, echo job name, move cursor 2 lines down
;    set Z normally, clear Z if pointing to own job

OPRJOB: MOVWL   JOB.OFFSET(MEM),D3
       MOV     JOBTBL,A3
       INCW    D3
10$:    MOV     (A3)+,D7
       BEQ     10$
       SOB     D3,10$
       MOV     D7,A3
       OUTNAM  JOBNAM(A3)
       ADD     #2,D0
       CURSOR  D0,#2
       CMM     A3,JOBCUR
       BEQ     20$
       LCC     #PS.Z
       RTN
20$:    LCC     #0
       RTN

;--- end of operator command - prompt for user to press a key to continue

ANYKEY: LOW
       CURSOR  #22.,#1
       CLREOS
       CURSOR  #23.,#2
       TYPE    <Press any key to continue: >
       HIGH
       KBD
       JMP     HEADER

;get field, return data in TEMP(MEM)

GET.FIELD:
       SAVE    A2,D2
       CLRB    D2                      ; clear position
       LEA     A2,TEMP(MEM)
       CON
GF.GET: KBD
       CMPB    D1,#40
       BLO     GF.CTL
       CMPB    D1,#'~
       BHI     GF.CTL
GF.TXT: TTY
       MOVB    D1,(A2)+
       INCB    D2
       BR      GF.GET
GF.CTL: CMPB    D1,#177
       JEQ     GF.DEL
       CMPB    D1,#'M-'@
       JEQ     GF.DON
       CMPB    D1,#'[-'@
       JEQ     GF.CAN
       CMPB    D1,#'C-'@
       JEQ     GF.CAN
GF.ERR: TTYI
       BYTE    7,0
       EVEN
       BR      GF.GET
GF.DEL: TSTB    D2
       BEQ     GF.ERR
       TCALL   5
       TYPESP
       TCALL   5
       DECB    D2
       DEC     A2
       JMP     GF.GET
GF.DON: COFF
       CRLF
       CLRB    @A2
       REST    A2,D2
       LCC     #PS.Z
       RTN
GF.CAN: COFF
       CRLF
       CLRB    @A2
       REST    A2,D2
       LCC     #0
       RTN

;--- new background color

COLOR:  BIT     #F$COLOR,FLAGS(MEM)
       JEQ     ERROR
       HIGH
       FWHITE
       CURSOR  #24.,#1
       TYPESP  Enter new background color (0-7):
       TIN
       PUSH    D1
       CURSOR  #24.,#1
       CLREOL
       CALL    LINE24
       POP     D1
       CMPB    D1,#'0
       JLO     ERROR
       CMPB    D1,#'7
       JHI     ERROR
       AND     #377,D1
       SUBB    #'0,D1
       ADDW    #-3_8.,D1
       TCRT
       FCYAN
       JMP     HEADER

;--- tab to next screen

TAB:    CMPW    MODE(MEM),#M$JOB
       JEQ     TERM.MODE
       CMPW    MODE(MEM),#M$TERM
       JEQ     DEV.MODE
       JMP     JOB.MODE

;--- set width to 80 columns

WIDTH.80:
       BIT     #F$WIDE,FLAGS(MEM)
       JEQ     HEADER.SCAN
       AND     #^C<F$WIDE>,FLAGS(MEM)
       MOVB    #78.,ARROW.COL(MEM)
       CLS
       NARROW
       COFF
       JMP     HEADER

;--- set width to 132 columns

WIDTH.132:
       BIT     #F$WIDE,FLAGS(MEM)
       JNE     HEADER.SCAN
       OR      #F$WIDE,FLAGS(MEM)
       MOVB    #130.,ARROW.COL(MEM)
       CLS
       WIDE
       COFF
       JMP     HEADER

;--- toggle height

HEIGHT: CMPW    TERM.FLAGS+TC.ROW(MEM),#42.     ;                               [120]
       BEQ     NORMAL.HEIGHT           ;                               [120]

SPECIAL.HEIGHT:
       MOVW    #-5_8.+42.,D1           ;                               [120]
       TCRT                            ;                               [120]
       BR      NEW.HEIGHT              ;                               [120]

NORMAL.HEIGHT:
       MOVW    #-5_8.+24.,D1           ;                               [120]
       TCRT                            ;                               [120]

NEW.HEIGHT:
       TRMCHR  TERM.FLAGS(MEM)         ;                               [120]
       MOVW    TERM.FLAGS+TC.ROW(MEM),D7 ;                             [120]
       SUBW    #2,D7                   ;                               [120]
       MOVB    D7,LAST.ROW(MEM)        ;                               [120]
       COFF                            ;                               [120]
       OR      #F$HEADER,FLAGS(MEM)    ;                               [120]
       MOVW    MODE(MEM),D7            ;                               [120]
       CMPW    D7,#M$JOB               ;                               [120]
       JEQ     FLAG.JOB                ;                               [120]
       CMPW    D7,#M$TERM              ;                               [120]
       JEQ     FLAG.TERM               ;                               [120]
       JMP     FLAG.DEV                ;                               [120]

;--- Help

DEFINE  REPEAT  TF,COUNT
       MOV     #COUNT-1,D0
1$$:    TCALL   TF
       DBF     D0,1$$
       ENDM

HELP:   LEA     A0,HELP.TEXT            ;

HELP.LOOP:
       CALL    HELP.CLEAR              ;
       MOV     #24.,D0                 ;
       MOV     #2,D2                   ;
10$:    CURSOR  D2,#2                   ;
20$:    MOVB    (A0)+,D1                ;
       BEQ     30$                     ;
       TTY                             ;
       BR      20$                     ;
30$:    TSTB    @A0                     ;
       BMI     40$                     ;
       INCW    D2                      ;
       CMPW    D2,#23.                 ;
       BLO     10$                     ;

       TIN                             ;

       CMPB    D1,#'[-'@               ;
       JEQ     HEADER                  ;

       BR      HELP.LOOP               ;

40$:    TIN                             ;
       JMP     HEADER                  ;

HELP.CLEAR:
       TCALL   0                       ;
       HIGH                            ;
       TCALL   23                      ;
       CURSOR  #1,#1                   ;
       TCALL   38                      ;
       REPEAT  46,78.                  ;
       TCALL   39                      ;
       MOV     #2,D2                   ;
10$:    CURSOR  D2,#1.                  ;
       TCALL   47                      ;
       CURSOR  D2,#80.                 ;
       TCALL   47                      ;
       INCW    D2                      ;
       CMPW    D2,#23.                 ;
       BLO     10$                     ;
       CURSOR  #23.,#1                 ;
       TCALL   40                      ;
       REPEAT  46,78.                  ;
       TCALL   41                      ;
       TCALL   24                      ;
       RTN                             ;

;;      HIGH
;;      SRCH    HELP.DDB,A0
;;      BEQ     10$
;;      GETIMP  D.DDB,A0
;       LEA     A6,HELP.DDB
;       MOV     (A6)+,-6(A0)
;       MOVW    @A6,-2(A0)
;       MOVW    #[DSK],D.DEV(A0)
;       CLRW    D.DRV(A0)
;       MOV     #[UST]_16.+[AT ],D.FIL(A0)
;       MOVW    #[HLP],D.EXT(A0)
;       MOVW    #7_8.+1,D.PPN(A0)
;       INIT    @A0
;10$:   LOOKUP  @A0
;       BEQ     HELP.OPEN
;       TTYI
;       BYTE    7,0
;       EVEN
;       JMP     HEADER
;
;HELP.OPEN:
;       OPENI   @A0
;
;;HELP.CLEAR:
;       CLS
;       CLR     D2
;10$:   FILINB  @A0
;       TCKI
;       JEQ     HELP.DONE
;       TST     D.SIZ(A0)
;       JEQ     HELP.DONE
;       TTY
;       CMPB    D1,#LF
;       BNE     10$
;       INC     D2
;       CMP     D2,#22.
;       BLO     10$
;       CURSOR  #24.,#16.
;       LOW
;       TYPE    [press any key for next page or escape to abort]
;       TIN
;       CMPB    D1,#ESC
;       JEQ     HELP.CLOSE
;       HIGH
;       JMP     HELP.CLEAR
;
;HELP.DONE:
;       CURSOR  #24.,#21.
;       LOW
;       TYPE    [press any key when finished reading]
;       TIN
;
;HELP.CLOSE:
;       CLOSE   @A0
;       JMP     HEADER

;--- Hold

HOLD:   FYELLOW
       HIGH
       CURSOR  #24.,#1
       BLKON
       TYPESP  *HOLD*
       BLKOFF
       FWHITE
       TYPE    [any key to resume]
       CLREOL
       TIN
       CURSOR  #24.,#1
       CLREOL
       CALL    LINE24
       FCYAN
       JMP     HEADER.SCAN

;--- Job Mode

JOB.MODE:
       CMPW    MODE(MEM),#M$JOB
       JEQ     HEADER.SCAN
       MOVW    #M$JOB,MODE(MEM)
       CLRW    JOB.OFFSET(MEM)
       DECB    JOB.ROW(MEM)

;--- set forced update flags for all jobs

FLAG.JOB:
       LEA     A6,JB.TBL(MEM)
       MOV     #MAX-1,D6
10$:    OR      #JB$NEW,JB.FLG(A6)
       ADD     #JB.SIZ,A6
       DBF     D6,10$
       BIT     #F$HEADER,FLAGS(MEM)    ;                               [120]
       JNE     HEADER                  ;                               [120]
       JMP     TITLE

;--- Terminal Mode

TERM.MODE:
       CMPW    MODE(MEM),#M$TERM
       JEQ     HEADER.SCAN
       MOVW    #M$TERM,MODE(MEM)
       CLRW    JOB.OFFSET(MEM)
       DECB    JOB.ROW(MEM)

;--- set forced update flags for all terminals

FLAG.TERM:
       LEA     A6,TM.TBL(MEM)
       MOV     #MAX-1,D6
20$:    OR      #TM$NEW,TM.FLG(A6)
       ADD     #TM.SIZ,A6
       DBF     D6,20$
       BIT     #F$HEADER,FLAGS(MEM)    ;                               [120]
       JNE     HEADER                  ;                               [120]
       JMP     TITLE

;--- Device Mode (if in operator mode, branch to Detach)

DEV.MODE:
       BIT     #F$OPR,FLAGS(MEM)       ; operator mode?                [105]
       BEQ     10$                     ;  no                           [105]
       CMPW    MODE(MEM),#M$JOB        ; job display?                  [105]
       JEQ     DETACH                  ;  yes - detach instead         [105]
10$:    CMPW    MODE(MEM),#M$DEV
       JEQ     HEADER.SCAN
       MOVW    #M$DEV,MODE(MEM)
       CLRW    JOB.OFFSET(MEM)
       DECB    JOB.ROW(MEM)

;--- set forced update flags for all devices

FLAG.DEV:
       LEA     A6,DT.TBL(MEM)
       MOV     #MAX-1,D6
10$:    OR      #DT$NEW,DT.FLG(A6)
       ADD     #DT.SIZ,A6
       DBF     D6,10$
       BIT     #F$HEADER,FLAGS(MEM)    ;                               [120]
       JNE     HEADER                  ;                               [120]
       JMP     TITLE

;--- Detach (operator mode only)

DETACH: SAVE    A0-A5,D0-D5
       MOVB    JOB.ROW(MEM),D0
       INCB    D0
       CURSOR  D0,#1
       CLREOS
       INCW    D0
       CURSOR  D0,#2
       HIGH
       TYPESP  Detach
       CALL    OPRJOB
       JNE     DETSLF
       MOV     JOBTRM(A3),D7
       JEQ     DETERR
       MOV     D7,A4
DETDET: CLR     JOBTRM(A3)              ; clear job link to terminal
       CLR     T.JLK(A4)               ; clear terminal link to job
       TYPE    <Job >
       OUTNM2  JOBNAM(A3)
       TYPE    < detached from Terminal >
       OUTNAM  -4(A4)
       CRLF
       JMP     DETRTN
DETSLF: TTYI
       BYTE    7,0
       TYPE    <?You cannot detach your own job>
       BR      DETRTN
DETERR: ADD     #2,D0
       CURSOR  D0,#2
       TTYI
       BYTE    7,0
       EVEN
       TYPE    <?Job is already detached>
DETRTN: REST    A0-A5,D0-D5
       JMP     ANYKEY

;--- Toggle ersatz display

ERSATZ.ON.OFF:
       CMPW    MODE(MEM),#M$JOB
       JNE     HEADER.SCAN
       XOR     #F$ERSATZ,FLAGS(MEM)
       DECB    JOB.ROW(MEM)
       JMP     TITLE

;--- Force input to another job (operator mode only)

FORCE:  BIT     #F$OPR,FLAGS(MEM)       ; in operator mode?             [105]
       JEQ     ERROR                   ;  no                           [105]
       CMPW    MODE(MEM),#M$JOB        ; job display?                  [105]
       JNE     ERROR                   ;  no                           [105]
       SAVE    A0-A5,D0-D5
       MOVB    JOB.ROW(MEM),D0
       INCB    D0
       CURSOR  D0,#1
       CLREOS
       INCW    D0
       CURSOR  D0,#2
       HIGH
       TYPESP  Force
       CALL    OPRJOB
       JNE     FRCSLF
       MOV     JOBTRM(A3),D7
       JEQ     DETERR
       MOV     D7,A5
       TYPE    <Enter keystrokes to force - press backslash (\) when done:>
       ADDW    #1,D0
FRCLIN: ADDW    #1,D0
       CURSOR  D0,#2
FRCGET: KBD
       CMPB    D1,#'\
       JEQ     FRCEND
       CALL    IMAGE
       TRMICP
       CMPB    D1,#13.
       BEQ     FRCLIN
       BR      FRCGET
FRCEND: ADDW    #2,D0
       CURSOR  D0,#2
       TYPE    End of force
       REST    A0-A5,D0-D5
       JMP     HEADER
FRCSLF: TTYI
       BYTE    7,0
       TYPE    <?You cannot force your own job>
       JMP     FRCRTN
FRCERR: TTYI
       BYTE    7,0
       TYPE    <?Job >
       OUTNM2  JOBNAM(A3)
       TYPE    < is not attached to a terminal and cannot be forced>
FRCRTN: REST    A0-A5,D0-D5
       JMP     ANYKEY

;--- output printable image of char in D1

IMAGE:  SAVE    D1
       CMPB    D1,#40
       BLO     IMGCTL
       CMPB    D1,#'~
       BHI     IMGNUM
       TTY
       BR      IMGRTN
IMGCTL: TYPE    ^
       ADDB    #'@,D1
       TTY
       BR      IMGRTN
IMGNUM: TYPE    {
       DCVT    0,OT$TRM
       TYPE    }
IMGRTN: REST    D1
       RTN

;--- Kill another job (operator mode only)

KILL:   BIT     #F$OPR,FLAGS(MEM)       ; in operator mode?             [105]
       JEQ     ERROR                   ;  no                           [105]
       CMPW    MODE(MEM),#M$JOB        ; job display?                  [105]
       JNE     ERROR                   ;  no                           [105]
       SAVE    A0-A5,D0-D5
       MOVB    JOB.ROW(MEM),D0
       INCB    D0
       CURSOR  D0,#1
       CLREOS
       INCW    D0
       CURSOR  D0,#2
       HIGH
       TYPESP  Kill
       CALL    OPRJOB
       JNE     KILSLF
       ORW     #J.CCC,JOBSTS(A3)
       TYPESP  Job
       OUTNM2  JOBNAM(A3)
       TYPE    < killed>
       JMP     KILRTN
KILSLF: TTYI
       BYTE    7,0
       TYPE    <?You cannot kill your own job>
KILRTN: REST    A0-A5,D0-D5
       JMP     ANYKEY

;--- Toggle user name field

USER.ON.OFF:
       CMPW    MODE(MEM),#M$JOB
       JNE     HEADER.SCAN
       XOR     #F$USER,FLAGS(MEM)
       DECB    JOB.ROW(MEM)
       JMP     TITLE

;--- Statistics On

STATS.ON:
       BIT     #F$HEADER,FLAGS(MEM)
       JNE     HEADER.SCAN
       OR      #F$HEADER,FLAGS(MEM)
       JMP     HEADER

;--- Statistics Off

STATS.OFF:
       BIT     #F$HEADER,FLAGS(MEM)
       JEQ     HEADER.SCAN
       AND     #^C<F$HEADER>,FLAGS(MEM)
       JMP     HEADER

;--- Page Back

PAGE.BACK:
       MOV     #22.,D0
       MOVBL   JOB.ROW(MEM),D1
       SU
B       D1,D0
       CMMW    JOB.OFFSET(MEM),D0
       JLO     HOME
       SUBW    D0,JOB.OFFSET(MEM)
       CURSOR  JOB.ROW(MEM),#1
       CLREOS
       DECB    JOB.ROW(MEM)
       JMP     TITLE

;--- Page Forward

PAGE.FORWARD:
       MOV     #22.,D0                 ;                               [115]
       MOVBL   JOB.ROW(MEM),D1         ;                               [115]
       SUB     D1,D0                   ;                               [115]
       MOVWL   JOB.OFFSET(MEM),D6      ;
       ADDW    D0,D6                   ;
       CMPW    MODE(MEM),#M$TERM       ;
       BEQ     PF.TRM                  ;
       CMPW    MODE(MEM),#M$DEV        ;
       BEQ     PF.DEV                  ;

PF.JOB: CMPW    D6,HD.TBL+HD.ALC(MEM)
       JHIS    HEADER.SCAN

PF.CNT: ADDW    D0,JOB.OFFSET(MEM)
       CURSOR  JOB.ROW(MEM),#1
       CLREOS
       DECB    JOB.ROW(MEM)
       OR      #F$UPDATE,FLAGS(MEM)    ; DEBUG DEBUG DEBUG
       JMP     TITLE

PF.TRM: CMPW    D6,TRM.COUNT(MEM)       ;
       JHIS    HEADER.SCAN             ;
       BR      PF.CNT                  ;

PF.DEV: CMPW    D6,DEV.COUNT(MEM)       ;
       JHIS    HEADER.SCAN             ;
       BR      PF.CNT                  ;

;--- Job Up (decrease offset)

JOB.UP:
       TSTW    JOB.OFFSET(MEM)
       JEQ     HEADER.SCAN
       CALL    OPR.UNMARK              ;                               [105]
       CURSOR  LAST.ROW(MEM),#1
       DELLIN
       CURSOR  JOB.ROW(MEM),#1
       INSLIN
       DECW    JOB.OFFSET(MEM)
       MOVWL   JOB.OFFSET(MEM),D0
       CMPW    MODE(MEM),#M$JOB
       BEQ     UP.JOB
       CMPW    MODE(MEM),#M$DEV
       BEQ     UP.DEV

UP.TRM: MUL     D0,#TM.SIZ
       LEA     A6,TM.TBL(MEM)
       ADD     D0,A6
       OR      #TM$NEW,TM.FLG(A6)
       JMP     HEADER.SCAN

UP.JOB: MUL     D0,#JB.SIZ
       LEA     A6,JB.TBL(MEM)
       ADD     D0,A6
       OR      #JB$NEW,JB.FLG(A6)
       CALL    OPR.MARK                ;                               [105]
       JMP     HEADER.SCAN

UP.DEV: MUL     D0,#DT.SIZ
       LEA     A6,DT.TBL(MEM)
       ADD     D0,A6
       OR      #DT$NEW,DT.FLG(A6)
       JMP     HEADER.SCAN

;--- Job Down (increase offset)

JOB.DOWN:
       MOVW    JOB.OFFSET(MEM),D0      ;                               [105]
       INCW    D0                      ;                               [105]
       CMMW    D0,HD.TBL+HD.ALC(MEM)   ;                               [105]
       BHIS    10$
       CALL    OPR.UNMARK              ;                               [105]
       INCW    JOB.OFFSET(MEM)
       CURSOR  JOB.ROW(MEM),#1
       DELLIN
       CURSOR  LAST.ROW(MEM),#1
       INSLIN
       CALL    OPR.MARK                ;                               [105]
10$:    JMP     HEADER.SCAN

;--- Home

HOME:   CALL    OPR.UNMARK              ;                               [105]
       CLRW    JOB.OFFSET(MEM)
       DECB    JOB.ROW(MEM)
       CALL    OPR.MARK                ;                               [105]
       JMP     TITLE

;--- Set Delay Time

SET.DELAY:
       AND     #177,D1
       SUB     #'0,D1
       CMP     D1,#0
       JLO     HEADER.SCAN
       CMP     D1,#9.
       JHI     HEADER
       MOV     D1,DELAY(MEM)
       JMP     HEADER.SCAN

;--- R)efresh command

REFRESH:
       JMP     HEADER

ERROR:  TTYI
       BYTE    7,0
       EVEN
       JMP     HEADER.SCAN

;--- set the operator cursor

OPR.MARK::                              ;                               [105]
       BIT     #F$OPR,FLAGS(MEM)       ; operator mode?                [105]
       BEQ     10$                     ;  no                           [105]
       CMPW    MODE(MEM),#M$JOB        ; job display?                  [105]
       BNE     10$                     ;  no                           [105]
       MOVB    JOB.ROW(MEM),D0         ; remove old job marker         [105]
       ADDB    OPR.MARKER(MEM),D0      ;                               [105]
       CURSOR  D0,#8.                  ;                               [105]
       REVOFF                          ;                               [105]
       CURSOR  D0,#1                   ;                               [105]
       REVON                           ;                               [105]
10$:    RTN                             ;                               [105]

;--- remove the operator cursor

OPR.UNMARK::                            ;                               [105]
       BIT     #F$OPR,FLAGS(MEM)       ; operator mode?                [105]
       BEQ     10$                     ;  no                           [105]
       CMPW    MODE(MEM),#M$JOB        ; job display?                  [105]
       BNE     10$                     ;  no                           [105]
       MOVB    JOB.ROW(MEM),D0         ; remove old job marker         [105]
       ADDB    OPR.MARKER(MEM),D0      ;                               [105]
       CURSOR  D0,#1                   ;                               [105]
       TYPESP                          ;                               [105]
10$:    RTN                             ;                               [105]

HELP.DDB:
       RAD50   /USTAT /
       RAD50   /DDB/

HELP.TEXT:
       ASCIZ   "USTAT command summary                                     page 1 of 3"
       ASCIZ   ""
       ASCIZ   "DISPLAY MODES"
       ASCIZ   ""
       ASCIZ   "        The J, T, and D keys change the display mode:"
       ASCIZ   ""
       ASCIZ   "                J  -  show job status"
       ASCIZ   "                T  -  show terminal status"
       ASCIZ   "                D  -  show device status"
       ASCIZ   ""
       ASCIZ   "HEADER CONTROL"
       ASCIZ   ""
       ASCIZ   "        The header statistics area may be turned off with the minus key (-),"
       ASCIZ   "        and back on again with the plus key (+)."
       ASCIZ   ""
       ASCIZ   "DISPLAY CONTROL"
       ASCIZ   ""
       ASCIZ   "        The R key redisplays the screen"
       ASCIZ   "        The SPACE BAR key suspends the screen; press SPACE again to resume"
       ASCIZ   ""
       ASCIZ   "Press any key to continue or ESC to quit: "

       ASCIZ   "USTAT command summary                                     page 2 of 3"
       ASCIZ   ""
       ASCIZ   "ADJUSTING THE DISPLAY"
       ASCIZ   ""
       ASCIZ   "        The job, terminal, or status display is a virtual window that is"
       ASCIZ   "        larger than the size of the terminal screen.  The keys described"
       ASCIZ   "        below allow you to move around in this window."
       ASCIZ   ""
       ASCIZ   "        The UP ARROW key scrolls the display up one line"
       ASCIZ   "        The DOWN ARROW key scrolls the display down one line"
       ASCIZ   ""
       ASCIZ   "        The PREV SCREEN key (Control-R) backs up one full screen"
       ASCIZ   "        The NEXT SCREEN key (Control-T) moves forward one screen"
       ASCIZ   ""
       ASCIZ   "        The HOME key (Control-^) moves to the beginning of the display window"
       ASCIZ   "        The s/HOME key (Control-E) moves to the end of the display window"
       ASCIZ   ""
       ASCIZ   "        Press W for a wide screen 132-column display, N for 80-columns"
       ASCIZ   "        Press X to switch between 24 & 42 line mode (if terminal supports it)"
       ASCIZ   ""
       ASCIZ   "Press any to continue or ESC to quit: "

       ASCIZ   "USTAT command summary                                     page 3 of 3"
       ASCIZ   ""
       ASCIZ   "JOB DISPLAY OPTIONS"
       ASCIZ   ""
       ASCIZ   "        The E key toggles the ersatz log feature.  When this feature is"
       ASCIZ   "        enabled (the default), ersatz names are shown for the log"
       ASCIZ   "        account of each job.  When the ersatz log feature is turned"
       ASCIZ   "        off, the actual device code and drive number is shown."
       ASCIZ   ""
       ASCIZ   "        The U key toggles the user name feature.  When this feature is"
       ASCIZ   "        enabled (the default), each user's name is shown as part of the"
       ASCIZ   "        job display line.  When the user name feature is turned"
       ASCIZ   "        off, disk reads, disk writes, and priority is shown instead."
       ASCIZ   ""
       ASCIZ   ""
       ASCIZ   ""
       ASCIZ   ""
       ASCIZ   ""
       ASCIZ   ""
       ASCIZ   ""
       ASCIZ   "Press any key to resume status display: "

       BYTE    -1
       EVEN

       END