MMPS for Sharp PC-1500 - A multi-process operating system with file system and virtual consoles

© Christophe Gottheimer, 1994-2014
Download ZIPped archive: mmps-090498.zip (1.2 MB).

Description:

MMPS is a multi-process operating system with file system and virtual consoles.

Notes: This code is expected to run in the Sharp PC-1500/A and the TRS-80 PC-2. This version is still in pre-alpha release. It is not fully mature and bugs may be present. It was tested only with ROM1 and ROM2 versions of the PC-1500. Before installing MMPS, be sure to save all your programs, data, variables...

Disclaimer:You use this software at your own risk! I am not responsible for any damage, hardware or/and software, resulting from the use of MMPS, and any processes developed later. C.G.

0. History

MMPS is the most complex project I developed for the Sharp PC-1500. I got the idea of a small operating system when I started working on real-time embedded systems.

My dream was to replace the BASIC ROM by a small OS, with all its utilities and a native development chain. But I froze the project because a lack of time, due to the complexity of the development, because also of new activities starting (Linux and other BSD systems) and because I had reached the limits of the Sharp PC-1500 as a development platform. I was no more able to develop safely, because of the amount of memory used for all parts: the kernel, the file system, the monitor XMON(r), the volatile data...

This code is an original one. I wrote it as a hobby. It was developed on the Sharp PC-1500 by using the monitor XMON (r). All the code (kernel, file system, libraries, structures), the documentation and the examples are copyrighted 1994-2014 Christophe Gottheimer. This code is distributed under the terms of GNU Public License (GPL) version 2.

1. Overview

MMPS is an multi-process operating system (several executables may be launched at the same time, and also several instances of a same executable) with a small file system (to store permanently the utilities, executable, data), a memory manager to allocate blocks to process, and also a virtual consoles mechanism to link the screen and the keyboard to one process.

MMPS supports 62 system calls (named kernel-jump ! but I do not remember why) to handle the following functionalities:
    . Memory management: allocation, release of blocks,
    . File system: create, remove, open, read, write,... and is able to manage several types of entry: files, consoles, queues, duplex, shared memory, mapped memory and locks,
    . Process management: create, kill, synchronous messages send and receive, delay, asynchronous events and debug,
    . A scheduler to wake up and start the process, depending of their states.

MMPS is a monolithic kernel. It is standalone and requires only 4 calls to the ROM routines to clear the scree, display and get the pressed key.

Executable and utilities may change without disturbing the kernel and kernel may change without need to rebuild the executable. Only the codes of the kernel jumps and the APIs need to be frozen.

The executables should be relocatable and re-entrant.

The kernel jump mechanism is realized by the instruction SBR (&E3), with the code of the kernel jump into the accumulator A. The registers BC, DE and HL are used to pass the arguments and/or receive the returned values. When returning, the CARRY is set if the kernel jumps was completed; else the CARRY is cleared and the error code is returned into A.

Example, to open a file, the kernel jump OPN:
        LD    BC,address-of-filename
        LD    E,open-mode (read, write, append...)
        LDA   &14    ;; kernel-jump code of OPN
        SBR   (&E3)
        ;; if the carry is cleared, an error occurred and A contains the error
        ;; code. In this case, no register except A are modified.
        JR    NC,go-error-handler
        ;; E contains the opened descriptor. It will be used for all operations
        ;; on the file until it will be closed

2. Installation

This archive contains the last version of the kernel (from april 9th 1998), along with the minimal file-system and the volatile area.

Several images are provided within this ZIP; The Standard Development (stddev) or Full (stdfull) images may be installed in all PC-1500, PC-1500A and PC-2. The 1500A Development (1500Adev) or 1500A Full (1500Afull) are only workable with a PC-1500A.

If you choose the Standard Development (stddev), do the following, in PRO mode:
        POKE &7865,&48,&00
        NEW
and load the 3 wav with CLOAD M
        Images/stddev/mmps-090498-stddev.wav
        Images/stddev/mmps-fs+lib-stddev.wav
        Images/stddev/mmps-volatile-stddev.wav

This image is really for MMPS kernel development. For a normal usage, the images below are preferred.

If you choose the Standard Full (stdfull), do the following, in PRO mode:
        NEW &4300
and load the 3 wav with CLOAD M
        Images/stdfull/mmps-090498-stdfull.wav
        Images/stdfull/mmps-fs+lib-stdfull.wav
        Images/stdfull/mmps-volatile-stdfull.wav

If you choose the 1500A Development (1500Adev), do the following, in PRO mode:
        NEW &5000
and load the 3 wav with CLOAD M
        Images/1500Adev/mmps-090498-1500Adev.wav
        Images/1500Adev/mmps-fs+lib-1500Adev.wav
        Images/1500Adev/mmps-volatile-1500Adev.wav

