Skip to content

ghoss/m2emul

Repository files navigation

Modula-2 M-Code Interpreter

Overview

This will become an interpreter and runtime environment for Lilith Modula-2 M-Code object files.

Work in progress.

Current Development Status

  • M-Code Loader fully functional (can load and stage modules and their dependencies).
  • Runtime debugging is functional:
    • Single-step execution
    • Set breakpoint / execute to breakpoint
    • Register and stack display
    • Procedure call chain display
    • Inspection of data words (variables)
  • Provides a minimal set of "standard" Modula-2 runtime libraries to run a simple command interpreter and the ETHZ single pass compiler developed by Niklaus Wirth.
  • Interpreter can already execute the ETHZ Modula-2 single pass compiler.
  • Some M-Codes are still disabled for debugging however (due to ongoing tests).

Key Features Compared To The Lilith Machine

Functionality in General

  • Supports the original M-Code instruction set implemented in the Lilith.
  • Binary compatible with the Lilith's object code format and able to execute code generated by the ETHZ Modula-2 single pass and multipass compilers.
  • Built-in runtime monitor and debugger.

Specific Changes And Improvements

  • Loads object files from underlying host filesystem (e.g. UNIX) and therefore does not rely on the original Honeywell D140 disk system. This is accomplished by a custom implementation of module "FileSystem" which performs low-level I/O via calls to the "supervisor" M-Code opcode.
  • Provides its own dynamic loader for staging of object files and does not rely on the Medos-2 operating system loader in module "Program".
  • Provides its own heap memory allocation functions, which again are tied in to the standard module "Storage" via supervisor calls.
  • On the Lilith, all modules share the same 65K (16-bit) address space. m2emul provides more memory to programs while still maintaining the original 16-bit instruction set by assigning each module its own code space (max. 65KB per module).

Current Limitations

  • No coroutines, interrupts, priorities and multitasking yet.

Build Process

Prerequisites

  • UNIX (Linux) system with ncurses support

Compiling And Installation

  1. Download the .tar.gz packages from the "Releases" page.
  2. Extract and build:
    $ tar xzf m2emul-x.y.tar.gz
    $ cd m2emul-x.y
    $ ./configure
    $ make && make install
    

Usage

Basic Syntax

USAGE: mule [-htvV] {-i path} [object_file]

-i	Search specified path(s) for objects and libraries
-t	Enable trace mode (runtime debugging)
-h	Show this help information
-V	Show version information

-v	Verbose mode

object_file is the filename of a Lilith M-Code (OBJ) file.

Additional include paths may be specified in the
environment variable MULE_PATH (delimited by colons).

Practical use

  • Download all runtime files in the GitHub directory disk to a directory of your choice (e.g. my_directory).
  • Start the MULE command interpreter (shell) with mule my_directory/Comint.
  • You can now compile any Modula-2 files in my_directory with Niklaus Wirth's Modula-2 single pass compiler by typing the command compile at the command prompt. Enter the source file name at the compiler's in> prompt (note: filenames are case-sensitive).
  • Exit the Modula-2 compiler by pressing the ESC (Escape) key at the in> prompt.
  • For example, compile the included "Hello World" program (Hello.MOD) and run it by typing Hello at the command interpreter prompt.
  • More commands and shell features to follow…

"Comint" Shell Commands

  • Comint is a basic command interpreter. You can launch it directly by entering mule my_directory/Comint.
  • Type the name of any existing Modula-2 object file to execute it (the .OBJ suffix may be omitted).
  • compile executes Niklaus Wirth's Modula-2 single pass compiler.
  • exit terminates the shell and returns to the host operating system.

Using Multiple Directories

The -i option and the MULE_PATH environment variable allow you to specify directories where the loader will attempt to locate object and library files. For example:

export MULE_PATH=some_directory1:some_directory2
mule -i some_directory3 Hello

will search for Hello.OBJ and SYS.Hello.OBJ in the directories some_directory3, some_directory1 and some_directory2 (in this order). Likewise, libraries required by Hello.OBJ for execution will be searched by (for example) FileSystem.OBJ and LIB.FileSystem.OBJ in the same directories.

With this feature, you can store system programs (such as the M2 compiler and standard libraries) in one dedicated "system" directory, while maintaining your Modula-2 projects in different directories.

References and Credits

Other Links

You might be interested in my other UNIX-based, Lilith-related tools, which I built to help develop this project:

  • m2decode, a Lilith M-code object file disassembler
  • m2disk, a tool to import/export individual files from/to the Lilith disk images provided by Jos Dreesen in his repository at ftp.dreesen.ch
  • obdisk, a tool to export files from Ceres disk images