GNU EMACS FOR OPENVMS VAX -- 19.28, 21.2 AND 22.3, BINARY AND SOURCE KIT
=======================================================================
Douglas P. Fields, Jr.  <symbolics@lisp.engineer>      10-OCT-2026
(first published 20 September 2026; this kit is built FROM THE
REPOSITORY -- vax/19.28, vax/21.2 and vax/22.3, commit ids in section 6)

Three terminal-only (no DECwindows) builds of GNU Emacs for OpenVMS VAX,
built and tested on OpenVMS VAX V7.3 with Compaq C V6.4 on a VAXstation
4000/96, and installed from this kit on a VAXstation 4000/60, a
VAXstation 4000/90, a VAXstation 3100 M38 (22.3 only, 32 MB) and on a
simulated MicroVAX 3900 (SIMH).

  GNU Emacs 22.3    The default.  Eric Brown's OpenVMS x86-64 port of 22.3,
                    made to run on VAX.  The newest and the most capable
                    (Lisp, dired, Gnus, Org, ...), and the slowest -- but
                    much quicker than in the first kit: it starts in
                    about 3 seconds in batch mode and 6 interactively on a
                    4000/96, and dired is twice as fast as in the 1-OCT
                    kit (section 4).  M-x compile finds DEC C's errors.
                    Font lock is off by default.
  GNU Emacs 21.2    Thien-Thi Nguyen's VMS port (emacs212_3), by way of
                    Eric Brown's x86-64 work on it.  Text-mode menu bar,
                    MULE, font-lock, 1,894 files, 76 MB.
  GNU Emacs 19.28   Richard Levitte's VMS port ("VMS patches created on
                    Wednesday, December 25 1996").  Small and quick:
                    about 815 files, 24 MB.  The long-proven one.

CREDITS.  This is other people's work with VAX fixes on top:
  * Richard Levitte -- the 19.28 VMS port.
  * Thien-Thi Nguyen -- the 21.2 VMS port.
  * Eric Brown -- the OpenVMS x86-64 ports of 21.2 and 22.3 (configure.com
    for current VMS, vms7-3.h, TRADCPP, his smoke test) that our 21.2 and
    22.3 sources start from.  Thank you.
  * The GNU Emacs authors and the Free Software Foundation.
  * The VAX changes, the tests, the kit and this document were built,
    tested and documented with Claude Code (Anthropic's Claude models:
    Fable, Opus and Sonnet), directed and reviewed by Douglas P. Fields,
    Jr.  Every change is a commit in the source kit, and every test
    result was measured on the machines named in section 5.

They install side by side, share no file, and can each be running as a
"kept editor" at the same time.  Emacs is free software under the GNU
General Public License (see ETC]COPYING in any tree); the matching
source, and every change made to it, is in the source kit.  There is NO
WARRANTY.


1. REQUIREMENTS
---------------
 * OpenVMS VAX V7.3.  Older versions are UNTESTED.  (Not Alpha, not
   Itanium: these are VAX images.)
 * TCP/IP Services for OpenVMS.  All images are linked against
   UCX$IPC_SHR; without it they presumably will not activate (untested).
 * About 830,000 free blocks (425 MB) on the system disk to install all
   three versions: 426,447 blocks for the savesets, which you can delete
   afterwards, and about 399,700 for the installed trees (measured:
   399,717 blocks allocated).  Installing over an existing installation
   needs room for a second copy of a tree until the old one is purged.
 * Memory: 22.3 with a shell running takes about 6.4 MB (13,000 pages)
   more than the system itself (MEASURED, R19).  It runs, and passed its
   tests, in 32 MB on a VAXstation 3100 M38 and on the simulator at 16 MB
   and 32 MB; on the M38 it is slow (the first C file takes 2.5 minutes).
 * SYSTEM (or SYSPRV) to install.  No compiler is needed.
 * The install location is FIXED.  The directory is compiled into the
   images, so they run from SYS$SYSDEVICE:[GNU...] and nowhere else:
        19.28   SYS$SYSDEVICE:[GNU.BIN], [GNU.LIB...], [GNU.INFO], ...
        21.2    SYS$SYSDEVICE:[GNU.EMACS21...]
        22.3    SYS$SYSDEVICE:[GNU.EMACS22...]
   To use another location, rebuild from the source kit with a different
   --prefix (section 6).


2. WHAT IS IN THE BINARY KIT
----------------------------
  EMACS1928_VAX.BCK      BACKUP saveset, 24,675,840 bytes (48,195 blocks)
  EMACS212_VAX.BCK       BACKUP saveset, 76,027,392 bytes (148,491 blocks)
  EMACS223_VAX.BCK       BACKUP saveset, 117,637,632 bytes (229,761 blocks)
  EMACS_KIT_INSTALL.COM  the installer
  GNU_EMACS_LOGIN.COM    defines EMACS, EMACS19, EMACS21, EMACS22 at login
  KEPTEMACS.COM          the kept-editor procedure
  SITE-START.EL          22.3's site-wide default (font lock off)
  EMACSTEST.COM, .EL     regression test
  EMACSTEST-HELPER.COM   makes the two record-format files EMACSTEST.EL
                         cannot make itself -- REQUIRED alongside them
  GNU_STARTUP.COM        19.28's own startup procedure (boot-time logicals)
  MAKE_EMACS_KIT.COM     how the savesets were made
  SHA256SUMS.TXT         checksums of all of the above
Any saveset may be left out; the installer installs what it finds.  The
kit comes as a ZIP (deflate); UnZip for VMS gets the transfer modes right.


