[net.micro.mac] The MAUDE Development System

winkler@harvard.UUCP (Dan Winkler) (12/03/85)

Here is some documentation on a Macintosh development system written at
Brown University.  The system is not ready for release yet, although if
you would be interested in using it when it is ready or in testing it
when it is almost ready, please let me know.  I am currently looking
for a company to market it for me (and to help me finish development)
so any leads in that direction would also be greatly appreciated.

Dan.

-----------------


MAUDE - Macintosh Assisted Unix Development Environment 

Dan Winkler
Box 1910
Brown University
Providence RI 02912
(401) 521-2076, (401) 863-1647
daw@brown.csnet, daw@browncs.bitnet, winkler@harvard.arpa

MAUDE is a package that allows you to write Macintosh programs on a
Unix minicomputer (or any machine with a C compiler).  It lets you
compile Macintosh applications with the host's native C compiler (cc
under Unix) and debug with its native debugger (dbx under Unix).  MAUDE
includes a complete set of header files to define Macintosh data
structures and entry points to Macintosh ROM routines.  When the
application calls a ROM routine, a series of commands is sent over a
serial line to a Macintosh directing it to call the ROM with the
required arguments.  Thus, it looks as though the program is running on
the Mac since all graphics output goes there and all keyboard and mouse
input comes from there.  Yet, you get all of the advantages of the more
powerful host computer.

In particular, on any decent minicomputer, you get much faster
compilation and much better debugging than any native Macintosh
development system currently offers.  In addition, whenever a bug in
your program causes the Macintosh to crash, you can use the host's
(usually source-level, symbolic) debugger to determine the cause of the
crash.  You also have full use of any utilities that may be available
such as the Unix programs make, lint, diff, grep, prof, vi and of any
resources of the host machine that may be useful in debugging such as
virtual memory and a large, fast file system that lets you share files
between many programmers.

All of the host's utilities and resources are guaranteed to work just
as they would for a regular host program since, under MAUDE, the
Macintosh application is a host program which treats the Macintosh
essentially as an i/o device.  Thus, MAUDE allows you to effectively
harness the power of a large host, much more so than a cross compiler
which only speeds up compile time and which may then require a long
time to download the object code or expensive gateway hardware to allow
the Macintosh to access the object file directly through Appletalk.

The Macintosh End - Harold

On the Macintosh end, a generic program named Harold monitors the
serial line to Unix.  It interprets and executes commands sent by
MAUDE.  Harold provides full access to the Macintosh ROM and hardware.
It provides a scratchpad for data transfer and a second stack where
arguments to the ROM can be accumulated before the trap is done.  It
can also get and set any register or any memory location to any value,
although most programmers will seldom have a need to use such low-level
capabilities.

If a buggy application passes bad values to the ROM routines it calls,
then Harold may commit suicide and throw up a Macintosh bomb alert
box.  But your application will not be dead since it is running on the
host.  So you can use the host's debugger to examine the state of the
application and to determine what function it was executing at the time
of Harold's demise, what arguments were passed to it, and what the
values of any variables were.  The eventual goal of the debugging
process is to wean Harold away from his morbid tendencies.

The Unix End - MAUDE

MAUDE consists of an underlying core of routines for communicating with
Harold and a set of header files defining Macintosh data structures and
ROM entry points.  MAUDE also provides C functions to access Harold's
low-level routines which can be used to accomplish tasks that would
normally be done with in-line assembly language or external assembly
language routines in a native C compiler.

MAUDE is implemented in such a way as to be independent of the
following machine specific characteristics: byte and word ordering,
structure padding and packing, and non-transparent networks.  These
problems become apparent when it is necessary to pass a structure to
the ROM.  The structure may contain binary values that are byte and
word reversed from the way the ROM expects them.  Its fields may occur
at different offsets from the start of the structure than the ROM
expects.  And it may contain bit patterns that would freeze up certain
non-transparent networks.

