GEM
IBM to ST
BY MARK SKAPINKER
When Digital Research first introduced GEM, the big drawing card was the ease with which developers could port graphic-oriented software between different processors. Just how easy is it? Mark Skapinker of Batteries included describes his experiences developing "trans-compatible" software for the IBM PC and the Atari ST.
When Batteries Included decided, in March 1985, to develop the ISGUR Portfolio System for MS-DOS using a graphics interface, GEM was the only major graphics system available for the IBM PC. Since we also knew it would become the interface on Atari's new ST computer, GEM was the natural choice for our software development.
THE TEAM
We established an in-house GEM development team in our Toronto offices, consisting of myself; Chris Bailey and Steve Couchman, our software engineers; Keith Hope, hardware engineer; Lloyd Speyer, tester; and Mike Reichmann, president of BI (with a special love for software development). Since the ST was not then available (and would have inferior development tools when it did become available), we decided to create our software on the IBM and port later to the ST. We have since developed- and are continuing to develop - a number of ST GEM applications using the MSDOS / IBM PC environment as a host machine.
Chris Bailey, a hacker at heart, volunteered to dive into the depths of GEM and become the GEM resource person" for both us and our outside developers. To accomplish this, he undertook two projects. First, since some people don't like mice, we wanted our GEM programs to be able to activate drop-down menus via the keyboard. By pressing a given function key, you would get a menu dropdown to fall, and by pressing the first letter of an item description, you could activate that element. Secondly, we needed a tool that would let us to use the GEM play and record functions (appl_record and appl_play) in a more usable and efficient manner than was provided with the GEM toolkit. As is typical with programming, these two tasks proved much more complicated than expected.
We discovered that once a menu item has been selected, control of the mouse is handed over to GEM exclusively, so how could we then see which key was pressed? Our solution was to have a desk accessory running that would look for keys at that time (since desk accessories could run as a separate task at the same time as a program). Thus, the desk accessory would intercept keystrokes from the keyboard at the time that the dropdown was lowered. Elegant, but complicated to say the least!
appl_record and appl_play should allow you to "record" mouse and keyboard movements then "play" them back at a later stage. Chris found these functions (particularly appl_record) very inefficient. For example, it might take 500 bytes of storage space to record a mouse movement across the page. Add mouse positions and timers and it becomes very large. He decided to write his own, more efficient version of these functions, which we called replays. Eventually, both replays and the function key accessory were combined into one desk accessory.
While Chris explored GEM, I began developing the ISGUR Portfolio System and was able to devote my time to the application side of the project. Steve Couchman joined us as our communications expert and began developing I*S-Talk under MS-DOS GEM, He also agreed that as soon as the ST was available to us, he would become our ST expert.
In the meantime, Keith Hope performed magic on our MSDOS machines. He added a 80286 board with two megabytes of RAM disks, cache memory, and a 40 megabyte hard disk to my Compaq. The Intel 80286 chip is the same processor found in the IBM PC AT, only this one ran at nine MHZ instead of six. The cache memory allowed the original 8088 chip in the Compaq to efficiently determine whether to access the disk for data, or whether the data was in memory already, thus cutting down on disk I/O. This effectively gave me a machine running 10 to 20 times faster than a regular IBM PC and gave us the freedom to concentrate on developing software. Truly a developers' heaven. We have become quite spoiled from all these hardware tools, as well as the myriad of MS-DOS software tools (Lattice C, Phoenix's linkers, debuggers, Lints, etc.) which are very sophisticated, bug free, fast and reliable.
EARLY ST
When the ST arrived later in the year, we knew we should start developing for it as soon as possible. But we were faced with a machine with almost no software tools, let alone fast hardware peripherals like hard disks. Pioneer ST developers will remember those amusing early version numbers: C compiler version 0.F, linker serial number 0000-AAAA. The time was ripe for system software to be developed on the ST We knew that if the machine was to survive, it would need some useful application software reasonably quickly. We decided to immediately try our hand at porting ISGUR Portfolio System and I*S Talk. Steve spent two weeks with the inadequate tools provided with the early ST-overflowing his floppy disk space, crashing. He later realized that he accomplished about as much in those two weeks as he now achieves in two hours.
After some frantic calls and long meetings, we decided to take a different approach: We would become GEM experts and concentrate on developing superior GEM applications under MS-DOS. At the proper time, we could port our code to the ST and make the necessary changes to take full advantage of the Atari hardware. In the meantime, Steve became a beta tester for everything we could find on the ST. He spent countless hours trying every compiler, linker, editor and got to know every available piece of systems software for the ST. The creative development environment was becoming a frustrating environment.
To make the IBM-ST port as straightforward as possible, the decision was made to develop our software in the C language. C is well known as an ideal language for cross development purposes. We opted for the Lattice compiler on the IBM because it was well suited to GEM, we had experience with it, it supported full C, and it was a mature system. Also, the developers at DRI had used Lattice to develop the GEM bindings and therefore recommended it. We also wrote our code in a structured, modular fashion-all data definition and machine specific codes were external, all I/O was localized in one position. Using C, we were able to write code that referred to external functions-such as memory allocation and I/O-in a very logical manner. (We found the header files PORTAB.H and MACHINE.H to be very useful in this regard.) We were determined to write code that would behave itself under GEM; it is very easy to write non-standard code. We wanted to behave first-then, at a later stage, fine tune the code for speed.
We were fortunate to be provided with an excellent role model. BI's only ST software at that time was DEGAS (an outside acquisition from Tom Hudson). Its sales were better than anyone ever imagined. Within the first three months, we sold more copies of DEGAS than we expected to sell in the first year. We also found our international sales very significant. Other developers seemed to be finding ST sales to be a bit tough. This proved to us there was a strong market for solid, well written ST products, and that it was very worthwhile to develop other powerful ST programs.
After fall Comdex, we decided that the ST's time had come. We elected to port the ISGUR Portfolio and I*S Talk over to the ST.
ST TOOLS
There are now some good hard disks for the ST and some usable development software has started appearing. The situation is improving rapidly, but some of our biggest frustrations are rooted in not knowing what to blame for a bug. When we were porting the ISGUR Portfolio System from MS-DOS, we had almost one megabyte of source code to transfer! We decided to use the Megamax C compiler on the ST side. It seemed a solid, fast and quite efficient compiler.
Megamax compiled our code very quickly but the system sometimes crashed
during the link Was our code too large?
create our software on the IBM
and port later
to the ST.
Were we passing some limits? Eventually we and Megamax discovered there was a problem in the memory allocation of the linker. We used this frustrating opportunity to fine tune our code and manually perform a lint. (Lint is a program that examines C code for correct syntax and structure. Under MSDOS we could simply have used such a program. The closest we could get on the ST was to manually go through the code line by line.) Megamax had presumed that TOS would allocate memory as documented; this was not the case. (With TOS, each time you request memory, you must free it. Otherwise, after a certain number of memory requests without "free-ups," you will bomb. One solution is to determine in advance your total memory needs and request it all at once.)
The port for our two programs was fairly straightforward-which is not to say that it was completely simple. Under MS-DOS, one can choose which "model" to develop under. This is not true for the 68000 machines. A model in the 8086 processor indicates how large program and data address space should be (and thus the compiler creates two or four-byte pointers). The 68000 only uses four-byte pointers. Structures not byte aligned under MS-DOS had to be reconsidered. Structures were forced on to positive bytes, thus changing their sizes. But thanks to the portability of C, the incredible similarities between MS-DOS and GEMDOS, and the similarities of GEM in the two environments, it was not too bad. Where no GEMDOS call existed, a close approximation could always be found. On the other hand. MS-DOS is far more forgiving if you ignore directory paths in I/O operations. (For example, MS-DOS will accept A:FILE.DOC, while GEMDOS insists on A:\FILE.DOC).
THE SIX WEEK PROGRAM
In March 1986 my wife and nine-month-old daughter went to Israel to spend six weeks with my in-laws. For myself, I saw the opportunity of six weeks in which to develop an ST product. Having come from the MS-DOS world, I knew just how successful add-on memory resident tools-such as Borland's Sidekick, and Lightning-were on the IBM PC. BI had already created BatteryPak, a set of useful desk accessories for the Macintosh which was doing well. With GEM, we also had the desk accessory capability available. I am a terrible speller and find a spelling checker vital to my work. I did not want to develop "just another spelling checker" so I began planning the ideal writer's tool for the ST. My only restraint was time. I needed to finish the bulk of the project in six weeks, and was determined to be completely finished before the 1986 Summer CES.
I also had some hopes about the effect of this product on the ST world. My responsibilities at BI include looking at the marketplace, trying to understand where things are going, and trying to create a market environment that will help such machines as the ST to succeed in a big way. I have looked at all the software coming out for the ST and am convinced that the only way the ST will succeed is if a consistent interface is used for all of its programs. What will revitalize the home computer marketplace is a common interface like that found on other consumer products such as cars, stoves and TVs. We have the GEM interface and, for better or for worse, we should make it work for us all. I hoped products like Thunder! would motivate other ST developers to follow the rules in developing well-behaved GEM applications. Accordingly I decided to develop a program that would work with any well behaved GEM ST product. I just hope that we are not all hurt by some of the early applications coming out for the ST-it is not good enough to ship piles of software if they are not of decent quality. Some early GEM programs, for example, leave "holes" in the screen after desk accessories have been activated. Ultimately, such programs will not be worthwhile and financially they will fail. Enough preaching.
I decided the only way I could develop the system in six weeks was by developing a bug-free program on my Compaq under MS-DOS GEM, and only then porting it over. The big lesson I had learned from our first ports was to develop just the "core" under MS-DOS, test it thoroughly, port it to the ST, then develop that last ten percent of the project (which always seems to take fifty percent of the time) on both machines simultaneously. This way, I would know the code worked before it got to the ST. The core of the program for me was a working, efficient version of the program that lived well in the GEM world. Any bugs would be easy to identify and fix. Once on the Atari, I could spend time making the code Stish.
THUNDER!
Thunder! is made up of two programs: a real-time desk accessory which we initially called Thunder, and a stand-alone program, which we were calling Bolt at that time (Thunderbolt). The user interface is written mostly in C, with the keyboard interrupts and the dictionary lookups written in assembler. The dictionary consists of 50,000 words intricately squeezed into 80K. These are 50,000 real words; thus walk, walks, walked and walking are considered one word, effectively giving many more than 50,000 words.
The desk accessory part of the program looks up words in the dictionary as they are typed in. The program thus intercepts keys from the keyboard as they are typed in. These keyboard interrupts were reasonably close to the way we had previously handled our function keys accessory, so we already had the basic routines in 8086 and 68000 assembler We had the dictionary routines in both assemblers as well. Thus, we were able to develop the C routines independently of the assembler routines.
On the 8086 side, we used Lattice C small model (data and program less
than 64k) to create efficient code. We were determined to maintain only
one set of source code, the same program would be maintained for both machines.
We could do this very smoothly by using the MACHINE.H and PORTAB.H files
supplied by DRI. MACHINE.H is a header file written by Digital Research
that defines machine specifics about routines used by some GEM routines,
such as defining of the size of ADDR pointers. PORTAB.H defines variables
such as BYTE, WORD, BOOLEAN, and LONG which were used instead of char,
int etc. By using these header files, our code became very portable between
the two machines. Where specific code was needed for a particular machine,
we simply defined PCDOS or MC68K in the header files and used, #ifdef
statements.
effectively gave me a
machine running 10 to 20 times
faster than a regular IBM
PC....Truly a developers'
heaven.
An example of the #ifdef statement in using the OSBIND.H file would be:
#if MC68K #include "osbind.h" #endif
or even defining the name of the main module:
#if MC68K main() #else GEMAIN() #endif
For the first four weeks, I developed the program on the MS-DOS side only Because of the speed of our tools, a normal compile-link-run GEM cycle would take about two to two-and-a-half minutes. For a program of about 40K object size, this was incredibly useful. It let me add a new routine or function and test each part almost immediately. Productivity in these four weeks was thus incredibly high, and by devoting some very long days, nights and weekends (wow, there goes spring!), I had the basic core finished in four weeks.
Now came the unknown: How long would it take to port it over to the ST? We-mostly Chris-had been working on the ST assembler routines and had already debugged most of them. Steve had ported most of I*S Talk over by then, and was very familiar with memory allocation and the I/O routines from the Atari developer's document, "Hitchiker's Guide to the BIOS." Because of the way Megamax handles (or rather doesn't handle) assembler interrupt routines, we decided to develop the stand-alone program under Megamax C, and the desk accessory under Alcyon C. Interrupt routines can happen at any time and use any of the 68000's registers. Megamax uses these registers to access GLOBAL variables. Megamax can be used if you keep saving and restoring your registers but, as fast and efficient as Megamax is, the overhead, in this case, was not worthwhile.
THE PORT
With Steve and Chris' help, we began our port one morning at 9:00 am. We were really amazed when, by noon we had the stand-alone program running on the ST. We used Tim Oren's resource mover to smoothly move the resources across, changed our MS-DOS I/O calls to GEMDOS calls, and recompiled. Using Megamax, it all worked first time! (Editor's note: Tim Oren's resource mover is available for $25. You can reach Tim through his CompuServe PPN# 76703,202.)
That afternoon, we began porting the desk accessory. This was more of an unknown; the two machines handled desk accessories in different ways. On the ST, a desk accessory is loaded at boot time, while under MS-DOS, it is loaded when you start GEM running. The port was smooth, and by the next evening we had the desk accessory running on the ST. The main reason for the delay was the incredibly slow compile and link speed of the Alcyon compiler. The Megamax compiler was about six to seven times faster than the Alcyon.
Over the next four weeks, we were able to fine tune Thunder! to take advantage of all the special features of the ST, including different resolutions, color, and speed. We did this for the MS-DOS environment as well.
At first we used Kermit to port the code, but we have since found an easier method. Just hook up a 3 1/2-inch drive to the PC. (It helps to have someone like Keith Hope for this.) By using any of the versions of MS-DOS made for the new portables (like Toshiba T1100), you format the disk on the MS-DOS side with FORMAT/3. which will make the disk 720K format. Incredibly we found that the disk is completely recognizable by the ST. Now that better tools exist, you can also port easily with communication software such as I*S TALK, FLASH or HOMEPAK.
With the help of Ian Chadwick's documentation, Marty Herzog's art direction and our in-house desktop publishing system, we had the program completed and packaged by June 1st for the summer CES. Chris finished his function keys and replay routine on both the MS-DOS and ST machines, and they are proving very useful. We have since decided to publish more than twelve ST products this year-by both outside developers as well as in-house.
CRAWLIES AND OTHERS
The most frustrating parts of the exercise were the "idiosyncrasies" (a euphemism for little crawly creatures). Here follow some examples, tips and hints from our experience:
It is hard to keep to the rules when you find that your desk accessory
is suddenly 40K bigger than it should be. Yes, it is true. Open a virtual
workstation in a desk accessory and it allocates the 300-400 bytes of memory
it needs somewhere far away from where it should. A temporary solution
is only to open the workstation when necessary.
develop "just another spelling
checker," so I began planning
the ideal writer's tool
for the ST.
If you use a regular form_do in a desk accessory, you may find that your keys fall through to the application, so be prepared to write your own. By "falling through", I mean that if you have a desk accessory on top of a word processor, for example, keys pressed during a form in the desk accessory are picked up and used by the word processor.
evnt__timer is a very dangerous call to make from a desk accessory. It sometimes causes the entire program to freeze up. (This one is true under MS-DOS as well, which has its own big list of idiosyncrasies.)
Before doing an fsel_input call-and before any I/O- make sure you have correctly set path names. (A: is not good enough, it must be A:\.)
The documentation for vex_motv is wrong-it requires a jump to the saved address to update the driver.
form__alert strings can only be about 30 characters per line.
You should modify the source of form_do (form_keybd) to change underscores to dashes. Underscores blow your application out of the water.
Appl_play and appl_record do not work without a ROM patch from Atari. (Editor's note: According to Atari, this code is available to developer's only. Contact Atari on the Atari 16-bit SIG of CompuServe.)
COMPILER PROBLEMS
Alcyon: appl_init returns the wrong value (always returns 1). Bindings for form_keybd and form_button are missing.
Megamax: No overlay linker support.
The most irritating part of the two compilers are that they have incompatible file formats for object code.
AND YET MORE CRAWLIES
At June CES, we showed the first version of Thunder! before actually shipping it. This was fortunate, because Murphy struck again. We discovered that the program would suddenly freeze up and the menu would stop working altogether. After some frantic tests, we found that the timer problems were even more serious than we thought. Not only should you not do any evnt_timer calls, you should not use MU_TIMER in your evnt__multi calls or have any reference to timer calls anywhere in a desk accessory. We replaced all these references with different evnt__multi calls and everything became stable once again. And then, another surprise. The newer versions of 1ST Word do not allow the Backspace key to buffer characters. (When you hold down the key it does not auto repeat). I presume they did this because the machine is so fast the user might delete too much of the document. This caused problems in the speed that Thunder! deleted characters, so we added an option to delay backspaces for such problems. (Who would believe that someone would write software to slow down the hardware!)
As time passes, it makes less and less sense to develop ST software on an IBM (unless you are developing for both machines simultaneously). As tools on the ST become more mature, and developers become used to the idiosyncrasies of the machine and the tools, (and these idiosyncrasies become documented), it becomes easier to use the ST for its own development. The tools are almost available (the new Megamax compiler compiles faster than my Compaq in 286 mode). Soon, we can expect other tools like Lint, some good debuggers, and, most importantly the confidence that these tools work as they should. Let us hope our period of frustration is almost over. The time for development of good application software for the ST is here. Only please, make the effort for us all-and make it good GEM-based software.
Batteries Included
30 Mural Street
Richmond Hill, Ontario L4B 1B5, Canada
(416) 881-9941
CIRCLE 203 ON READER SERVICE CARD