Automatic Commodore Program Selector
Steven A. Smith
Here are several ways to make disks easier to use with the VIC, Commodore 64, or PET/CBM. Are you setting up a business application and want to save users the trouble of working with LOAD and RUN? Are you planning a party and want to avoid spending all your time just showing friends how to run the games? Do you want to save yourself time and trouble in your everyday computing? Try out these various menu programs and see if they wouldn't be useful in many ways.
If you want to be able to choose from among a number of options within a program, one of the best methods available is a menu. The computer displays a list of items with numbers or letters assigned to each, and you press the number or letter corresponding to the option you want. This way, you don't have to worry about which responses are allowed or about how to spell a particular response, and it's much faster.
All this applies to disk drives, as well. Also, someone who is not familiar with the operating system of the computer can call up any of a number of programs without having to know about diskette directories or about LOADing or RUNning programs.
You can choose between two ways of automating program selection from a disk. The first one we'll describe uses specific, pre-defined menus for each diskette or function. The second can be used with any diskettes, determining at runtime which programs are available on the disk.
Pre-defined Menus
A pre-defined menu is written right into the BASIC menu program. Because of this, a new program must be written for each diskette for which you want a menu. However, there are several advantages to using a pre-defined menu. First, it's fast. As soon as you RUN it, the menu program knows what programs should be on the diskette and can go about the business of displaying the menu. Also, you can add program descriptions to the menu screens to show more information about the programs than just their names.
Another, less obvious advantage to pre-defined menus is that you can set up a menu for just a few of the programs on a diskette, have another menu for some others, and have other programs that are not accessed by any menus. This way, you can let someone have access to only the programs that a particular application requires.
Program 1 is a sample of a pre-defined menu for an inventory file maintenance system. Although it is short, it is surprising how impressive it can be in operation, especially to someone who is used to having to load and run individual programs via the traditional directory method.
Lines 120-130 set up an array of program names, one per array element.
Lines 140-230 display the actual menu. The numbers "1" through "8" are displayed in reverse, with a description of the associated programs next to them. The number of items on the menu is not significant — eight just happened to fit well on this menu. Just remember to change your array dimensioning and the error-checking in lines 250-260.
In this menu, the programs are grouped by type of operation to make things clearer for the user. Inventory file operations, transaction file operations, and setup operations are each grouped together and separated from the others by a line. Of course, you can display and group items on your menus any way you wish, remembering to have your item numbers and array elements correspond properly.
Lines 240-260 accept your menu item choice, making sure it is between one and the maximum item number on the menu. On this menu, choice number "8" simply ends the program.
Lines 270-300 are the heart of the menu program. Using the "dynamic keyboard" technique (where the computer enters its own instructions) the computer types the LOAD and RUN instructions on the screen, and then forces RETURNS into the keyboard buffer to make it execute them. For Original ROM BASIC, change line 300 to:
300 POKE 527, 13 : POKE 528,13 : POKE 525,2
To accomplish this "dynamic" effect, you need to POKE a value of 13 into the first two "Keyboard Buffer" bytes, and a value of two into "Number of Characters in Keyboard Buffer." These locations vary on different Commodore machines. For the VIC and the 64, change line 300 to:
300 POKE 631, 13 : POKE 632, 13 : POKE 198, 2 : END
Line 300 in the printed program works as is on Upgrade and 4.0 BASIC PET/CBMs.
This menu program will expect to find a "Library Inventory System" diskette in Drive 1. If you want to use Drive 0, just change the "1:" in line 280 to "0:".
Increasing Menu Items
Nine items can be placed on this menu before it begins to look crowded. There are two ways to improve on this number: the first is simply to use several menus and let each menu chain (call in) the next. You can let one menu item be the next menu program, or add a line:
245 IF A$ = CHR$(13) THEN C$(1) = "MENU2" : A$ = "1" : GOTO 270
This line will call the next menu program (here named MENU2) if RETURN, rather than one of the options shown, is pressed.
While this works quite well, you do have to wait for the new menu to be loaded each time you chain from one to the next. A faster way is shown in Program 2. Several menus can be stored in the same program. By pressing RETURN, you can go from one menu to the next without waiting to load a new menu program. A message is added to the bottom of the screen indicating that you can press RETURN to go on to the next menu. After the last menu is shown, pressing RETURN again will bring you back to the first menu. Of course, going to the next menu could itself be made a menu option, instead of being automatic.
To make menus especially useful to people unfamiliar with computers, you can make the programs called by the menu, themselves call the menu back when they finish. To do this, find where your program ends, whether by an END statement or by reaching the last of the line numbers. Change your END statements to GOTO 62000 and add the following lines:
62000 PRINT "{CLEAR}{04 DOWN}" 62010 PRINT "LOAD" CHR$(34) "0 : MENU" CHR$(34) ", 8{04 DOWN}" 62020 PRINT "RUN" : PRINT "{09 UP}" 62030 POKE 623, 13 : POKE 624, 13 : POKE 158, 2 : END
This assumes that your menu program is named "Menu" and is in Drive 0. As before, change line 62030 for your computer exactly as you modified line 300, to perform the "dynamic keyboard" on your model.
Once you load the menu program, you don't need to worry about loading any more programs. Each time you finish one program, the machine will take you back to your menu. This is why menus are especially helpful for inexperienced operators. A menu also works well at parties – you set it up with games which call back the menu, and you don't have to worry about being around to show people how to load and run their choices.
Fully Automatic Menus
Program 3 is a different method of generating menus, a fully automatic diskette menu. When you run this program, you can put any disk in Drives 0 and/or 1, and it will find out what programs are on the disk and build a menu around them. Although you can't add descriptions to the program names, with diskette files you do have 16-character names to work with, and you can make them quite descriptive.
This method is slower than using pre-defined menus because, before the program can generate the menus, it must read the diskette directory and fill its own array of program names. However, you don't have to write a new menu program for each diskette or change a menu program when you change the contents of a diskette.
The following is a description of the variables used in Program 3:
AE$ | :Filename Array |
AN | :Array Entry Number |
A0 | :Files From Drive 0 |
C$ | :Character Read In |
DE | :Directory Entry |
DR$ | :Drive Number |
ER | :Disk Error Number |
F$ | :Filename Found |
FL | :Filename Length |
I | :Iteration Variable |
J | :Iteration Maximum |
MM | :Maximum # On Menu |
MN | :Menu Number |
Lines 190-210 set up the variables and the program name array used by the program. Line 220 initializes the diskette in the drive currently being checked. Although the 4040 and 8050 diskette drives do not need to be initialized, this sets things up for line 230, which checks to see if a diskette was found in the drive. If not, the program goes over to the other drive.
Lines 240-250 are in the program mostly to let you know something is happening. While the program is reading the diskette directory, it lets you know how many programs it has found on that drive.
In lines 260-390, the diskette directory is opened and read as a sequential file. After skipping over the directory header, each directory block of eight file entries is checked for programs until the last entry is reached.
Line 310 skips entries which have their first byte equal to anything other than 130. That would indicate that the file was not a program file. You could use this line to create menus which displayed only USR or SEQ files if you wished. Line 330 puts the program name into string F$. Line 340 keeps the "Universal Wedge" DOS Support program from showing up on the menus. This line can be deleted if you wish. Line 350 updates your screen to tell you how many program entries have been found, and line 360 puts this program name and drive number into the array of filenames found. Lines 370-380 then read past the proper number of bytes to be ready to read in the next file entry.
Lines 410-420 finish up the work with one drive and switch to the other, if necessary. If no programs are found on either drive, the program ends here. Otherwise, the first menu is ready to be displayed.
Entering Your Choices
Line 440 prints the menu heading. The heading will include a menu number starting with "1" and going as high as necessary to show all of the program names found, in groups of nine. Line 450 checks to see if there are enough program names left in the array to display nine menu items. If not, the menu is shortened. Line 460 displays the menu item itself, and lines 470-480 display the messages at the bottom of the screen.
Lines 490-530 check for your choice of menu item. It must be between "1" and the maximum number on the menu, or it can be RETURN, in which case the program will display the next menu. If there are no more items in the program name array, the first menu is redisplayed.
If the key you pressed was one of the menu items shown, the program continues to line 540. Variable AE$ is now the drive number, a colon, and the 16-character name of the program you have chosen. Any blanks in the name are stored in the directory as shifted spaces, with an ASCII value of 160.
Lines 560-580 check to see how long the program name is by looking backwards from the end for the first character that is not a shifted space. When one is found, variable FL contains the length of the name plus the drive number. Then, the LOAD and RUN instructions are displayed, and the keyboard buffer is POKEd with RETURNS to load the chosen program, just as in the pre-defined menu programs. Line 600 of Program 3 should be modified as before for the "dynamic keyboard" appropriate to your model.
Using these programs with the 2020 disk drive requires no changes. Using them with the 8050 drive requires only one change in Program 3. Change line 230 to:
230 IF DS = 21 THEN 400