MAUDE uses algorithms that will work correctly regardless of these
quirks.  It is not even necessary to configure MAUDE to a particular
machine; it will work correctly on any system.  This  is an important
advantage since a Macintosh programmer may very well not know whether
his host does byte or word reversal or both or whether it does
structure padding or packing or both or padding only to word boundaries
or only to longword boundaries or which particular bit patterns will
cause his network to freeze up and so on.  Indeed, these details may
not be documented anywhere and it may only be possible to discover them
by trial and error or by examining system source code, if available.

Compatibility with Existing Macintosh C Compilers

MAUDE is development and debugging tool.  It cannot produce stand-alone
Macintosh executable object code.  However, there are mechanisms by
which source code written under MAUDE can be compiled without
modification on any one of a variety of Macintosh C compilers.  The
data structure definitions in the header files require only that you
have typedef'd the types byte, word, and longword to match the
corresponding built-in C data types, usually char, short, and long,
respectively.

String, Boolean, and Resource Type Conversion

Lisa Pascal strings and Booleans, which the Macintosh ROM uses, are
different from standard C strings and Booleans.  In particular, Lisa
Pascal uses counted strings whereas standard C uses null terminated
strings and Lisa Pascal uses only the low bit of the high byte in
Booleans, whereas standard C treats anything nonzero as TRUE.  Also,
Lisa Pascal allows you to pass a four character string like 'DRVR' to
the ROM as a resource type and packs the four bytes into a longword.
Some Macintosh C compilers automatically convert these types on call
and return; some do not.  For simplicity and compatibility, MAUDE does
not do any type conversion.  Instead it provides functions to do the
conversion, which are #ifdef'd to do nothing when compiling with a C
compiler which does the conversion automatically (such as Sumacc).

Handling the Two Address Spaces

Under MAUDE, the application code runs in the host's address space.
But the Macintosh ROM, as usual, runs in the Macintosh address space.
This is often an advantage since the host may provide a large virtual
address space which can be useful for development even though it will
not be available to the final version of the application on a
stand-alone Macintosh.  The programmer is not normally aware of the two
address spaces, since all of his code and variables are in the host's
address space and are automatically passed back and forth to the
Macintosh by MAUDE on ROM function call and return.  However, it is
occasionally necessary for the programmer to have access to the
Macintosh address space.  For example, he may wish to examine and
change some system data structure, such as a WindowRecord.  So MAUDE
provides two functions, Import and Export, to transfer data between the
two address spaces.  For compatibility with native Macintosh C
compilers, these functions are #ifdef'd to do nothing if the
application is being compiled for stand-alone execution.

Providing "Pascal Only" ("Not in the ROM") Routines

Some commonly used functions (such as FSOpen, FSRead, and FSWrite) are
not actually in the ROM; every compiler writer must write them
himself.  MAUDE provides these functions through a trick that exploits
the fact that Harold is compiled by a complete Macintosh C compiler
that does offer these routines.  Thus, by compiling them into Harold,
they become available to MAUDE through a calling convention very
similar to that used for actual ROM routines.

Calling Host Functions from the Macintosh ROM

The primary function of MAUDE is to allow pure C code running on the
host to call Macintosh ROM routines.  Occasionally, it is necessary to
allow calls in the other direction, such as when tracking a control.
To handle such cases, MAUDE intercepts the function address that the
application tries to pass to the ROM and replaces it with the address
of a function within Harold.  When the ROM calls that function, Harold
passes control back to MAUDE which then calls the host function that
the user intended.

MAUDE and MacApp

There is a C version of MacApp in use at Brown's IRIS that can be
adapted for use with MAUDE while maintaining compatibility with various
native C compilers.  The speed of a minicomputer such as a Vax is
particularly welcome when using MacApp -- it can take over half an hour
for a Lisa to compile, link, and download a large MacApp application.
Even Apple's next generation of Macintoshes, which may be two or three
times faster than the current ones, may not be sufficient to shorten
the edit to run time of MacApp to a desirable value.

Using MAUDE with Other Languages

It is actually possible to write Macintosh programs under MAUDE in any
language the host supports, as long as it can call the C functions that
MAUDE provides as an interface to the ROM.  This allows anyone porting
a new language to the Macintosh to begin writing Macintosh applications
in that langauge before a native compiler is available.