There are two basic problems with multi-tasking running MAC generic
programs that I see (note: I have limited knowlege of the MAC's OS):
(1) Many programs take over the display and write to screen memory
directly rather than openning a simple window. This means that no
other task would be able to use the screen.
(2) The memory allocation scheme doesn't seem to be geared to
Thus, I don't think it will be possible to make the MAC into a
multi-tasking machine and still have it run programs written for
the current OS. Of course, you could create a completely new MAC
box with an MMU and 68010 and build a multi-tasking OS on top
of that. With the MMU, you could manage several tasks that
think they are running on a normal mac and trying to write to
'THE SCREEN' at the same time by causing a fault to occur on writes
to screen memory and then doing some funny stuff with the fault
Assuming you don't care about compatibility with older programs,
and redesign the operating system from scratch, it can be done.
Hell, you've just turned your MAC into an Amiga.
> Many Solutions, one may be
> Menu Bar is for the system only (task info,system services,launches,etc)
> Processes run within subscreens (we know them as windows)
> Each process has it's own "system window" including menubar
> Current Process window is NOT updated on task switch
> Screen Dynamics are handled by user commands (mouse clicks, etc.)
Basically, each task must be 'nice' to the system, and use system
calls to write to its window and use other resources rather than write there
In terms of your terminology: "subscreens" isn't a good word... they
really are 'windows' (I think you agree with me here). On the Amiga, the
distinction is physical... you physically have multiple screens and each
screen may contain multiple windows. (If you ever thought the Amiga was
slow because it had to deal with multi-tasking when writing to windows/
screens, think again: A task can open an entirely new screen which no other
task even knows about and write to it directly, without worry of conflict).
> All I/O should be Asynchronous - increase device demand by putting
> processes to sleep if waiting for I/O
> Is there memory protection in the hardware for segmented addressing?
Since each I/O device would be a task, this is accomplished
very easily in a multi-tasking enviroment.
Most operations in a multi-tasking system are based on semaphores,
or 'locks'. You basically have two types of locks: The SHARED lock, and
the EXCLUSIVE lock. Thus, you can have several tasks reading some
global data structure simultaniously, but only one can write at a time.
While that *one* is writing, nobody is reading. The lock structuring is
usually hidden by the OS so the actual task only sees normal, everyday
The implimentation of, say, writing a text string to your window
gain lock for your screen
write the text
release lock for your screen
So when the OS moves a window around, it gets the lock (preventing
anybody from trying to write to the screen while it's getting moved), does
the move, and then releases the lock.
The screen lock is required as a global-locking mechanism. If your
going to allow multiple tasks to write to a single window, then you also
need a window-lock for each window.
Most people have the misconception that locks are slow. Actually,
they're extremely fast when the lock is free. On a 680x0 gaining a free
lock takes exactly two instructions: A test-and-set and a branch. When the
lock isn't free (the branch fails), and you have to block anyway.
In a Multi-tasking enviroment, tasks must be able to communicate
with each other. Since IO will be asyncronous, you want most things to
work via QUEUES. You want to know when an operation has completed, and
that can be accomplished by having the task on the other end send your
message back (or acknowlege it) to you via a reply port. Advantages:
(1) You can queue several operations and then do other things while
the device is working on them.
Example: You can queue disk writes for the 'capture' mode
on your terminal program so the display doesn't get jerky
when it dumps to the file.
(2) The communications medium allows passing of pointers to buffers
rather than the buffers themselves. Thus, you can pass around
data buffers without doing copy operations.
(3) The communications medium can be used for other inter-process
communication (say, between two programs working in cooperation).
Usually an integral part of the communication system. To be able to
Wait() for one or bits from a bit mask to be set via some other
(1) Signal when there is a message ready on some message port
(2) Signal keyboard keystrokes
(3) Any Other event.
Usually, you have most incomming events come to your task via a single
port and a single signal. For instance, in a typical terminal program
PORT1 Signal1 -keyboard/mouse_clicks/window_resize/menu
PORT2 Signal2 -data present on serial port (note: serial
device will queue the data so you need not
process on a character-by-character basis)
PORT3 Signal4 -BREAK pressed (or something like that).
The other signals... asyncronous file writes, etc... are usually
hidden from the programmer so he simply uses normal OS calls to
write to files etc....