Skip to content

Latest commit

 

History

53 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ndmonlib — SINTRAN III MON Call Emulation Library

Documentation: https://retrocorelabs.github.io/ndmonlib/ - one page per MON call (manual text, parameters, examples, ndmonlib status and handler notes), rebuilt on every push to main.

Production-grade emulation of SINTRAN III MON operating system calls for Norsk Data ND-series emulators.

Build MON calls C11 License

Overview

ndmonlib is a portable, callback-based MON (Monitor Call) subsystem for emulating SINTRAN III operating system calls. It registers 234 MON calls (62 implemented, 172 still stubs - see MON Calls Status) so that ND-series emulators can run real SINTRAN binary programs (:DOM files, kernels, utilities).

Key Features:

  • 234 registered MON calls (62 implemented) covering file I/O, terminal I/O, device operations, process control, and system information
  • Architecture-agnostic design — Single code base works for ND-100, ND-500, and other architectures via callbacks
  • O(1) dispatch — Hash table registry for fast MON call throughput
  • Comprehensive testing — Unit tests for core logic, integration tests for MON variants
  • Auto-generated documentation — docs/mon-implementation-status.md lists every registered call with its implementation status
  • SINTRAN semantics — File system (own-dir fallback to SYSTEM), path resolution, error codes match real SINTRAN
  • Automatic unimplemented detection — Reports which MON calls your program needs
  • No external dependencies — Portable C11, uses only libc and host file I/O

Quick Start

Build

cd ~/repos/ndmonlib
mkdir build && cd build
cmake ..
make
ctest

Integrate into Your Emulator

  1. Add as git submodule:

    cd ~/repos/nd500x
    git submodule add ../ndmonlib external/ndmonlib
  2. Implement architecture callbacks (e.g., src/cpu/nd500_mon_callbacks.c):

    #include <ndmon/mon.h>
    
    static uint32_t nd500_mon_read_word(void* cpu_ptr, uint32_t addr) {
        Nd500Cpu* cpu = (Nd500Cpu*)cpu_ptr;
        return nd500_mmu_read_word(cpu->mmu, addr);
    }
    
    void nd500_mon_init_callbacks(MonContext* ctx, Nd500Cpu* cpu) {
        ctx->cpu = cpu;
        ctx->read_word = nd500_mon_read_word;
        ctx->write_word = nd500_mon_write_word;
        // ... set all callbacks
    }
  3. Dispatch MON calls from your CPU:

    if (is_mon_call(instruction)) {
        MonContext ctx = {0};
        nd500_mon_init_callbacks(&ctx, cpu);
        MonResult result = mon_dispatch(&ctx, mon_number, arg_addresses);
        if (ctx.halt_requested) stop_execution();
        if (ctx.wait_requested) handle_input_wait(&ctx);
    }

See docs/INTEGRATION.md for detailed instructions.

Architecture

System Design

Your Emulator (ND-500, ND-100, etc.)
    │
    ├─ Instruction: CALLG segment 31, address XXB
    │
    ├─ CPU calls: mon_dispatch(&ctx, mon_number, arg_addresses)
    │
    ├─ Callbacks: ctx.read_word(), ctx.set_i1(), etc.
    │         (you implement these for your architecture)
    │
    └─ Handler executes via callbacks (no direct CPU/MMU access)
         Result: file opened, data read, process halted, etc.

Handler Organization

234 registered MON calls (from src/core/mon_registry.c), grouped by function as in chapter 2 of SINTRAN III Monitor Calls (ND-860228.2 EN):

Group Manual section Example Count
File Operations 2.4 1B INBT 48
Input and Output Monitor Calls 2.5 3B ECHOM 29
Monitor Calls for Terminal Handling 2.6 16B MGTTY 14
Monitor Calls for Printer Handling 2.7 234B SPEFI 1
Monitor Calls for Error Handling 2.8 56B PASET 9
File System Operations 2.9 41B ROBJE 21
RT Program Execution 2.10 11B TIME 28
Device Handling 2.11 31B EXIOX 14
Segment Administration 2.12 33B ALTON 23
Data Communication 2.13 200B XMSG 4
Monitor Calls for Internal Use 2.14 45B GTYPR 3
Commonly-Used Monitor Calls 2.3 0B LEAVE 3
Not grouped in manual - 34B ALTOFF 37
Total - - 234

