A schizophrenic picture viewer
by Charles F. Johnson
Charles F. Johnson is a professional musician and, now, a semi-professional computer programmer/reviewer/author. He lives in Los Angeles with his wife Patty and Spike, the world's most intelligent cat. Charles is a SYSOP on the ANALOG Publishing Atari SIG on Delphi; his user name is CFJ.
The first demonstration I ever saw on an Atari 520ST was a slideshow of pictures created with the Neo-Chrome drawing program. I was fascinated by the sharp 16-color graphics of the ST's low-resolution mode—I still am. I now have a collection of over 500 pictures drawn by ST artists from all over the world; and I suspect I'm not alone, judging from the number of pictures in the download sections of most BBSs and information services.
Art Gallery is a GEM desk accessory written in 68000 assembly language, using the AS68 assembler and "AS68 Helper" (ST-Log issue 12). I wrote Art Gallery because all the picture display utilities I had come across were in slideshow form. Now, slideshows are very nice for impressing the friends and neighbors, but I found that many times I wanted to look at just one picture; it got tedious to wait through all the other pictures on a disk to see the one I wanted.
I decided to write a program to show individual pictures saved in the formats used by the popular ST drawing programs, DEGAS and Neo-Chrome. I also chose to make it a desk accessory, so I could easily view pictures without leaving any GEM program (such as 1st Word, DEGAS Elite, or Flash). This turned out to be a fairly simple task, since both DEGAS and Neo-Chrome save pictures in a straightforward manner—they just copy the screen memory area to a disk file, along with color information and (in the case of Neo-Chrome) some other data. I then threw caution to the winds and also decided to show pictures saved in the popular public domain Tiny compression format (written by David Mumper), since many bulletin boards and services like Delphi, CompuServe, and GEnie feature pictures in this format. Here, I ran into a slight snag.
The only documentation I had for the Tiny compression format was an inaccurate and mistake-riddled text file captured from a local BBS. After attempting for some time (with change the drive being accessed by editing the directory line in the File Selector. Click on the filename of the picture you wish to load and click the "OK" box (or just double-little success) to translate this into workable code, I ran across a sample of C code that Tom Hudson had uploaded to CompuServe, for loading Tiny pictures. This code helped to fill in the gaps in my understanding of the Tiny format, and I was able to finish the decompression routine quickly after that. I haven't used Tom's code directly in this program, but I thought it only fair to mention it, since I had one wheel in the sand before coming across it. Thanks, Tom!
Using the program
Load ST BASIC and type in Listing 1, then check your typing carefully with "ST-Check". When you run the BASIC program, it will create a file on drive A called ART-GALRY.ACC. You can change the drive the program gets written to by changing filename$ in the first line of the BASIC program.
To install the Art Gallery accessory, just copy it to the main directory of your boot disk, or drive C for hard disk users. The next time you boot the ST, Art Gallery will load and be available from within any GEM application that uses drop-down menus. Just click on its name in the "Desk" drop-down menu. The screen will clear, and then you'll see the Art Gallery dialog box in its center. There are four buttons in the box, labeled in what I hope is a self-explanatory manner. Click on the appropriate buttons to display DEGAS or DEGAS Elite pictures (compressed or uncompressed), Neo-Chrome pictures (disabled in high resolution), or compressed Tiny picture files. The button marked EXIT will, of course, send you back to whatever you were doing.
Clicking on any of the buttons except EXIT will cause a GEM "File Selector" box to appear. The operation of the box is the same as in any other GEM program. You can click on the filename), and you'll be looking at that picture before you can say Vincent Van Gogh!
If you load a DEGAS Elite, Neo-Chrome, or Tiny picture that has color rotation information, Art Gallery will display the animation; if it's a DEGAS Elite picture, Art Gallery will display all four of its animation channels. When you wish to load another picture, just press the left mouse button once, and the File Selector will reappear. Click on "Cancel" to return to the main dialog box.
When you leave Art Gallery, the program that was running will redraw its screen area (assuming it's a properly written GEM application, of course) and you can continue from wherever you were. The Gallery is handy with a GEM-based terminal program; you can download pictures from your favorite BBS and have a look at them without ever leaving the terminal program. Instant gratification—isn't that the American Way?
The schizophrenic program
That's right, Art Gallery is a program with a severe identity crisis; it can't decide if it wants to be a program or a desk accessory. Instead, it seems to have come to terms with its psychosis and solved the problem by being both! If you name it with an extension of .ACC, as explained above, it will load and run as a desk accessory. But, if you give it a .PRG extension, the same file will work quite happily as a program you can run from the desktop. The subject seems well adjusted, despite its obvious schizophrenia.
To understand how this trick works, you need to know a little about the differences between accessories and programs. When GEMDOS (the part of TOS that deals with disk file manipulations and memory allocation, among other things) loads a program, it allocates the entire available RAM space for the use of the program.
The first thing the program must do is release back to GEMDOS the memory it doesn't need. Otherwise, since your program is greedily hogging all the RAM, operating system functions that allocate RAM for their own purposes will fail. The GEMDOS Mshrink() function is used to release back to GEMDOS the unused memory (the Abacus books call this function SETBLOCK). However, in the case of an accessory, TOS takes care of little details like this for you. All your accessory needs to do to be properly initialized is set up some stack space of its own and put that address in the 68000's stack pointer.
Another difference: a program usually exits by calling one of the GEMDOS terminate functions, which normally pops you back to the desktop. An accessory, on the other hand, never exits. When inactive, an accessory is sitting in an AES event call, waiting for you to select it from the "Desk" dropdown. When the accessory is closed (exited), it just goes back into that event call again; the GEMDOS terminate functions are never used.
With this info in hand, we can see how a program could run as either .ACC or .PRG... just check and see which extension it has, and branch around the unnecessary code. But another problem comes up when you try this: you could search the current disk directory for the filename of your program, but what if the user has renamed it? You won't find the name you're looking for!
The solution to this dilemma lies in a little-documented AES call, shel__read. This call will return the name of the currently active process; in other words, the name of your program. So, if the user has renamed ARTGALRY.ACC to ARTSTUFF.ACC, you'll still be able to tell whether it has an extension of .ACC or .PRG. Take a look at the source code for Art Gallery to see how this is done.
This technique can really help during the development process, since accessories can be quite difficult to debug. No debugger for the ST (that I know of) lets you run and trace through accessory code, so being able to test and debug a file as a program until you're ready to make it an accessory is a definite asset.
I hope you enjoy Art Gallery. If you're a programmer, take a look at the source code for some valuable hints on using the vertical blank interrupt, object trees, and other GEM structures, directly in 68000 assembly language. I included all the object trees in the source code instead of using an external .RSC file, because of a GEM bug that isn't very widely known. If an accessory loads a resource file created with the Resource Construction Set, it will keep stealing memory every time the screen resolution is changed with the desktop's "Set Preferences" option. This is because GEM doesn't release the memory allocated for an accessory's resource file on a resolution change. Therefore, the best practice is to always include object trees directly in an accessory program.