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