The manual lists some calls in more than one section. Here each call is counted once, in the first section it appears in (section 2.3 Commonly-Used Monitor Calls is checked last), so the rows add up to the total. Example = lowest MON number in the group. Generated by tools/generate_mon_status.py - do not edit by hand.

See docs/mon-implementation-status.md for the complete per-call listing.

MON Calls Status

Implementation completeness (from the authoritative registration table in src/core/mon_registry.c — regenerate with tools/generate_mon_status.py):

✅ VALIDATED (tested, fully working)     —  45 handlers  (19%)
🔶 IN_PROGRESS (partial, may need fixes) —  17 handlers  ( 7%)
❌ NOT_IMPLEMENTED (stubs only)          — 172 handlers  (74%)
   ────────────────────────────────────────────────────────
   Total registered                        234 handlers

Most MON calls are still auto-generated stubs: the dispatcher returns "not implemented" for them without calling the handler. See the full per-call breakdown in docs/mon-implementation-status.md (auto-generated; machine-readable copy in metadata/mon_status.json).

Check which MON calls your program needs:

# Run your program
./build/bin/nd500x --debug < myprogram.dom

# Unimplemented MON calls are logged automatically:
# [MON] ERROR: 412B not implemented (call #1 from PC=0x12345678)

# After execution, get a summary
mon_report_unimplemented_usage();
# Shows: MON 412B — called 3 times
#        MON 413B — called 1 time

For detailed status of each MON call: docs/mon-implementation-status.md

Identifying & Implementing Missing MON Calls

Quick Workflow

# 1. Program fails with unimplemented MON
# [MON] ERROR: 412B not implemented at PC=0x12345678

# 2. Look up the MON call
grep '`412B`' docs/mon-implementation-status.md
# Shows: name, status, handler file size, handler symbol

# 3. Implement it
# See: docs/CARVING.md (step-by-step guide)

# 4. Add tests and update metadata
python3 tools/generate_mon_status.py  # Regenerate status docs and README tables

For in-depth guide: docs/CARVING.md

Testing

cd build
ctest                         # All tests
ctest -R dispatcher -V        # One test, with its PASS/FAIL lines
                              # Tests: dispatcher, params, file_table, mon_handlers

Documentation

Document Purpose
docs/CARVING.md How to identify and implement missing MON calls
docs/INTEGRATION.md Step-by-step integration guide
docs/mon-implementation-status.md Auto-generated: implemented-vs-stub audit (validated/in-progress/stub counts, mismatches)

Tools

Generate MON status

python3 tools/generate_mon_status.py
# Reads:  src/core/mon_registry.c + src/handlers/*.c
#         + metadata/mon_function_groups.json
# Writes: metadata/mon_status.json, docs/mon-implementation-status.md,
#         and the function-group table in README.md

python3 tools/generate_mon_status.py --check
# Exit 1 if a handler's registered status disagrees with its source

NDINSIGHT_DIR=<NDInsight repo root> python3 tools/generate_mon_status.py --extract-groups
# Re-read the function groups from the SINTRAN III Monitor Calls manual
# (Developer/MON/Monitor Calls.md in the NDInsight repo)

Integration Examples

  • ND-500 emulator (nd500x) — external/ndmonlib as submodule
  • ND-100 emulator (nd100x) — Same submodule, different callbacks

Both share identical dispatcher and handlers; only callbacks differ per architecture.

Performance

  • Dispatcher: O(1) hash table lookup
  • Parameter access: O(1) per parameter
  • File operations: Host filesystem speed
  • Overall: Millions of MON calls/second on modern hardware

Portability

  • C Standard: C11 (libc only, no external dependencies)
  • Platforms: Linux, Windows, macOS, WebAssembly (Emscripten)
  • CPU Architectures: ND-100, ND-500, and others via callbacks

License

MIT License — See LICENSE for details.

Stats

Lines of Code:     17,410 (handlers + core)
MON calls:         234 registered (45 validated, 17 in progress, 172 stubs)
Tests:             4 programs (dispatcher, params, file_table, mon_handlers); coverage not measured
Build Time:        <1 second (native)

Latest Release: v1.0 | Stability: Production | Last Updated: 2026-07-23

About

Reusable library for emulated SINTRAN MON calls

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages