********************************************************************* This article is being presented through the *StarBoard* Journal of the FlagShip/StarShip SIGs (Special Interest Groups) on the Delphi and GEnie telecommunications networks. Permission is hereby granted to non-profit organizations only to reprint this article or pass it along electronically as long as proper credit is given to both the author and the *StarBoard* Journal. ********************************************************************* [ED. NOTE: This is LYLEG'S final article in his multi-part series on a Sequential File Reader. Included in this issue of the *StarBoard* Journal is the full PAL source code and the object code. Load Object Code,8,1 and then SYS49152 to use. If you haven't been following along for the last few months, be sure to go back and retrieve his earlier articles. They are excellent! ********************************************************************* MACHINE LANGUAGE PART VII by Lyle Giese (LYLEG on DELPHI) It looks like this month we will finish up the Sequential File Reader. So what will I do next month? Let me know what YOU want written about. I really want to write about something that will interest you, and the best way to do that is to tell me! My DELPHI username is LYLEG, and if you are on Genie tell deb! and she will forward the comments to me. When we left off last month we just opened the file to be read and now are ready to decide if we want to send it to the printer or the screen. Of course, we first print a message to the screen asking Screen or Printer? In line 1280, we get a character from the keyboard (if there is one, remember this routine will a CHR$(0) if there are no keys pressed). We check for an "s" for the screen. If we found one we JSR to the screen setup routine. If not we check for a "p". Let's look at the 'OSCR' subroutine starting at line 6500. Why are we opening a logical file for the screen? Doesn't the Programmers Reference Guide say it is not needed? Yes, that is true. But our output routine will need to be able to send to the screen or the printer. The printer needs the logical file to be there. So it can be easier to send the output to a logical file rather that decide for each character how to send it, depending on the output device selected. Of course, we could have written two output routines. Then every time we sent a character, we would have to check and see which output device was selected and branch to the proper routine. Ok, now if we want to send our file to our printer we will go to line 6000 for the PRINTER subroutine. There we ask what device number we are going to use. Here (in lines 6060-6090) we limit the device number to 4 through 7. After we get the device number we convert it from PETSCII to the number we must use for the SETLFS routine. Next we can select the secondary address within the limits zero to nine. I limited myself to this range to make the routines here simple. Again, we have to convert from PETSCII to the number to be used for the SETLFS routine. Now we can open the logical file. For a printer channel, we don't need a file name and set the length of the filename to zero and finally JSR OPEN. Why don't we check the printer file the same way we did the disk file? Well, first of all, nothing has been sent to the printer yet. Until we open the output channel (JSR CHKOUT) the secondary address and the listen commands are not sent. At that time is when we find out if the printer is not there, when the program hangs up (depending on the printer and interface). Finally we are getting to the heart of the whole thing! Read a character and send it to our output device. First (in line 1400-1410) we open an input channel to the disk drive. And then we try to get our first character from the disk drive. Some of CBM's DOS routines (depending on the type of drive) will send several null bytes before sending the first byte of the file, and here we trap them. Next we must store that character as we must read the status byte and store it also. Now here is where I made the routine "generic", by loading up the byte representing the outfile and opening an output channel to it. At this point we could care less if the output device was the screen, printer or even a disk drive (of course we would have to write a different subroutine for opening an output file on the disk drive.) In line 1490, we are checking for a successful opening of the output channel. If the channel is not openning, I do a CLRCHN (restore default I/O) and try again. Why? I had quite a bit of trouble with this routine locking up when sending a file to my printer until I put lines 1490-1530 in. It seems that my printer interface could not keep up with the rapid opening and closing of channels on the serial bus. It would miss the JSR CHKOUT in line 1480 once in a while. Then in line 1550, CHROUT assumes the channel is properly opened and will crash your program. This one place where the PRG misses an important point. If you look at the description of CHROUT on page 278-279 (of the PRG for the C-64), they miss that little detail. And of course I put in a way to break out of this loop in case the printer realy wasn't there (lines 1510-1530). Now is the time to check the status byte we stored in line 1460. At this point we are only interested in the end of file bit and use the AND instruction to look at only that bit. If it is not set we will continue on as we have not reached the end of the file yet. I decided that it would be nice to be able to pause the output in order to take time to read the contents of the screen before it scrolls out of sight. Or a way to abort out if we found out this file was not the one we really wanted to look at or if we wanted to just see what the file contained. I used the SHFLAG byte at $028D to see if the Shift key is pressed. This byte is updated by the systems normal IRQ routines. If the shift key only is down this byte holds a value of 1. If the CTRL key is down, a 4 is placed there. And if the logo key is down a 2 is found here. If 2 or more of these keys are depressed the sum of the key values is found there at $028D. As long as the shift key is down (or shift lock), the program will go into a loop rechecking the SHFLAG byte. If the Shift and Control keys are down (for a value of 6), then abort out just as if we hit the end of the file. In line 1650 we jump back to and get another byte for outputing. Now when we finish we have to start closing channels and logical files in line 1680. We have to close the read file before the disk command channel. In this program, it is not as important. But if we were writing to a disk file and closed the command file, that would close ALL open files in the drive, even if we didn't want them closed yet. Next we go after the printer (or screen). On some printers, incoming characters are buffered until the buffer is full or a carriage return is received. So here we send a carriage return to make sure the buffer is emptyed before we close up. Now a message is printed to tell us to press the return key before the program is allowed to start over, which clears the screen. There (if you remember) hitting the return with no character in our filename buffer will exit this program. And that concludes our file reader finally! Next month??? You tell me. PLEASE! Lyle Giese AKA LYLEG