ROM Exploring
Volume Number: 7
Issue Number: 4
Column Tag: Pascal Procedures
Related Info: Resource Manager
Exploring the ROM
By Micheal Budiansky, Berkeley, CA
[Michael Budiansky is a physicist-turned-engineer specializing in Macintosh
software. He worked in the areas of heavy-ion collisions, optical telescope design, and
semiconductor image processing, before discovering the Macintosh in 1986. He’s been
programming the Mac ever since, first for Bear River Associates, then for Applied
Bio systems. He received a Ph.D. in Physics from the University of California at
Berkeley.]
Re: Sources of Resources
Resources only come from the resource fork of disk files. Right? Wrong! Since
the days of the 128K ROM a number of important resources have also been stored in the
ROM itself. In this article, we’ll discuss how to get at these hidden resources - the
accompanying Pascal code for a simple MPW tool illustrates the necessary technique, as
well as providing a means of exploring what these resources are and finding out which of
them have been modified by later patches to the System software.
The Resource Chain
First, let’s review how resources are loaded by a program. When an application
requests a resource, the Resource Manager searches through a chain of resource files
until it is found. Normally, the chain begins with the most-recently-opened document’s
resource file, followed by the application’s resource fork, and then the System file. If
the resource isn’t in the document (or if there’s no document open), the manager looks
in the application. If it’s not in the application, the manager looks in the System file. If
it’s not in the System file, you’re probably in trouble.
To get at the ROM resources, you’ll need to adjust the resource chain by means of
techniques described in Inside Macintosh,Volumes IV and V. There are two different
methods: one is to set the values of certain low-memory globals before making an
ordinary Resource Manager call, and the other is to use the special toolbox call
RGetResource. The first method puts the ROM resource map at the front of the resource
chain for one call to the Resource Manager, as shown in Figure 1. Set the low-memory
global RomMapInsert to true and then make your call; the ROM resource map will be
searched first for that one call only. The second method is to use the RGetResource call;
this behaves exactly like GetResource, except that it puts the ROM resource map at the
end of the chain, as shown in Figure 2. After all the resource files in the chain have
been searched for the requested resource, RGetResource looks in the ROM resource map.
Figure 1. Moving ROM resources to the front
Figure 2. ROM resources at front
Roving around
What are the resources in the ROM and what good are they? Obtaining the
complete list is an exercise left to the reader - armed with the program that follows.
(Lazy readers can look up the answer in Inside Macintosh - but those lucky enough to
own one of the newer models may have to wait until volume VI is published.) Here are
three examples of how these resources can be used:
First, you may find a secret resource that is not present in the system file. The
only way to get at these is from the ROM. In Macintosh II class machines, for example,
the ROM contains a hidden ‘snd’ resource. It’s named “Brass Horn,” (although it
actually sounds more like a squeaky toy) and if it catches your fancy, you could copy it,
renumber it, and paste it into your System file to use as a beep sound.
Also, you can optimize your code to use a ROM resource if it is available, thus
saving the time required to read in the resource from disk. This technique is used by
MacApp to save time in reading the standard cursor resources (watch, plus, cross, and
I-beam). This is a fairly safe technique, since if for some reason the resource that you
expected to be in ROM is not there, the Resource manager will simply continue looking
for it farther along the resource file chain (probably to find it in the System file). You
need to be a little careful, however, since sometimes resources are present in both the
System file and in the ROM for a reason: the one in ROM is no good any more, and the
System file version is a replacement!
Finally, you may need to know about the ROM resources if you want to replace or
modify one of the standard system resources. If a resource is first loaded into the
System Heap from the ROM, then it doesn’t matter if you edit the copy in the System
file--you’re stuck with the ROM version. As it does for so many other functions,
however, the Macintosh operating system provides a “hook” that lets you override the
default behavior: the ‘Rov#’ resource. The System file contains a number of ‘Rov#’
resources; a ‘Rov#’ resource contains a list of types and ID numbers of ROM resources
that are to be replaced by their System file counterparts. In current systems, there is
one ‘Rov#’ resource for each version of the ROM (e.g., Mac Plus in resource #117,
Mac SE in resource #630, Mac II in resource #376, etc.). By editing the appropriate
‘Rov#’ resource in the System file, you can instruct the system to ignore the ROM
version of a resource and to use the version in the System file itself. Readers who are
now all set to disassemble and rewrite the Disk Driver ROM resource may proceed
without further delay; they probably wouldn’t pay much attention to the safety lecture
below, anyway. As for the rest of you, there is an example of resource overriding that
may be of interest to any programmer, even those who aren’t the daredevil type.
The Monaco font is a clean, monospaced, font--ideal for viewing program
listings on the screen. Its one deficiency, however, is that the digit ‘0’ and the capital
letter ‘O’ are indistinguishable, as are the lower case ‘l’ and the capital letter ‘I’. You
can repair this problem by using ResEdit to edit the Monaco ‘FONT’ resources (9 point
and 12 point) in a copy of your System file: add a dot in the middle of the zero digit and
add serifs (short horizontal lines at the top and bottom of the character) to the capital
‘I’. (Please! edit a copy, not your current and/or only version of the System file! And
read the safety lecture, too!) If you try out this edited System file on a Mac newer than
the Plus, however, you will probably find that while the modifications appear when
you use Monaco 12, they do NOT when you use Monaco 9; that’s because Monaco 9 is in a
ROM resource. To use the System file’s version of the font, you must edit the ‘Rov#’
resource appropriate for your machine by adding a entry for ‘FONT’ number 521. This
will take a certain amount of skill with ResEdit, since to add the entry requires editing
the resource in hex form. Open the ‘Rov#’ as a general hex resource. The second word
(group of 4 hex digits) in the resource is the number of overridden resources minus
one. Edit this number to be one greater than its current value, then add three words of
zeroes at the end of the resource; these three words are placeholders for the new entry.
Close the resource, then open it again, in the ordinary way that uses the ‘Rov#’
template. The last entry in the list should be blank; change it to FONT 521. If you run
into trouble, refer to Inside Macintosh IV-20 for the detailed format of the ‘Rov#’
resource. (Note: Inside Macintosh, Volume IV says that you’ll need to obtain a ‘Rovr’
resource from Developer Tech Support at Apple before you can do any overriding;
current System files already contain this resource, so there’s no need to bug the folks
at DTS to send it to you.)
ROMRes tool: Theory & Practice
This MPW tool has three options for exploring the ROM resources, plus a
self-contained help text. If no option or an invalid option is supplied, the help text is
printed out; this is a convenient feature for MPW tools in general, particularly those
that are not likely to be used frequently. The listing feature (-l) looks up and lists all
resources in the ROM; resources are listed by type, ID, and name. The override feature
(-r) looks in your System file and lists all the ‘Rov#’ resources found. For each one,
it lists the ROM resources that are flagged to be overridden. Note that only the
resources listed for the particular ‘Rov#’ that matches your machine will actually be
overridden in your machine. The extract feature (-x) copies a particular resource
from the ROM into the file of your choice; if the file does not exist, it will be created.
The comment at the beginning of the code contains the text for the make file; copy
the text between (* and *) and paste it into a file named ‘ROMRes.make’. The main
section of the program sets up a few variables and then has a case statement that
dispatches control to one of three subroutines, one for each feature. If there is a
problem with the command line arguments, the code at the end of the main section
prints out the help text. The tool gets access to the text on the command line via the
global variables ArgC and ArgV, which are defined in the unit IntEnv included in the
MPW development system.