Compiled by Todd Heimarck, Assistant Editor
Who hasn't felt the thrill of finding a new programming technique that's a little faster, takes less memory, or somehow seems to be a more elegant way of doing things? Here are a few such techniques discovered by readers of COMPUTE! and COMPUTE!'s GAZETTE. For Commodore 64, VlC-20, and PET.
Random Access DATA Statements
DATA statements are a handy way of feeding information to a program. You don't have to fool around with opening, reading, and closing tape or disk files. The information you need is right there in the program, waiting for a READ statement.
But there are two disadvantages to using DATA. First is that the program reads each item only once. After you use a piece of data, you can't go back and read it a few more times. Second is that, like tape files, DATA statements are sequential. You begin at the beginning and end at the end. Try to go past the last item and you get an ?OUT OF DATA error.
Of course, there is a way to solve the first problem, RESTORE resets the data pointer to the beginning of the list. RESTORE isn't too flexible, though. What we really need is a command to go back to a specific line number, like RESTORE to 1000. Some versions of BASIC, such as Atari BASIC, have this feature built-in.
Here's a way to do almost the same thing, with just a couple of POKEs:
POKE65, PEEK(61) : POKE66, PEEK(62)
This resets the DATA pointer (at locations 65 and 66) to the current position of the program counter (at locations 61 and 62, also used for the CONTinue command). In other words, it tells the computer, "Please start reading right here."
If you want to play a specific tune encoded in the DATA lines, for example, you would make the POKEs the first line in a subroutine, followed by the DATA statements and the READ, POKE section. (Note to PET users: Depending on which ROM you have, the technique is the same, but the zero-page locations will be different—62, 63 and 58, 59 for BASIC 4.0 PET/CBM machines.)
If you've ever tried to use capital letters or graphics symbols in a REMark, you know it can be frustrating. For example, when you enter:
10 rem Designed by Frank Dow
What you see after LISTing is:
10 rem str$esigned by ascrank str$ow
The computer interprets the shifted letters as BASIC tokens and prints them in full. Sometimes this quirk can be useful (SHIFT-L is interpreted as SYNTAX ERROR and stops people from LISTing past the line containing it), but usually it's annoying. A simple way to get around the problem is to enter quote mode. After the REM, type a quotation mark. The rest of your message will appear as you typed it, graphics and all.
Embedded Carriage Returns
Hla T. Thein
It's common knowledge that a carriage return is built into the PRINT statement unless you follow it with a semicolon or comma. To print three different things on three different lines, you would have to use three PRINTs:
10 PRINT "QUICK" : PRINT "BROWN" : PRINT "FOX"
But most people don't know there's a way of embedding carriage returns in a string. First type this line:
10 PRINT "QUICK BROWN FOX"
If you run the program, everything goes on the same line. Now list the program and cursor up to the space between QUICK and BROWN. Press RVS ON (CTRL-9) and type a SHIFT-M. Move the cursor right and do the same thing between BROWN and FOX.
The program now thinks there is a SHIFT-RETURN between the letters, and it will print the words on three different lines. Note that this trick also affects the way the program lists.
(Editor's Note: The two hints above can be combined for some interesting effects. Enter this line: 10 REM". Press RETURN, move the cursor up, turn on reverse, and right after the quotation mark put a REVERSE-SHIFT-M followed by a REVERSE-SHIFT-S. Now try to list line 10. The screen clears. The line is, in effect, unlistable. The SHIFT-M forces a carriage return, which turns off quote mode. The reverse heart then causes the screen to clear. Adding such a REM to every program line can help you hide the listing from snoopy users. You can also include cursor movements with REMarks.)
Machine Language Backup On Tape
A broken or worn-out tape can be a disaster if you don't have a backup. Duplicating BASIC programs is easy enough, but machine language (ML) programs are a headache to copy.
If you have a machine language monitor, and know the starting and ending addresses of the ML program, it's easy to make backups. But what if you don't have a monitor, or don't know where the program begins or ends?
Looking through a memory map suggests an answer. The tape header contains the information we need. And after a LOAD, the header information is stored in the cassette buffer at locations 829–832. BASIC expects to find the program's beginning and ending addresses at locations 43–46. The solution:
- LOAD "program name", 1, 1
- Type NEW
- POKE 43, PEEK (829) POKE 44, PEEK (830) POKE 45, PEEK (831) POKE 46, PEEK (832)
- SAVE "program name" (using a new tape)
Because you've changed the pointers, you'll have to cold start the computer after the SAVE. Either turn it off and then on again, or use the SYS described below.
On PETs, the cassette buffer is in the same place (location 828), but the pointers to the beginning and end of the program may vary.
Saving Wear On The On/Off Switch
A cold start (turning your computer off and then on) quickly clears memory and resets everything. But does it do any harm to the computer if you do it frequently?
The good news is, it doesn't do any significant harm to the circuits or chips, although it does cause minimal wear to the power switch. One way to do the same thing is to use this line: SYS 64802 (VIC), SYS 64738 (64), SYS 64790 (PET/CBM). After entering this line, you should see the usual opening message.
This can be a useful way to end a game—for example, if the user answers no to PLAY AGAIN (Y/N)?—or to reset the computer if you are working with custom characters or a high-resolution screen.
There are a few things which may not be reset. If you have POKEd 128 into 650, to make the keys repeat, you will find that the keys still repeat after the cold start.
Slightly different from the cold start SYS is a warm start SYS, which preserves the pointers to the beginning and end of memory.
If you have partitioned a section of memory to be used for custom characters or machine language, SYS 58232 (VIC) or SYS 58260 (64) will simulate a warm start. If you want to set the pointers before this SYS, POKE the beginning of BASIC (in low-byte, high-byte format) into 641 and 642, and the top of BASIC into 643 and 644.
One more tip: Certain televisions, when connected to a VIC, display a wavy, jumpy picture. I've discovered that POKE 36864, 133 corrects the problem, although RUN/STOP- RESTORE causes the picture to start bouncing again. Zenith TVs seem to be most affected by the bouncing.
Shawn K. Smith
On the VIC and 64, locations 774 and 775 contain a vector pointing to the LIST routine. If you change the values with a POKE, the program in memory becomes unlistable. What I do is POKE 774,255. It's a good idea to use a PEEK to learn what number should be in address 774 in case you want to reenable the LIST command.
If a program containing the POKEs is loaded, but not run, it can be listed, so this method can be circumvented. But in combination with other tamperproofing methods (like REM SHIFT-L, described above), you can keep most prying eyes out of your programs.
If you look at a good memory map, you can find some other useful vectors in the same area of memory. Locations 808 and 809 point to the STOP routine (called when unshifted RUN/STOP is pressed); put some new values there and you can disable the STOP key.
Defining A Joystick Function
DEFine FuNction can be very useful in a program that frequently reads the joystick. For example, to read the joystick in port 1 of the Commodore 64, use DEF FNJO(Y) = 15 -(PEEK (56320) AND 15).
To make it even easier to use, combine it with the ON-GOTO command:
10 DEFFNJO(Y)= 15 - (PEEK (5632O) AND15) 20 ON FNJO(Y) GOTO 50, 60, 20, 70, 30, 30, 30, 80 30 GOTO20 50 PRINT"NORTH" : GOTO 20 60 PRINT"SOUTH" ; GOTO 20 70 PRINT"WEST" : GOTO 20 80 PRINT"EAST" : GOTO 20
To include the fire button, define a separate function, or change every 15 in the function above to 31.
Since a defined function can include PEEKs, you can take this idea a step further and use it to check current screen position, watch for collisions, or read the jiffy clock.