Fade Away

Developer(s): Andy Pennell
Date: 1988
Type: Program
Platform(s): TS 2068
Tags: Utility

A screen saver that runs in the background under an interrupt routine while you carry on working in BASIC. The loader asks for a delay in seconds, installs the routine and tells you that USR 64994 switches it off again. Once the keyboard has been left alone for the chosen time, the routine copies the attribute file to a buffer and sets every attribute and the border to black, so nothing of the picture stays lit. A key press copies the saved attributes back and restore the border colour.

The REM credits the program to Andy Pennell and gives its source as “YOUR SINCLAIR” 4/88, with the note that FADE AWAY prevents burning in of an image on your TV screen.

Program Analysis

Loader

Line 30 sets RAMTOP with CLEAR 64198. Lines 40–70 then POKE 142 bytes from DATA into two blocks: 57 bytes at 64967–65023 and 85 bytes at 65281–65365. The loop jumps from 65024 to 65281, leaving the 257 bytes in between free for the interrupt vector table. Lines 80–100 multiply the delay by 50 and POKE it into the operand of an LD HL,nn at 65285, and line 110 calls the installer with RANDOMIZE USR 64967.

Interrupt Handler

The installer fills 257 bytes from 65024 (FE00h) with FDh, sets the I register to FEh, switches to interrupt mode 2 and sets an idle counter at 65019 to 1. Every interrupt therefore goes through FDFDh, where a JP leads to the handler at 64997. The handler starts with RST 38h, so the ROM still updates FRAMES and scans the keyboard. It then saves the registers and calls the routine at 65281 with the counter in DE, and stores the value it returns as the new counter. The routine at 64994 is just IM 1 and RET.

Blanking and Restoring

The routine at 65281 compares the counter with the delay. Below the delay it adds one, and resets the counter to 1 if bit 5 of FLAGS shows a new key press. When the counter reaches the delay, it copies the 768 attribute bytes to 64199, zeroes them as it goes, sends 0 to port 254 to blacken the border and sets the last attribute cell to 184, a flashing white square. A counter of zero sends the routine to the restore code at 65335, which waits for a key press, copies the attributes back with LDIR and takes the border colour from BORDCR.

Notable Techniques

  • The interrupt mode 2 handler calls RST 38h first, so the normal ROM interrupt work still runs and BASIC carries on as usual.
  • The delay is POKEd straight into the operand of an instruction, so no separate variable is needed.
  • The machine code sits in the pages either side of the vector table at FE00h and ends at 65365, just below the UDG area.
  • The idle counter doubles as a state flag: zero means the screen is blanked and waiting for a key.

Potential Issues

  • If the screen stays blanked, the next timeout copies the already black attributes over the saved copy, and the original colours are lost.
  • The delay is counted at 50 interrupts per second. On a 60 Hz TS2068 the screen blanks after about five-sixths of the time entered.

One byte was corrected for this release. On the disk, line 310 held 3,0,0 (INC BC and two NOPs) where the blanking routine ends, so the counter never returned to zero and a key press never brought the picture back. It now reads 33,0,0 (LD HL,0), and in ZEsarUX the screen blanks after the chosen delay and returns on a key press.

This program came from an Oliger (JLO SAFE) disk in the SNUG library set and was converted to load from tape. The program needed no changes; the tape copy autostarts at line 10, which the disk copy did not. It was tested in ZEsarUX on a stock TS2068 with a five-second delay, and the screen went black on time.

Related Articles

Machine code screen-saver type-in program originally published in the April issue of Your Sinclair. After a user-set delay of 1...

Image Gallery

Source Code

   10 REM "YOUR SINCLAIR" 4/88          by ANDY PENNELL          FADE AWAY prevents burning in ofan image on your tv screen
   20 RESTORE 
   30 CLEAR 64198
   40 FOR I=64967 TO 65365
   50 IF I=65024 THEN LET I=65281
   60 READ A: POKE I,A
   70 NEXT I
   80 INPUT "DELAY IN SECONDS IS ";S
   90 LET S=S*50: LET T=INT (S/256)
  100 POKE 65287,T: POKE 65286,S-256*T
  110 RANDOMIZE USR 64967
  120 PRINT "USR 64994 TO SWITCH OFF"
  130 DATA 33,0,254,6,0,243
  140 DATA 54,253,35,16,251,54
  150 DATA 253,62,254,237,71,237
  160 DATA 94,251,33,1,0,34
  170 DATA 251,253,201,237,86,201
  180 DATA 255,243,245,229,197,213
  190 DATA 237,91,251,253,205,1
  200 DATA 255,34,251,253,209,193
  210 DATA 225,241,251,201,2,0
  220 DATA 195,229,253
  230 DATA 122,179,40,50,33,232
  240 DATA 3,167,237,82,40,11
  250 DATA 235,35,253,203,1,110
  260 DATA 200,33,1,0,201,33
  270 DATA 0,88,17,199,250,1
  280 DATA 0,3,126,18,54,0
  290 DATA 35,19,11,120,177,32
  300 DATA 245,211,254,62,184,50
  310 DATA 255,90,33,0,0,201
  320 DATA 235,253,203,1,110,200
  330 DATA 33,199,250,17,0,88
  340 DATA 1,0,3,237,176,58
  350 DATA 72,92,230,56,15,15
  360 DATA 15,211,254,33,1,0,201

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.