MP/M on i386
Following on the work to port CP/M to C, I decided to take on MP/M, since it has multi-user capability. With Claude’s help this was a 2-stage process:
- Create modern 32-bit assembler for i386 that does the same as the original 8-bit 8086 assembler. This involves upgrading the assembler to the modern CPU semantics including code segments and data segments.
- Create C code that compiles to, as close as possible, the assembler from step 1.
The net result is C code that compiles to 32-bit real mode MP/M. You can see it in QEMU here:
qemu-system-i386 -drive file=build/mpm86c.img,format=raw,if=floppy -boot a -serial mon:stdio
-parallel file:build/printer.txt -display none -no-reboot
src-c boot: loading the kernel
MP/M-86 XIOS86Q -- QEMU target (serial console, floppy disk)
MP/M-86 src-c image-builder: pipeline ok
sup_init: ok (sysdat 1A5E, init uda 1ACA)
rt: MP/M-86 on the C kernel: code at 1000, SYSDAT at 1A5E, RSPs Tmp CLOCK ECHO MPMSTAT Cachinit
MP/M-86 XIOS86Q -- QEMU target (serial console, floppy disk)
MP/M-86 2.0 [5 Oct 81]
Copyright (C) 1981, Digital Research
0A>DIR
12:00:02 A:DIR.CMD
Directory for User 0:
A: KERNEL SYS : SUBMIT CMD : RANDOM CMD : ABORT CMD
A: ATTACH CMD : CONSOLE CMD : DIR CMD : DSKRESET CMD
A: ED CMD : ERA CMD : ERAQ CMD : PIP CMD
A: REN CMD : SET CMD : SHOW CMD : SPOOL CMD
A: SSPOOL CMD : MPMSTAT CMD : TOD CMD : TYPE CMD
A: DDT86 CMD : DEMO SUB
0A>TOD
12:00:06 A:TOD.CMD
Fri 09/25/81 12:00:06
0A>MPMSTAT
12:00:43 MPMSTAT Msg Qued
MP/M-86 2.0 [5 Oct 81]
Copyright (C) 1981, Digital Research
****** Status Display - Values Shown In Hexadecimal *****
Number of Physical Consoles = 01
Number of Virtual Consoles = 00
Number of List Devices = 01
Number of Free Process Descriptors = 04
Number of Free Memory Descriptors = 29
Number of Free Queue Control Blocks = 02
Free Queue Buffer Area = 00C3
Number of Flags = 20
Maximum Paragraphs Per Process = FFFF
Ready Process(es):
MPMSTAT [00] Idle [00]
Process(es) DQing:
[ECHO ] ECHO [00]
Process(es) NQing:
Delayed Process(es):
Polling Process(es):
Process(es) Flag Waiting:
01 - Tick [00]
02 - CLOCK [00]
Flag(s) Set:
Queue(s):
MPMSTAT ECHO MXdisk
Process(es) Attached to Consoles:
[00] - MPMSTAT
Process(es) Waiting for Consoles:
[00] - Tmp
Process(es) Attached to Printers:
[00] - Unattached
Process(es) Waiting for Printers:
Memory Partitions:
Start Length Process | Start Length Process | Start Length Process |
1C0C 0400 * FREE * 200C 0400 * FREE * 240C 0400 * FREE *
280C 0400 * FREE * 2C0C 0400 * FREE * 300C 0400 * FREE *
340C 0400 * FREE * 380C 0400 * FREE * 3C0C 0400 * FREE *
400C 0400 * FREE * 440C 0400 * FREE * 480C 0400 * FREE *
4C0C 0400 * FREE * 500C 0400 * FREE * 540C 0400 * FREE *
580C 0400 * FREE * 5C0C 0400 * FREE * 600C 0400 * FREE *
640C 0400 * FREE * 680C 0400 * FREE * 6C0C 0400 * FREE *
700C 0400 * FREE * 740C 0400 * FREE * 780C 0400 * FREE *
7C0C 0400 * FREE * 800C 0400 * FREE * 840C 0400 * FREE *
880C 07F4 * FREE *
0A>
A couple notes:
- The source tree is https://github.com/teverett/MP-M-86-2.x
- The ‘orig’ directory includes the publically available source code I could find, along with manuals in pdf format.
- The ‘src-assem’ directory is step 1: creating 32-bit real mode assembler for i386
- The ‘src-c’ directory is step 2, creating C code that compiles to “as close as possible” the code from step 1.
- The clock is not wrong. MP/M predates on-board RTC’s, so the time has to be set manually.