SAVE YOUR CRT SCREEN


                      A program to turn off the high voltage to your CRT.


                                       by: Richard Eakin
                                Quaker State Oil Refining Corp.
                                        Research Center



               A  problem  that  all CRT users will eventually encounter is
          the etching or burning-in of an image on the screen. After a long
          enough period, the resolution and intensity of the screen will be
          degraded, and  eventually  necessitate  the  replacement  of  the
          screen  and/or terminal.  In an effort to spend budgeted money on
          new additions and  upgrades  instead  of  replacements,  we  have
          developed a system to help minimize the burning of an image.

               Most  applications  are  menu  driven by any of a variety of
          menu systems. The AlphaMENU system is  nice,  but  new  and  time
          consuming  to convert existing systems. The easily maintained and
          possibly most common method is to write a BASIC  program  listing
          the programs available, then CHAIN to them from the menu program.
          The  programs  in  turn CHAIN back to the menu program.  Programs
          can be added and deleted from the system simply by  changing  the
          menu program. A new version of a program can be developed, tested
          and  then  implemented  by  simply changing the CHAIN file in the
          menu program.

               This system works fine but it usually ends up  with  a  menu
          being displayed on the screen for a large percentage of the time.
          This  is the image that gets burned into the screen. In an effort
          to alleviate this problem,  we  have  tried  several  methods  of
          turning the screens off. Alpha Micro has provided for turning the
          screen on and off, by software control, if it is supported by the
          terminal.  TCRT  codes  36  and  37 (Extended TABS in AlphaBASIC)
          control the high voltage to the screen. A  simple  BASIC  program
          can  be  written  to PRINT TAB(-1,36) to each screen, after it is
          out of the menu program. The first working solution was to create
          a command file to run at the end of each day  to  exit  the  user
          from  the menu program and run the screen off program. This was a
          good solution, but it still allowed  the  screen  to  be  on  for
          several  hours  unnecessarily  during  the day (over lunch hours,
          etc).

               A better method  is  provided  here.  That  is  to  have  an
          assembly  language subroutine to monitor the use of the terminal.
          If the terminal is not being used for a relatively  short  period
          of time, have the screen turned off. The subroutine below will do
          just that with a few additional enhancements.

               First  the  time  period  to  wait  for  a keyboard entry is
          approximately 2 minutes. Upon receiving no keyboard entries,  the
          subroutine  will turn off the screen. Any keyboard stroke will be
          captured by the subroutine and used to turn the screen on  again.
          This  cycle  will  continue  as  long  as  necessary.  To  make a
          selection from the menu, the subroutine will capture the keyboard
          entry and assign it to the calling variable.  Since our menus are
          all numerical choices, we have written  it  to  pass  a  floating
          point  variable.  At  the bottom of the listing is the code to be
          inserted to use a string variable.  The subroutine thus takes the
          place of an INPUT or INPUT LINE statement  in  a  BASIC  program.
          The variable being passed to the subroutine must be MAPped in the
          BASIC program.

               To  avoid  using  large  quantities  of CPU time, we put the
          terminal into a sleep state  in  between  checking  for  keyboard
          entries.  We have allowed for control C interrupts throughout the
          subroutine to return to AMOS/L. The stack pointer for CMD and  DO
          files  is  also preserved, in the event that arguments are passed
          through the menu program by one of these means.

               As added features, we have allowed the  system  time  to  be
          displayed  at  the  coordinates  defined  in  the subroutine, the
          cursor may also be positioned at the desired point on the  screen
          by defining the coordinates in the subroutine.

               Thus  with this subroutine you can display a real time clock
          while the screen is on the menu, and you can save the screen from
          becoming etched by the image of the menu.

               We are relatively new at assembly language programming,  but
          in  an  effort to provide some assembly language programs through
          AMUS  for  the  AM-100/L  processor,  we  have   submitted   this
          subroutine. We welcome suggestions, comments and questions.

               Remember  that  USRCHK.SBR  must  be transfered into account
          DSK0:[7,6] to be run by all programs on the system.
          Below is a sample BASIC program implementing USRCHK:

          MAP1 SELECT,F

          TOP:
          PRINT TAB(-1,0);
          PRINT TAB(3,1) 
          PRINT 
          PRINT "                    1) Enter a customer"
          PRINT "                    2) Edit a customer"
          PRINT "                    3) Print out a customer file"
          PRINT "                    4) Search for a customer"
          PRINT "                    5) Move a customer to inactive status"
          PRINT "                    6) Reactiviate a customer"
          PRINT "                   99) Exit to AMOS/L"
          MENU'SELECTION:
          PRINT TAB(10,1);
          PRINT TAB(-1,32);" Select the ";TAB(-1,33);TAB(11,1);
          PRINT TAB(-1,32);"   number   ";TAB(-1,33);TAB(12,1);
          PRINT TAB(-1,32);"    \  /    ";TAB(-1,33);TAB(13,1);
          PRINT TAB(-1,32);"     __     ";TAB(-1,33);TAB(13,7);

          XCALL USRCHK,SELECT

          PRINT TAB(-1,0);TAB(3,1);
          IF (SELECT = 1) CHAIN "CUSTIN.RUN"
          IF (SELECT = 2) CHAIN "EDTCST.RUN"
          IF (SELECT = 3) CHAIN "PRTCST.RUN"
          IF (SELECT = 4) CHAIN "SRCHCS.RUN"
          IF (SELECT = 5) CHAIN "INACTV.RUN"
          IF (SELECT = 6) CHAIN "REACTV.RUN"
          IF (SELECT = 99) CHAIN "EXIT.RUN"
          GOTO TOP
          END



          ;This subroutine is developed for the AMOS/L processor and will work
          ;on terminals that support software control of screen on/screen off.
          ;In AlphaBASIC these are the extended tabs (-1,36) and (-1,37) respectively.



          ;This subroutine checks for any character input to the terminal,
          ;if no input for approx 2 minutes the high voltage is turned off.
          ;This causes the screen to go dark and prevents image burn-in. 
          ;The subroutine then goes into a loop to receive any key. On detecting
          ;a keystroke the H.V. is turned back on for another cycle. Any input
          ;while the screen is on is accepted and assigned to the calling variable.
          ;This variable must be mapped in the calling program as a floating point
          ;variable. The keystroke entered while the screen is off is ignored, thus
          ;any key may be used to turn on the screen.

          ;This subroutine will take the place of an INPUT statement in the calling
          ;program.

          ;The subroutine will also display a real time clock while the screen is on.

          ;This subroutine is reuseable and reentrant; it can read and write system
          ;memory. This subroutine can be interrupted by a ^C  ASSUMING the user's
          ;terminal has CTRLC SET.

          ;The sleep time will vary depending upon the other demands being placed on
          ;the processor.

          ;The hash code for USRCHK.SBR is 307-622-306-012 with floating pt variable
          ;                                232-324-511-557 with string variable

          ;The authors give permission for the use of this subroutine to licensed
          ;Alpha-Micro users and members of AMUS.

          ;11/08/83 Quaker State Oil Refining Corp. Research Center - sgm/rme

          SEARCH SYS.UNV
          SEARCH SYSSYM.UNV
          SEARCH TRM.UNV
          RADIX 8

          VMAJOR=1.                               ;VERSION NUMBER 1.1A(101)
          VMINOR=1.
          VSUB=1.
          VEDIT=101.

          OBJNAM  USRCHK.SBR                      ;ASSEMBLER WILL RENAME USRCHK.LIT TO USRCHK.SBR

          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;                                                                            ;
          ;       ASSIGN ROW AND COLUMN LOCATIONS FOR INPUT AND CLOCK  HERE            ;
          ;                                                                            ;
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

          CROW=^D13                               ;CURSOR ROW = 13 (DECIMAL)
          CCOL=^D7                                ;CURSOR COLUMN = 7 (DECIMAL)
          CKRW=^D1                                ;CLOCK ROW = 1 (DECIMAL)
          CKCL=^D3                                ;CLOCK COL = 3 (DECIMAL)

          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;                                                                            ;
          ;       input cursor is now set for (13,7) and clock for (1,3)               ;
          ;                                                                            ;
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;                                                                            ;
          ;       Set number of cycles the screen is on                                ;
          ;               350 = approximately 2 minutes                                ;
          ;                                                                            ;
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

          CYC=^D350                               ;CYCLES = 350

          EVEN

          HEADER:                                 
                  PHDR    -1,PV$RSM!PV$WSM,PH$REE!PH$REU

                  MOV     4(A3),A1                ;SAVE VARIABLE LOCATION
                  JOBIDX  A4                      ;GET THE JOB'S INDEX
                  MOVW    JOBCMZ(A4),D1           ;ARE WE IN A COMMAND FILE?
                  TST     D1                      ;ZERO MEANS NO
                  JNE     VARIN                   ;A NUMBER MEANS YES WE ARE!
          BEGIN:  
                  MOVB    #CROW,D1                ;POSITION THE CURSOR AT THE INPUT POSITION
                  LSLW    D1,#10                  ;THIS IS WHERE WE WANT THE INPUT TO APPEAR
                  MOVB    #CCOL,D1                ;WHEN A SELECTION IS ENTERED.
                  TCRT
                  CLRW    D1
                  MOV     JOBTRM(A4),A0           ;GET THE JOB'S TERMINAL DEF POINTER
                  MOVW    #1,(A0)                 ;SET THE FORCED IMAGE MODE (FOR KBD CALL)
                  MOV     #CYC,D2                 ;NUMBER OF LOOPS IN 1st CYCLE
                  CLRW    D1                      ;CLEAR OUT ANY JUNK 
          TOP:
                  MOVW    #177445,D1              ;MAKE SURE SCREEN IS ON
                  TCRT    
                  CLRW    D1                      ;CLEAR OUT ANY JUNK
                  TCKI                            ;ANYTHING IN INPUT BUFFER?
                  JEQ     VARIN                   ;YES - END THE SUBROUTINE
                  SLEEP   #10000                  ;NO  - SLEEP FOR A BIT

          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;this routine gets the system time in the format of one long word          ;
          ;with 'minutes''hours''blank''seconds' as the byte order.                  ;
          ;the times are stored as a binary number and must be converted to decimal. ;
          ;This routine will print the time at position defined above.               ;
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

          CLOCK:  
                  MOVW    #177435,D1      ;TURN THE CURSOR OFF
                  TCRT
                  CLRW    D1              ;CLEAR OUT ANY JUNK
                  MOVB    #CKRW,D1        ;POSITION THE CLOCK
                  LSLW    D1,#10
                  MOVB    #CKCL,D1
                  TCRT
                  CTRLC   EXIT            ;CONTROL C ABORT TO EXIT
                  CLR     D0              ;CLEAR OUT WORKING REGISTERS
                  CLR     D1
                  CLR     D3
                  CLR     D5
                  GTIMES  D3              ;GET THE SYSTEM TIME IN SEPERATED FORMAT
                  MOVB    D3,D0           ;STORE THE SECONDS IN D0 (BINARY FORMAT)
                  ROR     D3,#8.          ;ROTATE TO THE NEXT BYTE (THIS IS THE BLANK BYTE)
                  ROR     D3,#8.          ;ROTATE PAST THE BLANK BYTE 
                  MOVB    D3,D5           ;STORE THE HOURS IN D5
                  ROR     D3,#8.          ;ROTATE TO THE NEXT BYTE
                  MOVB    D3,D4           ;STORE THE MINUTES IN D4
                  MOVB    D5,D1           ;GET THE HOURS
                  CMPB    D5,#12.         ;COMPARE HOURS WITH 12(DEC)
                  JLT     OUTHR           ;IF LESS THAN 12 THEN ITS AM == PRINT OUT THE HOUR
                  JEQ     OUTHR           ;IF EQUAL TO 12 THEN ITS NOON OR MIDNIGHT 
                  SUBB    #12.,D1         ;IF HOURS GREATER THAN 12 THEN ITS PM == SUBTRACT 12 TO GET OUT OF MIL TIME
          OUTHR:  DCVT    2,OT$TRM        ;CONVERT IT TO DECIMAL = 2 DIGITS = PRINT ON TERMINAL
                  TYPE    <:>
                  MOVB    D4,D1           ;GET THE MINUTES
                  DCVT    2,OT$TRM        ;CONVERT IT TO DECIMAL = 2 DIGITS = PRINT ON TERMINAL   
                  TYPE    <:>
                  MOVB    D0,D1           ;GET THE SECONDS
                  DCVT    2,OT$TRM        ;CONVERT IT TO DECIMAL = 2 DIGITS = PRINT ON TERMINAL
                  CMPB    D5,#12.         ;COMPARE THE HOURS TO A DECIMAL 12
                  JLT     AM              ;IF HOURS < 12 THEN ITS AM 
          PM:     TYPESP
                  TYPE    <pm>            ;IF HOURS > 12 THEN ITS PM
                  JMP     CYCLE
          AM:     TYPESP
                  TYPE    <am>

          CYCLE:  
                  CLRW    D1              ;CLEAR OUT ANY JUNK
                  MOVB    #CROW,D1        ;POSITION THE CURSOR AT THE INPUT LOCATION
                  LSLW    D1,#10          
                  MOVB    #CCOL,D1
                  TCRT
                  SUB     #1,D2           ;SUBTRACT ONE FROM THE CYCLE COUNT
                  CTRLC   EXIT
                  TST     D2              ;IS IT ZERO?
                  JEQ     FINI            ;YES - TURN OFF THE H.V.
                  JMP     TOP             ;NO - GO BACK TO TOP OF CYCLE
          FINI:                           ;THIS ROUTINE TURNS OFF THE H.V.
                  CLRW    D1              ;CLEAR OUT ANY JUNK
                  MOVW    #177444,D1      ;TURN OFF THE H.V.
                  TCRT
                  CLRW    D1              ;CLEAR OUT ANY JUNK
                  MOV     JOBTRM(A4),A0   ;SET FORCED IMAGE MODE AND NO ECHO TO 
                  MOVW    #3,(A0)         ;THE TERMINAL
          OFFLP:  
                  CTRLC   EXIT
                  SLEEP   #3000           ;SLEEP FOR A BIT
                  TCKI                    ;ANY INPUT
                  JNE     OFFLP           ;NO - KEEP SCREEN OFF AND CHECK AGAIN
                  KBD                     ;YES - GET THE CHARACTER OUT OF THE BUFFER
                  JMP     BEGIN           ;JUMP TO TOP OF THE H.V. ON CYCLE
          VARIN:
                  CLRW    D1              ;CLEAR OUT ANY JUNK
                  MOVW    #177445,D1      ;TURN THE SCREEN BACK ON
                  TCRT
                  MOVW    #0,(A0)         ;TAKE THE TERMINAL OUT OF FORCED IMAGE MODE
                  MOVB    #CROW,D1        ;POSITION THE CURSOR AT THE INPUT POSITION PLUS ONE
                  LSLW    D1,#10          ;SINCE THERE IS A CHARACTER IN THE BUFFER ALREADY -
                  MOVB    #CCOL,D1        ;WE POSITION THE CURSOR FOR THE NEXT CHARACTER
                  ADD     #1,D1           ;
                  TCRT
                  KBD                     ;INPUT VARIABLE

          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;Code for floating point variable:                                        ;
                                                                                   ;
                  GTFLT   (A1)            ;FLOATING POINT CONVERTION MACRO          ;
                                          ;TO PUT IN INPUT IN VARIABLE LOCATION     ;
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

          RETRN:
                  CLRW    D1              ;CLEAR OUT ANY JUNK
                  MOVW    #177434,D1      ;TURN THE CURSOR ON
                  TCRT
                  RTN                     ;RETURN TO THE CALLING PROGRAM

          EXIT:                           ;Exit is an abnormal path only available through a ^C abort
                  CLRW    D1              ;CLEAR OUT ANY JUNK
                  MOVW    #177445,D1      ;TURN ON THE SCREEN - THIS IS AN ABNORMAL PATH
                  TCRT                    ; ONLY AVAILABLE FROM THE CTRLC ABORT
                  MOVW    #177434,D1      ;TURN ON THE CURSOR
                  TCRT                    
                  EXIT                    ;EXIT TO AMOS

          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          ;Code for string variable to replace the above marked code:               ;
          ;                                                                         ;
          ;       MOV     10(A3),D3       ;SIZE OF STRING VARIABLE                  ;
          ;CMPR:                                                                    ;
          ;       CMPB    (A2),#15        ;IS IT A CARRIAGE RETURN                  ;
          ;       JEQ     RETRN           ;YES - RETURN TO CALLING PRG              ;
          ;       MOVB    (A2)+,(A1)+     ;NO - MOVE IT TO THE VARIABLE LOC         ;
          ;       SUB     #1,D3                                                     ;
          ;       TST     D3              ;END OF VARIABLE ?                        ;
          ;       JEQ     RETRN           ;YES - GO TO CALLING PRG                  ;
          ;       JMP     CMPR            ;NO - GO GET NEXT CHARACTER               ;
          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

          END