Newer
Older
uBix-Retro / dump / oa-2.0.9 / doc / nommu.html
<html><head>
<title> OS/A65 Operation without MMU </title>
</head><body>
<p><h1 align=center> OS/A65 Operation without MMU </h1></p>
<p> <h2 align=center> (c) 1989-98 Andre Fachat </h2></p>
<hr><p>
Using OS/A65 without an MMU used to require some special measures. One of it
was to coordinate all running tasks concerning their memory usage.<br>
With the new relocatabel o65 fileformat the lib6502 implemetation
takes care of that.
</p><p>
This means when building lib6502 programs, you do not have to actively
care about the stuff below, but it is probably good to know anyway.
</p><p>
There is one thing that's difficult to handle on a 6502, the stack.
It's only 256 byte large (small that is...). And with a multitasking
OS the stack has to be used by several programs at the same time. 
One approach is to copy the stack contents to another place every time
a task switch is done. But that's a big speed penalty.
Instead I split the stack into 6 pieces, 5 of them for a task and the
last one for the system. So on a system without MMU, only five tasks 
can be running concurrently.
</p><p>
With version 1.3.9 we got a new config option, STACKCOPY. With this option
the stack of a task is saved in some save area when doing a task switch.
This is slower, but allows much more stack space in a task and much more
tasks.
</p><p>
There is one other thing that cannot easily be coordinated - the SEND buffer.
This buffer is used for communication with the kernel. As 
OS/A65 originated from a system with MMU, there was no real need not to
use an absolute address for the buffer,
thus saving registers for other purposes.<br>
For all systems now the usage of the SEND buffer 
has to be coordinated between the tasks. Therefore 
a system semaphore is used. 
<pre>
#define	SEM_SENDBUF	&lt-1
</pre><p>
Before accessing the SEND buffer at $02**, the task has to allocate
it with a PSEM operation on the SEM_SENDBUF semaphore.
After the system call, it has to be freed with a VSEM operation.
<p>
Well, and here we are with the known resource allocation problem.
Imagine two tasks communicating via send/receive. Then, if the order
in which messages are sent is not fixed and therefore predictable,
precautions against a lock have to be taken: task 1 allocating the
send buffer to send a message to task 2. The same time task 2 tries
to allocate the send buffer to send a message to task 1. If it not
tries to receive messages while waiting for the semaphore, it will lock.
<br>
Therefore the filesystems, for example, do not release the send buffer
while executing a command or open a file. In the meantime another
task could send a message to the filesystem, locking the send buffer.
But the buffer is needed by the filesystem to send the reply message.
The filesystems in their current form are not prepared for this situation,
so that they don't release the send buffer.
</p><p>
Be careful when using the send buffer - you are warned!
</p><p>
<!--- concerned oldlib only!
Another topic is the STDIO library. A part of the routines is 
now thread-save, i.e. can be used without problems. These routines are
*putc, *getc, dezbout, hexout and txtout. The directory routines
and the assign routines are <strong>not thread-save</strong>! 
They can be used by a single program only. For using them, another
system semaphore, SEM_STDIO is defined - the current implementation
doesn't know about it, though. 
--->
The lib6502 library is thread-save. It can be used by any thread at any
time. Internal locks (semaphores) are used to avoid any interference if
necessary.
</p>
<hr>
Suggested reading: "Operating Systems, design and implementation", Andrew S.
Tanenbaum, Prentice-Hall
</body>
</html>