TRACKING THE ELUSIVE GDOSTHOSE MISSING METAFILES
by Tim Oren
A valuable examination of GDOS and metafiles by the programmer who helped write the GEM system. Discover why Atari's "color Mac" is currently incapable of using multiple fonts. Never heard of GDOS? Read on.
An important chunk of GEM was left out of the Atari ST when 105 was placed in ROM. It's called GDOS, and its absence is the reason your ST does not have multiple, Macintosh-like fonts. But GDOS (Graphics Device Operating System) can be added to your system, and with its associated "metafiles," you may output identical images to such diverse peripherals as the screen, printers, cameras, and more. GDOS was first used for the ST in Easy Draw, from Migraph. An official version should be available from Atari soon.
In theory, a fully implemented GEM system utilizing metafiles permits, among other things, graphic output to various peripherals at the highest resolution of which the peripheral is capable. For example, a metafile, creating a picture image on a medium-resolution screen, will take advantage of the highest matrix density of a graphics printer. The same picture may also be output to a plotter or camera. Again, much of this is "in theory." Digital Research has yet to complete full implementation of all capabilities of GDOS-and its related OUTPUT. PRG application. But some of the abilities are currently available for the ST. Let's take a closer look.
To understand the role of GDOS on the Atari ST, let's look at the system software (TOS) which already exists in ROM. (See figure 1.) There are two sections: GEMDOS, which handles disk and keyboard input and output, and GEM, which manages the mouse and on-screen graphics and windowing.
GEMDOS has three parts. The BIOS (Basic Input/Output System) handles hardware level interaction, such as getting a single character from the keyboard or reading a sector from a floppy disk. The XBIOS (Extended BIOS) contains hardware level calls peculiar to the ST, such as setting palette registers and configuring the sound chip. The BDOS (Basic Disk Operating System) handles disk interactions at the logical level, such as creating, writing, and reading files.
The GEM portion of TOS, with which we will be the most concerned, is also composed of three major parts. The first is the VDI(Virtual Device Interface), which handles graphic I/O functions such as drawing lines and performing bit-blit operations. (Bit-blit stands for Bit Block Transfer, a technique of moving- or copying-a block of pixels from one place to another.) The AES (Application Environment Services) performs logical level screen actions, such as window handling, drawing and processing dialogs, and animating the menus. Finally, the GEM Desktop application provides the user's window and icon interface to the file system.
The terms "virtual" and "device" in the definition of VDI mean that it, in effect, creates a new graphics machine which you can program instead of writing directly to the graphics screen yourself. The "VDI machine" is able to create lines and circles, write graphics text, blit portions of the screen, and so on. An application which uses only VDI calls to create graphics should work on any machine which uses GEM, or on any device attached to the ST for which a VDI driver has been written. By accepting this restriction, a developer gains portability for his or her program, and leverage for his or her efforts.
ST'S ABSENT GDOS
On most GEM machines, the VDI consists of three parts: fonts, drivers, and GDOS. Fonts define various styles and sizes of characters which can be written on an output device. A driver is the piece of code which implements the VDI machine for a particular output device. The GDOS is the device-independent part of the VDI, which (among other things) sends an application's VDI calls to the correct output device.
However, there is currently a problem in using this method with the Atari ST. The VDI as implemented in the ST's ROMs includes only a single device driver and set of fonts. The driver includes code for all three resolutions of the ST's graphic screen, and there are two font sizes defined for each resolution. The parts missing from the ROMs are the GDOS and VDI drivers for other devices, such as printers.
Because the GDOS is missing, a GEM program on the ST loses the device independent capabilities of the VDI. Specifically, it is unable to load new drivers or fonts, or to use the NDC (Normalized Device Coordinate) scaling system to draw pictures. The lack of a GDOS leads to several problems for ST developers and users. (We can point the finger two ways here: Digital Research did not deliver the GDOS code to Atari soon enough, and, in any case, Atari did not have enough room in their TOS ROM to include it.)
Since VDI graphics cannot be written directly to a printer, programs are forced to do bit-by-bit printer dumps of screen images, using specially written driver code. Thus, a paint program like DEGAS has to include a different driver for each printer which might be hooked to the ST. Worse, no other program can make use of these drivers. Because there is no standardized GDOS to define the driver interface, each developer ends up wasting a good deal of time.
A second problem is the loss of ability to load fonts. Although there is a way to force the ST screen driver to accept a different font (see sidebar), the standard GDOS load and unload font commands are not available. Also, since Digital Research purchased its original fonts from an outside source, the GEM developer's software has never included a Font Editor. These two problems have so far prevented the creation of a wide variety of fonts on the ST, such as has occured on the Macintosh.
Fortunately, a GDOS has been written for the ST by Digital Research, and should soon become available to developers. As of April 1986 Atari is testing a final version of the GDOS software. Already one product which incorporates the GDOS, Easy-Draw from MiGraph, has been released. (Developers should be warned, however, that the GDOS shipped by MiGraph is a preliminary version which may contain bugs in functions not actually used by Easy-Draw).
The GDOS for the ST is shipped as a loadable program, GDOS.PRG, which is placed in the AUTO folder to be run at boot time. The GDOS is a terminate-and-stay-resident program which means that once it is loaded it returns control (hut not consumed memory) to the OS. When it is run, it places a pointer to itself in the 68000's TRAP 2 vector, saving the previous value, which is the vector to the VDI and AES. When an application is running, all TRAP 2 calls are screened by the GDOS, which processes functions that it recognizes and passes others on to the AES and ROM-resident VDI code.
When it is first run, GDOS also reads a file named ASSIGN.SYS (see figure 2). This file tells the GDOS which drivers and fonts should be loaded into RAM for all programs to use. (This loading subtracts from the RAM available for your applications to run.) The exact format of ASSIGN.SYS is described in the VDI manual. For our purposes it suffices that it associates numeric device IDs with their driver filenames and font files.
It is useful to know a few of the standard device IDs. The value one (1) is always associated with the screen. Device ID 21 is the printer, if one is installed. Device ID 31 is for a metafile driver, which will be described later. A device ID must used with the open workstation v_opnwk VDI call, so that the GDOS can tell which physical device you want to address.
Notice, by the way, that you do not need to open the screen as a workstation if you are using the AES. The AES automatically initializes the screen workstation at boot time, and returns its handle as a result of the graf_handle call. Your application then uses this handle as an input to the v_opnvwk VDI call, which opens a VIRTUAL workstation for your use.
This is a good point to define the difference between a physical workstation and a virtual workstation. The physical VDI workstation is associated directly with the device itself, so only one physical station can be open for any one device at a time. A virtual workstation is a software construct which is associated with the physical workstation, but saves an independent set of VDI parameters such as line thickness, writing mode, text style, and so on. Using the virtual workstation method, your application, the desk accessories, and the AES itself can all write to the display screen via its physical workstation, but without destroying each other's MDI parameter settings.
|01p SCREEN.SYS||;ROM resident screen driver|
|21 FX80.SYS||; Epson printer driver|
|31 META.SYS||; Meta file driver|
Returning to the ASSIGN.SYS file, the driver filenames all end with a SYS extention. For example, FX80.SYS is a driver for an Epson FX-80 printer, and METASYS is the metafile driver. The special name SCREENSYS refers to the screen drivers which are already present in the ST's ROMs.
Font files always have names ending in FNT. One or more font files will be associated with each driver. Fonts come in a variety of styles and sizes, and the file name usually describes the device, style, and size of the characters it contains. For instance, a file named EPSHSS10.FNT contains a 10-point type face for use with the Epson printer's high resolution mode.
Note that an application is not restricted to only those fonts named in the ASSIGN.SYS file. When the GDOS is present, the application can also use the vst_load_fonts VDI call to bring additional font files into RAM from the disk. It can then use set_font to switch to the alternate typeface. However, fonts loaded in this manner are only available to the application which called them; they will disappear when the program terminates.
Using the GDOS and alternate drivers, your program can write to devices such as the printer using the same graphics commands that work on the screen: lines, circles, text, and so on. However, bit-blit operations only work with the screen and internal RAM of the ST. To create a bit image on the printer, you must first store the image in a file and then use the VDI's Output Bit Image File v_bit_image command to write the file to the output device.
In many cases, the device driver builds a bit-by-bit image of the printed page in memory, and you will need to use the update workstation call v_ updwk, to force output to actually begin, and then the clear workstation function v_clrwk, to advance to a new page. The output window function, v_output_window, is also available if you need to force only a part of the picture to the printer.
It is the metafile driver, however, which has the most interesting implications for ST developers. To understand the definition of a metafile, recall the notion that the VDI creates a virtual graphics engine, which is driven by commands sent by the application via the VDI bindings. In these terms, a metafile is simply a recording of the commands which created a given picture. By "replaying" these commands with a suitable program, you can generate a copy of the picture on any VDI output device.
Such a program is provided with the GDOS distributed by MiGraph and Digital Research. It is a full-fledged GEM application called OUTPUT.PRG, which you may invoke from the Desktop. If your application simply needs a method to create graphics which may be replayed for any device, this stock program should suffice. Unfortunately, due to bugs in the shell_write call, there is currently no reliable way to invoke OUTPUT.PRG from an application.
A GEM application generates a metafile by opening a physical workstation with the metafile device ID 31. By default, the metafile will be named GEMFILE.GEM, but you can change this by executing a vm_filename command immediately after opening the metafile workstation. From this point on, you can use most Control, Output and Attribute VDI functions with the workstation, (see figure 3). Note that, like a printer, a metafile can only accept bit image data if it is provided in a file.
The metafile commands are accumulated in a buffer and written to the disk when the buffer is filled. Closing the metafile workstation forces the contents of the buffer to the disk and closes the metafile.
Useful though the playback ability of the metafile may be, it has greater implications for those writing applications which do on-screen graphics editing. Consider a standard "Paint" type application, such as DEGAS or Neochrome. When such a program generates a square or circle on the screen, it becomes a mere collection of bits. There is no way, short of erasing and redrawing, to change the size or shape of the object once it has been drawn.
Let's extend the notion of metafile to solve this problem. If the metafile is a copy of the instructions which drive the VDI engine to create a particular picture, then you can equally well store this sequence within the program's memory This allows you to edit the commands, rather than the bits generated. This technique is the origin of "Draw" type graphics programs, which allow the figures on the screen to be manipulated as objects rather than images.
In such a program, the objects on screen are typically equipped with "handles" which may be moved using the mouse to redefine the location and size of the figure. You can also edit such attributes as color, line type and size, and fill pattern. In each case, the user's action results in a modification of the stored VDI command sequence, which is then replayed in whole or part to regenerate the picture on the screen. In most of these programs, you can also group sets of drawing objects, which may then be scaled and edited together.
Beyond simple screen editing, many other types of programs are made possible with the concept of graphical objects. For instance, objects can be linked up to fields or records of a database. The result is a point-and-click information retrieval system. This approach is best exemplified by the Filevision package available for the Macintosh.
VDI METAFILE COMMANDS FIGURE 3
We have so far assumed that the location, size, and shape of the objects are under user control. If these values are instead determined by the program, we get another family of applications.
When the values are computed from underlying data, the result is a data graphing application. Such a grapher might also allow you to manipulate handles on the objects forming the graph, and cause a change in the related values.
You could also write a program which would relate each object's location, size, and shape to those of the other objects on the screen. For instance, you might force two lines to lie parallel, or to be of equal length. Such "constraint based" graphics editors are as old as Ivan Sutherland's original Sketchpad program, and are available in some CAD packages, but have yet to appear on machines of the ST's size and price.
As a final idea, consider a programming language which would include graphic objects in its command set and workspace. In such a language, you could write routines to compute objects' appearances as the result of a simulation. The results might range from simple animation sequences, such as a bouncing ball, to very complex situations like a rendezvous with a space station.
Whatever the application envisioned, a program which uses graphic objects must be able to read as well as write metafiles, because that is the format in which graphical commands will be stored. This requires a more detailed understanding of their format, because the VDI does not provide an input function. The definitive document on metafile format is currently the GEM VDI manual, but the following paragraphs should provide enough information to allow you to do some exploration.
The metafile is composed of a header followed by an arbitrary number of commands. Each command consists of at least four words, and is generated by one of the functions given in the table in figure 3. The first word in the four is the command opcode. The second word is the number of vertices in the command. This field is used with the polyline and polymarker commands, for instance. The third word is the number of integer parameters required for the command. The fourth word is the sub-opcode, when it is required. If any of the last three fields are not used for the command, they are forced to zero.
Immediately following the required four words are the vertices, if any were specified. This is an image of the ptsin binding array associated with the VDI function which created the command. After the vertices, the integer parameters, if any exist, are written. They are an image of the intin binding array
The close workstation command forces a final single word command to be written at the end of the metafile. It is a word of all ones (hexadecimal FFFF).
The standard metafile header consists of 14 words. Only the first four are required. The first word is a tag value, again hexadecimal FFFF. The next word is the length of the header in words. The third word is a version tag, and the next word shows whether the metafile workstation was opened for Raster Coordinates (RC), or Normalized Device Coordinates (NDC).
The remaining entries in the header provide information which will help OUTPUT.PRG when it attempts to regenerate the drawing on another device. You may set them using VDI calls after opening the metafile workstation. If they are not set, they are filled with zeros, and OUTPUT will use default values to generate the display.
The first four optional values define (in order) the minimum and maximum X and Y coordinates to be found in the metafile. This allows OUTPUT to bound the space in which graphics will appear. Your application may set these values with the v_meta_extents call.
The next two words in the header are the physical page size on which the graphic should be reproduced. The units are tens of millimeters, and the values are given in width-height order. While Appendix H of the VDI manual describes this call, there is no standard binding provided, so you will have to write your own if you wish to use it. If you do not set this value, OUTPUT will do its best to fir the drawing onto the target device, using the assumption that its pixel elements are square.
USING FONTS WITHOUT GDOSThe following technique will let you load and use alternate fonts without using GDOS. Your font must be in the standard format (including header) as defined in the VDI manual, Either compile the font into your application, or load it from a file at run time.
Instead of doing the normal vst_load_fonts call, you will alter your application's control array directly. Control words 7 and 8 must be a 32-bit pointer to the font. Control words 10 and 11 are a 32-bit pointer to a scratch buffer which will be used by the VDI when doing special effects such as bold or italics. Control word 9 must be set to the length in words of this buffer. The buffer should be at least four times the size of the largest character in the font.
After setting up the control array, you should be able to select the font using the set_font function. When you are done with the font, or with your program, do a regular vst_unload_fonts call so the VDI doesn't continue to think the font is available.
(Thanks to John Feagens of Atari for this information.)
The final four words in the header may be
used to define the coordinate space for the metafile.
They contain, in order, the X and Y coordinates of the lower left corner of the drawing area, and the X and Y values of the upper right corner. These values are mapped onto the drawing area as defined in the last paragraph. Again, there is no standard binding for this function, but it is described in the VDI appendices. If the information is omitted, OUTPUT will use a default raster or normalized coordinate space, depending on how the metafile was opened.
As a last refinement, consider the v_write_meta VDI function. This works only with metafiles, and allows you to insert commands of your own definition into the metafile. This capability could be useful, for instance, in establishing the data/object relationships in the applications proposed earlier.
If you use this ability, you must avoid sub-opcodes 10, 11, 50, 51, and 81, which are used by Digital Research's GEM Draw program. These codes are given special handling by OUTPUT; their functions are defined in the VDI appendices should you wish to use them. With these exceptions, OUTPUT will ignore commands inserted with v_write_meta since it has no idea how they should be interpreted. You may also encounter problems if the metafile is later edited using a graphics program which does not understand your special commands. In most cases, the information will be lost in the editing process.
In this article, I have tried to show how GDOS and metafiles fit into the framework of the ST's software, and how they can be used to avoid wasting effort on rewriting of device drivers. If more applications appear which use the GDOS, it should encourage manufacturers of printers and other peripherals who want to sell to the Atari market to write drivers compatible with GDOS. This can save us all time which can he better spent on programs that stretch the abilities of the ST.
Smalltalk-80: The Language and its Implementation, by Adele Goldberg
and David Robsen, Addison-Wesley Publishing Company, Menlo Park, CA
(Sketchpad: A Man-Machine Graphical Communication System,, by Ivan E.Sutherland,
Proceedings - Spring Joint Computer Conference, 1963, pp. 329-346.
- (The Programming Language Aspects of Thinglab, a Constraint-Oriented Simulation Laboratory, by Alan l3orning, ACM Transactions on Programming Languages and Systems, 3:4, October 1981. Pp. 353-387.