3. INSTALLING
-------------
Get all the files into ONE directory on the VAX.  Create the directory
at a terminal first.  TRANSFER MODES MATTER:

  the three .BCK savesets        BINARY  (FTP "binary")
  every .COM, .EL and .TXT file  TEXT    (FTP "ascii")

A procedure sent in binary arrives as 512-byte fixed-length records, and
DCL answers the first command you type with
        %RMS-W-RTB, 512 byte record too large for user's buffer
The kit is not corrupt: send the text files again in ascii mode.  (UnZip
for VMS gets both kinds right by itself.)

The savesets arrive with the wrong record attributes however they travel,
and BACKUP would say "not a BACKUP save set"; the installer fixes that
itself, with
        SET FILE/ATTRIBUTES=(RFM:FIX,LRL:32256,MRS:32256,RAT:NONE)

  $ SET DEFAULT dev:[the.kit.directory]
  $ @EMACS_KIT_INSTALL CHECK        ! says what it would do; changes nothing
  $ @EMACS_KIT_INSTALL

It announces each step:
  1. sets the savesets' record attributes
  2. restores them to SYS$SYSDEVICE:[GNU...] with BACKUP/NEW_VERSION (every
     restored file becomes the new highest version), then PURGEs
     SYS$SYSDEVICE:[GNU...] down to one version per file -- so installing
     twice, or over an older copy of this kit, is safe and leaves exactly
     one copy of everything.  (An earlier version of this installer used
     BACKUP/REPLACE, which only overwrites a file already on disk at the
     SAME version number the saveset carries; once a target's own versions
     had drifted -- any earlier reinstall bumps them -- the next kit landed
     BESIDE the old files instead of replacing them, roughly doubling the
     tree.  Fixed R09, MEASURED: see reviews/R09-request.md.)  A file you
     edited IN PLACE under [GNU...] is still overwritten -- keep site
     changes in the SITE-LISP directory (22.3: SYS$SYSDEVICE:[GNU.EMACS22.
     LIB.EMACS.SITE-LISP]; the installer keeps its SITE-START.EL in step
     with the kit's, so put your own settings in your own .EMACS).
  3. makes everything world-readable
  4. copies the shared procedures to SYS$SYSDEVICE:[GNU], and 22.3's
     SITE-START.EL (font lock off) into its SITE-LISP directory
  5. copies GNU_STARTUP.COM to SYS$COMMON:[SYS$STARTUP] if none is there;
     if one is, leaves it alone and says whether it matches the kit's
  6. shows the lines that SYLOGIN.COM needs and ASKS before adding
     them (the old file remains as the previous version); on a 19.28
     install, ASKS SEPARATELY before adding the ETAGS/B2M/EMACSCLIENT line
     too (see below), inserted ABOVE the first.  It never touches
     SYSTARTUP_VMS.COM; it prints the one line to add yourself:
        $ @SYS$STARTUP:GNU_STARTUP * "TABLE=/SYSTEM,QUIET"
     (19.28 only: the ESHELL logical name and the GNU help library.)
  7. prints each installed version's banner, then runs the regression test
     for all of them; the procedure's exit status is the test's.

The SYLOGIN lines define EMACS, EMACS19, EMACS21, EMACS22 and the RUNEMACS
commands.  19.28's other commands -- ETAGS, B2M, EMACSCLIENT -- come from
GNU_STARTUP itself; the installer offers to add this line for you,
ABOVE the lines it added for EMACS/EMACS19/EMACS21/EMACS22 -- answer its
second question, or add it yourself:
        $ @SYS$STARTUP:GNU_STARTUP * NOLOGICALS,QUIET
Either SYLOGIN edit goes before a final "$ EXIT" (any case, with or
without a status) if the file ends with one, otherwise at the end.  THE
INSTALLER DOES NOT DETECT an EXIT inside an IF block, or a SYLOGIN.COM
that branches around its own end -- it will append after such an EXIT
instead of before it.  Read the result (the procedure prints the new
file's version number) if your SYLOGIN.COM does either.
It stops, having changed nothing further, if BACKUP cannot restore.

To remove:  delete SYS$SYSDEVICE:[GNU.EMACS22...] for 22.3,
[GNU.EMACS21...] for 21.2, or all of [GNU...] for everything; take the
hook lines out of SYLOGIN.COM and SYSTARTUP_VMS.COM; delete
SYS$COMMON:[SYS$STARTUP]GNU_STARTUP.COM.


4. USING IT
-----------
After the next login (or  @SYS$SYSDEVICE:[GNU]GNU_EMACS_LOGIN ):

  $ EMACS22 [file]   22.3     $ EMACS21 [file]   21.2
  $ EMACS19 [file]   19.28    $ EMACS   [file]   the default version
  $ RUNEMACS22 -batch -l file.el               run directly, no kept process

EMACS / EMACS19 / EMACS21 / EMACS22 start a KEPT EDITOR: C-z returns you
to DCL and leaves Emacs alive in a subprocess; the same command
re-attaches to it with your buffers intact.  C-x C-c really exits.

The default is 22.3 if installed, then 21.2, then 19.28.  To change it,
define the logical name GNU_EMACS_DEFAULT as 19, 21 or 22 -- for everyone:
  $ DEFINE/SYSTEM/EXECUTIVE GNU_EMACS_DEFAULT 21      (and at boot)
or for yourself, in LOGIN.COM, followed by @SYS$SYSDEVICE:[GNU]GNU_EMACS_LOGIN

M-x compile, M-x shell and dired (22.3; the user guide, docs/EMACS_ON_VAX_
USER_GUIDE.md, has the detail and what was tested):
  * M-x compile runs a DCL command: replace the offered "make -k " with
    CC FOO.C, CC/LIST FOO.C or MMS.  After a failing CC the mode line
    says Compilation:exit [42] and the buffer "exited abnormally with
    code 42" (the low bits of the VMS status, as 21.2 says).  C-x `
    (next-error) then visits the file and line of each DEC C error or
    warning in turn, also with the kit's font lock default (off, see below).
    21.2 shows the same code, but its C-x ` finds nothing in DEC C's
    messages.
  * dired (C-x d DEV:[DIR]) lists a directory itself, without a
    DIRECTORY command in a subprocess.  RET or f visits a file, d then x
    deletes, C copies, R renames, + makes a directory, g re-reads, ^ goes
    up.  The listing is DIRECTORY's, line for line, for /SIZE /DATE
    /OWNER /PROTECTION (dired-listing-switches); a switch outside those
    still runs DIRECTORY.
  * M-x shell is DCL (LOGOUT ends it); a line a program writes is no
    longer cut at the window width (21.2 still cuts it).
  * Saving files: no NAME.TXT~ backups on VMS; every save makes the next
    version, NAME.TXT;2, ;3 ... (PURGE when they pile up).

Font lock (syntax colouring) is OFF in 22.3 by default.  22.3 turns it on
for every buffer, and on a VAX it costs a lot: 8 pages of a C file under
C-v took 1.54 s with it off and 8.64 s with it on (VAXstation 4000/96).
The kit's SITE-START.EL switches it off.  To have it back, put this in
your own .EMACS (or use M-x font-lock-mode for one buffer):
        (global-font-lock-mode 1)
21.2 and 19.28 never turned it on by default.

Speed of 22.3 (MEASURED, R19, 10/11-OCT-2026, this kit installed, 80x24
terminal; medians of 5 runs on the 4000/96 and 4000/90, 3 on the
4000/60 and the 3100 M38; seconds; "before" is the 29-SEP kit):
                                      before        now
                                   VAX96 VAX60  VAX96 VAX60 VAX90 M38
  emacs -batch, start and exit      12.4  32.1    2.5   6.4   3.5  16.4
  emacs -q, interactive start       15.4  41.0    5.8  15.6   8.1  41.4
  first file-name completion        12.2  34.4    3.2   8.9   4.2  19.5
  M-x shell, DIRECTORY SYS$SYSTEM:   4.0   8.3    1.9   5.9   2.6  23.9
  dired of SYS$LOGIN: (C-x d)        4.6     -    2.3   3.0   2.9   1.2
  dired of SYS$SYSTEM:               4.6     -    2.4   4.9   3.0  10.3
  first C file (loads cc-mode)      16.9  51.8   16.2  51.6  22.4 156.6
  Machines: 4000/96 (KA49, 100 MHz, 128 MB), 4000/60, 4000/90 (KA49-A,
  71 MHz, 128 MB), 3100 M38 (about 3.8 VUPs, 32 MB, 22.3 only).
  "before": the 29-SEP kit (22.3 71f7db8), docs/EMACS_PERFORMANCE.md
  sections 2 and 3; dired: the 1-OCT kit on VAX96, 5-OCT, section 11b.
  "now": the 10-OCT kit (22.3 cc0460b), same document, section 12.
  USER1's home on the M38 holds 3 files (the 4000/60's held 380 on 1-OCT):
  its dired of SYS$LOGIN: is not comparable.  "First C file" is the
  cc-mode load (section 8).  The simulator is 3 to 5 times as fast as the
  4000/96.
Where the time went: every `load' of a full VMS file name searched all of
load-path (a bug in 22.3's VMS name handling), and the dump file was
summed byte by byte at every start; see section 7.  What is left is mostly
loading Lisp and the disk.

Checking the dump file (22.3).  Emacs 22.3 starts by mapping its dump file
(EMACS-22_3.DUMP) into memory.  At start-up it checks only that the dump
was made by the image being run: the dump records the link time and size
of the image that made it, and a dump from any other image is refused
with "... was not dumped by this image" and "Emacs cannot start from this
dump file." The pages of the dump are then read from the disk as Emacs
uses them.  Until this version Emacs also summed every byte of the dump
at every start, which cost about 2.5 seconds on a VAXstation 4000/96.
That full check is still there, on demand:

  $ DEFINE EMACS_DUMP_CHECK FULL

makes every Emacs 22.3 started afterwards in that process sum each range
of the dump and stop with "checksum mismatch" if one differs (the start
is slower); DEASSIGN EMACS_DUMP_CHECK to go back.  In a running Emacs,

  M-x vms-verify-dump-file

reads the dump file from the disk, sums each range again and says "Dump
file ... OK", or names the range that differs.  It checks the file, not
the memory of the running Emacs.  From Lisp, (vms-verify-dump-file FILE)
checks another dump file, and (vms-dump-file-name) returns the name of
the one this Emacs was started from.  If a dump file is reported damaged,
reinstall the kit's EMACS-22_3.DUMP and EMACS-22_3.EXE together: a dump
is of use only to the image it was made with.

Keyboards (user guide, sections 3 and 4).  A VT420 has no Meta key: "M-x"
means press ESC, then x.  DEC LK201 / LK401 / LK411 keyboards have no Esc
key: use F11 (in VT200 to VT500 mode; all three versions turn the
sequence it sends into ESC), or Ctrl-[ or Ctrl-3, which send ESC in every
mode.  Alt is not Meta.  F10 opens the menu bar (21.2 and 22.3).

If C-x C-s freezes the screen or does nothing, something between the
keyboard and Emacs is using Ctrl-S for flow control: the VT itself (DEC's
VT420 manual says it does not send Ctrl-S or Ctrl-Q while its Set-Up
XOFF setting is on, the default; not tried on a real VT420), a terminal
server port, or a terminal program.  To save anyway:  M-x save-buffer
(22.3: also F10, Enter, s).  To get C-s back:  M-x enable-flow-control ;
then C-\ is C-s, C-x C-\ saves and C-^ is C-q (a real Ctrl-S then
freezes the screen and Ctrl-Q releases it).  For every start, put this
in your .EMACS file (SYS$LOGIN:.EMACS):
        (enable-flow-control-on "vt200" "vt300" "vt400" "vt500")
The user guide says what was tested on the simulator and what only a
real VT420 can show.

Terminal types VT100 through VT500-series are recognised as VMS reports
them (SET TERMINAL/INQUIRE).  For anything else, tell VMS:
  $ SET TERMINAL/DEVICE_TYPE=VT300
or tell Emacs the screen type alone (the function keys still follow what
VMS reports):
  $ DEFINE EMACS_TERM "vt200"


5. TESTING
----------
  $ @SYS$SYSDEVICE:[GNU]EMACSTEST [19|21|22|ALL] [mutate-check-name]

261 (19.28), 269 (21.2) and 341 (22.3) checks, in 20 (19.28), 21 (21.2)
and 26 (22.3) named GROUPs: the Lisp system, regexps, strings and lists,
time and timers, VMS file version numbers, VMS file names and search
lists, record formats (Stream, Variable, VFC), backup and auto-save,
file attributes, file-name completion (the class the 21.2 completion
crash slipped through) and dired (22.3: its own directory listing, line
for line against DIRECTORY, and C, R, +, d x, g, ^), M-x compile with
DEC C and C-x ` (22.3), the dump check (22.3), access checks compared with the
privileges the process actually holds, synchronous and asynchronous DCL
subprocesses, garbage collection under load, byte compilation, editing
primitives, suspend and re-attach (21.2, 22.3), and system information;
for 22.3 also Eric Brown's own smoke test.  It prints "GROUP name" once
per group, "PASS name" / "FAIL name: detail" per check, "KNOWN_BUG name"
for a check that asserts a currently-open bug's behaviour on purpose,
and a final "EMACSTEST: n passed, m failed, k known bugs" line; it exits
with a VMS error status if anything FAILED (a KNOWN_BUG does not count
as a failure).  RUN IT AS AN ORDINARY USER TOO: several of the bugs
below exist only for unprivileged users or only in -batch.

P2, if given, is a check NAME exactly as printed: that one check's
outcome is deliberately negated (EMACSTEST_MUTATE), so its FAIL line and
this procedure's own bad exit status can be demonstrated on demand --
the fail-first proof every check in this suite has been shown to pass,
either this way or against a real known-bad image.  To run against a
different image for one version (such as a known-bad build), define
RUNEMACS19, RUNEMACS21 or RUNEMACS22 locally in the session before
calling this procedure -- it reads whatever symbol is in effect.
EMACSTEST-HELPER.COM (it creates the Variable-length and VFC files the
record-formats group reads) travels next to EMACSTEST.COM and
EMACSTEST.EL -- in the installed SYS$SYSDEVICE:[GNU] for the command
above, or wherever else you copy all three files together.  EMACSTEST.COM
defines the EMACSTEST_HOME logical to that directory before loading
EMACSTEST.EL, which finds the helper there.  Nothing needs to be copied
into SYS$LOGIN: first: the command above works for any account, from a
fresh login, with nothing uploaded.

What was verified (MEASURED).  Three machines: the build machine (VAX96,
VAXstation 4000/96), the hardware install machine (VAX60, VAXstation
4000/60) and a simulator; three accounts: SYSTEM, an unprivileged
account and an account with no privileges at all.

THIS KIT, 10-OCT-2026 (22.3 is vax/22.3 cc0460b, built on VAX96 on
5-OCT-2026 in 26 minutes from the repository; 19.28 and 21.2 are those of
the 1-OCT kit, unchanged; reviews/R18-request.md has every count and
transcript).  Each cell below is one account on one machine, and the
installed kit is what ran: EMACSTEST as @SYS$SYSDEVICE:[GNU]EMACSTEST for
19.28, 21.2 and 22.3 (261, 269 and 341 checks, plus 1 known bug in each:
run-at-time in 19.28; in 21.2, a line sent to a program before it reads
is cut to its first character; ods5-long-filename
in 22.3) and the scripted full-screen tests of the test suite (10, 11 and
12 scripts).  Every machine ran the same 22.3 image (2,848 blocks, with
its 11,385-block dump; same file dates on all three machines).
  Clean-room simulator (VSIM10, Open SIMH f6274d84, started from a system
    disk with no Emacs on it), install from this kit's ZIP unzipped on
    VMS: the installer's own test, then all 9 cells (3 accounts x 3
    versions): 0 failed checks, every script passed.  Installing the kit
    a second time over itself left the same 82 directories and 5,381
    files, no second version of any file, and the same results.
  Build machine VAX96, 9 cells: 0 failed checks, every script passed.
    22.3 was installed there from the build of 5-OCT-2026.
  Hardware install machine VAX60, installed from this kit's ZIP: the
    installer's own test 261, 269 and 341 checks, 0 failed, and 9 cells:
    0 failed checks.  Scripts: 21.2 11 of 11 and 22.3 12 of 12 in every
    account; 19.28 10 of 10 in every account at the second run -- in
    the first run as SYSTEM, "two subprocesses" (the second one's
    sentinel) did not run once, and passed 3 of 3 times when repeated
    (19.28 is unchanged and frozen; this check has failed now and then
    since 29-SEP).  22.3's M-x compile script failed in the first run in
    all three accounts: the first C-x ` loads cc-mode, which takes 45
    seconds on this machine (MEASURED, 2 runs), and the script waited 30;
    with the wait lengthened it passes.  The first C-x ` after M-x
    compile therefore takes about 45 seconds on a 4000/60 (under 30 on
    the 4000/96 and on the simulator, where the script passed).  R19,
    11-OCT-2026, `(require 'cc-mode)' in -batch: 55 seconds on the
    4000/60 and 18 seconds on the 4000/96 (21.2: 37 and 13); it is CPU
    time, all eleven files are .ELC (EMACS_PERFORMANCE.md section 12e).
  A line sent to a one-shot straight after start-process reached its
    image whole 40 times of 40 on VAX60 (USER1, standalone).
  R19, 11-OCT-2026 (reviews/R19-request.md; docs/EMACS_KIT_AND_DEPLOYMENT.md
    section 15), a VAXstation 4000/90 (71 MHz, 128 MB), installed from
    this kit over the 1-OCT kit: [GNU...] 82 directories, 5,381 files,
    376,102 blocks (22.3's image and dump replaced, one version of every
    file); the installed kit's EMACSTEST in all three accounts 261, 269
    and 341 checks passed, 0 failed, 1 known bug each, and all 9 cells of
    the scripted tests (10, 11 and 12 scripts) passed.  Also a
    VAXstation 3100 M38, 32 MB, 22.3 only, installed from
    this kit's 22.3 saveset: 44 directories, 2,645 files, 215,910 blocks.
    The installed kit's EMACSTEST as SYSTEM, an unprivileged account and
    EMTEST: 340, 339 and 339 passed, 1 known bug each, and two FAILs that
    are the machine's, not Emacs's: the check that runs MMS (the M38 has
    none) and, in the two unprivileged accounts, a check that bounds the
    CPU of a 3-second sleep to 0.5 s and reads 0.53 s on that slow machine
    (the sleep itself uses 0.00 s: measured).  The simulator at 32 MB and
    16 MB: 342 checks, 0 failed.

THE 1-OCT-2026 KIT, for the record (22.3 bd022fe; reviews/R15-request.md
has every count, transcript and machine).  Each cell below is one account
on one machine, and the installed kit is what ran: EMACSTEST as
@SYS$SYSDEVICE:[GNU]EMACSTEST for 19.28, 21.2 and 22.3 (261, 269 and
316 checks, plus the 1, 1 and 4 known bugs of that kit) and the scripted
full-screen tests of the test suite (10, 11 and 11 tests).  Every
machine ran the same 22.3 image (built 1-OCT-2026 04:24 on the build
machine; M-x emacs-version shows no date, the variable emacs-build-time
does).
  Clean-room simulator (VSIM10, started from a fresh system disk with no
    Emacs on it), install from this kit's ZIP unzipped on VMS: all 9
    cells (3 accounts x 3 versions): 0 failed.  Installing the kit a
    second time over itself left the same 82 directories and 5,380
    files, no second version of any file, and the same results.
  Build machine VAX96, 9 cells: 0 failed; 22.3 built there from the
    repository the same day (27 minutes) and installed.
  Hardware install machine VAX60, 9 cells (1-OCT-2026): the full-screen
    tests passed in all nine (19.28 10 of 10, 21.2 and 22.3 11 of 11 in
    every account; the completion test that failed there in the 29-SEP
    kit passes).  EMACSTEST: 7 cells 0 failed, and two cells with one
    failed check each, both as SYSTEM:
    - 21.2: "call-process does not spin while another subprocess's output
      waits unread".  The 21.2 image is the one of the 29-SEP kit, which
      passed this check on VAX60 as SYSTEM.  Today it failed 4 of 4 runs
      as SYSTEM (1.8-1.9 s of CPU in a 2 s command, limit 1 s) and passed
      as the other two accounts, and on VAX96 and the simulator as
      SYSTEM.  On 5-OCT-2026 it was not reproduced (full suite twice as
      SYSTEM, and 4 standalone runs per account: 0.27-0.35 s of CPU;
      reviews/R16-request.md).  The cause was never found.
    - 22.3: "a line sent to a one-shot straight after start-process
      reaches its image whole": fixed in this kit's 22.3 (section 7).
The kept editor was also tested through a detach and re-attach on each
machine (test_kept_editor, installed 22.3).  Timing-sensitive checks are
run on both the simulator and the hardware, because a pass on one speed
of machine says little about the other.
Earlier kits, for the record: 33 checks (20-SEP), 245 (22-SEP), 254
(23-SEP, the first kit built from the repository).


6. THE SOURCE KIT, AND WHAT WAS CHANGED
---------------------------------------
The source kit is built straight from this project's own git repository:
  emacs-19_28-19961225.zip           Richard Levitte's 19.28 VMS kit,
                                      UNMODIFIED (the true upstream)
  emacs-21.2-vms-x86-64.zip          Eric Brown's 21.2 VMS x86-64 kit
                                      (emacs212_3), UNMODIFIED
  emacs-22.3-vms-x86-64.zip          Eric Brown's 22.3 VMS x86-64 kit,
                                      UNMODIFIED
  emacs-19.28-vax-source-8ef4c9a.zip `git archive` of this repository's
                                      vax/19.28 branch, commit
                                      8ef4c9ae6e8f1d7509920252b23bb667e
                                      54f3e98 -- the COMPLETE tree as
                                      built (every file, not a diff)
  emacs-21.2-vax-source-0e31873.zip  `git archive` of vax/21.2, commit
                                      0e31873729cb8713afa05d4666d26c1a98
                                      5fa1a1 -- likewise complete
  emacs-22.3-vax-source-cc0460b.zip  `git archive` of vax/22.3, commit
                                      cc0460bc4327664ece69defda5066a8bb7
                                      14dbe3 -- likewise complete
  SOURCE_KIT_README.TXT, SHA256SUMS.TXT
The three vax/* archives ARE the changes below (and every build-system
repair), already applied, as ordinary source files -- "diff" them against
the unmodified upstream archives yourself, or read the changes as commits
in the repository's own `emacs/` submodule history (`git log vax/19.28`,
`git log vax/21.2`, `git log vax/22.3`).

To build 21.2 or 22.3 from its vax/* archive: unzip it in a directory
under your own account, then
  $ SUBMIT/NOPRINT/LOG_FILE=SYS$LOGIN:E22.LOG/PARAMETERS=(CONFIGURE) -
        dev:[...]BUILD_EMACS22.COM         (BUILD_EMACS21.COM for 21.2)
(about 18 minutes for 21.2 on a 4000/96), and the same with
/PARAMETERS=(INSTALL) as SYSTEM.  P2 is the prefix if you want another
one.  Needs Compaq C and MMS.  19.28 has no such procedure; build it the
way docs/EMACS_ON_VAX_INSTALLATION.md section 7 describes (configure.com,
then the generated makefiles repaired -- legacy-changes/19.28/
fix_generated.py -- then MMS).

Emacs 21.2 -- ten changes.  1-7 and 10 are VAX-only and leave Alpha/x86
alone (22.3 carries the same ones, ported):
  1 m/vax.h        compile switch /OPTIMIZE=(LEVEL=5,TUNE=HOST) is Alpha's
  2 emacs.c        <libicb.h> does not exist on VAX (and is not used)
  3 sysdep.c       64-bit integers: the VAX compiler has none.  Privilege
                   mask held as two longwords
  4 vmsproc.c      "long long" delta time -> LIB$EMUL; and XPROCESS()
                   applied to what is already a struct pointer
  5 vmsmap.c       the VAX linker puts the BSS markers beside DATA, so the
                   BSS range duplicated DATA and the dump aborted
  6 vmsfns.c       a symbol name from VSI C on x86-64, typed into the
                   source; on VAX the function is plain sys_access
  7 descrip.mms_in_in   make-docfile commands too long for DCL when the
                   build directory is deep; that batch of docstrings was
                   silently left out of DOC.  Re-batched 3 files per command
  8 vmsproc.c      ALL PLATFORMS.  The last record a subprocess wrote before
                   exiting was dropped (M-! SHOW TIME printed nothing)
  9 sysdep.c       ALL PLATFORMS.  Under -batch, file access was checked as
                   the account that BUILT Emacs, because the UIC is cached
                   in a static that the dump file preserves
 10 dired.c         Compaq C for VAX inlines a function that calls the
                   alloca builtin, then keeps using SP-relative slots after
                   SP has moved: file-name completion (C-x C-f TAB, RET in
                   dired) jumped into data and killed Emacs.  That buffer
                   now comes from the heap.  19.28 is immune: it uses
                   Emacs's own alloca.c
  + etc/termcap.src    VMS terminal names (vt200-80 ...) and VT400/VT500
  + lisp/term/vt500.el new
A traditional C preprocessor (TRADCPP, in the 21.2 kit) is used in place
of Compaq C's, which puts a space between every token and so wrecks the
generated MMS files.  The 19.28 build predates our finding that, and
repairs the generated files with a script instead (fix_generated.py).

Emacs 22.3 -- Eric Brown's port plus the VAX changes above, and the
process-path work of 21.2 (section 7), a VAX build procedure
(BUILD_EMACS22.COM: it also byte-compiles the port's changed Lisp after
the dump, so no stale .ELC is left), NO_ARG_ARRAY and no symbolic links
or fchmod on VAX, alloca.c linked on VAX, and the two 22.3-only fixes in
section 7 (dired, termcap), the speed-ups and the dump check of section 7,
and, since the 1-OCT kit, M-x compile with DEC C, dired's own listing,
wider subprocess terminals, the send-before-read wait and the smaller
fixes of section 7.  69 commits; the list is `git log
upstream/emacs-22.3-openvms-x86_64-worktree..vax/22.3`.

Emacs 19.28 -- build-system repairs, plus:
  vmsproc.c        the same dropped-record bug as 8 above
  callproc.c       close() was called on an index into Emacs's own mailbox
                   table; in "emacs -batch -l file.el" that closed the file
                   being loaded, and Emacs died at the next read of it
  etc/termcap.dat  VT400/VT500;  lisp/term/vt500.el new


7. FIXES, BY SYMPTOM
--------------------
Since the 21-SEP-2026 kit, one line each (full detail: PLAN.md's Status
table and TODO register; commit ids in section 6 are where they landed).
Versions in brackets; "all" is 19.28, 21.2 and 22.3.
 * 22.3 [22.3], new since the 1-OCT kit (nicer to live in):
   - M-x compile with DEC C: C-x ` said "Moved past last error" after a
     failing CC (also CC/LIST, a file named with device, directory and
     version, and an MMS build that fails in CC).  It now visits each
     error and warning, in the right file and line.  (21.2 still does not.)
   - M-x compile's exit status was shown as "code -268435414" for a
     failing CC; 21.2 says "code 42".  22.3 now says "code 42" too (the
     VMS status without its four control bits).
   - Long lines in M-x shell and M-x compile were cut at the window width
     (a 150-character line arrived as its first 80 characters, and a DEC C
     message naming a long file lost the end of the name, so C-x ` found no
     file).  Subprocess terminals are now 511 columns wide with wrap.
     (21.2 still cuts them.)
   - dired is twice as fast on a 4000/96 (4.6 -> 2.3 s for SYS$LOGIN:;
     section 4): the listing is made inside Emacs instead of by a DIRECTORY
     command in a subprocess, and dired-vms.el is byte-compiled.
   - dired's C (copy), R (rename) and + (make directory) made the file but
     added no line for it; they do now.
   - A line typed to a program straight after it starts could reach it as
     its first character only (7 of 40 lines on a 4000/96, 14 of 40 on a
     4000/60); now 0 of 40 on both.  The first write waits until the
     program has started to read (at most half a second).
   - In -batch, once a one-shot subprocess had finished every later wait
     (sleep-for) used all the CPU; it no longer does.
   - In the *COMMAND* buffer of an interactive DCL (M-$), RET sent DCL's own
     prompt along with the command (%DCL-W-IVVERB).  Fixed.
   - (make-directory DIR t) failed "invalid argument" on VMS (it broke the
     auto-save directory).  Fixed.
 * 22.3 [22.3], new since the 29-SEP kit -- it was slow, and is now much
   quicker (section 4 has the numbers):
   - Start-up: every `load' of a full VMS name (DEV:[DIR]FILE) searched
     all of load-path, thousands of failed file probes at every start,
     because `substitute-in-file-name' dropped the DEV: part.  Fixed.
   - Start-up: the dump file was summed twice, byte by byte, at every
     start, 2.5 s on a 4000/96.  Now it is checked cheaply (see section
     4), and the full sum is one logical name away.
   - File-name completion (C-x C-f TAB): a stat and a re-encoding of the
     ignored-extensions list for every name, and a file-exists-p for
     every candidate.  Cut to what is needed.
   - dired: mouse highlighting was set up on a terminal that has no
     mouse.  No longer.
   - M-x shell: the first command of every new shell waited 2 seconds
     for a terminal state that an interactive DCL never reaches.  Now it
     does not wait.
   - File-name prompts showed "VSIM10$$DUA0:" (a doubled dollar sign)
     in the minibuffer.  Fixed (21.2 never had it).
 * 22.3 [22.3]: dired opened an existing file as if it were new ("(New
   file)"): dired dropped the first two characters of every file name it
   listed, so C-x C-f, RET and f went to a name that did not exist.
 * 22.3 [22.3]: an installed 22.3 said "Cannot open termcap database
   file" and quit, interactively (it worked in -batch and in a build
   tree): it could not find its own TERMCAP.SRC without a logical name.
   It now finds the installed one.
 * 22.3 [22.3]: the kept editor crashed after a re-attach (C-z, then
   EMACS22 again): a cached value of GETENV was freed when Emacs
   suspended and used again later.  Fixed, and EMACSTEST has a suspend
   group that checks it.
 * 22.3 [22.3]: an old byte-compiled vms-patch.elc (its dired listing
   code) could survive a build; the build now recompiles it.
 * 21.2 [21.2]: M-x shell was slow -- DIRECTORY SYS$SYSTEM: 10.97 -> 1.81 s
   on VAX96 (per-record CPU cost in the pty read path, drained per read).
 * A one-shot asynchronous subprocess [all] never exited -- DCL kept
   reading for another command, so no sentinel ever ran.
 * A one-shot subprocess's last output record could be dropped at exit
   [all].
 * A -batch pty subprocess delivered every output record to its filter
   truncated to its first 10 characters [21.2, 22.3].
 * delete-process of a genuinely idle interactive DCL child hung [21.2,
   22.3].
 * An interactive shell's exit sentinel ran only at the next keystroke
   [19.28]; sit-for never returned after an interactive child logged out
   in -batch [19.28].
 * A failing subprocess's exit status was shown as a Unix signal instead
   of the real VMS completion code [21.2, 22.3].
 * dired's RET said "Buffer is read-only" instead of visiting the file
   [19.28] (now bound the same as f).
 * start-process with a program but no argument (a bare interactive
   subshell) crashed the whole image [19.28, 21.2; EMACSTEST checks 22.3].
 * file-writable-p on an unprivileged account's OWN home directory said nil
   although writing there works [21.2, 22.3].
 * A one-shot subprocess doing one DCL INQUIRE never exited [21.2, 22.3];
   call-process lost output that came after a pause, and spun the CPU
   while another subprocess had output pending [21.2, 22.3].
 * The terminal was resized and Emacs did not notice [21.2, 22.3]: M-x
   vms-resize asks the terminal and redraws; C-z and re-attach also pick
   the size up.
 * The kit installer doubled the installed tree on a reinstall --
   BACKUP/REPLACE only overwrites a file already at the SAME version the
   saveset carries.  Fixed with BACKUP/NEW_VERSION + PURGE.
 * EMACSTEST-HELPER.COM was missing from the kit; then EMACSTEST.EL still
   looked for it in SYS$LOGIN:, so a fresh account following section 5
   failed the record-formats group.  Both fixed (EMACSTEST_HOME).
 * The installer offers the ETAGS/B2M/EMACSCLIENT SYLOGIN line (19.28),
   and now installs 22.3, its SITE-START.EL, and the three-version
   command set.
 * tools/vaxsync.py (the upload/build helper in the repository, not in this
   kit): `unpack` refuses a non-empty target unless --purge is given, and
   `build` now waits for the batch job to end, not for a line in its log.


8. KNOWN LIMITATIONS
--------------------
 * 21.2 images built before 20-SEP-2026 20:30 (none was published) die in
   file-name completion: change 10 above.  To tell, complete a file name:
   a fixed Emacs prints a list, an unfixed one dies with a traceback
   naming file_name_completion.  EMACSTEST checks it.
 * 22.3, -batch: a subprocess's sentinel does not run while Emacs waits
   in sit-for or sleep-for (GNU 22.3 itself does it that way on VMS;
   sentinels run in waits that redisplay).  M-x list-processes runs
   them; the test suite calls it after its waits.
 * 22.3: a line sent to a program that never reads its input (a one-shot
   WRITE, WAIT, DIRECTORY or SHOW SYSTEM started with start-process)
   makes the first send wait about 2 seconds (VAX96 2.00 s, VAX60
   2.07-2.45 s, simulator 2.3 s: 5-OCT-2026); nothing is lost.  The text
   then goes to a terminal with nobody reading it, and the terminal
   driver may start a login on it (Username: appears in the output;
   measured on the simulator).  A program that reads a reply fast is
   answered in 0.02-0.09 s.
 * 22.3: the first write to a program started by start-process waits for
   the program to begin reading, at most half a second.  A program that
   opens its terminal and starts to read only after that would still get
   the old behaviour (its first line cut to one character).  Never seen
   in the tests (the wait it needed was 10 ms, in 5 of 20 runs).
 * 22.3, dired: the listing is made by Emacs itself and equals
   DIRECTORY's line for line on everything tried (a prepared directory
   and SYS$SYSTEM:, three accounts, simulator and VAX96).  A file whose
   end-of-file block is 0 shows its allocation, as DIRECTORY does; that
   rule was checked on one file only.  If the system's message for an
   unreadable file header cannot be fetched, the line may show
   garbage (a known one-line fault, to be fixed).
 * 22.3 open item in Eric Brown's own smoke test, recorded as a
   KNOWN_BUG: ods5-long-filename.
 * 21.2: C-x ` (next-error) finds no error in DEC C's "At line number N
   in FILE" lines after M-x compile.  (22.3 does.)
 * 21.2, M-x shell and M-x compile: every line a subprocess writes is cut
   at the width of the window (80 columns on a normal terminal), so a long
   file name in a DEC C message loses its end.  22.3 has this fixed.
 * 21.2 on VAX60, SYSTEM account only: EMACSTEST's check "call-process
   does not spin while another subprocess's output waits unread" failed
   in 4 of 4 runs on 1-OCT-2026 (1.8-1.9 s of CPU in a 2 s command; it
   passed there in the 29-SEP kit, and passes in the other accounts, on
   VAX96 and on the simulator).  Not reproduced on 5-OCT-2026 (two full
   runs as SYSTEM, and standalone runs in all three accounts: 0.27-0.35 s);
   the cause was never found.  If it is real, a call-process that waits
   on a slow command while another subprocess has output nobody has read
   yet uses the CPU while it waits.
 * 21.2: text sent to a subprocess (process-send-string) before the
   program in it has started reading can arrive cut to its first
   character.  Send once the program is ready -- after its prompt or its
   first output.  (22.3 fixed this: 0 of 40 lines cut on VAX96 and on
   VAX60, 5-OCT-2026; EMACSTEST has a KNOWN_BUG for 21.2.)
 * 22.3 on a slow VAX: file-name completion in a large directory is
   still slow the first time -- about 9 seconds on a VAXstation 4000/60
   for a home directory of 380 files (1-OCT-2026; 34 seconds in the 29-SEP
   kit; the second one 3 s), 3.4 s on a 4000/96 (5-OCT-2026).  It does
   complete.
 * 22.3: the first C file you visit (or the first C-x ` after M-x
   compile) loads cc-mode, 11 files of byte-compiled Lisp, and that is
   slow: 18 seconds on a VAXstation 4000/96 and 55 seconds on a 4000/60
   (R19, 11-OCT-2026; 21.2: 13 and 37).  It is CPU time, not disk, and
   happens once per Emacs session (a kept editor pays it once).
 * 22.3, M-! in USER1 on the 4000/96 and the 4000/90: M-! SHOW TIME
   takes 1.8 s and 2.6 s, of which 1.6 and 2.4 s are Emacs's own CPU
   (29-SEP: 0.54 s on the 4000/96; 21.2 on the same machines 0.4-0.5 s; on
   the 4000/60, the M38 and the simulator it did not change).  It depends
   on the account, not the machine: as EMTEST, on the same 4000/90, the
   same command takes 0.6 s.  The cause is not found (R19).
 * A subprocess command (M-!, M-x compile, start-process) that runs DCL's
   INQUIRE -- or anything else that reads SYS$COMMAND at DCL level --
   reads end-of-file, an empty answer, not the terminal and not what
   Emacs sends.  A program the command runs does read what Emacs sends
   (process-send-string).  One such read is fine; a command doing TWO
   still waits for good on 21.2 (22.3 answers both).
 * 19.28: run-at-time never fires a scheduled timer in -batch mode (it
   shells out to a `timer` helper program this port never builds).
   KNOWN_BUG in EMACSTEST.  21.2 and 22.3 are unaffected.
 * 19.28, M-x shell: the mode line keeps saying "run" after the subshell
   has logged out.
 * No version notices by itself that the terminal window was resized:
   VMS sends it no signal.  On 21.2 and 22.3 use M-x vms-resize (a kept
   editor also asks the terminal when it starts or re-attaches), on 19.28
   suspend with C-z and type the command again.
 * Output captured from a subprocess ends with one extra blank line.
 * No X/DECwindows support was built.
 * 19.28 is configured with the VMS 5.5 system description, the newest
   that kit has; it works on 7.3.
 * The link reports %LINK-W-MULDEF for DECC$MALLOC, DECC$FREE ... and the
   directory routines: Emacs's own versions replacing the C library's, by
   design, in all ports.
 * GNU_STARTUP.COM carries the build machine's node name in comment lines.
   They are data for the kit's own installer and are never executed.
