Internal Developing Model 204 from WSL: Difference between revisions
No edit summary |
No edit summary |
||
| (11 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
__NOINDEX__ | __NOINDEX__ | ||
<div style="border:1px solid #c00; padding:6px;">'''Internal use only.''' This page is intentionally not linked from the main page or any category. Do not link it from customer-facing pages.</div> | <div style="border:1px solid #c00; padding:6px;">'''Internal use only.''' This page is intentionally not linked from the main page or any category. Do not link it from customer-facing pages.</div> | ||
__TOC__ | |||
= Developing Model 204 from WSL or macOS (internal) = | = Developing Model 204 from WSL or macOS (internal) = | ||
| Line 10: | Line 11: | ||
! Command !! Purpose | ! Command !! Purpose | ||
|- | |- | ||
| <code>make204</code> || Incrementally assemble Model 204 and link CMS and z/OS modules | | [[#Building with make204|<code>make204</code>]] || Incrementally assemble Model 204 and link CMS and z/OS modules | ||
|- | |||
| [[#Running and testing under emu204|<code>emu204</code>]] || Run the real linked Model 204 module on the workstation | |||
|- | |- | ||
| <code> | | [[#Automated smoke test with testM204Qa|<code>testM204Qa</code>]] || Start Model 204 under <code>emu204</code> and run a QA smoke test | ||
|- | |- | ||
| <code> | | [[#Create the maintenance branch with prezap|<code>prezap</code>]] || Create the header for a new maintenance ZAP | ||
|- | |- | ||
| <code> | | [[#Find patch space with scanzap|<code>scanzap</code>]] || Find the next available local and <code>PTCH$</code> patch offsets | ||
|- | |- | ||
| <code> | | [[#Build the ZAP with make204 and bldzap|<code>bldzap</code>]] || Compare two object decks and generate VER/REP statements | ||
|- | |- | ||
| <code> | | [[#Testing on CMS with putmod|<code>putmod</code>]] || Upload a linked CMS module and map for mainframe testing | ||
|- | |- | ||
| <code> | | [[#Testing on z/OS with putmodzos and gitzosl|<code>putmodzos</code>]] || Upload the z/OS object deck that the z/OS binder uses to create the test load module | ||
|- | |- | ||
| <code> | | [[#Running a local Online with Janus TNSERV|<code>c3270</code> / <code>s3270</code>]] || Connect directly to a Janus Telnet Server running under <code>emu204</code> | ||
|} | |} | ||
This page describes the Model 204 8.0 | This page describes the Model 204 8.0 and 8.1 workflows. Release 8.0 is under '''ZAP maintenance''', so its baseline and ZAP objects must be kept separate. Release 8.1 is under normal development and currently builds directly into <code>obj/</code>. | ||
== Workstation setup == | == Workstation setup == | ||
| Line 75: | Line 78: | ||
If <code>emu204</code> reports that <code>@rocket/em204-linux-x64</code> is not installed, reinstall <code>@rocket/m204-tools</code> without <code>--no-optional</code> or <code>--ignore-scripts</code>. | If <code>emu204</code> reports that <code>@rocket/em204-linux-x64</code> is not installed, reinstall <code>@rocket/m204-tools</code> without <code>--no-optional</code> or <code>--ignore-scripts</code>. | ||
This installation procedure was verified on WSL on 5 November 2026 with <code>@rocket/m204-tools</code> 1.1.167. Updating the nvm installation put <code>make204</code>, <code>emu204</code>, <code>testM204Qa</code>, Imagine, and the ZAP utilities under the same npm prefix. Older copies under <code>/usr/local/bin</code> remained present but no longer took precedence. | |||
== Repositories == | == Repositories == | ||
| Line 81: | Line 86: | ||
* <code>~/gitm204</code> contains the build tools, assembler, linker, emulator, and their tests. | * <code>~/gitm204</code> contains the build tools, assembler, linker, emulator, and their tests. | ||
* <code>~/m204-80</code> contains the Model 204 source | * <code>~/m204-80</code> contains the ZAP-maintained Model 204 8.0 source. | ||
* <code>~/m204-81</code> contains the Model 204 8.1 development source. | |||
The Model 204 directory name matters. It must end in the two-digit release, such as <code>m204-80</code>, because the tools derive the release and CMS disk names from it. | The Model 204 directory name matters. It must end in the two-digit release, such as <code>m204-80</code> or <code>m204-81</code>, because the tools derive the release and CMS disk names from it. | ||
Before beginning a change: | Before beginning a change: | ||
<pre> | <pre> | ||
cd ~/m204- | cd ~/m204-81 | ||
git status --short --branch | git status --short --branch | ||
git switch master | git switch master | ||
| Line 101: | Line 107: | ||
<pre> | <pre> | ||
cd ~/m204- | cd ~/m204-81 | ||
make204 -- | make204 --force | ||
</pre> | </pre> | ||
On the first build, <code>make204</code> downloads the macro and object libraries it needs from CMS. You need a CMS userid with FTP access. The userid defaults from <code>$USER</code>, truncated to eight characters. If the workstation login name is not the CMS userid, set <code>M204_FTPVM_USERID</code> in the shell. | For 8.0, use <code>make204 --no-zap</code> to create the baseline instead. On the first build, <code>make204</code> downloads the macro and object libraries it needs from CMS. You need a CMS userid with FTP access. The userid defaults from <code>$USER</code>, truncated to eight characters. If the workstation login name is not the CMS userid, set <code>M204_FTPVM_USERID</code> in the shell. | ||
On WSL, the tools can offer to install and configure <code>gnome-keyring</code> and <code>libsecret-tools</code> so the CMS password can be saved. If the keyring is not configured, the tools can still run but may ask for the password again. On macOS, they use the system Keychain. | On WSL, the tools can offer to install and configure <code>gnome-keyring</code> and <code>libsecret-tools</code> so the CMS password can be saved. If the keyring is not configured, the tools can still run but may ask for the password again. On macOS, they use the system Keychain. | ||
Library fetches are recorded in <code>.m204libs</code>. If a fetch was interrupted, <code>make204</code> recognizes the half-fetched library and downloads it again. A large number of unknown assembler operations usually means that the macro library is incomplete. | Library fetches are recorded in <code>.m204libs</code>. If a fetch was interrupted, <code>make204</code> recognizes the half-fetched library and downloads it again. An older tree that already has populated libraries but no note is accepted as-is. A large number of unknown assembler operations usually means that the macro library is incomplete. | ||
== | == Building with make204 == | ||
Model 204 assembler source, copy members, macros, and ZAP files are under <code>src/</code>. Build outputs are ignored by Git: | Model 204 assembler source, copy members, macros, and ZAP files are under <code>src/</code>. Build outputs are ignored by Git: | ||
| Line 134: | Line 140: | ||
<pre> | <pre> | ||
cd ~/m204- | cd ~/m204-81 | ||
# Edit src/MODULE.ASSEMBLE, a COPY member, or a MACRO. | # Edit src/MODULE.ASSEMBLE, a COPY member, or a MACRO. | ||
| Line 170: | Line 176: | ||
</pre> | </pre> | ||
The default is controlled by <code>m204.jsonc</code>: | |||
* 8.0 has <code>"zap": true</code>. A bare <code>make204</code> builds under <code>zapobj/</code>; use <code>--no-zap</code> for the baseline. | |||
* 8.1 has <code>"zap": false</code>. A bare <code>make204</code> builds normally under <code>obj/</code>. | |||
On the WSL test machine, <code>make204 --force</code> for 8.1 assembled the complete tree with no assembler warnings or errors and linked both <code>M204ONLN.MODULE</code> and <code>M204ONLN.ZOSMOD</code>. A second bare <code>make204</code> correctly reported every module up to date and skipped the link. | |||
The current 8.1 link prints warnings that no object was found for EVCP and that RSQL was not found in the search path. The link still succeeds. Treat additional missing objects or unresolved externals as errors rather than assuming every linker warning is expected. | |||
== | == Running and testing under emu204 == | ||
<code>emu204</code> runs the real z/OS Model 204 module locally. It is not a source-level reimplementation of Model 204. | <code>emu204</code> runs the real z/OS Model 204 module locally. It is not a source-level reimplementation of Model 204. | ||
=== Automated smoke test with testM204Qa === | |||
The simplest supported baseline smoke test is: | The simplest supported baseline smoke test is: | ||
<pre> | <pre> | ||
cd ~/m204- | cd ~/m204-81 | ||
make204 | make204 | ||
testM204Qa --tree="$HOME/m204- | testM204Qa --tree="$HOME/m204-81" | ||
</pre> | </pre> | ||
<code>testM204Qa</code> starts <code>obj/M204ONLN.MODULE</code> under <code>emu204</code> and runs the <code>UL*</code>, <code>REGEX*</code>, and <code>CMD*</code> QA patterns. It takes roughly half a minute. Results are written under <code>m204qa/out/</code> beside the Model 204 tree. | <code>testM204Qa</code> starts <code>obj/M204ONLN.MODULE</code> under <code>emu204</code> and runs the <code>UL*</code>, <code>REGEX*</code>, and <code>CMD*</code> QA patterns. It takes roughly half a minute. Results are written under <code>m204qa/out/</code> beside the Model 204 tree. | ||
For 8.0, substitute <code>m204-80</code> and build the unmodified baseline with <code>make204 --no-zap</code>. Do not run <code>--no-zap</code> on an 8.0 ZAP branch: it would replace the baseline objects with changed source and destroy the comparison that generates the ZAP. | |||
'''Do not judge this run by the emulator return code.''' Tests deliberately provoke Model 204 errors, so a successful run can have a nonzero Model 204 return code. <code>testM204Qa</code> reads QARUN's output and checks that every pattern finished, ran tests, reported no failures, and produced no SNAP. | '''Do not judge this run by the emulator return code.''' Tests deliberately provoke Model 204 errors, so a successful run can have a nonzero Model 204 return code. <code>testM204Qa</code> reads QARUN's output and checks that every pattern finished, ran tests, reported no failures, and produced no SNAP. | ||
For an interactive or specialized run, | The 8.1 run on 5 November 2026 completed successfully with 647 tests reported passed. Model 204 ended with return code 32, which <code>testM204Qa</code> correctly identified as expected. | ||
Two messages from that run were informational: | |||
* <code>MSIR.1097</code> reported that DFLTCC hardware compression was unavailable under the emulator. | |||
* Two <code>m204proc</code> filenames differed only in case and both folded to procedure <code>CA_DIGICERTGLOBALROOTCA</code>; <code>emu204</code> reported the collision and ignored the second. | |||
When run from an installed tool package, <code>testM204Qa</code> creates <code>m204qa/out/</code> beside the Model 204 tree. In the current 8.1 tree the containing <code>m204qa/</code> directory is not ignored, so <code>git status</code> shows it as untracked after the test. Remove it after preserving any print, audit, or SNAP files needed for diagnosis. | |||
=== Building an emu204 case === | |||
For an interactive or specialized run, create a directory containing an <code>emu204.jsonc</code> configuration, CCAIN, and any files used by the run: | |||
<pre> | |||
mkdir -p ~/em204-cases/mycase/{files,out} | |||
cd ~/em204-cases/mycase | |||
vi emu204.jsonc | |||
vi ccain.txt | |||
emu204 | |||
</pre> | |||
With no <code>--config</code>, <code>emu204</code> reads <code>emu204.jsonc</code> in the current directory. Relative paths in the configuration are resolved against the directory containing the configuration, not against the shell's current directory. This makes the case directory movable. | |||
The complete reference is: | |||
<pre> | <pre> | ||
emu204 --help | emu204 --help | ||
emu204 --help=config | emu204 --help=config | ||
| Line 199: | Line 236: | ||
</pre> | </pre> | ||
A configuration | A useful starting configuration is: | ||
<pre> | |||
{ | |||
"module": "/home/user/m204-81/obj/M204ONLN.MODULE", | |||
"lst": "/home/user/m204-81/lst", | |||
"cpuid": "FF379B789175", | |||
"jobName": "EMU204ON", | |||
"parm": "SYSOPT=X'A0',LIBUFF=3072,LOBUFF=7168,SIRFUNC=X'01',SIRTUNE=0", | |||
"storage": "2G", | |||
"dd": { | |||
"SITEPARM": {"path": "siteparm.txt"}, | |||
"CCAIN": {"path": "ccain.txt"}, | |||
"CCAPRINT": {"path": "out/ccaprint.txt"}, | |||
"CCAAUDIT": {"path": "out/ccaaudit.txt"}, | |||
"CCASNAP": { | |||
"path": "out/ccasnap.txt", | |||
"sequence": true, | |||
"cc": true | |||
}, | |||
"CCASTAT": { | |||
"path": "files/M204.CCASTAT.binary", | |||
"blocked": true | |||
} | |||
}, | |||
"ddDirs": [ | |||
{"path": "files", "suffix": "M204FILE", "m204file": true} | |||
] | |||
} | |||
</pre> | |||
Change the module path to <code>zapobj/M204ONLN.MODULE</code> when the purpose of the case is to test a ZAP-linked module. | |||
=== Identity and authorization === | |||
<code>cpuid</code> is the twelve hexadecimal digits reported by the emulated machine. Model 204 checks it against the authorization in the module, so it must be a CPU ID authorized by the development key. | |||
<code>jobName</code> becomes the name in the TIOT header. A bare <code>LOGIN</code> is trusted as this user, so the name must exist in CCASTAT. If the configured CCASTAT path does not exist, <code>emu204</code> creates a minimal table containing the configured job name. This is normally simpler than copying a password table from a mainframe. | |||
If a real CCASTAT is used, download it with FTP block-mode framing intact and specify <code>"blocked": true</code>. A plain binary byte stream cannot preserve the record boundaries of its undefined-format records. | |||
=== EXEC PARM, SYSOPT, and CCAIN === | |||
The configuration's <code>parm</code> value is the EXEC PARM presented when Model 204 is entered. It is where user-zero parameters such as SYSOPT, LIBUFF, and LOBUFF are normally supplied: | |||
<pre> | |||
"parm": "SYSOPT=X'A0',LIBUFF=3072,LOBUFF=7168,SIRFUNC=X'01',SIRTUNE=0" | |||
</pre> | |||
For the development cases: | |||
* SYSOPT <code>X'80'</code> enables the audit trail. | |||
* SYSOPT <code>X'20'</code> includes RK lines in the audit trail. | |||
* <code>X'A0'</code> enables both. | |||
* Do not add <code>X'02'</code> unless CCAGRP is allocated. | |||
* Do not add <code>X'01'</code> unless CCASYS is already available during initialization. | |||
* A security configuration requiring login must agree with the supplied CCASTAT and CCAIN login commands. | |||
CCAIN is ordinary workstation text. <code>emu204</code> translates it to EBCDIC and pads it to 80-byte card images. Model 204 reads only through column 72; a continued parameter line ends with a dash '''in column 72''', after padding with blanks. A dash that follows the last comma directly, or that sits earlier in the line, is not recognized as a continuation: Model 204 fails with <code>M204.1122: Invalid parameter = -</code>. | |||
A small CCAIN might be (each line ending in a dash is padded so that the dash is in column 72): | |||
<pre> | |||
HDRCTL=3,LVTBL=60000,LNTBL=18000,LSTBL=480000, - | |||
LFTBL=400000,LGTBL=400000, - | |||
NFILES=200,NDCBS=200,NDIR=200,PAGESZ=6184,SPCORE=120000, - | |||
TEMPPAGE=20000,OUTMRL=80,NSERVS=8,SERVSIZE=5000000 | |||
LOGIN | |||
OPEN M204PROC | |||
OPEN QAPROC | |||
I QARUN MYTEST* | |||
EOJ | |||
</pre> | |||
Use <code>TEMPPAGE</code> when an in-memory CCATEMP is sufficient. If the test specifically needs a disk-backed CCATEMP, allocate it as an <code>m204file</code> with <code>new</code> and <code>pages</code> instead. | |||
=== Allocating existing Model 204 files === | |||
An <code>m204file</code> is a flat, untranslated sequence of 6184-byte Model 204 pages. For one file: | |||
<pre> | |||
"PAYROLL": { | |||
"path": "files/PAYROLL.M204FILE", | |||
"m204file": true | |||
} | |||
</pre> | |||
The DDNAME is the JSON key (<code>PAYROLL</code>). For an existing file, omit <code>pages</code>; the allocated size is inferred from the number of pages in the host file. | |||
To allocate every appropriately named file in a directory: | |||
<pre> | |||
"ddDirs": [ | |||
{ | |||
"path": "files", | |||
"suffix": "M204FILE", | |||
"m204file": true | |||
} | |||
] | |||
</pre> | |||
With this form, <code>files/PAYROLL.M204FILE</code> becomes DDNAME <code>PAYROLL</code>. The portion before the suffix must be a valid one-to-eight-character DDNAME. Files with the wrong suffix case or invalid DDNAMEs are reported rather than silently used. | |||
The maximum number of pages available to an existing file is its host-file size divided by 6184. Verify a transferred page image before running: | |||
<pre> | |||
bytes=$(wc -c < files/PAYROLL.M204FILE) | |||
test $((bytes % 6184)) -eq 0 && echo "$((bytes / 6184)) pages" || | |||
echo "not a whole number of Model 204 pages" | |||
</pre> | |||
=== Creating a new or scratch Model 204 file === | |||
For a persistent file that does not exist yet, provide its extent with <code>pages</code>: | |||
<pre> | |||
"NEWDATA": { | |||
"path": "files/NEWDATA.M204FILE", | |||
"m204file": true, | |||
"pages": 1000 | |||
} | |||
</pre> | |||
The host file is created when Model 204 opens it. CCAIN must still issue the normal Model 204 CREATE, OPEN, and INITIALIZE commands. Do not specify <code>new</code> for a persistent database file: <code>new</code> empties the host file at the first open of every emulator run. | |||
For deliberately disposable storage: | |||
<pre> | |||
"CCATEMP": { | |||
"path": "out/ccatemp.pages", | |||
"m204file": true, | |||
"new": true, | |||
"pages": 5000 | |||
} | |||
</pre> | |||
This is suitable for CCATEMP or a test file that must start empty on every run. | |||
=== Getting files from CMS or z/OS === | |||
<code>emu204</code> does not log on to CMS or z/OS and fetch database files itself. Put the required files in the case directory before starting it. | |||
For a physical z/OS Model 204 data set, download it in binary mode with no character translation. The resulting workstation file must be only the concatenated 6184-byte pages: | |||
<pre> | |||
ftp zos-host | |||
binary | |||
get 'HLQ.PAYROLL' files/PAYROLL.M204FILE | |||
quit | |||
</pre> | |||
FTP command syntax and quoting vary by client. After the transfer, verify that the byte count is a multiple of 6184. Do not mark a page image <code>blocked</code>; <code>blocked</code> is for record-oriented files transferred with FTP block-mode framing, not Model 204 database pages. | |||
For example, the following was tested with <code>TOM.PROCFILE</code> on <code>rss1</code>. Transfer the data set in binary and save it under the local Online case: | |||
<pre> | |||
mkdir -p ~/em204-cases/m204-81-tnserv/files | |||
ftp rss1.rocketsoftware.com | |||
binary | |||
get 'TOM.PROCFILE' /home/user/em204-cases/m204-81-tnserv/files/TOM.PROCFILE.m204file | |||
quit | |||
</pre> | |||
The downloaded file was 111,312,000 bytes, exactly 18,000 6184-byte pages. Allocate it to the Online as DD <code>TOMPROC</code>: | |||
<pre> | |||
"TOMPROC": { | |||
"path": "files/TOM.PROCFILE.m204file", | |||
"m204file": true | |||
} | |||
</pre> | |||
The z/OS data set name is <code>TOM.PROCFILE</code>, but the Model 204 file and DD name are <code>TOMPROC</code>. No <code>DEFINE DATASET PROCFILE</code> command is needed. After restarting the Online: | |||
<pre> | |||
OPEN TOMPROC | |||
</pre> | |||
The tested open reported <code>M204.0620: File TOMPROC opened</code>. | |||
The same binary-transfer and DD-allocation process was tested for the release 8.1 procedure files and CCASYS: | |||
{| class="wikitable" | |||
! z/OS data set !! Local DD/file name !! Pages | |||
|- | |||
| <code>ULSPFTOM.V81.QAPROC</code> || <code>QAPROC</code> || 18,000 | |||
|- | |||
| <code>ULSPFTOM.V81.M204PROC</code> || <code>M204PROC</code> || 4,800 | |||
|- | |||
| <code>ULSPFTOM.CCASYS</code> || <code>CCASYS</code> || 2,400 | |||
|- | |||
| <code>ULSPFTOM.CCAGRP</code> || <code>CCAGRP</code> || 120 | |||
|- | |||
| <code>ULSPFTOM.SIRLOCAL</code> || <code>SIRLOCAL</code> || 1,080 | |||
|} | |||
Add the downloaded page images to <code>emu204.jsonc</code>: | |||
<pre> | |||
"QAPROC": { | |||
"path": "files/ULSPFTOM.V81.QAPROC.m204file", | |||
"m204file": true | |||
}, | |||
"M204PROC": { | |||
"path": "files/ULSPFTOM.V81.M204PROC.m204file", | |||
"m204file": true | |||
}, | |||
"CCASYS": { | |||
"path": "files/ULSPFTOM.CCASYS.m204file", | |||
"m204file": true | |||
}, | |||
"CCAGRP": { | |||
"path": "files/ULSPFTOM.CCAGRP.m204file", | |||
"m204file": true | |||
}, | |||
"SIRLOCAL": { | |||
"path": "files/ULSPFTOM.SIRLOCAL.m204file", | |||
"m204file": true | |||
} | |||
</pre> | |||
A file copied while another Online has it open can retain that Online's shared-DASD enqueue entry. Display the entries in the '''local copy''' before forcing anything: | |||
<pre> | |||
ENQCTL M204PROC | |||
</pre> | |||
The tested M204PROC copy contained one exclusive <code>CMS ULSPFTOM</code> entry. After confirming that this was only the copied source entry, it was removed locally with: | |||
<pre> | |||
ENQCTL M204PROC CMS ULSPFTOM | |||
</pre> | |||
Do not use a broad <code>ENQCTL</code> against a shared production file. This command was safe here because it modified an isolated workstation copy. | |||
To make Model 204 open CCASYS and CCAGRP during initialization, include both DDs and set the two low-order SYSOPT bits: | |||
<pre> | |||
"parm": "SYSOPT=X'A3',..." | |||
</pre> | |||
The tested Online initialized successfully with <code>SYSOPT X'A3'</code>. After startup, <code>OPEN QAPROC</code> and <code>OPEN M204PROC</code> succeeded; CCASYS was available for subsystem processing and CCAGRP supplied the <code>SIRSYS</code> group. | |||
SIRPRO also requires <code>SIRLOCAL</code>. Without that DD, subsystem scanning succeeds but startup ends with <code>M204.1521: SIRLOCAL does not exist</code> and <code>M204.0473: Unable to initialize SIRPRO</code>. With <code>LFSCB=20000</code> and SIRLOCAL allocated, the tested startup completed with: | |||
<pre> | |||
M204.0430: Subsystem SIRPRO started | |||
</pre> | |||
CMS Model 204 files may be on direct-access minidisks rather than represented as ordinary CMS files. Such a file cannot simply be fetched by CMS filename. Use the site's normal utility to make either: | |||
* a physical sequential page image that can be downloaded without translation; or | |||
* a Model 204 DUMP data set, which can be restored into a newly allocated local <code>m204file</code>. | |||
The same dump-and-restore method works when direct access to a z/OS data set is unavailable. | |||
If the dump data set was downloaded with FTP <code>MODE B</code>, preserve its record framing: | |||
<pre> | |||
"PAYDUMP": { | |||
"path": "files/PAYROLL.DUMP", | |||
"blocked": true | |||
}, | |||
"PAYROLL": { | |||
"path": "files/PAYROLL.M204FILE", | |||
"m204file": true, | |||
"pages": 10000 | |||
} | |||
</pre> | |||
The target extent must be large enough for the restored file. The CCAIN stream can then create and initialize the target and restore the dump DD: | |||
<pre> | |||
CREATE FILE (NOFORMAT) PAYROLL | |||
END | |||
OPEN FILE PAYROLL | |||
IN FILE PAYROLL INITIALIZE | |||
OPEN PAYROLL | |||
IN FILE PAYROLL RESTORE 192 FROM PAYDUMP | |||
</pre> | |||
Use the site's established DUMP options and restore page size; <code>192</code> above is the value used by current Model 204 QA restore procedures, not a universal replacement for the source environment's dump procedure. | |||
=== Using procedure directories === | |||
Source-controlled procedure directories can be presented as read-only Model 204 procedure files without exporting a binary procedure file: | |||
<pre> | |||
"M204PROC": { | |||
"path": "/home/user/m204-81/m204proc", | |||
"procDir": true | |||
}, | |||
"QAPROC": { | |||
"path": "/home/user/m204-81/qaproc", | |||
"procDir": true | |||
} | |||
</pre> | |||
Each host file becomes one procedure, with its filename folded to upper case. Subdirectories are searched and flattened. Duplicate procedure names are reported. The procedure image is rebuilt when Model 204 opens the file, so host edits are seen after every user has closed the procedure file and it is opened again. | |||
=== Output files and interactive control === | |||
Text DDs such as CCAPRINT and CCAAUDIT are written as readable workstation text. Use <code>"sequence": true</code> for CCASNAP so that each open produces <code>ccasnap1.txt</code>, <code>ccasnap2.txt</code>, and so on instead of replacing the preceding dump. | |||
While Model 204 runs, a console line beginning with <code>#</code> is an emulator command. A bare <code>#</code> stops the guest at the <code>EM></code> prompt; <code>BEGIN</code> resumes it. Use <code>#HELP</code> or <code>emu204 --help=em</code> for display, traceback, trap, trace, and profiling commands. | |||
== ZAP-maintenance workflow == | == ZAP-maintenance workflow == | ||
=== | === Refresh the unmodified baseline === | ||
Every generated ZAP is a comparison against the baseline objects in <code>obj/</code>. Build those objects from current, unmodified master: | Every generated ZAP is a comparison against the baseline objects in <code>obj/</code>. Build those objects from current, unmodified master: | ||
| Line 216: | Line 559: | ||
This step is mandatory. A stale baseline can produce ZAPs for modules that were not changed. Rebuild it after master moves or after a change to the assembler, pinned build date, version settings, or other build configuration. | This step is mandatory. A stale baseline can produce ZAPs for modules that were not changed. Rebuild it after master moves or after a change to the assembler, pinned build date, version settings, or other build configuration. | ||
=== | === Create the maintenance branch with prezap === | ||
The branch name must match <code><release>Z<PDS-number></code>: | The branch name must match <code><release>Z<PDS-number></code>: | ||
| Line 227: | Line 570: | ||
<code>prezap</code> creates <code>src/80Z9206.ZAP</code>. Edit its header to describe the symptom, fix, prerequisites, and any genuinely necessary special instructions. Leave the <code>80Zxxx</code> placeholder in the header; the distribution build assigns the sequence. | <code>prezap</code> creates <code>src/80Z9206.ZAP</code>. Edit its header to describe the symptom, fix, prerequisites, and any genuinely necessary special instructions. Leave the <code>80Zxxx</code> placeholder in the header; the distribution build assigns the sequence. | ||
=== | === Check whether the target can be generated automatically === | ||
<code>SIRE2</code> and <code>EWDP</code> are excluded from automatic object comparison in the current 8.0 configuration. A source change in either module can assemble and link successfully while being absent from the branch ZAP. Such a fix must be cut by hand on CMS or shipped in a relinked module. | <code>SIRE2</code> and <code>EWDP</code> are excluded from automatic object comparison in the current 8.0 configuration. A source change in either module can assemble and link successfully while being absent from the branch ZAP. Such a fix must be cut by hand on CMS or shipped in a relinked module. | ||
| Line 233: | Line 576: | ||
Check the target module before doing the implementation. | Check the target module before doing the implementation. | ||
=== | === Find patch space with scanzap === | ||
For a change that uses a module's local patch area or <code>PTCH$</code>: | For a change that uses a module's local patch area or <code>PTCH$</code>: | ||
| Line 244: | Line 587: | ||
The output reports the next <code>PTCH</code> offset and the next local offset for each named module. Then edit the source under <code>src/</code>. | The output reports the next <code>PTCH</code> offset and the next local offset for each named module. Then edit the source under <code>src/</code>. | ||
=== | === Build the ZAP with make204 and bldzap === | ||
Use a clean ZAP directory for the first build: | Use a clean ZAP directory for the first build: | ||
| Line 276: | Line 619: | ||
</pre> | </pre> | ||
=== | === Prove the test and test the patched module === | ||
First prove that the test exposes the bug in the unpatched baseline: | First prove that the test exposes the bug in the unpatched baseline: | ||
| Line 308: | Line 651: | ||
The standard <code>testM204Qa</code> command reads the normal object directory from <code>hlasm.jsonc</code> and therefore tests <code>obj/M204ONLN.MODULE</code>, not <code>zapobj/M204ONLN.MODULE</code>. Do not cite that smoke test as evidence that the generated ZAP was applied. Test the ZAP build explicitly on CMS/z/OS, or create a separate <code>emu204</code> configuration whose <code>module</code> names the ZAP-linked module. | The standard <code>testM204Qa</code> command reads the normal object directory from <code>hlasm.jsonc</code> and therefore tests <code>obj/M204ONLN.MODULE</code>, not <code>zapobj/M204ONLN.MODULE</code>. Do not cite that smoke test as evidence that the generated ZAP was applied. Test the ZAP build explicitly on CMS/z/OS, or create a separate <code>emu204</code> configuration whose <code>module</code> names the ZAP-linked module. | ||
=== | === Final review === | ||
Before committing: | Before committing: | ||
| Line 319: | Line 662: | ||
* Run <code>git status --short</code> and stage source paths explicitly. Do not stage build output or unrelated files. | * Run <code>git status --short</code> and stage source paths explicitly. Do not stage build output or unrelated files. | ||
== Testing on CMS == | == Testing on CMS with putmod == | ||
<code>putmod</code> uploads the linked CMS MODULE and map to the build disk derived from the release and userid. In the Online's <code>SETUP NAMES</code>, set <code>:tester.</code> to the builder userid so the Online loads that user's module. | <code>putmod</code> uploads the linked CMS MODULE and map to the build disk derived from the release and userid. In the Online's <code>SETUP NAMES</code>, set <code>:tester.</code> to the builder userid so the Online loads that user's module. | ||
| Line 339: | Line 682: | ||
</pre> | </pre> | ||
== Testing on z/OS == | == Testing on z/OS with putmodzos and gitzosl == | ||
The workstation linker produces a concatenated, fixed-80-byte z/OS object deck: | The workstation linker produces a concatenated, fixed-80-byte z/OS object deck: | ||
| Line 461: | Line 804: | ||
Then IPL CMS or start the configuration nickname again. | Then IPL CMS or start the configuration nickname again. | ||
== Running a local Online with Janus TNSERV == | |||
A Janus port of type <code>TNSERV</code> supplies direct TN3270 access to a Model 204 Online. It does not use OMNI, SDS, OPENSERV, VTAM, or <code>IODEV=7</code>: | |||
<pre> | |||
c3270 or s3270 | |||
| | |||
v | |||
localhost:7777 | |||
| | |||
v | |||
Janus TNSERV in Model 204 under emu204 | |||
</pre> | |||
The emulator's IUCV TCP/IP service turns the guest listener into a real workstation socket. The test described below was run successfully against the 8.1 module: <code>s3270</code> connected to port 7777, logged in, and <code>VIEW TNDEV</code> returned <code>TNDEV 21</code>. | |||
=== Install a TN3270 client === | |||
For normal interactive use, the most common client is '''Rocket Terminal Emulator''' on Windows. '''ZOC''' is also commonly used and is available on both Windows and macOS. Configure either product for TN3270 and connect to host <code>127.0.0.1</code>, port <code>7777</code>. | |||
The open-source x3270 family is useful when a command-line or scriptable client is needed: | |||
On Ubuntu or WSL: | |||
<pre> | |||
sudo apt update | |||
sudo apt install c3270 s3270 | |||
</pre> | |||
On macOS: | |||
<pre> | |||
brew install x3270 | |||
</pre> | |||
Homebrew itself must be installed first; the macOS command-line tools do not provide it. | |||
<code>c3270</code> is interactive. <code>s3270</code> accepts commands on standard input and is useful for repeatable tests. Rocket Terminal Emulator, ZOC, <code>c3270</code>, and <code>s3270</code> all provide the required TN3270 support. A plain line-oriented <code>telnet</code> client is not sufficient. | |||
=== Build the local case === | |||
Create the case directory. It is not part of the repository or the npm package, so the files below are the complete case: | |||
<pre> | |||
mkdir -p ~/em204-cases/m204-81-tnserv/{files,out} | |||
cd ~/em204-cases/m204-81-tnserv | |||
</pre> | |||
Its <code>emu204.jsonc</code> names the 8.1 module, sets <code>tcpVm</code> to the same <code>TCPIP</code> service-machine name used by Model 204, and supplies the tested CCAIN, CCASTAT, output, procedure-file, CCASYS, and SIRLOCAL DDs: | |||
<pre> | |||
{ | |||
"module": "/home/user/m204-81/obj/M204ONLN.MODULE", | |||
"lst": "/home/user/m204-81/lst", | |||
"cpuid": "FF379B789175", | |||
"jobName": "ULSPFQA", | |||
"tcpVm": "TCPIP", | |||
"parm": "SYSOPT=X'A3',LIBUFF=3072,LOBUFF=7168,SIRFUNC=X'01',SIRPRMPT=1,SIRTUNE=0", | |||
"storage": "2G", | |||
"dd": { | |||
"CCAIN": {"path": "ccain.txt"}, | |||
"CCAPRINT": {"path": "out/ccaprint.txt"}, | |||
"CCAAUDIT": {"path": "out/ccaaudit.txt"}, | |||
"CCASTAT": {"path": "files/M204.CCASTAT.binary", "blocked": true}, | |||
"CCASNAP": {"path": "out/ccasnap.txt", "sequence": true}, | |||
"TOMPROC": {"path": "files/TOM.PROCFILE.m204file", "m204file": true}, | |||
"QAPROC": {"path": "files/ULSPFTOM.V81.QAPROC.m204file", "m204file": true}, | |||
"M204PROC": {"path": "files/ULSPFTOM.V81.M204PROC.m204file", "m204file": true}, | |||
"CCASYS": {"path": "files/ULSPFTOM.CCASYS.m204file", "m204file": true}, | |||
"CCAGRP": {"path": "files/ULSPFTOM.CCAGRP.m204file", "m204file": true}, | |||
"SIRLOCAL": {"path": "files/ULSPFTOM.SIRLOCAL.m204file", "m204file": true} | |||
} | |||
} | |||
</pre> | |||
The local filenames shown above preserve the source z/OS data set names for clarity. Qualifiers such as <code>TOM</code> and <code>ULSPFTOM</code> are specific to the user or account that owns the source files and will vary for another person running the Online. Substitute the names used for that user's downloaded copies throughout <code>emu204.jsonc</code>. The DD names on the left, such as <code>QAPROC</code>, <code>M204PROC</code>, <code>CCASYS</code>, and <code>CCAGRP</code>, must still match the Model 204 file names expected by the procedures. | |||
On macOS use <code>/Users/<var>name</var>/m204-81</code> in the two paths. The <code>ccain.txt</code> is below. Each line ending in a dash must have that dash in column 72 (see above): | |||
<pre> | |||
HDRCTL=3,LOGADD=5,LVTBL=60000,LITBL=104, - | |||
LTTBL=2000,LNTBL=18000,LOBUFF=26000,LQTBL=70000,LSTBL=480000, - | |||
LFTBL=400000,LGTBL=400000, - | |||
NFILES=100,NDCBS=100,NDIR=100,PAGESZ=6184,SEQOPT=1,SPCORE=120000, - | |||
UDDLPP=0,OUTMRL=80,NUSERS=8,SDAEMDEV=15,NSUBTKS=12, - | |||
ALOCPRIV=7,NSERVS=8,TEMPPAGE=40000,SIRFACT=X'F9',MSGCTL=0, - | |||
OUTLPP=0,LANGUSER=US,SIRTERM=3,LOUTPB=16000,SCRNSTBL=20000, - | |||
LFSCB=20000,TNDEV=21,SERVSIZE=5000000,MAXDAEM=5,NCMPBUF=2,LECHO=0, - | |||
SESNPRV=400,SESNPUB=400,SESUMAX=100,SESDEFOW=2,NUMBUFG=1000 | |||
IODEV=15,NOTERM=7,DUPTERM=6,LINEND=X'0D' | |||
LOGIN | |||
JANUS DEFINE TNSERV 7777 TNSERV 5 WSFQUERY TCPKEEPALIVE - | |||
BINDADDR 127.0.0.1 | |||
JANUS START TNSERV | |||
HALT 48,MODEL 204 JANUS TELNET SERVER READY ON PORT 7777,3,EOD | |||
EOD | |||
HALT 33,ON-LINE USERS REQUESTED TO LOGOFF,3,EOJ | |||
EOJ | |||
</pre> | |||
<code>SYSOPT=X'A3'</code> enables the audit options and causes both CCASYS and CCAGRP to open during initialization. CCAGRP supplies the <code>SIRSYS</code> group used by SIRMON. <code>TNDEV=21</code> enables Janus Telnet sessions. <code>SIRTERM</code> and <code>WSFQUERY</code> support terminal screen geometry. <code>LFSCB=20000</code> gives CCASYS subsystem procedures enough file-group select-list space; the default value of 8 causes <code>M204.1342: FSCB full</code> followed by <code>M204.1457</code>. <code>LGTBL=400000</code> and <code>LFTBL=400000</code> provide the global and file table space needed by the subsystem-definition procedures; the default <code>LGTBL=288</code> caused <code>M204.0562: Request too long - GTBL</code>, again followed by <code>M204.1457</code>. <code>SESNPUB=400</code> permits SIRMON to create its public <code>sirmonMenu</code> session; the default value of zero makes <code>$SESSION_CREATE</code> return code 2 and ultimately causes <code>MSIR.0491</code>. The other session values match the proven QA configuration. With these settings, the tested startup created and opened <code>sirmonMenu</code> and reported <code>M204.0430: Subsystem SIRMON started</code>. Notices for statistics unavailable in this Online were nonfatal. <code>NCMPBUF=2</code> supplies compression buffers required by the compression tests. <code>TCPKEEPALIVE</code> is appropriate for long-lived terminal connections. <code>BINDADDR 127.0.0.1</code> keeps the development port local to the workstation. | |||
The tested case uses a copy of the development CCASTAT rather than a generated account. CCASTAT is an undefined-format, record-oriented data set, so a plain binary stream is not sufficient. Download it with EBCDIC block-mode framing preserved: | |||
<pre> | |||
ftp rss1.rocketsoftware.com | |||
binary | |||
quote type e | |||
quote mode b | |||
get 'M204.CCASTAT' /home/user/em204-cases/m204-81-tnserv/files/M204.CCASTAT.binary | |||
quit | |||
</pre> | |||
Allocate it with <code>"blocked": true</code>, not <code>"m204file": true</code>: | |||
<pre> | |||
"CCASTAT": { | |||
"path": "files/M204.CCASTAT.binary", | |||
"blocked": true | |||
} | |||
</pre> | |||
The <code>TYPE E MODE B</code> transfer preserves the descriptor byte and two-byte count preceding each record. The tested copy was 13,841 bytes in three framed records. Users log in with their existing development CCASTAT user IDs and passwords. | |||
The numbers before the two HALT messages are exact message lengths, not timeouts. An incorrect count causes User 0 to continue reading CCAIN and can immediately reach <code>EOJ</code>. | |||
=== Start the Online === | |||
Start the case with: | |||
<pre> | |||
#!/usr/bin/env bash | |||
set -euo pipefail | |||
cd "$(dirname "$0")" | |||
exec emu204 | |||
</pre> | |||
<pre> | |||
chmod +x run.sh | |||
./run.sh | |||
</pre> | |||
Keep standard input attached to the terminal: the operator replies to the HALT messages (see below) are read from it. Without a terminal, for example under <code>nohup</code>, give it a pipe that stays open, such as <code>sleep 600 | ./run.sh</code>. | |||
Wait for: | |||
<pre> | |||
MODEL 204 JANUS TELNET SERVER READY ON PORT 7777 | |||
</pre> | |||
From another terminal, confirm that the listener exists: | |||
<pre> | |||
nc -vz 127.0.0.1 7777 | |||
</pre> | |||
=== Connect and test === | |||
For an interactive session: | |||
<pre> | |||
c3270 127.0.0.1:7777 | |||
</pre> | |||
At the Model 204 prompt, log in with an account from the copied development CCASTAT and run a test command: | |||
<pre> | |||
LOGIN userid | |||
password | |||
VIEW TNDEV | |||
</pre> | |||
The password is entered in response to <code>M204.0347</code> and is not displayed. The expected result includes: | |||
<pre> | |||
M204.0353: userid ... login | |||
TNDEV 21 IODEV number for TNSERV threads | |||
</pre> | |||
To automate the same check, pipe <code>Connect</code>, <code>String</code>, <code>Enter</code>, <code>Wait</code>, and <code>Ascii</code> actions to <code>s3270 -script</code>. Do not put a real password in a committed script or shell history. | |||
=== Shut down cleanly === | |||
For the quickest shutdown, issue <code>EOJ</code> from a privileged session and answer <code>Y</code> when Model 204 asks for confirmation. The TN3270 connection closes and <code>emu204</code> reports normal Online termination. | |||
Alternatively, log out and quit the TN3270 client. At the <code>emu204</code> operator terminal, reply to the first HALT with: | |||
<pre> | |||
EOD | |||
</pre> | |||
After users have disconnected, reply to the second HALT with: | |||
<pre> | |||
EOJ | |||
</pre> | |||
Model 204 should report that all users are logged out and begin normal Online termination. | |||
== Working on the tools themselves == | == Working on the tools themselves == | ||
| Line 510: | Line 1,052: | ||
|- | |- | ||
| QA run has a nonzero return code || Read the <code>testM204Qa</code> verdict. The Model 204 return code is not the pass/fail result. | | QA run has a nonzero return code || Read the <code>testM204Qa</code> verdict. The Model 204 return code is not the pass/fail result. | ||
|- | |||
| <code>m204qa/</code> appears as untracked after a test || The installed QA driver writes its case and output beside the Model 204 tree. Preserve anything needed from <code>m204qa/out/</code>, then remove the generated directory. | |||
|- | |||
| <code>MSIR.1097</code> says hardware compression is unavailable || Expected under the current emulator; it does not by itself fail the QA run. | |||
|- | |- | ||
| Need more emulator detail || Use <code>emu204 --help</code>, <code>emu204 --help=config</code>, and <code>emu204 --help=em</code>. | | Need more emulator detail || Use <code>emu204 --help</code>, <code>emu204 --help=config</code>, and <code>emu204 --help=em</code>. | ||
|- | |||
| <code>M204.1122: Invalid parameter = -</code> at startup || A continuation dash is not in column 72. Pad the line with blanks so that the dash is the 72nd character. | |||
|- | |||
| Port 7777 closes immediately after startup || Check the HALT message lengths in CCAIN. They must exactly match the message text or User 0 can continue to <code>EOJ</code>. | |||
|- | |||
| A copied CCASTAT cannot be read or logins fail unexpectedly || Download it with <code>binary</code>, <code>quote type e</code>, and <code>quote mode b</code>, then configure it with <code>"blocked": true</code>. | |||
|- | |||
| A plain <code>telnet</code> client connects but does not produce a usable screen || Use a TN3270 client such as <code>c3270</code>; TNSERV requires TN3270 negotiation. | |||
|} | |} | ||
| Line 523: | Line 1,077: | ||
* <code>m204-80/.github/skills/testing.md</code> | * <code>m204-80/.github/skills/testing.md</code> | ||
* <code>m204-80/.github/skills/zos-crossbuild.md</code> | * <code>m204-80/.github/skills/zos-crossbuild.md</code> | ||
* <code>m204-81/DEVELOPMENT.md</code> | |||
* <code>m204-81/.github/skills/building.md</code> | |||
* <code>m204-81/.github/skills/testing.md</code> | |||
Latest revision as of 17:38, 6 November 2026
Developing Model 204 from WSL or macOS (internal)
The @rocket/m204-tools package makes it possible to edit, assemble, link, patch, and test Model 204 from WSL or macOS. The main commands are:
| Command | Purpose |
|---|---|
make204 |
Incrementally assemble Model 204 and link CMS and z/OS modules |
emu204 |
Run the real linked Model 204 module on the workstation |
testM204Qa |
Start Model 204 under emu204 and run a QA smoke test
|
prezap |
Create the header for a new maintenance ZAP |
scanzap |
Find the next available local and PTCH$ patch offsets
|
bldzap |
Compare two object decks and generate VER/REP statements |
putmod |
Upload a linked CMS module and map for mainframe testing |
putmodzos |
Upload the z/OS object deck that the z/OS binder uses to create the test load module |
c3270 / s3270 |
Connect directly to a Janus Telnet Server running under emu204
|
This page describes the Model 204 8.0 and 8.1 workflows. Release 8.0 is under ZAP maintenance, so its baseline and ZAP objects must be kept separate. Release 8.1 is under normal development and currently builds directly into obj/.
Workstation setup
The published tools support:
- WSL 2 or another x86-64 Linux environment; and
- macOS on Apple silicon.
The npm package does not currently include an Intel macOS emulator binary.
WSL
Use WSL 2 with a current Ubuntu distribution. Keep the Git repositories in the Linux filesystem, for example under ~/gitm204 and ~/m204-80, rather than under /mnt/c. Linux builds and Git operations are faster there and do not inherit Windows filename and permission behavior.
Install Git and Node.js/npm, and make sure npm has access to Rocket's registry.
macOS
Install Git and Node.js/npm. The command-line developer tools supplied by Xcode are sufficient for Git. Homebrew or nvm can be used for Node.js; use one installation consistently so an old global npm prefix does not remain earlier on PATH.
The CMS and z/OS passwords are stored in the macOS Keychain. No Linux keyring setup is needed.
The upload commands invoke an ftp command-line client. Modern macOS does not supply one, so verify command -v ftp. If it is absent, install a compatible client such as tnftp with Homebrew.
Install the tools
On either platform, install or update the complete tool suite:
npm install -g @rocket/m204-tools@latest hash -r
The single package supplies make204, hlasm, cmslink, zapobj, emu204, testM204Qa, the ZAP utilities, and the Imagine JavaScript runtime.
Verify the installation:
make204 --help emu204 --help testM204Qa --help type -a make204 emu204 testM204Qa prezap scanzap
All commands should normally come from the same npm installation. If the shell finds a mixture of commands under /usr/local/bin, an nvm directory, a Homebrew prefix, or another npm prefix, remove or update the obsolete installation. A split installation can make make204 use one package version while emu204 uses another.
If emu204 reports that @rocket/em204-linux-x64 is not installed, reinstall @rocket/m204-tools without --no-optional or --ignore-scripts.
This installation procedure was verified on WSL on 5 November 2026 with @rocket/m204-tools 1.1.167. Updating the nvm installation put make204, emu204, testM204Qa, Imagine, and the ZAP utilities under the same npm prefix. Older copies under /usr/local/bin remained present but no longer took precedence.
Repositories
The two repositories have different purposes:
~/gitm204contains the build tools, assembler, linker, emulator, and their tests.~/m204-80contains the ZAP-maintained Model 204 8.0 source.~/m204-81contains the Model 204 8.1 development source.
The Model 204 directory name matters. It must end in the two-digit release, such as m204-80 or m204-81, because the tools derive the release and CMS disk names from it.
Before beginning a change:
cd ~/m204-81 git status --short --branch git switch master git pull
Do not discard uncommitted work. Resolve or preserve it before changing branches.
First build and CMS libraries
From the Model 204 repository root:
cd ~/m204-81 make204 --force
For 8.0, use make204 --no-zap to create the baseline instead. On the first build, make204 downloads the macro and object libraries it needs from CMS. You need a CMS userid with FTP access. The userid defaults from $USER, truncated to eight characters. If the workstation login name is not the CMS userid, set M204_FTPVM_USERID in the shell.
On WSL, the tools can offer to install and configure gnome-keyring and libsecret-tools so the CMS password can be saved. If the keyring is not configured, the tools can still run but may ask for the password again. On macOS, they use the system Keychain.
Library fetches are recorded in .m204libs. If a fetch was interrupted, make204 recognizes the half-fetched library and downloads it again. An older tree that already has populated libraries but no note is accepted as-is. A large number of unknown assembler operations usually means that the macro library is incomplete.
Building with make204
Model 204 assembler source, copy members, macros, and ZAP files are under src/. Build outputs are ignored by Git:
| Directory | Contents |
|---|---|
obj/ |
Baseline object decks and linked modules |
lst/ |
Baseline assembly listings |
ref/ |
Baseline dependency information |
zapobj/ |
ZAP-build objects, per-module ZAPs, and linked modules |
zaplst/ |
ZAP-build listings |
zapref/ |
ZAP-build dependency information |
A typical edit/build loop is:
cd ~/m204-81 # Edit src/MODULE.ASSEMBLE, a COPY member, or a MACRO. make204 MODULE # assemble the named source and link if needed make204 # assemble everything that changed and link if needed
Useful options:
| Option | Meaning |
|---|---|
--force |
Reassemble everything, ignoring dependency timestamps |
--link |
Force a link even when no object appears to have changed |
--no-link |
Assemble without linking |
--stdout |
Show assembler output |
--errLines=N |
Show the first N diagnostic lines for each failed module |
--errMax=0 |
Continue after assembly failures instead of stopping at the first one |
--clear |
Empty the selected build directories before building |
make204 MODULE names an input source, not necessarily an output object. For example, one input may produce more than one output module.
Review the corresponding listing after an assembly:
less lst/MODULE.LST80
The default is controlled by m204.jsonc:
- 8.0 has
"zap": true. A baremake204builds underzapobj/; use--no-zapfor the baseline. - 8.1 has
"zap": false. A baremake204builds normally underobj/.
On the WSL test machine, make204 --force for 8.1 assembled the complete tree with no assembler warnings or errors and linked both M204ONLN.MODULE and M204ONLN.ZOSMOD. A second bare make204 correctly reported every module up to date and skipped the link.
The current 8.1 link prints warnings that no object was found for EVCP and that RSQL was not found in the search path. The link still succeeds. Treat additional missing objects or unresolved externals as errors rather than assuming every linker warning is expected.
Running and testing under emu204
emu204 runs the real z/OS Model 204 module locally. It is not a source-level reimplementation of Model 204.
Automated smoke test with testM204Qa
The simplest supported baseline smoke test is:
cd ~/m204-81 make204 testM204Qa --tree="$HOME/m204-81"
testM204Qa starts obj/M204ONLN.MODULE under emu204 and runs the UL*, REGEX*, and CMD* QA patterns. It takes roughly half a minute. Results are written under m204qa/out/ beside the Model 204 tree.
For 8.0, substitute m204-80 and build the unmodified baseline with make204 --no-zap. Do not run --no-zap on an 8.0 ZAP branch: it would replace the baseline objects with changed source and destroy the comparison that generates the ZAP.
Do not judge this run by the emulator return code. Tests deliberately provoke Model 204 errors, so a successful run can have a nonzero Model 204 return code. testM204Qa reads QARUN's output and checks that every pattern finished, ran tests, reported no failures, and produced no SNAP.
The 8.1 run on 5 November 2026 completed successfully with 647 tests reported passed. Model 204 ended with return code 32, which testM204Qa correctly identified as expected.
Two messages from that run were informational:
MSIR.1097reported that DFLTCC hardware compression was unavailable under the emulator.- Two
m204procfilenames differed only in case and both folded to procedureCA_DIGICERTGLOBALROOTCA;emu204reported the collision and ignored the second.
When run from an installed tool package, testM204Qa creates m204qa/out/ beside the Model 204 tree. In the current 8.1 tree the containing m204qa/ directory is not ignored, so git status shows it as untracked after the test. Remove it after preserving any print, audit, or SNAP files needed for diagnosis.
Building an emu204 case
For an interactive or specialized run, create a directory containing an emu204.jsonc configuration, CCAIN, and any files used by the run:
mkdir -p ~/em204-cases/mycase/{files,out}
cd ~/em204-cases/mycase
vi emu204.jsonc
vi ccain.txt
emu204
With no --config, emu204 reads emu204.jsonc in the current directory. Relative paths in the configuration are resolved against the directory containing the configuration, not against the shell's current directory. This makes the case directory movable.
The complete reference is:
emu204 --help emu204 --help=config emu204 --help=em
A useful starting configuration is:
{
"module": "/home/user/m204-81/obj/M204ONLN.MODULE",
"lst": "/home/user/m204-81/lst",
"cpuid": "FF379B789175",
"jobName": "EMU204ON",
"parm": "SYSOPT=X'A0',LIBUFF=3072,LOBUFF=7168,SIRFUNC=X'01',SIRTUNE=0",
"storage": "2G",
"dd": {
"SITEPARM": {"path": "siteparm.txt"},
"CCAIN": {"path": "ccain.txt"},
"CCAPRINT": {"path": "out/ccaprint.txt"},
"CCAAUDIT": {"path": "out/ccaaudit.txt"},
"CCASNAP": {
"path": "out/ccasnap.txt",
"sequence": true,
"cc": true
},
"CCASTAT": {
"path": "files/M204.CCASTAT.binary",
"blocked": true
}
},
"ddDirs": [
{"path": "files", "suffix": "M204FILE", "m204file": true}
]
}
Change the module path to zapobj/M204ONLN.MODULE when the purpose of the case is to test a ZAP-linked module.
Identity and authorization
cpuid is the twelve hexadecimal digits reported by the emulated machine. Model 204 checks it against the authorization in the module, so it must be a CPU ID authorized by the development key.
jobName becomes the name in the TIOT header. A bare LOGIN is trusted as this user, so the name must exist in CCASTAT. If the configured CCASTAT path does not exist, emu204 creates a minimal table containing the configured job name. This is normally simpler than copying a password table from a mainframe.
If a real CCASTAT is used, download it with FTP block-mode framing intact and specify "blocked": true. A plain binary byte stream cannot preserve the record boundaries of its undefined-format records.
EXEC PARM, SYSOPT, and CCAIN
The configuration's parm value is the EXEC PARM presented when Model 204 is entered. It is where user-zero parameters such as SYSOPT, LIBUFF, and LOBUFF are normally supplied:
"parm": "SYSOPT=X'A0',LIBUFF=3072,LOBUFF=7168,SIRFUNC=X'01',SIRTUNE=0"
For the development cases:
- SYSOPT
X'80'enables the audit trail. - SYSOPT
X'20'includes RK lines in the audit trail. X'A0'enables both.- Do not add
X'02'unless CCAGRP is allocated. - Do not add
X'01'unless CCASYS is already available during initialization. - A security configuration requiring login must agree with the supplied CCASTAT and CCAIN login commands.
CCAIN is ordinary workstation text. emu204 translates it to EBCDIC and pads it to 80-byte card images. Model 204 reads only through column 72; a continued parameter line ends with a dash in column 72, after padding with blanks. A dash that follows the last comma directly, or that sits earlier in the line, is not recognized as a continuation: Model 204 fails with M204.1122: Invalid parameter = -.
A small CCAIN might be (each line ending in a dash is padded so that the dash is in column 72):
HDRCTL=3,LVTBL=60000,LNTBL=18000,LSTBL=480000, - LFTBL=400000,LGTBL=400000, - NFILES=200,NDCBS=200,NDIR=200,PAGESZ=6184,SPCORE=120000, - TEMPPAGE=20000,OUTMRL=80,NSERVS=8,SERVSIZE=5000000 LOGIN OPEN M204PROC OPEN QAPROC I QARUN MYTEST* EOJ
Use TEMPPAGE when an in-memory CCATEMP is sufficient. If the test specifically needs a disk-backed CCATEMP, allocate it as an m204file with new and pages instead.
Allocating existing Model 204 files
An m204file is a flat, untranslated sequence of 6184-byte Model 204 pages. For one file:
"PAYROLL": {
"path": "files/PAYROLL.M204FILE",
"m204file": true
}
The DDNAME is the JSON key (PAYROLL). For an existing file, omit pages; the allocated size is inferred from the number of pages in the host file.
To allocate every appropriately named file in a directory:
"ddDirs": [
{
"path": "files",
"suffix": "M204FILE",
"m204file": true
}
]
With this form, files/PAYROLL.M204FILE becomes DDNAME PAYROLL. The portion before the suffix must be a valid one-to-eight-character DDNAME. Files with the wrong suffix case or invalid DDNAMEs are reported rather than silently used.
The maximum number of pages available to an existing file is its host-file size divided by 6184. Verify a transferred page image before running:
bytes=$(wc -c < files/PAYROLL.M204FILE) test $((bytes % 6184)) -eq 0 && echo "$((bytes / 6184)) pages" || echo "not a whole number of Model 204 pages"
Creating a new or scratch Model 204 file
For a persistent file that does not exist yet, provide its extent with pages:
"NEWDATA": {
"path": "files/NEWDATA.M204FILE",
"m204file": true,
"pages": 1000
}
The host file is created when Model 204 opens it. CCAIN must still issue the normal Model 204 CREATE, OPEN, and INITIALIZE commands. Do not specify new for a persistent database file: new empties the host file at the first open of every emulator run.
For deliberately disposable storage:
"CCATEMP": {
"path": "out/ccatemp.pages",
"m204file": true,
"new": true,
"pages": 5000
}
This is suitable for CCATEMP or a test file that must start empty on every run.
Getting files from CMS or z/OS
emu204 does not log on to CMS or z/OS and fetch database files itself. Put the required files in the case directory before starting it.
For a physical z/OS Model 204 data set, download it in binary mode with no character translation. The resulting workstation file must be only the concatenated 6184-byte pages:
ftp zos-host binary get 'HLQ.PAYROLL' files/PAYROLL.M204FILE quit
FTP command syntax and quoting vary by client. After the transfer, verify that the byte count is a multiple of 6184. Do not mark a page image blocked; blocked is for record-oriented files transferred with FTP block-mode framing, not Model 204 database pages.
For example, the following was tested with TOM.PROCFILE on rss1. Transfer the data set in binary and save it under the local Online case:
mkdir -p ~/em204-cases/m204-81-tnserv/files ftp rss1.rocketsoftware.com binary get 'TOM.PROCFILE' /home/user/em204-cases/m204-81-tnserv/files/TOM.PROCFILE.m204file quit
The downloaded file was 111,312,000 bytes, exactly 18,000 6184-byte pages. Allocate it to the Online as DD TOMPROC:
"TOMPROC": {
"path": "files/TOM.PROCFILE.m204file",
"m204file": true
}
The z/OS data set name is TOM.PROCFILE, but the Model 204 file and DD name are TOMPROC. No DEFINE DATASET PROCFILE command is needed. After restarting the Online:
OPEN TOMPROC
The tested open reported M204.0620: File TOMPROC opened.
The same binary-transfer and DD-allocation process was tested for the release 8.1 procedure files and CCASYS:
| z/OS data set | Local DD/file name | Pages |
|---|---|---|
ULSPFTOM.V81.QAPROC |
QAPROC |
18,000 |
ULSPFTOM.V81.M204PROC |
M204PROC |
4,800 |
ULSPFTOM.CCASYS |
CCASYS |
2,400 |
ULSPFTOM.CCAGRP |
CCAGRP |
120 |
ULSPFTOM.SIRLOCAL |
SIRLOCAL |
1,080 |
Add the downloaded page images to emu204.jsonc:
"QAPROC": {
"path": "files/ULSPFTOM.V81.QAPROC.m204file",
"m204file": true
},
"M204PROC": {
"path": "files/ULSPFTOM.V81.M204PROC.m204file",
"m204file": true
},
"CCASYS": {
"path": "files/ULSPFTOM.CCASYS.m204file",
"m204file": true
},
"CCAGRP": {
"path": "files/ULSPFTOM.CCAGRP.m204file",
"m204file": true
},
"SIRLOCAL": {
"path": "files/ULSPFTOM.SIRLOCAL.m204file",
"m204file": true
}
A file copied while another Online has it open can retain that Online's shared-DASD enqueue entry. Display the entries in the local copy before forcing anything:
ENQCTL M204PROC
The tested M204PROC copy contained one exclusive CMS ULSPFTOM entry. After confirming that this was only the copied source entry, it was removed locally with:
ENQCTL M204PROC CMS ULSPFTOM
Do not use a broad ENQCTL against a shared production file. This command was safe here because it modified an isolated workstation copy.
To make Model 204 open CCASYS and CCAGRP during initialization, include both DDs and set the two low-order SYSOPT bits:
"parm": "SYSOPT=X'A3',..."
The tested Online initialized successfully with SYSOPT X'A3'. After startup, OPEN QAPROC and OPEN M204PROC succeeded; CCASYS was available for subsystem processing and CCAGRP supplied the SIRSYS group.
SIRPRO also requires SIRLOCAL. Without that DD, subsystem scanning succeeds but startup ends with M204.1521: SIRLOCAL does not exist and M204.0473: Unable to initialize SIRPRO. With LFSCB=20000 and SIRLOCAL allocated, the tested startup completed with:
M204.0430: Subsystem SIRPRO started
CMS Model 204 files may be on direct-access minidisks rather than represented as ordinary CMS files. Such a file cannot simply be fetched by CMS filename. Use the site's normal utility to make either:
- a physical sequential page image that can be downloaded without translation; or
- a Model 204 DUMP data set, which can be restored into a newly allocated local
m204file.
The same dump-and-restore method works when direct access to a z/OS data set is unavailable.
If the dump data set was downloaded with FTP MODE B, preserve its record framing:
"PAYDUMP": {
"path": "files/PAYROLL.DUMP",
"blocked": true
},
"PAYROLL": {
"path": "files/PAYROLL.M204FILE",
"m204file": true,
"pages": 10000
}
The target extent must be large enough for the restored file. The CCAIN stream can then create and initialize the target and restore the dump DD:
CREATE FILE (NOFORMAT) PAYROLL END OPEN FILE PAYROLL IN FILE PAYROLL INITIALIZE OPEN PAYROLL IN FILE PAYROLL RESTORE 192 FROM PAYDUMP
Use the site's established DUMP options and restore page size; 192 above is the value used by current Model 204 QA restore procedures, not a universal replacement for the source environment's dump procedure.
Using procedure directories
Source-controlled procedure directories can be presented as read-only Model 204 procedure files without exporting a binary procedure file:
"M204PROC": {
"path": "/home/user/m204-81/m204proc",
"procDir": true
},
"QAPROC": {
"path": "/home/user/m204-81/qaproc",
"procDir": true
}
Each host file becomes one procedure, with its filename folded to upper case. Subdirectories are searched and flattened. Duplicate procedure names are reported. The procedure image is rebuilt when Model 204 opens the file, so host edits are seen after every user has closed the procedure file and it is opened again.
Output files and interactive control
Text DDs such as CCAPRINT and CCAAUDIT are written as readable workstation text. Use "sequence": true for CCASNAP so that each open produces ccasnap1.txt, ccasnap2.txt, and so on instead of replacing the preceding dump.
While Model 204 runs, a console line beginning with # is an emulator command. A bare # stops the guest at the EM> prompt; BEGIN resumes it. Use #HELP or emu204 --help=em for display, traceback, trap, trace, and profiling commands.
ZAP-maintenance workflow
Refresh the unmodified baseline
Every generated ZAP is a comparison against the baseline objects in obj/. Build those objects from current, unmodified master:
cd ~/m204-80 git switch master git pull make204 --no-zap
This step is mandatory. A stale baseline can produce ZAPs for modules that were not changed. Rebuild it after master moves or after a change to the assembler, pinned build date, version settings, or other build configuration.
Create the maintenance branch with prezap
The branch name must match <release>Z<PDS-number>:
git switch -c 80Z9206 prezap
prezap creates src/80Z9206.ZAP. Edit its header to describe the symptom, fix, prerequisites, and any genuinely necessary special instructions. Leave the 80Zxxx placeholder in the header; the distribution build assigns the sequence.
Check whether the target can be generated automatically
SIRE2 and EWDP are excluded from automatic object comparison in the current 8.0 configuration. A source change in either module can assemble and link successfully while being absent from the branch ZAP. Such a fix must be cut by hand on CMS or shipped in a relinked module.
Check the target module before doing the implementation.
Find patch space with scanzap
For a change that uses a module's local patch area or PTCH$:
scanzap SCOMP scanzap SCOMP OTHERMOD
The output reports the next PTCH offset and the next local offset for each named module. Then edit the source under src/.
Build the ZAP with make204 and bldzap
Use a clean ZAP directory for the first build:
make204 --clear
Subsequent builds can be incremental:
make204
In ZAP mode, make204:
- assembles into
zapobj/,zaplst/, andzapref/; - compares each changed object with the baseline object in
obj/; - invokes
bldzapto create per-module NAME/VER/REP statements; - links
zapobj/M204ONLN.MODULEandzapobj/M204ONLN.ZOSMOD; and - appends the generated statements to
src/<branch>.ZAP.
A successful run reports a header and one or more generated ZAPs. Header only (no ZAPs) means that no object difference was found. The usual causes are an unchanged source, a baseline that already contains the fix, or a target excluded by m204.jsonc.
Review all three forms of the result:
less src/80Z9206.ZAP less zaplst/MODULE.LST80 git diff -- src/80Z9206.ZAP src/MODULE.ASSEMBLE
Prove the test and test the patched module
First prove that the test exposes the bug in the unpatched baseline:
putmod --no-zap
Recycle the CMS Online and run the test. It should fail or reproduce the reported BUG/SNAP.
Then upload the ZAP-applied build:
make204 --zap putmod --zap
For z/OS, upload the ZAP-build object deck:
putmodzos --zap
Run the z/OS bind described below, recycle the Online, and run the same test. To switch back:
putmod --no-zap putmodzos --no-zap
The standard testM204Qa command reads the normal object directory from hlasm.jsonc and therefore tests obj/M204ONLN.MODULE, not zapobj/M204ONLN.MODULE. Do not cite that smoke test as evidence that the generated ZAP was applied. Test the ZAP build explicitly on CMS/z/OS, or create a separate emu204 configuration whose module names the ZAP-linked module.
Final review
Before committing:
- Verify that the branch ZAP names only the modules expected for the fix.
- Verify every VER and REP block and the correct patch offsets.
- Check the prerequisite ZAP line; remove it if there is no prerequisite.
- Remove the template's special-instructions block unless it is required.
- Make sure the instructions name every load module that must be patched.
- Run
git status --shortand stage source paths explicitly. Do not stage build output or unrelated files.
Testing on CMS with putmod
putmod uploads the linked CMS MODULE and map to the build disk derived from the release and userid. In the Online's SETUP NAMES, set :tester. to the builder userid so the Online loads that user's module.
The normal recycle is:
EOJ IPL CMS
At the CMS Ready prompt, PROFILE EXEC normally starts the Online. Run the reproducing QA procedure after the Online is ready.
Procedure changes are separate from the module upload. Push modified procedure directories with:
gitproc push qaproc gitproc push m204proc
Testing on z/OS with putmodzos and gitzosl
The workstation linker produces a concatenated, fixed-80-byte z/OS object deck:
- baseline:
obj/M204ONLN.ZOSMOD - ZAP build:
zapobj/M204ONLN.ZOSMOD
putmodzos uploads that object deck to the PDSE member named by zos.jsonc. It does not create the executable z/OS load module by itself. The gitzosl job on the Builder runs the z/OS binder and creates the test load module.
Configuration
The Model 204 tree needs zos.jsonc containing the z/OS FTP host, userid, object library, and member:
{
"host": "...",
"user": "...",
"objlib": "...",
"member": "..."
}
Do not put the password in this file. putmodzos obtains it from the workstation credential store, prompting on first use.
Build and upload
For an unpatched baseline test:
cd ~/m204-80 make204 --no-zap putmodzos --no-zap
For a ZAP-maintenance test:
make204 --zap putmodzos --zap
The upload is binary into an FB 80 PDSE member. If putmodzos says the object deck is missing, run make204 first and confirm that the selected obj/ or zapobj/ directory contains M204ONLN.ZOSMOD.
Bind on z/OS
On the Builder, run:
gitzosl
The submitted job deletes the prior test load module, compresses the test load library, binds M204ONLN with IEWL, and applies the required ZAPs. Its output returns to the Builder's virtual reader through RSCS/NJE.
Use rl (RDRLIST), then PF11 to inspect the job output. A successful bind includes:
$HASP395 ONLINE ENDED - RC=0000
Do not start the test Online if the bind failed or if the expected object deck was not used.
Select the z/OS Online
On the Online's CMS console:
EOJ xedit setup names a
Change:
:opsys.CMS
to:
:opsys.MVS
The XEDIT command is:
c/:opsys.CMS/:opsys.MVS/ * file
Leave :tester. set to the builder userid. It still selects the test version of M204ONLN.
Start and test
Start with either a full CMS IPL or the configuration nickname:
IPL CMS
PROFILE EXEC builds and submits the startup JCL. The JES messages include receipt of the job and completion of the submission step with MAXCC=0000. Unlike a CMS Online, Model 204 is now running as a z/OS batch job; the CMS console returns to VM read instead of displaying the local ONLINE message.
Connect from the normal user session:
M204F suffix LOGIN OPEN QAPROC I QARUN pattern
Run the same reproducer used for the baseline. For a ZAP fix, keep evidence that the baseline failed and the ZAP build passed.
Return to CMS testing
Shut down the z/OS Online, edit SETUP NAMES, and change:
c/:opsys.MVS/:opsys.CMS/ * file
Then IPL CMS or start the configuration nickname again.
Running a local Online with Janus TNSERV
A Janus port of type TNSERV supplies direct TN3270 access to a Model 204 Online. It does not use OMNI, SDS, OPENSERV, VTAM, or IODEV=7:
c3270 or s3270
|
v
localhost:7777
|
v
Janus TNSERV in Model 204 under emu204
The emulator's IUCV TCP/IP service turns the guest listener into a real workstation socket. The test described below was run successfully against the 8.1 module: s3270 connected to port 7777, logged in, and VIEW TNDEV returned TNDEV 21.
Install a TN3270 client
For normal interactive use, the most common client is Rocket Terminal Emulator on Windows. ZOC is also commonly used and is available on both Windows and macOS. Configure either product for TN3270 and connect to host 127.0.0.1, port 7777.
The open-source x3270 family is useful when a command-line or scriptable client is needed:
On Ubuntu or WSL:
sudo apt update sudo apt install c3270 s3270
On macOS:
brew install x3270
Homebrew itself must be installed first; the macOS command-line tools do not provide it.
c3270 is interactive. s3270 accepts commands on standard input and is useful for repeatable tests. Rocket Terminal Emulator, ZOC, c3270, and s3270 all provide the required TN3270 support. A plain line-oriented telnet client is not sufficient.
Build the local case
Create the case directory. It is not part of the repository or the npm package, so the files below are the complete case:
mkdir -p ~/em204-cases/m204-81-tnserv/{files,out}
cd ~/em204-cases/m204-81-tnserv
Its emu204.jsonc names the 8.1 module, sets tcpVm to the same TCPIP service-machine name used by Model 204, and supplies the tested CCAIN, CCASTAT, output, procedure-file, CCASYS, and SIRLOCAL DDs:
{
"module": "/home/user/m204-81/obj/M204ONLN.MODULE",
"lst": "/home/user/m204-81/lst",
"cpuid": "FF379B789175",
"jobName": "ULSPFQA",
"tcpVm": "TCPIP",
"parm": "SYSOPT=X'A3',LIBUFF=3072,LOBUFF=7168,SIRFUNC=X'01',SIRPRMPT=1,SIRTUNE=0",
"storage": "2G",
"dd": {
"CCAIN": {"path": "ccain.txt"},
"CCAPRINT": {"path": "out/ccaprint.txt"},
"CCAAUDIT": {"path": "out/ccaaudit.txt"},
"CCASTAT": {"path": "files/M204.CCASTAT.binary", "blocked": true},
"CCASNAP": {"path": "out/ccasnap.txt", "sequence": true},
"TOMPROC": {"path": "files/TOM.PROCFILE.m204file", "m204file": true},
"QAPROC": {"path": "files/ULSPFTOM.V81.QAPROC.m204file", "m204file": true},
"M204PROC": {"path": "files/ULSPFTOM.V81.M204PROC.m204file", "m204file": true},
"CCASYS": {"path": "files/ULSPFTOM.CCASYS.m204file", "m204file": true},
"CCAGRP": {"path": "files/ULSPFTOM.CCAGRP.m204file", "m204file": true},
"SIRLOCAL": {"path": "files/ULSPFTOM.SIRLOCAL.m204file", "m204file": true}
}
}
The local filenames shown above preserve the source z/OS data set names for clarity. Qualifiers such as TOM and ULSPFTOM are specific to the user or account that owns the source files and will vary for another person running the Online. Substitute the names used for that user's downloaded copies throughout emu204.jsonc. The DD names on the left, such as QAPROC, M204PROC, CCASYS, and CCAGRP, must still match the Model 204 file names expected by the procedures.
On macOS use /Users/name/m204-81 in the two paths. The ccain.txt is below. Each line ending in a dash must have that dash in column 72 (see above):
HDRCTL=3,LOGADD=5,LVTBL=60000,LITBL=104, - LTTBL=2000,LNTBL=18000,LOBUFF=26000,LQTBL=70000,LSTBL=480000, - LFTBL=400000,LGTBL=400000, - NFILES=100,NDCBS=100,NDIR=100,PAGESZ=6184,SEQOPT=1,SPCORE=120000, - UDDLPP=0,OUTMRL=80,NUSERS=8,SDAEMDEV=15,NSUBTKS=12, - ALOCPRIV=7,NSERVS=8,TEMPPAGE=40000,SIRFACT=X'F9',MSGCTL=0, - OUTLPP=0,LANGUSER=US,SIRTERM=3,LOUTPB=16000,SCRNSTBL=20000, - LFSCB=20000,TNDEV=21,SERVSIZE=5000000,MAXDAEM=5,NCMPBUF=2,LECHO=0, - SESNPRV=400,SESNPUB=400,SESUMAX=100,SESDEFOW=2,NUMBUFG=1000 IODEV=15,NOTERM=7,DUPTERM=6,LINEND=X'0D' LOGIN JANUS DEFINE TNSERV 7777 TNSERV 5 WSFQUERY TCPKEEPALIVE - BINDADDR 127.0.0.1 JANUS START TNSERV HALT 48,MODEL 204 JANUS TELNET SERVER READY ON PORT 7777,3,EOD EOD HALT 33,ON-LINE USERS REQUESTED TO LOGOFF,3,EOJ EOJ
SYSOPT=X'A3' enables the audit options and causes both CCASYS and CCAGRP to open during initialization. CCAGRP supplies the SIRSYS group used by SIRMON. TNDEV=21 enables Janus Telnet sessions. SIRTERM and WSFQUERY support terminal screen geometry. LFSCB=20000 gives CCASYS subsystem procedures enough file-group select-list space; the default value of 8 causes M204.1342: FSCB full followed by M204.1457. LGTBL=400000 and LFTBL=400000 provide the global and file table space needed by the subsystem-definition procedures; the default LGTBL=288 caused M204.0562: Request too long - GTBL, again followed by M204.1457. SESNPUB=400 permits SIRMON to create its public sirmonMenu session; the default value of zero makes $SESSION_CREATE return code 2 and ultimately causes MSIR.0491. The other session values match the proven QA configuration. With these settings, the tested startup created and opened sirmonMenu and reported M204.0430: Subsystem SIRMON started. Notices for statistics unavailable in this Online were nonfatal. NCMPBUF=2 supplies compression buffers required by the compression tests. TCPKEEPALIVE is appropriate for long-lived terminal connections. BINDADDR 127.0.0.1 keeps the development port local to the workstation.
The tested case uses a copy of the development CCASTAT rather than a generated account. CCASTAT is an undefined-format, record-oriented data set, so a plain binary stream is not sufficient. Download it with EBCDIC block-mode framing preserved:
ftp rss1.rocketsoftware.com binary quote type e quote mode b get 'M204.CCASTAT' /home/user/em204-cases/m204-81-tnserv/files/M204.CCASTAT.binary quit
Allocate it with "blocked": true, not "m204file": true:
"CCASTAT": {
"path": "files/M204.CCASTAT.binary",
"blocked": true
}
The TYPE E MODE B transfer preserves the descriptor byte and two-byte count preceding each record. The tested copy was 13,841 bytes in three framed records. Users log in with their existing development CCASTAT user IDs and passwords.
The numbers before the two HALT messages are exact message lengths, not timeouts. An incorrect count causes User 0 to continue reading CCAIN and can immediately reach EOJ.
Start the Online
Start the case with:
#!/usr/bin/env bash set -euo pipefail cd "$(dirname "$0")" exec emu204
chmod +x run.sh ./run.sh
Keep standard input attached to the terminal: the operator replies to the HALT messages (see below) are read from it. Without a terminal, for example under nohup, give it a pipe that stays open, such as sleep 600 | ./run.sh.
Wait for:
MODEL 204 JANUS TELNET SERVER READY ON PORT 7777
From another terminal, confirm that the listener exists:
nc -vz 127.0.0.1 7777
Connect and test
For an interactive session:
c3270 127.0.0.1:7777
At the Model 204 prompt, log in with an account from the copied development CCASTAT and run a test command:
LOGIN userid password VIEW TNDEV
The password is entered in response to M204.0347 and is not displayed. The expected result includes:
M204.0353: userid ... login TNDEV 21 IODEV number for TNSERV threads
To automate the same check, pipe Connect, String, Enter, Wait, and Ascii actions to s3270 -script. Do not put a real password in a committed script or shell history.
Shut down cleanly
For the quickest shutdown, issue EOJ from a privileged session and answer Y when Model 204 asks for confirmation. The TN3270 connection closes and emu204 reports normal Online termination.
Alternatively, log out and quit the TN3270 client. At the emu204 operator terminal, reply to the first HALT with:
EOD
After users have disconnected, reply to the second HALT with:
EOJ
Model 204 should report that all users are logged out and begin normal Online termination.
Working on the tools themselves
Use ~/gitm204 only when changing make204, emu204, the assembler/linker, or another tool:
cd ~/gitm204 npm install npx make npm test
Useful narrower checks are:
npm run testci npm run testmake npm run testm204 npm run testm204qa
To prove the working-tree tools can build and run Model 204:
npx make npx testM204Build --tree="$HOME/m204-80" npx testM204Qa --tree="$HOME/m204-80"
testM204Build empties obj/ and ref/ in the tree it is given. Do not point it at a working tree whose current build output must be preserved.
Troubleshooting
| Symptom | Action |
|---|---|
make204 is not found |
Reinstall @rocket/m204-tools, run hash -r, and inspect type -a make204.
|
emu204 says its platform package is missing |
Reinstall without --no-optional or --ignore-scripts; check for an older command earlier on PATH. Published binaries support x86-64 Linux and Apple-silicon macOS.
|
| Hundreds of unknown assembler operations | The macro libraries are probably absent or half-fetched. Run getmaclib --direct, then rebuild.
|
| Linker reports unresolved LE symbols | Fetch the required object library with getobjlib --direct.
|
| ZAP file has only its header | Confirm the source really differs from the baseline, refresh the baseline from unmodified master, and check whether the module is excluded from automatic ZAP generation. |
| ZAP unexpectedly contains many modules | The baseline or a pinned build setting is stale. Return to master and rebuild with make204 --no-zap.
|
| QA run has a nonzero return code | Read the testM204Qa verdict. The Model 204 return code is not the pass/fail result.
|
m204qa/ appears as untracked after a test |
The installed QA driver writes its case and output beside the Model 204 tree. Preserve anything needed from m204qa/out/, then remove the generated directory.
|
MSIR.1097 says hardware compression is unavailable |
Expected under the current emulator; it does not by itself fail the QA run. |
| Need more emulator detail | Use emu204 --help, emu204 --help=config, and emu204 --help=em.
|
M204.1122: Invalid parameter = - at startup |
A continuation dash is not in column 72. Pad the line with blanks so that the dash is the 72nd character. |
| Port 7777 closes immediately after startup | Check the HALT message lengths in CCAIN. They must exactly match the message text or User 0 can continue to EOJ.
|
| A copied CCASTAT cannot be read or logins fail unexpectedly | Download it with binary, quote type e, and quote mode b, then configure it with "blocked": true.
|
A plain telnet client connects but does not produce a usable screen |
Use a TN3270 client such as c3270; TNSERV requires TN3270 negotiation.
|
Source references
gitm204/BUILD.mdgitm204/em204/README.mdm204-80/DEVELOPMENT.mdm204-80/ZAP-WORKFLOW.mdm204-80/.github/skills/building.mdm204-80/.github/skills/testing.mdm204-80/.github/skills/zos-crossbuild.mdm204-81/DEVELOPMENT.mdm204-81/.github/skills/building.mdm204-81/.github/skills/testing.md