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