Classic Computer Magazine Archive COMPUTE! ISSUE 19 / DECEMBER 1981 / PAGE 111

Blinking Characters

Frank C. Jones

Silver Spring, MD

The inverse video key on the Atari 400/800 computer allows messages to be displayed in inverse video for special emphasis or eye-catching effects. Another, sometimes even more dramatic, method of catching the viewer's eye is to have the message flash on and off, or blink. There is no simple command in Atari BASIC to produce this effect, but the key to producing it lies in the register, maintained by the operating system, called CHACT (Dec-755, Hex-2F3). If bit 1 in this register is set true, inverse video characters are displayed in inverse video; if it is set to zero they are displayed normally. However if bit 0 is set true, these characters are displayed as blank spaces (inverse video or normal blanks depending on bit 1).

Looking For A Faster Solution

With this information we can write a program that will produce blinking characters on the screen. (Program 1). The trouble with this approach is that our BASIC program is completely preoccupied with timing loops and toggling bit 0 of CHACT. If we try to incorporate this method in a program that does anything else, the timing problem gets very difficult, if not downright impossible. What we really want is a routine that will sit in the background and toggle bit 0 of CHACT on a regular basis without interfering with any BASIC program that might be running at the time. Fortunately the Atari has in it the resources we need to do just this.

The Atari operating system maintains five separate timers which are incremented or decremented during every vertical blank period (the period between successive TV picture frames during which the screen is dark). One of these, called CDTMV2 (Hex21A) is a two byte down counter that can be set to any value between 1 and 65535. Every 60th of a second, during vertical blank, the operating system reduces this number by one and, when it counts to zero, initiates a subroutine jump to the address that it finds in the two byte vector CDTMA2 and returns to the operating system, waiting for the next time the counter counts down to zero.

Program 2 achieves this result by poking a machine language program into memory starting at page 6 (Dec1536, Hex 0600) and transferring control to it via the USR function. Since the operation of this program is obvious, we will spend no time discussing it. Rather, we will turn our attention to the assembly language version of the program that does all of the work, Program 3.

Lines 20-30: Identifies the hex locations of the names times and registers.

Lines 50: Starts the program assembly at location hex 0600 (decimal 1536).

Lines 60-130: Initialize jump vector and start timer.

Line 60: Pops one number off the stack. This is required by the USR function; the routine will work without this step, but you will get an Error-9 on return to BASIC.

Lines 70-100: Stores the address of the routine that begins on line 140 in the subroutine jump vector CDTMA2.

Line 110-120: Stores a number in the timer, CDTMV2, to get it going; the number itself is arbitrary.

Line 130: Return from initializing subroutine.

Line 140: Start of subroutine that does the blinking; load the register CHACT into the accumulator.

Line 150: AND the accumulator with the number one, turns off all bits except bit 0.

Line 160: EOR—exclusive OR the accumulator with the number one; reverses the state (toggles) of bit zero.

Line 170: Stores the result back into the register CHACT.

Line 180-190: Resets the timer CDTMV2 at 30 (½ sec.).

Line 200: Return from blink subroutine.

This program, in machine language, is contained in the string of numbers in the DATA statement, line 50, of the BASIC in Program 2. A few of the numbers are readily identified and can be changed by the user to obtain different effects. First of all, the last #30 in the list (the 29th number) is the number that is loaded into the countdown timer each cycle. It determines the delay time between each jump to the toggling routine and hence the blink frequency. Since the counter is decremented every 1/60 of a second, loading 30 in the timer causes the characters to be on for ½ second and blank for another ½ second. This number may be changed by the user to be anything between 1 and 255 to make the blink frequency anything between 1/30 of a second to 8½ seconds.

See For Yourself

The two ones in the list, the 22nd and 24th numbers are the ones that are AND'ed and EOR'ed against the contents of CHACT. Changing the first one to 23 leaves inverse video on during the blanking. If both ones are changed to threes, inverse video is on when the characters are on, but the blanks are normal. Changing both ones to twos causes the characters to alternate between normal and inverse video. Finally putting fours in place of the ones produces an effect that you will just have to see for yourself; I still haven't figured out a use for this one.

Once the BASIC program has been entered and run, it may be erased by typing NEW, (RETURN), and entering a new program and the flashing will continue (the flashing will stop during I/O to or from a disk or cassette since stage two vertical blank processes are suspended during I/O operations). System Reset will stop the flashing and bring back inverse video; however, merely typing A = USR (1536) (RETURN) will reinstate the flashing characters without having to reload and run the BASIC program.

This program may be added on to almost any other BASIC program to produce the flashing characters and should add some new twists to your special effects.