If you choose the 1500A Full (1500Afull), do the following, in PRO mode:
        NEW &4000
and load the 3 wav with CLOAD M
        Images/1500Afull/mmps-090498-1500Afull.wav
        Images/1500Afull/mmps-fs+lib-1500Afull.wav
        Images/1500Afull/mmps-volatile-1500Afull.wav

MMPS requires a CE-161 or a memory extension of 16Kbytes, since it uses the area from &0000 to &3FFF. The kernel is not relocatable !

    MMPS was tested only with ROM1 and ROM2 versions of the PC-1500. However, since it uses only 4 calls into the BASIC ROM, it may work on a ROM0 (PEEK &E2B9 <> 56).

MMPS uses the code instructions &34 (LDA N) and &FD &3A (POP MN). To run it under an emulator, be sure that these instructions are emulated, else the kernel may crash.

The zip archive contains the following files:
        COPYING           - The GNU Public license v2
        MMPS.inc          - MMPS header to develop with lhTools
        MMPS.macro.inc    - MMPS macros for the kernel
        MMPS.volatile.inc - MMPS volatile variables and address
        README            - This introduction
        mkmmps.sh         - Script to build bin and wav
        mmps-090498.asm   - The assembly code of the MMPS kernel
        mmps-fs+lib.asm   - The assembly code of the FS and utilities
        mmps-volatile.hex - The hexa source code of the MMPS volatile area
        mmps-volatile.ds.hex   - Volatile DS table code
        mmps-volatile.heap.hex - Volatile HEAP area and table code
        mmps-volatile.proc.hex - Volatile process, FS tables and kernel stack code
        mmps.abw          - The whole documentation for AbiWord
        mmps.pdf          - The whole documentation in PDF
        BDGRD.asm         - An example of executable
        RUNPRO.asm        - An example of a executable
        SHOWKEY.asm       - An example of executable
        RTLIB.asm         - The RUN-TIME Library
        STARTER.asm       - The starter process
        FILES.asm         - The FILES executable
        PROCESS.asm       - The PROCESS executable
        DISPLAY.asm       - The DISPLAY executable
        DEBUG.asm         - The DEBUG executable
        MAKER.asm         - The MAKER executable
        Images/stddev/    - All images WAV/BIN for the Standard development
        Images/stdfull/   - All images WAV/BIN for the Standard full
        Images/1500Adev/  - All images WAV/BIN for the 1500A development
        Images/1500Afull/ - All images WAV/BIN for the 1500A full
        Images/Examples/  - All images WAV/BIN of the examples

Before installing MMPS, be sure to save your important programs or data, because MMPS requires a large amount of memory.

A load from the tape is first needed. This is done in 3 steps:
        . the MMPS kernel (use CLOAD M see 'MMPS 9/04/1998')
        . the runtime and the utilities within the minimum file system
            (use CLOAD M see 'MMPS FS+LIB')
        . the initialization volatile area (use CLOAD M see 'MMPS VOLATILE')
After the system is loaded into the memory, it may be called directly by the BASIC instruction CALL &C5 under the editor or a program.

The file system and the volatile data are kept when exiting MMPS. To start MMPS again, just do CALL &C5 under the BASIC editor, or in a program.

        ---------------------------- IMPORTANT ----------------------------
        At this time, a real bug exists: if the auto-power-off timeout is
        elapsed under the EDI kernel-jumps (waiting on a console), MMPS
        will be frozen when powering on, because the scheduler is not
        restarted. So, press very fast the RESET button on the reverse side
        of the PC-1500/PC-2.
        There is no way to bypass this problem. So be careful.
        -------------------------------------------------------------------

When starting, the system will first perform a 'DOWN'; it means that it will terminate all running processes, close all the descriptors and release all the blocks and pages not reserved for the file system.
Then, it will create a CONSOLE entry named 'CONSOLE', make it the active one and try to start the process 'STARTER' on this console.

If all has worked, STARTER will display the MMPS banner (see 'MMPS 09Apr.1998') and be waiting for a command. To clear a message pending on a CONSOLE, use the 'RCL' key.
STARTER assumes that all the commands given are the name of a process to start followed by its arguments. If the process is started, STARTER will display '>N' where N is the PID of the process. If the process can not be launched correctly, STARTER will display '!EE' where EE is the error code returned by MMPS.
When a new process starts, STARTER activates and selects the console to it. To change the active console, use the 'DOUBLE-ARROW' key located on the left of 'RCL'. When a process is normally finished, STARTER catches the event and displays '>N +4:RRRR' with N the PID of the ended process and RRRR the return value.
When a process is killed, STARTER catches the event and display '>N -5' with N the PID of the ended process.

