1571-4.TXT rev 1 96-11-12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * THIS DOCUMENT IS COPYRIGHT (C) 1988, 1996 BY HERNE DATA SYSTEMS LTD. THE MATERIAL CONTAINED HEREIN MAY BE FREELY USED FOR PERSONAL INFORMATION ONLY. IF YOU REPRODUCE IT, THIS COPYRIGHT NOTICE MUST NOT BE REMOVED. THIS MATERIAL MAY NOT BE EXPLOITED FOR COMMERCIAL PURPOSES. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Herne Data Systems Ltd., PO Box 250, Tiverton, ON N0G 2T0 CANADA. Voice/fax 519-366-2732, e-mail herne@herne.com, internet: http://www.herne.com * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Batch File Programming on the C-64 and C-128 SYS 65478 seems like an innocent and well documented routine. Opening a file as an input channel. What could be simpler? While this may be its normal use from within a program, the KERNAL CHKIN routine can be put to some much less obvious uses in immediate mode. One of the more interesting of these enables a Commodore 64 or 128 (and other CBM machines with a similar KERNAL structure) to execute a series of commands contained in a disk file, similar to an MS-DOS batch file or a CP/M submit file. The CHKIN routine resets the input device flag (normally 0 to indicate the keyboard) at zero page location hex $99 (on the VIC-20, C-64 and C-128), or $98 (on the Plus/4 and C-16) to a value coresponding to the device from which normal input would be received. The main BASIC immediate mode input loop checks this location before trying to fetch an input byte. If the value is 0, a normal entry occurs by fetching a byte from the keyboard buffer. However, if the value is 8, for example, the fetch routine will attempt to read a byte from serial port device 8 (usually a disk drive). If device 8 has an open file capable of giving output, a byte is read from this file and placed in BASIC's input buffer, just as if it had been entered from the keyboard. If a carriage return is encountered, the commands contained in the input buffer are executed, assuming there is no line number at the beginning. Thus you can execute commands contained in a disk file. It should be noted that even with normal input redirected to respond to an external device, the keyboard is still scanned by the IRQ interupt handling routines and the results placed in the keyboard buffer only, up to the maximum number of characters allowed for the buffer. BASIC's input editor will not see any of these characters until control has been restored to the keyboard. To avoid confusion, I call this type of SEQ file a sequential disk command (SDC) file. The procedure for using an SDC is not the same thing as LOADing and RUNnig a disk PRG program file. There are several major differences: A regular PRG type file contains a series of tokenized BASIC lines (complete with link addresses and line numbers) or machine language op codes (see the section in chapter 7 on PRG files for a full description). The sequential disk command file, on the other hand, contains a series of immediate mode commands written out in plain English, just as you would type them in from the keyboard. In addition, a PRG file must be resident in RAM for execution. In most 8 bit computer operating systems (Commodore KERNALs included), only one program can be in memory for execution at a given time (assuming that you have not artificially partitioned the memory into separate work spaces.) A SDC type program is not memory resident! It resides entirely in a disk file and is called up and executed statement by statement, without affecting any program(s) stored in the computer's main RAM unless you deliberately want to. However, since it resides on disk, a SDC program may take longer to execute than a RAM resident program because of Commodore's notoriuosly slow disk access speeds. SDC's are useful as utility and easy to use reference data files since they can be called up and executed without fear of erasing main computer memory. This allows a programmer to interupt work, call up and consult an on-line data table, for example, and then resume the task at hand, all with relative ease and speed. SDC's can also be used for storing customized keyboard macros. (For those unfamiliar with the concept, a keyboard macro is an oftem lengthy and/or complicated series of frequently used keystrokes/commands that can be automatically invoked by using a shorter, easier to remember key sequence.) These can be very useful for setting up sprites, sound and graphics on older CBM machines such as the C-64 which lack hich level commands for doing so. (Can you honestly remember the POKE sequence to play the first few bars of HAPPY BIRTHDAY on the C-64?) Setting up an SDC A sequential disk command file is very easy to create. You use your favorite word processing program to create a SEQ file containing a series of immediate mode BASIC commands, just as you would type them in to execute from the keyboard. BASIC keywords (such as PRINT) can be entered in either their long or abbreviated forms. Of course, the same limits on line length as for normal programming apply to the lines in your SDC file (e.g. 80 characters for the C-64, 160 characters for the C-128, etc). This is a restriction imposed by the size of the input buffer on the computer. Any immediate mode command can be used except for disk access commands. You should not use OPEN, LOAD, SAVE, DIRECTORY, etc. because these commands will reset the input device to the default keyboard value after they have executed, thus cutting off the rest of your command file. A DIRECTORY can be used as the last item in an SDC because it will return control to the keyboard upon excution which is desirable in this case. The program mode only commands, such as INPUT, GET, GOTO, GOSUB, etc., cannot be used in SDC's because an SDC is executed in immediate mode not under program control. Line numbers should not be used in SDC's (except on the C-128 where they provide a different effect as outlined later). In order to be properly interpreted when they are read in, the BASIC keywords must be typed in a style that allows them to be saved as un-shifted PETSCII characters in a disk file. (This is the way that you would normally enter them from the keyboard.) With most word processors, this means that they are typed in lower case only and the file is saved as a SEQ file. Word processors which use PRG type screen code files only should not be used for creating SDC's. Making a graceful exit from an SDC back to keyboard input can be somewhat tricky. The easiest way is to include a statement at the end of your SDC which POKEs a 0 value back into the input device flag location described earlier. Simply CLOSEing the disk file from within the SDC or using the BASIC commands END or STOP, will not return control to the keyboard because they do not automatically reset the input device flag. Another way to exit is to include a garbage statement or deliberate syntax error as the last line. Upon reaching such an error, the SDC will crash and control will be returned to the keyboard. The least elegant way to exit is by the familiar / key combination. Crude but effective. Once the SDC has been entered, it should be saved as a SEQ disk file with an appropriate name. Executing the SDC Now comes the fun part. Executing the SDC is really quite simple. All that is required is to open the disk file in immediate mode with a statement such as: OPEN 1,8,8,"filename" Second, you must activate the CHKIN routine. On the C-128, with the above OPEN statement you would use: SYS 65478,0,1 With a C-64 or similar type machine, a double statement is required: POKE 781,1 followed by: SYS 65478 This latter technique is also applicable to other Commodore machines which lack BASIC 7.0's enhanced SYS command. Of course, the 781 should be replaced by the appropriate memory location for the X shadow register on other machines. The commands in the SDC will then be executed, one line at a time until control is returned to the keyboard by one of the methods previously outlined. You will note that the actual commands are not printed to the screen before they are executed, but the "READY." message is printed after each line has been executed. Once the SDC has finished executing, the disk file should be closed with a DCLOSE or CLOSExx as applicable for your machine. Example SDC's The following are some short examples of SDC's. While it may appear that some of the statements are repetitive, it should be remembered that they were created with a word processor. (If your word processor does not have cut, paste and copy commands, then perhaps it is time to splurge for a new one!!) The first example is for the C-64 or C-128 (in 40 or 80 column mode) which prints out a simple calendar for the month of January 1987. You will note that most of the lines begin with the sequence "PRINT UP$". "UP$" is defined in the first line as three cursor ups. This allows you to get around the nasty habit of immediate mode BASIC of printing a few carriage returns and a READY after each line it executes. UP$ is included to properly format the screen display in this case. Note also that special control characters are given as their CHR$() values. This is the only way to enter them with a word processor. UP$=CHR$(145)+CHR$(145)+CHR$(145):POKE53280,6:POKE53281,6 PRINT CHR$(147)CHR$(5); PRINT UP$" JANUARY 1997" PRINT UP$" SUN MON TUES WED THUR FRI SAT" PRINT UP$"+----+----+----+----+----+----+----+" PRINT UP$" 1 2 3 4 " PRINT UP$"+----+----+----+----+----+----+----+" PRINT UP$" 5 6 7 8 9 10 11" PRINT UP$"+----+----+----+----+----+----+----+" PRINT UP$" 12 13 14 15 16 17 18" PRINT UP$"+----+----+----+----+----+----+----+" PRINT UP$" 19 20 21 22 23 24 25" PRINT UP$"+----+----+----+----+----+----+----+" PRINT UP$" 26 27 28 29 30 31 " PRINT UP$"+----+----+----+----+----+----+----+" POKE 153,0 This next example will print out a handy hex-dec conversion chart on the 80 column screen of the C-128. It is similar in nature to the above example, but works in C-128 FAST mode. The 80 column screen is required because of the width of the table. UP$=CHR$(145)+CHR$(145)+CHR$(145):PRINT CHR$(147)CHR$(5);:FAST PRINT UP$" HEX-DEC CONVERTER" PRINT UP$" 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" PRINT UP$"+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+" PRINT UP$" 00 : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" PRINT UP$" 10 : 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31" PRINT UP$" 20 : 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47" PRINT UP$" 30 : 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63" PRINT UP$" 40 : 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79" PRINT UP$" 50 : 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95" PRINT UP$" 60 : 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111" PRINT UP$" 70 :112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127" PRINT UP$" 80 :128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143" PRINT UP$" 90 :144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159" PRINT UP$" a0 :160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175" PRINT UP$" b0 :176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191" PRINT UP$" c0 :192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207" PRINT UP$" d0 :208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223" PRINT UP$" e0 :224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239" PRINT UP$" f0 :240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255" PRINT UP$:SLOW:POKE 153,0 The final example is interesting for several reasons. It is essentially a self contained data file which can read and display itself on the screen automatically! The WAIT and POKE values of 208 in the lines are set up for a C-128. For a C-64, change all of the 208's to 198's. This is the location of the keyboard buffer flag which indicates the number of characters in the buffer. The file will display one entry at a time and wait for you to press a key before displaying the next entry. (Remember, the keyboard scan and buffer filling still occurs when a SDC is being executed even if its input is ignored by the BASIC input routine, hence the need to clear the buffer by POKEing a 0 to it before reading the next entry.) To stop the display before it reaches the end, a / should be used. This last example demonstrates that although you cannot read the keyboard directly with GET's, INPUT's, etc, you can still obtain data from the keyboard via direct PEEK's and POKE's to the keyboard buffer areas. UP$=CHR$(145)+CHR$(145):PRINT CHR$(147)CHR$(5); PRINT UP$" MINI PHONE FILE ":PRINT PRINT UP$" NAME: JOHN DOE PHONE:123-456-7890" WAIT 208,1:POKE 208,0 PRINT UP$" NAME: JANE SMITH PHONE:123-456-7890" WAIT 208,1:POKE 208,0 PRINT UP$" NAME: FRED BLACK PHONE:123-456-7890" WAIT 208,1:POKE 208,0 PRINT UP$" NAME: JACK & JILL PHONE:123-456-7890" WAIT 208,1:POKE 208,0 (ETC. more names and addresses) POKE 153,0