;********************************************************************
;*      TRMOFF.M68  (Terminal Off) .... now this is really cool!
;*
;*      Monitor system JOBs for lack of input...turn off screen after
;*      a three minute grace period if no CPU time used.
;*
;*      by Dave Heyliger - AMUS (May '86)
;*
;*###################################################################
;# How it works:
;#      Similar to NETSPY, a mini JOB is set up that basically sleeps
;#      all day, peeking every once in a while at each JOBs CPU time.
;#      If the terminal is ON, and there is no activity within 3 mins,
;#      TRMOFF will turn OFF the terminal without interrupting the
;#      JOB that this terminal is attached to (i.e., if a BASIC menu
;#      program is just sitting there, TRMOFF will turn off the screen
;#      while the menu is still "running"). To turn the terminal back ON,
;#      just hit any key or a return. The input key is ignored, the
;#      screen comes back on, and everybody is happy.
;#
;# What you need to do:
;#   Step 1: modify your terminal driver ("piece of cake" - ha ha).
;#           Assuming an AM62, AM62A, AM70, TVI925, etc. do the following
;#
;#           (NOTE: AM70TO, AM62TO, and T925TO.M68 all have been placed in
;#                  the driver account, [100,53], for you to use if you would
;#                  rather just obtain a modified driver).
;#
;#           a. COPY AM70TO.M68=AM70.M68   (for example)
;#           b. VUE AM70TO.M68
;#           c. from the ">" type S INP: {return}
;#           d. now hit ONE control-x, you should be at the input routine
;#              it will look something like this:
;#
;#
;#INP:  BMI     INMLT                   ; skip if multi-byte processing
;#      CMPB    D1,#1                   ; function code?
;#      BEQ     INPM                    ;   yes - could be multi-byte sequence
;#      CMPB    D1,#33                  ; escape?
;#      BEQ     INPM                    ;   yes - could be multi-byte sequence
;#      LCC     #0                      ;   no - normal processing
;#      RTN
;#
;#INPM: LCC     #PS.N                   ; possible multi-byte - return N flag
;#      RTN
;#
;#           e. place the cursor at the line LCC #0 and hit a bunch of
;#              control-B's, and insert the code listed below. I have left
;#              in the code above so you can see exactly where it needs to
;#              go.
;#
;#INP:  BMI     INMLT                   ; skip if multi-byte processing
;#      CMPB    D1,#1                   ; function code?
;#      BEQ     INPM                    ;   yes - could be multi-byte sequence
;#      CMPB    D1,#33                  ; escape?
;#      BEQ     INPM                    ;   yes - could be multi-byte sequence
;#;
;#;++++++ NEW STUFF FOR AUTO TURN-ON WITH TRMOFF.LIT +++++++++
;#;
;#      PUSH    D1                      ;save everything (paranoid, we are)
;#      PUSH    D7
;#      PUSH    A6
;#      PUSH    D3
;#      CLR     D1                      ;clear the reg
;#      MOVW    T.STS(A5),D6            ;get the terminal status word
;#      PUSH    D6                      ;and save the original
;#      ANDW    #20000,D6               ;get this bit
;#      CMPW    D6,#20000               ;see if this bit is on (tv OFF)
;#      BLO     CONT                    ;NO, tv is ON, so normal processing
;#      POP     D6                      ;tv OFF, so get the status word
;#      MOVW    #20000,D7               ;and the bit indicating it's OFF
;#      COMW    D7                      ;complement
;#      ANDW    D7,D6                   ;and turn this bit off (tv will be ON)
;#      MOVW    D6,@A5                  ;move this into the status word
;#      LEA     A6,C37                  ;get the "turn on" byte string address
;#      MOV     A6,D1                   ;move this address to D1 for TRMBFQ
;#      MOV     #2,D3                   ;the number of bytes for turn on
;#      TRMBFQ                          ;turn tv ON
;#CONT: POP     D6                      ;restore junk
;#      POP     D3
;#      POP     A6
;#      POP     D7
;#      POP     D1
;#;
;#;++++++ END OF "NEW HOT STUFF" - ZOUNDS! ++++++++++++++++
;#;
;#      LCC     #0                      ;   no - normal processing
;#      RTN
;#
;#INPM: LCC     #PS.N                   ; possible multi-byte - return N flag
;#      RTN
;#
;#           f. It might be wise to make sure that label C37: inside
;#              the terminal driver IS the TURN ON code (most are).
;#
;#           g. Now assemble the new terminal driver, and place it in
;#              DSK0:1,6.
;#
;#   Step 2: look at the bottom of this code and insert the proper JOB names
;#           that you would like scanned. Be sure to have a full SIX
;#           characters between the "/      /" (use blanks if necessary).
;#
;#   Step 3: modify your AMOSL.INI file (by making a COPY and testing
;#           it first!!!). Set up a mini JOB that will have a pseudo
;#           terminal driver on it. Have it run TRMOFF. TRMOFF uses
;#           microscopic CPU time and will not bog you down. Also, be
;#           sure to change the TRMDEF lines so that the "new" terminal
;#           drivers are attached.
;#
;********************************************************************

       OBJNAM  TRMOFF.LIT              ;the final product

       SEARCH SYS                      ;get the monitor calls...
       SEARCH SYSSYM
       SEARCH TRM

       VMAJOR=1                        ;define a version number
       VMINOR=0
       VEDIT=100.

;--- Macro Definition
;
DEFINE  PRTTAB  AA,BB           ;PRINT TAB (#,#)
       MOVB    #AA,D1
       LSLW    D1,#10
       MOVB    #BB,D1
       TCRT
ENDM

       PHDR    -1,0,PH$REU             ;program header

       BR      INI                     ;bypass SLEEP when INI'ed.

TOP:    SLEEP   #1800000.               ;sleep for 3 minutes (#600000.=1 min.)
       CTRLC   STOP                    ;quit on controlC
INI:    MOV     JOBTBL,A0               ;JOB TABLE address to A0
       LEA     A1,JOBS                 ;JOBS (list to check) address to A1
       MOV     #0,D4                   ;D4 will be a counter for offset use

;--- Scan for the JOBs to be checked
;
SCAN:   MOV     (A0)+,A3                ;A3 now points to each JCB per SCAN
       MOV     A3,D1                   ;Set the status register
       JMI     TOP                     ;if at end of JOBTBL, clean-up time
       BEQ     SCAN                    ;if a "0" then look at next JCB
       LEA     A4,JOBNAM(A3)           ;valid JOB so get the NAME of the JOB
       CMM     @A1,@A4                 ;see if this name matches name in list
       BEQ     TIME                    ;found a match!
       JMP     SCAN                    ;else try the next JOB on the system

;---    Time to check to see if CPU time is same as 3 minutes ago.
;
TIME:   LEA     A4,JOBCPU(A3)           ;"tiw"... but for how long???
       LEA     A2,CPUBUF               ;point A2 to start of CPU usage array
       LEA     A6,FLAGS                ;on-off flags
       ADD     D4,A2                   ;offset adjustment
       ADD     D4,A6                   ;offset adjustment
       CMM     @A2,@A4                 ;time same as 3 minutes ago???
       BEQ     TIME2                   ;yup, time to turn off if not OFF
       MOV     (A4),@A2                ;else store the "new" CPU time
       CLR     @A6                     ;flag NOT set cuz CPU time indicated
NOOFF:  ADD     #4,D4                   ;and adjust offset value
       ADD     #4,A1                   ;point A1 to next JOB on list
       JMP     SCAN                    ;and begin scanning system again
TIME2:  CMP     @A6,#1                  ;already turned off?
       BEQ     NOOFF                   ;yup
       MOV     #1,@A6                  ;nope, set flag saying "I'm OFF"

;--- Terminal not being used, so
;       1) detach that terminal from that unused JOB
;       2) attach that terminal to the JOB running this program
;       3) turn it off
;       4) attach terminals back to the original JOBs
;
ONOFF:  PUSH    D4                      ;our beloved offset value
       JOBIDX  A6                      ;this JCB
       MOV     JOBTRM(A6),A5           ;this TB^
       PUSH    A5                      ;save it
       MOV     JOBTRM(A3),A5           ;their TB^
       PUSH    A5                      ;save it
       LEA     A5,JOBTRM(A3)           ;address of their TB^
       JLOCK   ;----------------------------------------------------------
       CLR     @A5                     ;"detach" their terminal
       LEA     A4,JOBTRM(A6)           ;A4 points to this TB^ memory area
       POP     @A4                     ;TB^ now is their terminal
       PUSH    @A4                     ;and save it too (need it later)
       PRTTAB  377,44                  ;turn the sucker off
       POP     @A5                     ;attach it back to original owner
       POP     @A4                     ;attach OUR original terminal back
       MOV     JOBTRM(A3),A5           ;get their terminal status word
       CLRW    D0                      ;clear for use
       MOVW    T.STS(A5),D0            ;move in the tsw
       ORW     #20000,D0               ;flip on this bit for the .TDV to see
       MOVW    D0,@A5                  ;and place it in the tsw
       JUNLOK  ;-----------------------------------------------------------
UPDATE: POP     D4                      ;get our beloved offset value
       ADD     #4,D4                   ;increment offset adjustment
       ADD     #4,A1                   ;point to next JOB
       JMP     SCAN                    ;and continue scan

;--- List of JOBs that have terminals that don't auto turn off.
;    You MUST list these JOBS IN ORDER (i.e., how STAT lists them, ok?).
;
JOBS:   RAD50   /SPOCK /
       RAD50   /BONES /
       RAD50   /YEOMAN/
       EVEN

;--- CPU time usage array and ON/OFF flags array. 10 = 8 JOBs max. If you
;    need more than 8 JOBs monitored, then 15 = 13 JOBs, 20 = 16 JOBs, etc
;    (Learn base 8, members. It's good for you!).
;
CPUBUF: BLKL    10                      ;original setup for eight JOBs
FLAGS:  BLKL    10

STOP:   EXIT
       END