# Runtime Architecture

This page explains how the packaged BBS boots, keeps state across Atari BASIC
program loads, routes caller I/O, and dispatches modules. Source of truth:
`source/text/*.bas`, `source/config/MMSAPPS.CFG`, `mms/src/public.inc`, and
`mms/src/constants.inc`.

## Boot Flow

Normal auto-start ATR:

```text
AUTOEXEC.BAT
  -> D1:RHND850.COM
  -> D1:MMS.COM
  -> BASIC /I <<D1:AUTOGO
AUTOGO
  -> RUN "D1:>CORE>RUNBBS"
RUNBBS
  -> USR(MMS_INIT)
  -> request WFC in MMS handoff
  -> RUN "D1:>CORE>APPMGR"
APPMGR
  -> resolve requested stable key in MMSAPPS.DAT
  -> RUN requested module
```

Normal online flow:

```text
RUNBBS -> APPMGR -> WFC -> CORE
CORE -> MESGAREA / FILEBASE / SYSOP / DOORS / XFER
```

Offline utilities are packaged under `D1:>CORE>` but are not part of the online
handoff flow: `INIT`, `FILEMGR`, and `MSGMGR`.

## Module Switching Contract

Online modules are standalone BASIC programs. A `RUN` discards BASIC variables,
so persistent session state must live in MMS, disk files, or the app registry.

The common online-module entry pattern is:

1. Discover `MBASE` from `$03EC/$03ED`.
2. Validate handoff magic/version at `SS=MBASE+$B0`.
3. Restore caller identity, modes, access level, user number, and session time.
4. Call `USR(MOPEN)` to reattach R: without dropping carrier.
5. Apply terminal modes through `MMS_SERVICE`.
6. Call `USR(MRESUME)`.
7. Open `E:` and `K:` for caller I/O.
8. Check `MMS_CONN_STATE` at prompt/input boundaries.
9. Save handoff and return through `APPMGR`.

Modules dispatch by writing a requested stable app key into `SS+90/+91`, an
optional return key into `SS+92/+93`, optional command data into command/handoff
bytes, then running `D1:>CORE>APPMGR`.

## Application Registry Data Flow

Editable source: `source/config/MMSAPPS.CFG`.
Packed runtime file: `D1:>DATA>MMSAPPS.DAT`.

Each registry row contains:

```text
handle,key,return,type,flags,access,route,term,name,path
```

Current stable keys:

| Key | Module | Path |
| ---: | --- | --- |
| `$0001` | WFC | `D1:>CORE>WFC` |
| `$0010` | CORE | `D1:>CORE>CORE` |
| `$0020` | DOORS | `D1:>CORE>DOORS` |
| `$0030` | MESGAREA | `D1:>CORE>MESGAREA` |
| `$0040` | FILEBASE | `D1:>CORE>FILEBASE` |
| `$0050` | SYSOP | `D1:>CORE>SYSOP` |
| `$0060` | XFER | `D1:>CORE>XFER` |

`APPMGR` reads `MMSAPPS.DAT`, verifies the `MAPR` header, applies access checks,
publishes app state into MMS public bytes, prints `Loading <name> ...`, and
runs the target path.

## MMS State Blocks

MMS publishes:

- jump table at `MBASE`;
- `MMS_PUBLIC` at `MBASE+$60`;
- `MMS_COMMAND` at `MBASE+$A0`;
- `MMS_HANDOFF` at `MBASE+$B0`.

`MMS_PUBLIC` is for status, diagnostics, current app state, carrier state, and
runtime settings like `MMS_BAUD_CODE`. `MMS_COMMAND` is a short argument/result
block used by `MMS_SERVICE`. `MMS_HANDOFF` is the cross-`RUN` session block used
by BASIC modules.

## Caller I/O

Normal text I/O uses CIO:

```basic
OPEN #3,12,0,"E:"
OPEN #4,4,0,"K:"
PRINT #3;"TEXT"
GET #3,X
```

MMS HATABS owns the BBS communication layer and routes `E:`/`K:` behavior based
on MMS route and terminal mode state. Raw transfers use `MMS_RGET` and
`MMS_RPUT` through `XFER` after entering raw mode.

## Carrier Handling

MMS keeps public connection state in `MMS_CONN_STATE` and fast handler-facing
state in `MMS_CARRIER_STATUS`. Online modules check carrier at prompt and input
boundaries:

```basic
R=USR(MSTAT):IF PEEK(MCONN)<>3 THEN RUN "D1:>CORE>WFC"
```

On hangup or carrier loss, modules return to `WFC`; they should not spin inside
long prompt loops after carrier is gone.

## Runtime Module Responsibilities

- `RUNBBS`: initializes MMS and requests WFC.
- `APPMGR`: resolves stable app keys and loads modules.
- `WFC`: wait-for-call, registration, login, users, ACL/time, caller history.
- `CORE`: main menu, static text, bulletins, modes, feedback, caller list, dispatch.
- `MESGAREA`: caller message-base commands.
- `FILEBASE`: caller file-area commands and XMODEM dispatch.
- `DOORS`: catalog-driven door listing and launch.
- `SYSOP`: sysop yell/chat command path.
- `XFER`: raw XMODEM upload/download.
- `INIT`: offline baseline data initialization.
- `FILEMGR`: offline file-area maintenance.
- `MSGMGR`: offline message-base maintenance.