Another STARTER process may be started. It is finished by pressing the 'UP-ARROW' key. In this case, the process just returns to the scheduler except if STARTER has the PID 0 (that means that it is the son of the kernel) and in this case it will turn down the system. When the system is 'DOWN'ing, it will terminated all the processes, close all the descriptors and release all the pages. After, it will restore the BASIC stack and give it back the control.
It is not possible to start more than one process neither to start another process STARTER at the 'BOOT' time (except by writing another process and give to it the name 'STARTER').

Please refer to the documentation for a complete presentation about the MMPS kernel and other components.

3. Another example: A client/server using the QUEUE

The example described here is a mechanism of client/server using an asynchronous queue (QUE). The first instance of the executable BDGRD will create a queue (QUE) named qBDGRD and inherit the read access; it is the server. The second instance (and all others) will not be able the create the queue and will just reach to OPN it; it is the client. The client wait for a message from its console, and send it to the server, the server will print it on his console.
The example has no interest except to learn how to work with MMPS. Instead of printing the messages, it is possible to save them in a file, etc.
This principle is more or less what is done when you send a document to a print spooler, or like the syslogd daemon on the UNIX systems.

The source of BDGRD executable:
        ;; BDGRD - Server/client Queue tests for MMPS
        ;; this test will test a mechanism of the
        ;; asynchronous queues. These queues are
        ;; anonymous.

        ;; The first instance of BDGRD will create the
        ;; queue qBDGRD. It has the read access and
        ;; becomes the server. Only one server may
        ;; exists, because MMPS will fails to create
        ;; another queue of the same name. All messages
        ;; read from the queue will be written to the
        ;; out descriptor D.

        ;; All the following instances will try to
        ;; open the queue qBDGRD. They will have the
        ;; write access, and become client.
        ;; Client will read from its in descriptor
        ;; and write to the server through the queue.
        ;;
        .ORIGIN:  2000

        ;; MMPS kernel-jump and macros
        ;;
        .INCLUDE: MMPS.inc

        ;; MMPS executable header. Perhaps a macro, no?
        ;
        .BYTE
        F3 00 60 01 00 40

        ;;
        .CODE
        ;; The process enters here
        ;;   BC = global address
        ;;   D in and E out descriptor
        ;;   HL = argument address

        ;; Server queue name in BC
        ;;
        LD      B,<qName
        LD      C,>qName
        LD      L,01
        ;; Create a queue
        ;;
        MMPS    krn.QUE
        JR      C,doalloc

        ;; Unable to create a queue. Not server
        ;; So client just tries to open it
        ;;
        LD      E,04
        MMPS    krn.OPN
        JR    NC,outerr

        ;; If we open the queue, we read from D
        ;; and write to the queue. So exchange
        ;; the D and E descriptors
        ;;
        LDA     D
        STA     H
        LDA     E
        STA     D
        LDA     H
        STA     E

doalloc:
        ;; Ok. So we need a page (64 bytes) as
        ;; a buffer to receive and send messages.
        ;; We will allocate it.
        ;; Request 1 page in L and the address
        ;; of the block is returned into BC
        ;;
        LD      L,01
        MMPS    krn.BAL
        JR      NC,outerr

forever:
        ;; main loop: wait from descriptor E
        ;; MMPS will suspend for wait only if E is
        ;; a queue else we return with CARRY set
        ;;
        MMPS    krn.WAI
        JR      NC,outerr

        ;; Because in header we request 1 page
        ;; for global area, so 1 page = 64 bytes
        ;; Prepare to read 63 bytes max from
        ;; descriptor R
        LD      L,3F
        MMPS    krn.REA
        JR      NC,outerr

        PUSH    DE
        ;; Now we exchange D and E to write on
        ;; the out descriptor
        ;;
        LDA     D
        STA     E

        ;; Refresh the output. Nice if E is a
        ;; console...
        MMPS    krn.RFR

        ;; Write the received buffer, L contains
        ;; the number of bytes really read
        ;;
        MMPS    krn.WRI

        ;; Next loop
        POP     DE
        JR      C,forever

outerr:
        ;; Error. Return error code from A into
        ;; E and set D to 0.
        LD      D,00
        STA     E
        RET

        .TEXT
        ;; Name of the server queue: qBDGRD
qName:
        "qBDGR\00"

        .END
        .SYMBOLS:

This program is included in the MMPS zip archive, but not inside the original minimum file system because od the small amount of memory remaining. See in the documentation the way to install it into the MMPS file system.

4. Copyright and license

Copyright 1994-2014 Christophe Gottheimer

MMPS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Note that I am not granting permission to redistribute or modify MMPS under the terms of any later version of the General Public License.

This program is distributed in the hope that it will be useful (or at least amusing), but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program (in the file "COPYING"); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

Return to main page