Printing Graphics from the XEP-80
Printing Graphics from the XEP-80
Jeff McWilliams, AC Staff Columnist
The title of this column aptly describes my computing environment. As a full time engineering student and Dad, most of my Atari tinkering occurs in the dark hours of the night, or on weekends. "Moonlight Workshop" will be a sort of tinkerer's workbench for Atari Classics. What you'll mostly find here are little programs, utilities, and hardware projects for your computer. The column will be centered around solving little problems to make 8bit computing easier.
A variety of languages will be used, including BASIC, Action!, maybe C, and every now and them some assembly language. The sophistication level will vary from beginner to slightly advanced, but I'll make an effort to present "Moonlight Workshop" so that everyone will get something out of each installment, no matter what their level of computer knowledge.
Additionally, "Moonlight Workshop" will serve as your Question and Answer resource. If you have a problem with your 8 bit, send it in by U.S. mail or electronic mail. I'll use my knowledge, that of my fellow Atari Classics staff cohorts, and others in the Atari community to try to solve your problem as much as possible. A challenging problem could provide the basis for the entire topic of discussion covered in that installment of "Moonlight Workshop"-of which this month's installment is a perfect example!
There's this fancy BBS thing called the Cleveland Atari Freenet. [Internet users can access the Freenet by Telnetting to freenet-in-a.cwru.edu. The IP address is 22.214.171.124. Non Internet users can dial into the Freenet with their modems at (216)368-3888. Get to the Atari SIG by typing "go atari" at any menu.] The sysop of the Freenet is a colorful fellow named Michael Current. One day Michael posted the following message in the Atari 8-bit SIG of the Freenet:
"This spring for my Computational Physics class special project I did some programming and graphing on my 130XE. Since a poster presentation was required, I needed hardcopies of the graphs I produced. Simple, right? Not in this case. My Epson LX-810 is about as standard a 9-pin dotmatrix parallel printer as you can get, but my lone printer interface is the XEP-80 Interface Module.
"This alone is annoying because I can't print anything unless I have that XEP80HAN.COM file loaded. Most of my printing I do from AtariWriter80, so I already have the handler loaded. But now I had to load the handler, then use a special BASIC XIO command to return to the ANTIC display so I could print through the interface at the same time as I had a GRAPHICS 8 screen displayed.
A plea to "comp.sys.atari.8bit" on Usenet resulted in a couple different codings in BASIC for dumping a GRAPHICS 8 screen to the printer. But they each froze the computer before the printing began! After many frustrating re-boots of the system I learned that once the XEP-80 handler is loaded, the act of entering any graphics mode of 6 or higher will cause a system lock-up. Problem identified.
"I had two choices. One was to get a normal printer interface like the ICD P:R:Connection, so I could print any time I want to. I may get around to doing that someday. But with the presentation date fast approaching, I found a good work-around. Instead of dumping right to the printer, I adjusted my BASIC code to PRINT to a data file instead. So I could run my program, save the graph to a file, go to DOS, load the XEP-80 handler, then COPY the data file from disk to printer. A convoluted but effective graphics screen dump. Project saved. Michael Current."
XEP-80: WHAT Parallel Port?
There are probably quite a few people who bought an XEP-80 not only for the nice 80-column video display, but also for its standard parallel printer port. Having access to parallel printers opens up a whole new world of productivity for us Atari 8 bit users. Imagine receiving an order from the UPS man, and opening the box to find the XEP-80 you ordered. You tear into the box, quickly scan the documentation, and connect the XEP-80 to your existing 8 bit system. You boot PrintShop and try to print. Nothing happens. Okay, try another printer driver. No luck yet. You check all the cables: everything looks OK. You boot your favorite 80 column word processor and try again. Nothing happens. Eventually, you find the sun peeking over the horizon. And you're still sitting there: annoyed, frustrated, and furious.
Nothing in the ads said the XEP-80 has serious limitations on use of the printer port. If you read carefully through the manual, you'll eventually discover Atari's caveats on using this potentially useful hardware feature. For the computer to recognize the existence of the port, you need to install a "printer handler": a special little executable program that loads into memory. It tells the computer it can access a parallel printer, but that there is a special method that the computer needs to use in order to send data to that device. Unlike the 850 Interface, P:R:Connection, MIO or Black Box, you can't operate the printer connected to the XEP-80 without this handler installed.
Those other hardware interfaces work either by presenting a connection to the printer over the SIO bus (where the computer normally looks for printers), or they automatically load their own printer handler when the computer is turned on. The former applies to the 850 and P:R:Connection, while the latter applies to the MIO and Black Box devices. What makes the XEP-80 different is that it talks to the computer through the joystick port. Although this hardware path is a little odd, the XEP-80 isn't the only device in the joystick-port category.
There was another printer device called the ICEPIC available long ago that worked the same way. Analog Computing also published a do-it yourself printer interface that connected to the joystick port. Why did Atari "cripple" the XEP-80? Compatibility reasons, among other things. The powers that be at Atari decided the XEP-80 should be able to plug into ANY Atari 8 bit (you 400/800 and 1200XL users will appreciate this). The compromise was to connect it via the joystick port.
The printer handler is part of the XEP80HAN.COM file that Michael Current mentioned. On the XEP-80 utility software disk, it's called AUTORUN.SYS. In order to install the printer handler, you need to be able to load it from DOS. With programs like PrintShop-which is already a boot disk-that's impossible. There's currently no way to get a program like PrintShop to print through the XEP-80 because you can't load the handler into memory prior to running the PrintShop program. As Michael related above, even with the handler loaded, printing graphics files can be tricky. If you don't have a working knowledge of your 8-bit and how to do some well-considered programming, you're really stuck. Michael was at least able to program his way around a nasty pitfall that arises from working with the XEP-80.
A Graphics/Printer Handler
I can't make PrintShop print through an XEP-80, but I can show you how your XEP-80 can print those Graphics 8 and 7+ images AND display them on your XEP-80 screen as well. Keep in mind the XEP80 has its own video output jack that connects to your computer monitor. This means the computer now sends two displays, one from the regular 40column display jack on the back or side of your computer, and the second (80-column output) from the XEP-80. Unless you have two monitors, you can't see both displays at the same time. Who wants to print an image you can't view first anyway? Sure would be nice to see it first, make sure it got labelled with the proper filename, etc.
If the program were to display the image on the 40-column output, you would have to switch from your XEP-80 display to the 40-column display in order to view it. If you have Ben Poehland's infamous "80-Column Switcher" ("The 8-Bit Alchemist", Current Notes, April 1991, pp. 12-14) this isn't really a problem, but it can be distracting. Best to just throw the image up on the XEP-80's display.
So, how do you do it? It turns out to be pretty straightforward-but only after I went digging into my Antic Magazine archives. In the October 1988 issue, Matthew Ratcliff shows some sample programs that throw graphics images up on the XEP-80 display. I studied his BASIC program listing and noticed all these mysterious machine language calls imbedded in the program. Matt briefly mentioned what the routines did, but he didn't explain HOW. The method he used to send graphics to the XEP-80 were hidden from the casual programmer by all those machine language routines.
On a hunch, I jumped into BASIC XL and started fooling around with my own BASIC program, following hints in Matt's code. I was amazed when I found out just how easy it is to send graphics to the XEP-80.
A graphic image is held in the memory area of the XEP-80 exactly like a GRAPHICS 8 image is held in the computer's memory. The data consists of bytes placed end-to-end left to right, and from top to bottom, to describe a 320x200 display. This means a GRAPHICS 8 picture file can be loaded from disk and sent directly to the XEP-80 without any manipulation or processing. The hard part is telling the XEP-80 to go into GRAPHICS mode and sending it data. The following steps are required: 1) Load the graphics image into memory, usually into a STRING which is 7680 bytes long. 2) Open an I/O Channel for writing to the "E:" device. (Remember that "E:" stands for screen "E"ditor. This means we're going to talk to the XEP-80, since it's displaying our screen.) 3) Do a GRAPHICS 24 call. (Graphics 24 is a special command for the XEP-80. It tells the XEP-80 to go into graphics mode and prepare for high speed data transfer.) 4) Send the data in the string. We could use something like the following:
10 REM GRAPHICS FILE HAS BEEN LOADED INTO PIC$
20 OPEN #1,8,0,"E:"
30 GRAPHICS 24
40 FOR A=1 TO 7680
50 PUT #1;ASC(PIC$(A,A))
60 NEXT A
70 CLOSE #1
That would work just fine, but it would be really slow. Who wants time to eat their lunch whey they wait for the XEP-80 to display a graphics image? It's quite easy to make the program run much faster by implementing a routine which sends all the data to the XEP-80 in one big chunk. For this I used a machine language routine much like Matt's. This routine does two jobs: it reads graphics data from disk, then sends it to the XEP-80. It and the following graphics dump routine are taken from a book called "BASIC Turbocharger" by Jeff Bader. Sold by Alpha Systems, this book and the accompanying disk offer a wealth of little utilities that make programming much easier. (Hey, I'm not about to reinvent the wheel. If there's some routines already available, and they do the job, I'm gonna use 'em!)
How It Works
The program in Listing 1 should work with any BASIC for the Atari. Look at line #1120: it shows how to call the I/O routine via BASIC's "USR" call. The code has been stored into RW$ at the beginning of the program. After the address of this routine, the next parameter in the USR call is the channel number through which data will be sent. The next parameter tells the routine whether to read, or write, data. RVAL is used for read, and WVAL is used for write. Following this is the address in memory where the data is to be written to or read from. Since we want the data in a string called PIC$, we used "ADR(PIC$)" for this parameter. The last number the routine needs is the length of the file transferred. Both GRAPHICS 8 and GRAPHICS 7+ image files take up 7680 bytes in uncompressed form, so that's the value supplied to the routine.
Lines 1150 through 1170 send the image data-now stored in PIC$-to the XEP-80. Notice these lines follow steps 2 through 4 above. We use almost the same parameters in the USR call as we did for reading the data, except that WVAL us being used in line 1170 instead of RVAL in line 1120.
Lines 1320 through 1360 print the image to the printer by calling the second machine language routine stored in PR$. Before printing the image, I switched the XEP-80 back into character mode. An interesting thing happened when I tried keeping the graphics image on the screen and called the print routine. The lower 1/3 of the display became filled with jarbled dots that shifted as data was sent to the printer through the XEP-80. What this told me was that the XEP-80 has a limited amount of memory, just enough to hold a GRAPHICS 8 image. When you send the XEP-80 data to be passed to the printer, it has to temporarily store it somewhere, so it overwrites part of the screen display to do so. In the USR call that prints the image, BUFFER$ is a temporary storage area that the machine language routine uses for its own purposes. If you replace "CNORM" with "CINV" in the USR call, the picture will be printed white on black instead of black on white.
You'll hear a bell ring after the image is displayed to the screen. Press any key to have the program print the image. If you don't want to print that file, answer no when it asks, and the program will rerun. The program ends when a graphics picture has been successfully sent to the printer. Neat, huh?
Try Some Variations...
If you want to use BASIC XL, BASIC XE, or TurboBASIC XL, you can modify the program as follows: First delete line 1030, and lines 1450 through 1490. Then replace line 1120 with:
1110 BGET #1,ADR(PIC$),7680
and replace line 1170 with:
1160 BPUT #1,ADR(PIC$),7680
Note that the first machine language routine does nothing but add these two commands to standard Atari BASIC.
If you own a 24 pin printer, you can indicate so just before the program prints. This doesn't increase the resolution, it just fixes a vertical spacing problem that occurs with some 24 pin printers.
If you want to write a slideshow sort of program, send multiple images to the XEP-80 as follows: 1) Get the first image; 2) Open channel to "E:"; 3) GRAPHICS 24; 4) Send the image to the XEP-80; 5) Send the contents of EX$ to the XEP-80; 6) Get next image; 7) GOTO step #4.
Look at lines 1010 and 1050: line 1010 sets the length of EX$ to 512 bytes, and 1050 fills it with zeros. Even in graphics mode the XEP-80 has a cursor. When you first enter this mode it's at the top left of the screen waiting for data. After the image is received, the cursor lies at the bottom of the screen. You could close "E:, reopen it, and do another GRAPHICS 24 to reinitialize the XEP-80, but you don't really have to.
In order to get the XEP-80's cursor back at the top of the screen, a 7680 byte image needs to be followed by 512 bytes. There are 200 lines on the XEP80's graphic display. Of those, your standard GRAPHICS 8 picture only uses 192 of them. So this program could be modified to send the picture data, then 320 bytes of data that would make "PRESS ANY KEY" appear just below the picture. (A line is 320 dots wide, divided by 8 dots per byte = 40 bytes per line; 8 lines X 40 bytes/line = 320 bytes.) Then send 192 extra ZERO bytes to the XEP-80, and the cursor would wrap to the top of the screen, ready for the next block of image data. I noticed that while using this method, the cursor that scans across the screen as the XEP-80 draws the graphics image disappears when the second image in succession is being drawn. For each additional image, no cursor appears. Interesting!
If you're using SpartaDOS-X, the handler built into the cartridge called "XEP80.SYS" doesn't work with this program. What you want to do is copy the "AUTORUN.SYS" file from the XEP-80 disk to your SpartaDOS-X main disk, renaming it XEP80.COM. Then type the following at the command line prompt:
Now go to BASIC and run LISTING 1. This method is a little unstable, it may not work for all XEP-80 type programs. If it fails, fall back to either a disk-based SpartaDOS, AtariDOS, or an AtariDOS lookalike, and just use the AUTORUN.SYS file from the XEP-80 disk.
Hopefully this month's topic helped all you fellow XEP-80 users out there. The printing routine isn't the greatest to be sure, but the supplied program can serve as an excellent foundation upon which a more sophisticated XEP-80 print utility can be built.
If you have questions or problems with your 8bit, or you have a comment or suggestion, feel free to write or send me e-mail. I can't guarantee I'll answer every letter, but I'll do my best. With a little luck, I'll see you all here again with another installment of "Moonlight Workshop"!