Atari Mutineer Core Programmers Guide
Atari Mutineer is a set of standalone Atari BASIC programs loaded with RUN.
REMMS owns communications and session state so the current program can be
discarded without losing caller identity or connection state.
See Runtime Architecture for the end-to-end flow, REMMS Programmers Guide for the resident API, and Data And File Formats for disk layouts.
Runtime Modules
RUNBBS -> APPMGR -> WFC -> APPMGR -> LOGIN -> APPMGR -> CORE
CORE -> APPMGR -> DOORS / MESGAREA / FILEBASE / SYSCHAT / XFERSEL
| Module | Responsibility |
|---|---|
RUNBBS | initialize REMMS and request WFC |
APPMGR | resolve stable key, validate access, prepare route, and RUN |
WFC | answer calls, terminal detection, local dashboard |
LOGIN | login, registration, registration confirmation, and profile editing |
CORE | main caller command loop and subsystem dispatch |
MESGAREA | multi-base scan/read/enter/kill |
FILEBASE | multi-area list/download/upload/info |
DOORS | catalog lookup, access check, and external door launch |
SYSOP | sysop availability/config actions |
SYSCHAT | line-mode caller/sysop chat |
XFERSEL | transfer protocol selection and native protocol dispatch |
INIT | offline board initialization |
FILEMGR | offline file-area maintenance |
MSGMGR | offline message-base maintenance |
LOGIN is the supported login, registration, and user profile implementation.
Common BASIC Routines
Reusable routines live under source/text/inc/. A module includes one at a
physical line-number base:
2005 INCLUDE "console_open_tail.inc"
Include files use strictly increasing relative lines beginning at 0. The
preprocessor adds the directive base to every included line and to branch
targets that name another line in the same include. Targets not declared by
the include remain absolute, so calls to module-owned routines keep their
normal physical numbers. Includes cannot include other includes.
Keep module declarations, menu policy, error destinations, and domain logic in
the owning .bas file. Use a shared include only when its variable and error
contracts match every consumer. Keep shared routines small and explicit so a
module's line ownership remains easy to inspect.
Application Registry
The packed runtime registry is D1:>DATA>APPREG.DAT.
Rows contain:
handle,key,return,type,flags,access,route,term,name,path
Current stable keys:
| Key | Name | Default return |
|---|---|---|
$0001 | WFC | $0000 |
$0008 | LOGIN | $0001 |
$0010 | CORE | $0001 |
$0020 | DOORS | $0010 |
$0030 | MESGAREA | $0010 |
$0040 | FILEBASE | $0010 |
$0045 | SYSCHAT | $0010 |
$0050 | SYSOP | $0010 |
$0060 | XFERSEL | $0040 |
Modules dispatch by writing the requested key to session +90/+91, the
optional return key to +92/+93, saving owned session state, and running
D1:>CORE>APPMGR.
When adding a module, reserve a stable key, decide the return key, define the minimum access level, and decide whether APPMGR should enter it as a caller module or a local-only tool. Caller modules inherit the current terminal mode, line-feed mode, user identity, access level, time limit, and online state from the REMMS session block.
Online Module Contract
Every supported online module:
- Discovers API, public state, and session through
$03E8. - Validates session magic
77and supported version1..3. - Restores identity, modes, access, user number, session deadline, and any module-specific byte.
- Calls
USR(ROPEN)for a remote session. - Sets mode host and route both; local sessions set both to local.
- Opens caller-facing
E:andK:channels as needed. - Calls
USR(RSTAT)at input boundaries and returns to WFC if session+87is no longer online. - Saves owned fields before another
RUN.
Do not assume BASIC variables or IOCBs survive RUN. Do not parse RING,
CONNECT, or NO CARRIER in BASIC; that belongs to REMMS.
Module Design Checklist
Use this checklist for a new caller-facing module:
- Read
RAPI,RPUB, andSSfrom the discovery record. - Validate
PEEK(SS)=77andPEEK(SS+1)=6. - Restore only the session fields the module owns.
- If
PEEK(SS+87)=1, callUSR(ROPEN,0)and thenUSR(RMODE,1):USR(RROUTE,2). - If
PEEK(SS+87)=8, treat it as a local sysop session and use local route. - Open caller-facing
E:andK:channels after route/mode is set. - Use a timed prompt in the same shape as the other modules:
[ HH:MM:SS Command >,[ HH:MM:SS Msg Command >, or[ HH:MM:SS File Command >. - Before disk reads or writes during a remote call, suspend the modem owner
with
USR(RCLOSE,1), perform bounded disk work, close disk IOCBs, and resume withUSR(ROPEN,0). - Call
USR(RSTAT)orUSR(REVENT)at blocking input boundaries. - On carrier loss or fatal REMMS status, call
USR(RFAIL,reason)and run WFC. - Before dispatching another module, store caller identity, access, time, modes,
and module-specific handoff bytes back to
SS.
Avoid global side effects. A module should not clear all 192 session bytes, change the answer-rings policy, close R: with hangup semantics, or alter terminal mode unless that is the explicit command being handled.
Prompts And Menus
Menus are ordinary text files and are reloaded whenever a parent command loop regains control. Prompts are generated by the module so they can include time-left and the right command noun. Do not embed or cache menu text in BASIC.
Main prompt:
[ HH:MM:SS Command >
Message prompt:
[ HH:MM:SS Msg Command >
File prompt:
[ HH:MM:SS File Command >
Door prompt:
[ HH:MM:SS Door Command >
HH:MM:SS is the caller's remaining session time. Local sysop sessions may use
the same prompt shape with unrestricted or configured local time.
Use the resident pager for long caller-facing displays. Use direct output only for short status lines, prompts, and command responses.
Session Fields Used By BASIC
| Offset | Meaning |
|---|---|
+0/+1 | magic/version |
+2..+42 | handle length/text |
+43..+83 | secondary identity length/text |
+84 | ATASCII mode |
+85 | line-feed mode |
+86 | expert/transfer mode |
+87 | 1 remote online, 8 local sysop handoff |
+90..+93 | requested/return stable keys |
+96 | transient module or transfer mode |
+97 | current message/file/door handoff byte |
+102 | current runtime app handle |
+122 | delayed remote byte |
+123 | access level |
+124/+125 | user number high/low |
+126/+127 | session end minute high/low |
+155/+156 | exit reason and pending-stat flag |
+159/+160 | answer-after rings and ring count |
+161/+162 | next/return runtime handles |
+163..+191 | transfer pathname length/text |
Many modules clear all 192 bytes before constructing a new handoff. When adding
a field, update remms/src/constants.inc, every store/restore routine that owns
it, the contract checker, and the REMMS documentation together.
REMMS Module Skeleton
1000 IF PEEK(1000)<>82 OR PEEK(1001)<>69 OR PEEK(1002)<>77 THEN RUN "D1:>CORE>WFC"
1010 RAPI=PEEK(1004)+256*PEEK(1005):RPUB=PEEK(1006)+256*PEEK(1007):SS=PEEK(1010)+256*PEEK(1011)
1020 RMODE=RAPI+3:RROUTE=RAPI+6:ROPEN=RAPI+9:RSTAT=RAPI+15:RGET=RAPI+18:RPUT=RAPI+21:RTGET=RAPI+27
1030 IF PEEK(SS)<>77 OR PEEK(SS+1)<1 OR PEEK(SS+1)>3 THEN RUN "D1:>CORE>WFC"
1040 IF PEEK(SS+87)=1 THEN R=USR(ROPEN):IF R<>0 THEN RUN "D1:>CORE>WFC"
1050 IF PEEK(SS+87)=1 THEN R=USR(RMODE,1):R=USR(RROUTE,2)
1060 OPEN #3,12,0,"E:":OPEN #4,4,0,"K:"
1070 R=USR(RSTAT):IF PEEK(SS+87)<>1 THEN RUN "D1:>CORE>WFC"
For text input, call RTGET; retry on $0100 (256) and hand
carrier/fatal/timeout results to RFAIL.
Use raw RGET/RPUT only for terminal detection and binary protocols. Text
editors use canonical ATASCII 7E for destructive backspace and 7F for a
one-space tab, and ignore unsupported extended editing controls.
Return Paths
Use APPMGR for normal module switches. Write the requested app key to
SS+90/+91, write the desired return key to SS+92/+93, save module state,
and run D1:>CORE>APPMGR.
Use direct RUN "D1:>CORE>WFC" only after explicit logoff, local shutdown,
carrier loss, fatal REMMS failure, or an unrecoverable application failure.
Use direct RUN "D1:>CORE>CORE" only for local-only maintenance flows that
have already restored their session state.
Disk Ownership Pattern
Remote modules should follow this shape around disk work:
2600 IF ONLINE<>1 THEN RETURN
2610 R=USR(RCLOSE,1):RETURN
2620 IF ONLINE<>1 THEN RETURN
2630 R=USR(ROPEN,0):R=USR(RMODE,1):R=USR(RROUTE,2):RETURN
Open disk files only between the suspend and resume calls. For long displays, read a chunk into a string, close the disk file, resume R:, emit the buffered text, and repeat. Do not wait for caller input while a disk IOCB is open.
CORE Command Surface
CORE currently dispatches:
A: ASCII/ATASCII toggle.B: bulletins.C: caller list.D: doors.E: feedback.F: filebase.G: confirmed goodbye.Hor?: help/function list.I: information.L: line-feed toggle.M: message area.Q: quick logoff.T: text files.W: welcome.X: expert prompt toggle.Y: sysop chat/fallback.
WFC remote entry offers login, new user, and goodbye. Its local controls are START for local sysop CORE, SELECT for offline tools, and OPTION for shutdown.
Persistence
- Users:
USERS.DAT,USERS.IDX,NEXTUSER.DAT,ACL.CFG. - Caller history:
CALLERS.DAT. - Feedback:
FEEDBACK.DAT. - Messages:
MSGBASE.CFGandMESG?.MET/.DAT/.IDX. - Files:
FILE?.MET/.DAT/.IDX. - Doors: offline
DOORS.CFG, runtimeDOORCAT.DAT, generatedDOORMNU, and the configured external disk/path.
INIT, MSGMGR, and FILEMGR own offline creation, verification, rebuild,
and compaction. Runtime modules should preserve existing record sizes and
pointer semantics described in Data And File Formats.
Current Implementation Notes
- The active runtime registry is
APPREG; APPMGR reads bounded packed records. - REMMS wraps and chains
E:,K:, andR:. Local E:/K: calls go directly to the saved handlers; IOCB 5 is reserved for R:. - Page-six helpers load menu data in blocks and emit the local copy with one CIO buffer operation. Remote bytes still use the normal REMMS translation and carrier-failure path.
- CORE, MESGAREA, FILEBASE, DOORS, MSGMAIL, and MSGMOD reload their packaged text menu on every parent-loop return. DOORS uses the fixed-record door catalog instead of parsing CSV while callers wait.
- Terminal detection is performed by WFC from the first caller return before normal line input.
- Every bundled door uses the REMMS API and the canonical text-input contract.