Michigan Terminal System (MTS) notes

Table of contents:

Getting started

Downloading Hercules & MTS

First, install Hercules, hopefully via your favourite package manager.

Then, grab a copy of MTS D6.0A from the MTS Archive; replace its stock hercules.cnf with the updated copy (MTSD6.0A.cnf) available from that site. Mostly this fixes a few small issues with case sensitivity, etc.

3270 terminal emulation

You’ll also need a 3270-compatible terminal emulator like x3270 (for anything with an X server); wc3270 or wx3270 (for Windows); or tn3270 X (for macOS / OS X).

If you are planning to run x3270 on macOS, I encourage you to compile it yourself, as the Homebrew version doesn’t include X support, having dropped all options from formulae [1] [2]. (Don’t even get me started…)

Note that x3270 / wc3270 versions prior to 3.6ga4 (released 2017-12-29) had an issue which prevented the Sys Req key from working at all, even when clicking the Sys Req button in the keyboard tray. (Older versions of x3270 / wc3270 sent the wrong bytes for Sys Req.) This issue seems to affect MTS more than other IBM mainframe operating systems, since MTS uses the Sys Req key for some common actions.

x3270 configuration: Mac keybindings

Unlike tn3270 X, x3270 doesn’t have a default key mapping for Sys Req. And in macOS, x3270’s mappings for PA1 (⌘1) and PA2 (⌘2) conflict with the XQuartz mappings for window selection. In this case, I find the tn3270 X keybindings to be more “macOS friendly”. For Mac users, I suggest adding the following into your ~/.Xresources file:

! These are some useful additions for macOS, originally found in tn3270 X.
! Actually Command-, is used for XQuartz Preferences, but Command-Shift-,
! (ie, Command-<) works with this addition.
x3270.keymap.tn3270XAdditions: \
  Meta<Key>slash: SysReq()\n\
  Meta<Key>comma: PA(1)\n\
  Meta<Key>period: PA(2)\n\
  Meta<Key>backslash: PA(3)
! Add the overrides above.
x3270.keymap: tn3270XAdditions

The above will add keybindings as follows:

Key seq.Action
⌘, or
⌘. or

After that, you may need to merge the updated resources into your running X session:

$ xrdb -merge ~/.Xresources

Subsequent launches of XQuartz should load these automatically.

x3270 configuration: non-Mac keybindings

On other systems (eg cygwin), there’s no conflict with PA1 and PA2; only Sys Req is missing. So I suggest you put the following into your ~/.Xresources file:

! Define SysReq keymap.
x3270.keymap.addSysReq: \
  Alt<Key>/: SysReq()
! Select SysReq keymap.
x3270.keymap: addSysReq

This makes Alt-/ emit a Sys Req key (similar to tn3270 X).

As with the Mac case, you may need to merge the updated resources into your running X session:

$ xrdb -merge ~/.Xresources

x3270 configuration: X font path

Another possible issue: the directory containing the 3270 bitmap fonts may not be in the X font path. On my macOS system, the default X font path looks like:

$ xset q | grep fonts | tr ',' '\n'

So either the font files (*.pcf.gz, eg 3270.pcf.gz) need to exist in one of those directories, or you have to add the x3270 font directory to your font path, like:

$ xset +fp /opt/suite3270/share/fonts/X11/misc

Replace /opt/suite3270 with the path to your installation. You may also need to run mkfontdir.

Without the correct fonts, your terminal session will be æsthetically inferior :-) as shown below:

x3270 using 'fixed' (standard X font)
Figure 1: Using a Unix font to access a mainframe operating system (sacrilege)
x3270 using proper '3270' font
Figure 2: Using the 3270 font to access a mainframe operating system (correct)

As an added bonus, using the 3270 font will get you special 3270 characters in the status bar which won’t appear when using a different font.

wc3270 configuration (Windows)

Similar to x3270, wc3270 doesn’t have a default key mapping for Sys Req. Also I found the blue used for the protected text colour in wc3270 to be impossible to read, especially in the MTS operator’s console. Here’s the X resource data I use with wc3270:

! Change the default protected text colour.
wc3270.hostColorForProtected: turquoise
! Define SysReq keymap.
wc3270.keymap.addSysReq: \
  Alt<Key>/: SysReq()
! Select SysReq keymap.
wc3270.keymap: addSysReq

For wc3270, I find the easiest way to integrate this configuration is via the wc3270 Session Wizard; select 25. Edit miscellaneous resources with Notepad in the wizard and paste in the above at the very end.

Some typographical conventions

Many sites show the commands entered, etc, but not the output. Personally I find it helpful to see the screen as complete as possible, with input and output interspersed. I also dislike using screenshots, as this prevents fulltext searching. The colour-coding also helps to differentiate the three different types of screen: Unix shell, 3270 operator console, and 3270 terminal.

The Unix shell and Hercules control panel examples look like this; things you type are marked in blue:

$ cmp hercules.cnf.old MTSD6.0A.cnf
hercules.cnf.old MTSD6.0A.cnf differ: char 100, line 3

The 3270-type sessions use the same colours as x3270 does in its default colour scheme: blue for protected fields, green for unprotected fields, and red for invisible (“nondisplay” ?) fields (eg, passwords). Things that you type are in a lime green for clarity (as unprotected input and output can be mixed together).

The main difference in appearance between the operator’s console and a standard terminal (besides the status lines at the top of the operator’s console) is the output text. For the operator’s console, the output is protected (ie, immutable), while in a standard session, most output can be modified. Here are roughly the same commands side-by-side:

Operator’s console:Standard terminal:
- Pages to print:  none
- Cards to punch:  none
- Exec queue: none
- Pages to print:  none
- Cards to punch:  none
- Exec queue: none

(Ignoring throughout this doc the fact that the /Q actually turns to /Q after you press Enter!)

Startup and shutdown

Startup (IPL) procedure


First, launch Hercules:

$ hercules
Hercules Version 3.10
(c)Copyright 1999-2010 by Roger Bowler, Jan Jaeger, and others
Built on Mar 31 2015 at 01:20:18
Build information:
  Modes: S/370 ESA/390 z/Arch
  Max CPU Engines: 8
  Using setreuid() for setting privileges
  Dynamic loading support
  Using shared libraries
  HTTP Server support
  Regular Expressions support
  Automatic Operator support
  Machine dependent assists: cmpxchg1 cmpxchg4 cmpxchg8
Running on isomer.local Darwin-14.1.0.Darwin Kernel Version 14.1.0: Thu Feb 26 19:26:47 x86_64 MP=8
HHCHD018I Loadable module directory is /usr/local/Cellar/hercules/3.10/lib/hercules
Crypto module loaded (c) Copyright Bernard van der Helm, 2003-2010
  Active: Message Security Assist
          Message Security Assist Extension 1
          Message Security Assist Extension 2
          Message Security Assist Extension 3
          Message Security Assist Extension 4
HHCCF065I Hercules: tid=7FFF75637300, pid=42297, pgid=42297, priority=0
HHCTE001I Console connection thread started: tid=1030FF000, pid=42297
HHCTE003I Waiting for console connection on port 3270
HHCTA004I 0180: Tapes/d6.0util.aws is a AWS Format tape file
HHCTA066I 0180: option 'ro' accepted.
HHCTA102E 0180: Error opening Tapes/d6.0util.aws: No such file or directory
HHCTA004I 0181: Tapes/d6.0dr1.aws is a AWS Format tape file
HHCTA066I 0181: option 'ro' accepted.
HHCTA102E 0181: Error opening Tapes/d6.0dr1.aws: No such file or directory
HHCTA004I 0182: Tapes/d6.0dr2.aws is a AWS Format tape file
HHCTA066I 0182: option 'ro' accepted.
HHCTA102E 0182: Error opening Tapes/d6.0dr2.aws: No such file or directory
HHCTA004I 0183: Tapes/d6.0dr3.aws is a AWS Format tape file
HHCTA066I 0183: option 'ro' accepted.
HHCTA102E 0183: Error opening Tapes/d6.0dr3.aws: No such file or directory
HHCTA004I 0184: Tapes/d6.0t1.aws is a AWS Format tape file
HHCTA066I 0184: option 'ro' accepted.
HHCTA102E 0184: Error opening Tapes/d6.0t1.aws: No such file or directory
HHCTA004I 0185: Tapes/d6.0t2.aws is a AWS Format tape file
HHCTA066I 0185: option 'ro' accepted.
HHCTA102E 0185: Error opening Tapes/d6.0t2.aws: No such file or directory
HHCTA004I 0186: Tapes/d6.0t3.aws is a AWS Format tape file
HHCTA066I 0186: option 'ro' accepted.
HHCTA102E 0186: Error opening Tapes/d6.0t3.aws: No such file or directory
HHCTA004I 0187: Tapes/d6.0t4.aws is a AWS Format tape file
HHCTA066I 0187: option 'ro' accepted.
HHCTA102E 0187: Error opening Tapes/d6.0t4.aws: No such file or directory
HHCTA004I 0188: Tapes/d6.0t5.aws is a AWS Format tape file
HHCTA066I 0188: option 'ro' accepted.
HHCTA102E 0188: Error opening Tapes/d6.0t5.aws: No such file or directory
HHCTA004I 0189: Tapes/d6.0t6.aws is a AWS Format tape file
HHCTA066I 0189: option 'ro' accepted.
HHCTA102E 0189: Error opening Tapes/d6.0t6.aws: No such file or directory
HHCTA004I 018A: Tapes/cmd001.aws is a AWS Format tape file
HHCDA020I Disks/mts600.dsk cyls=885 heads=15 tracks=13275 trklen=47616
HHCCP002I CPU0000 thread started: tid=10B2F2000, pid=42297, priority=15
HHCTT001W Timer thread set priority -20 failed: Permission denied
HHCTT002I Timer thread started: tid=10B3F5000, pid=42297, priority=15
HHCCP003I CPU0000 architecture mode ESA/390
HHCPN001I Control panel thread started: tid=7FFF75637300, pid=42297
HHCAO001I Hercules Automatic Operator thread started;
          tid=10B796000, pri=16, pid=42297
Back to the shell for a moment to start your 3270 emulator and connect it to Hercules (which is listening on
$ x3270 &
Back to Hercules:
HHCTE009I Client connected to 3270 device 0:0001
Command ==> ipl 260
Now in x3270:
Do you want to run the current system (yes or no)?
D6.0A-AN172 ENTRY=56D18 PSECT=100008 VIRTUAL=B0000...191A70 VIRTUAL_START=100000
 WRITTEN BY ID MTS. AT 23:34:04 TUE JAN 17/12 BY
 COM Patch the timezone name and timezone offset in TABLES to be EST
 COM and GMT minus 5 rather than EDT and GMT minus 4. (jco)
00000   ** UMMPS/XA ** assembled 04/19/88
00000 CONFIG CPU 0000 online
00001 INIT Time and date have been set to  07:37:20 on 03-31-15.
00002 OPERATOR   Started at 07:37:20 on 03-31-15  Model 3090 Serial 000611
00002 OPERATOR   Using display DS01 & printer CON1 (1052)
00004 MTS  Current time of 07:37 Tue Mar 31/15 is more than 12 hours later than
00004 MTS   last recorded signoff time of 22:45 Tue Jan 17/12.
00004 MTS  If you are sure the time is set correctly, enter "OK" to proceed with
00004 MTS   IPL; otherwise re-IPL now.
At this point, we receive a warning about the clock being several years later than the last boot; this is expected, so we can just say OK.
00004 MTS  Reload at 07:41:57 on 03-31-15.  Model: IBM 3090/FF  Serial: 611
00004 MTS  System: D6.0A-AN172 written at 23:34:04 on TUE JAN 17/12.
00004 MTS  Enter initials and reason for reloading:
Now it wants to know why we reloaded the system. It’s just free-form text for the log, so enter something reasonable, eg:
00006 PDP MTS600 on D400 (*PAG001         )
00007 MTS  
00007 MTS  Attention: the following device or devices
00007 MTS  were found to be inoperational at IPL time:
00007 MTS  D600,D601,D602,D603
00007 MTS ** *CHK: Routine check for offline devices.
00007 MTS ** Just cancel after you have checked the offline devices.

00004 MTS  Contents of IPL file "*IPL.0":
00004 MTS D6.0A-AN172 ENTRY=56D18 PSECT=100008 VIRTUAL=B0000...191A70 VIRTUAL_START=100000 UMLOADTV=2000
00004 MTS  WRITTEN BY ID MTS. AT 23:34:04 TUE JAN 17/12 BY 
00004 MTS  COM Patch the timezone name and timezone offset in TABLES to be EST 
00004 MTS  COM and GMT minus 5 rather than EDT and GMT minus 4. (jco)
00010 MTS  Filesave directory update completed
00018 MTS  *CMD: The CMDSTAT pickup program has been started.
00004 MTS      3 RECORDS
00008 MTS 0*** Post-IPL system successfully loaded.
00020 MTS *NAL1 complete
00021 MTS *NAL2 complete
00022 MTS *NAL3 complete
00024 MTS *NAL5 complete
00023 MTS *NAL4 complete
00026 MTS *NAL7 complete
00025 MTS *NAL6 complete
00019 MTS  *NAL -> nalmap(10000) has changed.  Component:   SEG2:CKID         NAS=10000           (ASN=1    BI
00019 MTS  *NAL ->     (this message is just FYI, it is not an error).
00019 MTS   This is not an error.
00019 MTS *NAL complete
00019 MTS PEEK initialization begins
00019 MTS PEEK initialization complete

That line about “Just cancel…” is just a warning that some of the tape drives advertised by Hercules are in fact offline.

As it says, you can just press cancel (PA2) to dismiss the warning, at which point you’ll see:

*** Cancelled ***
At this point, MTS is effectively in single-user mode, awaiting your commands. You can start up the batch processing subsystem, HASP, like so:
00029 HASP HASP initialization -- phase 2
$*Enter HASP requests
00035..MTS *HSP
00035 MTS HASP START (17 January 2012)
Finally, we can “let out the lines” (ie, start MTS listening for new terminal connections), then “release execution” (ie, allow batch jobs to be processed by HASP):
00039..MTS *LAS
00039 MTS Line configuration (17 January 2012) 
00039 MTS Jobs on: DS02-DS05
00039 MTS   Other: *CLK, *TPR, *MGR, *TCM, *FTPSERV
00046 MTS The Messagefile Manager has started up successfully
00047 MTS  There are no available Telnet (TLNT) connections.
At this point, everything is up and running. Fire up another 3270 terminal and you can log into MTS:
 University of Michigan Computing Center - Device: DS02   Task:    40  

                   MM        MM  TTTTTTTTTTTT   SSSSSSSSSS   
                   MMM      MMM  TTTTTTTTTTTT  SSSSSSSSSSSS  
                   MMMM    MMMM       TT       SS        SS  
                   MM MM  MM MM       TT       SS            
                   MM  MMMM  MM       TT       SSS           
                   MM   MM   MM       TT        SSSSSSSSS    
                   MM        MM       TT         SSSSSSSSS   
                   MM        MM       TT                SSS  
                   MM        MM       TT                 SS  
                   MM        MM       TT       SS        SS  
                   MM        MM       TT       SSSSSSSSSSSS  
                   MM        MM       TT        SSSSSSSSSS   

How does this work?

A simple interactive MTS session

To help introduce my typographical conventions, here follows a transcript of a simple interactive session, program execution, and logoff. At the 3270 terminal:
# Enter password.
? ST00
# No Charges 
# User ST00 signed on at 08:17:39, Wed Mar 31/15
# Execution begins   08:17:48 
  PIL/2: Ready
  THE SQUARE ROOT OF 4.12345 =  2.030628
# Execution terminated   08:18:25  T=0.004 
# ST00 08:17:39 to 08:19:20, Wed Mar 31/15
# No Charges 
# Elapsed time               1.666 minutes 
# CPU time used               .039 seconds 
# Wait storage VMI           1.351 page-hr. 
# Disk I/O                      54 
#      Approximate cost of this run:             $.00
#      Approximate remaining balance:        $1000.00
The colour-coding is exactly the same as in x3270, except I’ve darkened the output text to help differentiate it from the input, which is a bright green. Red text is ordinarily invisible, but shown here.

Shutdown procedure


At the operator’s console:

00049 SHUTDOWN Shutdown All complete.
At this point, the system should be shut down. Check for any running MTS tasks:
/T M
- Specified job(s) not found

If you see any MTS tasks, try to $RERUN batch jobs and STOP interactive jobs.

Then in Hercules:

Command ==> stopall
Command ==> quit
How does this work?

Basic usage

Available userids

There are effectively two main types of userid (or sometimes ‘ccid’) in MTS: shared system userids (privileged) and private userids (unprivileged). Signing on with a private userid is relatively straightforward; just $SIGNON with the username and password, as seen in “A simple interactive MTS session” above.

Signing on to a shared system userid requires that you also have a private userid which has been granted permission to use shared system userids. (More details on this process in the sections “Accounting database”, and CKID and sigfiles”.)

Here is a table of the available userids:

userid typeuseridpassword
Private useridST00 through ST99.Same as userid, eg, .
Shared system userid
(Initial $SIGNON)
eg, MTS.
(See below for a complete list.)
Second-level userid
(ID? prompt)
ST00 through ST09.Same as userid, eg, .

Unix-to-MTS command equivalents

The following table may help Unix users get started. Some of the commands may only be approximately equivalent.

MTS also has an excellent online help facility; just enter $HELP topic at the MTS prompt.

Unlike Unix commands, MTS commands can be abbreviated, usually to two or three characters. Here they will be listed out in full for posterity, then in a short form, though not necessarily the shortest. Commands are also case-insensitive, unlike in Unix (where most commands are usually small executables in a case-sensitive filesystem).

The dollar sign is no longer required before MTS command names, but is left in because I think it looks nice.

Unix commandMTS command (long)(short)notes
bc$CALCCALCThere’s also a PL/I-based calculator with much the same functionality: $RUN *DCALC
echo '7*6' | bc$CALC 7*6CALC 7*6
cat file$COPY fileC fileWithout specifying a destination, *SINK* (ie, your terminal) is the default destination. $COPY doesn’t do line-wrapping, so if you just want to see the file, $LIST might be a better choice.
cat -n file$LIST fileL fileThe main difference is that there are no native “line numbers” in Unix, while in MTS the line numbers are actually stored in the file itself. (In other words, $COPY is actually hiding the line numbers.)
cat file1 file2$COPY file1+file2C file1+file2
chmod o+r file$PERMIT file READ OTHERSP file$PERMIT has a lot more flexibility than chmod(1) – not surprising, as Unix has a very limited set of file permission bits. By default, the access granted is READ and the ‘accessor’ (in MTS jargon) is OTHERS, which is why just running $PERMIT file is appropriate here.
chown newu file$RENAME oldu:file newu:fileREN oldu:file fileChanging the owner of a private file is possible by moving the file from someone else’s userid to your own. You must have permission to $DESTROY the old file to take ownership in this way. (This example assumes you are signed on as newu.) A closer approximation in Unix to the MTS command might be: mv ~oldu/file ~newu && chown newu ~newu/file
CHONID changes the owner of public files. The user executing this needs rights to $SET PROT=OFF. When prompted, supply the name of a file and the new owner ID, one pair per line, eg: *FOO ST00. Give an end-of-file (PA2/CNCL) when finished. Strictly speaking, the CHONID macro doesn’t require MTS:CMDMACLIB, but other macros in FILE:CMDMACLIB do.
cp oldname newname$DUPLICATE oldname newnameDUP oldname newnameThe $COPY command doesn’t make an exact copy, unlike cp(1).
fortune$DISPLAY JOKED JOKELike fortune(6) some of the jokes are better than others.
grep string file$EDIT file :SEARCH@ALL 'string'ED file :S@A 'string'The pattern format expected by $EDIT isn’t regex; see MTS Volume 18, The MTS File Editor, for options.
grep -i string file$EDIT file :SEARCH@ALL@ANYCASE 'string'ED file :S@A@AC 'string'
head -3 file$COPY file *SINK*(1,3)C file *SINK*(1,3)You may be tempted to write C file(1,3) – or even C file(FIRST,FIRST+2) – but line numbers aren’t necessarily contiguous (nor is the first line number necessarily 1.) During a $COPY, lines are renumbered (by default); therefore, you can be sure that 1 is the first line number, and all the lines thereafter are numbered sequentially.
less(See the entry for more.)
ls a*$FILESTATUS a?F a?
ls a?c$FILESTATUS a??cF a??cn consecutive ? characters will match n−1 arbitrary characters in the file name.
ls -l a*F a? COL NOHEAD SA,OWNER,SIZE,LASTC,NAMELike ls(1), $FILESTATUS has an obscene number of possible parameters. (In this case, the “long” version of this command wasn’t given, as even the “short” one seems quite long enough.)
F a? COL CATThis might be a more practical command than the above for regular usage.
man topic$HELP topicHELP topic
mesg n$SET DISPATCHES=off or
Both of these commands are directly equivalent to mesg n: they completely disable receiving all dispatches from other users. However, $MESSAGESYSTEM PERMIT  is much more flexible. For example, you can block dispatches from certain users, or only allow dispatches from certain users.
mesg y$SET DISPATCHES=on or
more file%page then either
$LIST file or
$COPY file
%page then either
L file or
C file
You could use the %page terminal output mode to get one page at a time; see the section “Terminal configuration – Standard terminal” for more details.
mv oldname newname$RENAME oldname newnameREN oldname newname
passwd$SET PASSWORDSET PWPasswords must be between 1 and 12 characters long with no embedded blanks or commas.
passwd user$SIGNON WPSW
Sets the password for CCID to a new, random six-character password.
ps ax$SYSTEMSTATUS TASKSSY TYou could also use /T or TASKS from the operator’s console. As far as I can tell, there’s no way to see which program a given task is $RUNning (but if there is, I want to know about it!).
rm file$DESTROY fileDES fileThere’s an amusing story about the $DESTROY command. Unfortunately it no longer seems to be true.
rm -f file$DESTROY file OKDES file OKAppending OK to the end of a command to suppress its confirmation prompt is a fairly standard convention.
tail -3 file$COPY file -tempfile
$COPY -tempfile(LAST-2,LAST)
C file -tempfile
C -tempfile(*L-2,*L)
This requires slightly more effort than the head(1) equivalent, as one can’t do, eg, *SINK*(*L-2,*L): the value of *L (the last line number) is only known after the write completes, by which point it’s too late.
The combination of these two commands would show the equivalent of uptime(1).
wTry a combination of the equivalents for uptime(1) and who(1).
SY T M or
SY T T 3270
The first command shows only MTS jobs; that is what end users are executing. (There will be some other system MTS tasks listed also.) The second command shows all jobs connected to a 3270 device, which could be another useful way to filter out actual signons. The output shows the device ID (eg, DS02) which is likely as close as one can get to the ‘address’ at this point. Not sure how to get the logon time, either.
write user$MESSAGESYSTEM DISPATCH TO ID=userME DISPA TO ID=userYou can add TEXT='your text here' OK to send just one line without confirmation. Or, you could add CONVERSE if you want to send multiple messages (ie, start a conversation). By default, the dispatch is sent to the task with the lowest task number; you can add ALLSIGNONS to send to all current signons of the recipient.
write user ttyS1$MESSAGESYSTEM DISPATCH TO DEV=ds01ME DISPA TO DEV=ds01It’s not necessary to include the ID again if you know the device to which you want to send the message. Instead of ID=user or DEV=dsnn you can use OPERATOR to send a dispatch to the operator’s console.

Note that there are no command equivalents for manipulating directories; (almost) all named directories in MTS are actually user accounts (as was common for systems of this era).

Commands I’m still looking for or working on: cal/calendar, df/du (*DSK?), find (packmap?), quota, su, top ($sy l?), wall (broadcst?), units

File specifications

(source 1, p. 13 [PDF p. 19]; source 2; source 3, pp. 87–92)

There are three types of files in MTS:

  1. Public files. Also called star files. These begin, but do not end, with an asterisk (*). They may be up to 16 characters long (including *).
    eg, *PIL
    To obtain a list of all public files (to which you have access):
    # $F *?
  2. Private–permanent files. These may be from 1 to 12 characters long (16 including the userid).
    eg, W010:VIDEOTAPE
    You can see files in someone else’s catalog with a command like:
    # $F W010:?
  3. Private–temporary files. These may be from 1 to 8 characters long, and prefixed with a dash (-), unless you change this behaviour ($SET SCRFCHAR). They are automatically destroyed at $SIGNOFF.
    eg, -LOAD
    These are actually stored in the <SF> (scratch file) catalog. Thus you can see them all with:
    # $F <SF>:?
Besides the aforementioned length restrictions, file names are limited to the following characters:
A-Z 0-9 < > $ * - % # / . _ !
Private files can’t start with an asterisk – that would be a public file! They also shouldn’t start with > or # (known as flag characters). Technically you could do this by including your userID, eg: $CREATE W010:#FILE but it’s probably not a good idea.

Flag characters

Thus far, I’ve discovered the following flag characters:
flag character$SET parameternotesother uses
#$SET FILECHARIndicates that what follows is a plain file name. One potential use for # would be to identify a permanent file beginning with -, eg: $CREATE #-PERMFILE (though one would imagine it better to find a new file name).The standard MTS Command Mode prompt.
-$SET SCRFCHARIndicates that what follows is a temporary file. Thus the - isn’t actually a part of the temporary file name on disk, just a convenient way of accessing it.Can also be used as a line continuation character ($SET CONTCHAR), like \ at the end of a line in Unix shells. Used as a prompt character in $SYSTEMSTATUS.
>$SET DEVCHARIndicates that what follows is a device name, eg, >T901.Can also be used to invoke the macro processor, eg, >DISPLAY SYSTEM_VARIBLES. Used as a prompt in the $LIST command, and as a prefix character in $COPY output.

Terminal configuration

Operator’s console

(source 1; source 2, pp. 328–333 [PDF pp. 334–339])

Device commands begin with a percent sign (%); you can use %PF? to find out the PF key mappings:

00002 OPERATOR P 1:MTS OPER                       P 2:MTS *_        
00002 OPERATOR P 3:STOP _                         P 4:BROADCST _    
00002 OPERATOR P 5:$DISPLAY JOB _                 P 6:$RELEASE JOB _
00002 OPERATOR P 7:$BACKLOG ALL                   P 8:$BACKLOG _    
00002 OPERATOR P 9:$DRAIN _                       P10:_             
00002 OPERATOR P11:_                              P12:_             
 ...    ....   ...     ...                        ...     ...
00002 OPERATOR         Screen output mode is %FAST

PF13–PF24 (ie, Shift-PF1–Shift-PF12) are identical to the above.

Reformatted a bit nicer, to look more like my regular terminal:

PA1: attention interruptPA2: Cancel / end of file
Clear: refresh screenSys Req: pause / continue

Standard terminal


You can use the device command %? or %PF?:

# %? 
   Roll mode   Rate=5   Duplex=on    Width=078   Timeout=00030
   Dcc="%"   Keyboard=lc    Hex=off "'"   Buffer=04    Tabs=off "?"

   PA1 = attention interrupt             PA2 (CNCL) = end of file  
   CLEAR = refresh screen                SYS REQ = pause / continue

PF1 =%Wb=*                PF2 =$Copy *msource*@sp * PF3 =%?        
PF4 =%Wf=*                PF5 =%Mode=page           PF6 =%Enter    
PF7 =%Wf                  PF8 =%Mode=line           PF9 =%Mode=roll
PF10=%Wl                  PF11=%Wl=60               PF12=%Wr=60    
As in the operator’s console, PF13–PF24 are identical to PF1–PF12. There are four possible device output modes:
%rollThe default output mode. This is a kind of “smooth scrolling”. Equivalent to %line with %hist=41.
%lineText fills the screen; when the screen is full, it is cleared, then a few of the most recent lines are displayed at the top (and the screen filling resumes). %hist determines how many recent lines are redisplayed (14 by default). Kind of an “overlapping pagination“.
%pageText fills the screen; when the screen is full, the output is paused. Press Sys Req (⌘/ in tn3270) or enter %pause to resume. May not be suitable for commands that produce line-by-line output, eg: $SYSTEMSTATUS LOAD.
%fastText fills the screen, but the screen isn’t updated until input is requested again. Like %page, this makes this mode unsuitable for some commands.
Some of my more common device commands:
%activityDisplays a variety of status information, including user ID, project ID, task number, memory usage, current time & date, CPU time, elapsed session time, task status, devices in use, and pages printed. Especially nifty because it doesn't require you to interrupt whatever other program you’re executing (ie, you don’t need to be in MTS Command Mode to use this feature).
%pf2=%pauseThe default mapping of %pf2=$COPY *MSOURCE*@SP *PRINT* is fairly useless to me, and Sys Req can be a hard key to press, so I find it helpful to map that to PF2.
%rate=9I’m a pretty fast reader; if I can’t use %fast for some reason, at least this way the scrolling can happen at a reasonable pace.
%timeout=offBy default, there’s a 30-minute inactivity timer, after which point you will be logged off. This command suppresses the timeout.
As an aside, you can run, eg, $CONTROL *MSOURCE* timeout=off as an alternate way to invoke these commands. This could be useful in a sigfile, so your settings take effect at each signon.

Programming languages

There is another site, try-mts.com, which is an excellent resource, especially when it comes to different programming languages. Check out the programming languages tag to narrow your search.


(See the documentation, and also the excellent BASIC posts on the try-mts.com site.)

I’ve documented the various quirks of MTS BASIC on my other notes page, so here I will explain only the mechanics of launching BASIC, running programs, saving, etc.

Following standard MTS convention, the BASIC system is launched by $RUN *BASIC, where *BASIC is a public file. You then use the /OPEN command to start a new file. (Unlike most BASICs, you can’t just start typing BASIC after launching it.) Then you may enter program text and /RUN the file in memory.

# run *basic
# Execution begins   23:15:39
: /open hello
&  "HELLO" has been created.
: 10 print "Hello, World!"
: run
  Hello, World!
+  Program Ends

The forward slash (/) before BASIC commands is optional, much like the dollar sign ($) is at the MTS prompt. I used it before /OPEN, but not before /RUN.

At this point, the program exists only in memory. You can prove this easily enough by running $FILESTATUS from within BASIC:

: $f
# $F

Here the $ is required to let BASIC know it needs to pass the command through to MTS. (I have no files in this account yet, which is why the output is empty.) Also notice that the “confirmation line” starts with the # symbol, indicating it was recognized as an MTS command.

Let’s try to make a new file:

: new
&  Invalid command.
: scratch
&  Invalid command.

Oh dear. Looks like neither of the ‘standard’ commands work here.

The /FREE command can be used to “destroy only the ‘temporary’ or ‘core’ copy of a file” (documentation, p. 91). If you /FREE your active file, then you will no longer have an active file, and thus you must /OPEN one again.

: /free hello
&  "HELLO" is to be freed. - Please confirm.
? ok
& Done
: /open hello
&  "HELLO" has been created.
: list
& End-Of-File

Let’s try something a bit more interesting:

: 10 q=atn(1)
: 20 print "  x","  sin(x)","  cos(x)"
: 30 print " ----------"," ----------"," ----------"
: 40 for i=-8 to 8
: 50 x=q*i
: 60 p=x
: 70 gosub 180
: 80 x$=p$
: 90 p=int(sin(x)*1e8)/1e8
: 100 gosub 180
: 110 y$=p$
: 120 p=int(cos(x)*1e8)/1e8
: 130 gosub 180
: 140 z$=p$
: 150 print x$,y$,z$
: 160 next i
: 170 end
: 180 p$=nts(p)
: 190 p$=" "+p$
: 200 if p>=0 then: p$=" "+p$
: 210 return
: run
   x              sin(x)         cos(x)
  ----------     ----------     ----------
  -6.283185       0              1
  -5.497787       0.7071068      0.7071068
  -4.712389       1              0
  -3.926991       0.7071068     -0.7071068
  -3.141593       0             -1
  -2.356194      -0.7071068     -0.7071068
  -1.570796      -1              0
  -0.7853982     -0.7071068      0.7071068
   0              0              1
   0.7853982      0.7071068      0.7071068
   1.570796       1              0
   2.356194       0.7071068     -0.7071068
   3.141593       0             -1
   3.926991      -0.7071068     -0.7071068
   4.712389      -1              0
   5.497787      -0.7071068      0.7071068
   6.283185       0              1
+  Program Ends

Okay, not terribly interesting, but you get the idea. I’ll /SAVE this for later, /QUIT BASIC (using a synonym, /BYE), and come back to this file again:

: /save
& Done
: /bye
&  Off at 00:27:55 on 10-27-19
# Execution terminated   00:27:55  T=0.69
# run *basic
# Execution begins   00:28:50 
: /permcatalog
&  Total =   1 files using     2 pages.
: /open sincos
: list 170
  170 end

The /PERMCATALOG command above lists only BASIC files in your account. You will see your BASIC files in a regular $FILESTATUS display, but it’s some binary format which you can’t $COPY or $LIST:

: $f
# $F
: $copy bsc.ssincos
> SSINCOS ??????????????????aaaaaa??????????????? 10 q=atn(1)aaaaa
> ???-????????????20 print "  x","????  sin(x)","  cos(x)"aaaaaaaa?????????????
: $list bsc.ssincos(1,1)
# $LIST bsc.ssincos(1,1)
       1     SSINCOS ??????????????????aaaaaa??????????????? 10 q=atn(1)aaaaa

All this, plus the notes on MTS BASIC’s quirks should be enough to get you up and running.

System operations

Accounting database

Returns what is apparently a list of all accounts grouped by project, reproduced here:
  LINE     ID  LENGTH  ELEMENTS                                              

                       COUN CREP C87. DIFF DIST DMGR DSP. DSR. DUMP EDIT ETC.
                       IF66 IF77 IG$. KERB LIB. LISP LSPX MAC. MAIL MCP. MINI
                       TMTS TNGO TSTP UMPS UNSP VMXA V370 WPSW WSCV WXA1 W009
                       W052 W062 W494 W930 

00000200  WOPN  00032  FIX. INIT RSTR SEG2 STRT SYS. 
00000300  WNET  00012  K1Y9 
00000400  WJMB  00012  ALWB 
00000500  WDLB  00012  DLB. 
00000600  WDRH  00012  DRH. 
00000700  WDWB  00012  DWB. 
00000800  WKLB  00012  KLB. 
00000900  WMTA  00012  MTA. 
00000A00  WSRB  00012  SRB. 
00000B00  WWSG  00012  WSG. 
00000C00  WCFE  00012  W013
00000D00  WGHL  00012  W030
00000E00  WCEL  00012  W05Q
00000F00  WEJF  00012  W070
00001000  WGRH  00012  W170
00001100  ST00  00012  ST00
    .       .     .     .
    .       .     .     .
    .       .     .     .
00007400  ST99  00012  ST99
For those of you keeping count, that’s 16 unique projects (plus 100 STnn projects):
And 112 unique userids (plus 100 STnn ccids):
ACC.    CREP    FILE    KERB    MTS.    PLOG    SLID    WPSW    STRT    W030
AMDB    C87.    FORT    LIB.    MTSS    PLUS    SWAT    WSCV    SYS.    W05Q
APL.    DIFF    FVS.    LISP    NASD    PMF.    SYSU    WXA1    K1Y9    W070
APLI    DIST    GDOC    LSPX    NET.    POST    TAPE    W009    ALWB    W170
ARC.    DMGR    GOM.    MAC.    NETS    PSEE    TAR.    W052    DLB.
ASMH    DSP.    GRAF    MAIL    NEW.    RATF    TMTS    W062    DRH.
BCC.    DSR.    HASP    MCP.    NPRV    REPL    TNGO    W494    DWB.
CKID    DUMP    HELP    MINI    OLD.    RMGR    TSTP    W930    KLB.
CLIB    EDIT    HOST    MM$.    OPER    RMRD    UMPS    FIX.    MTA.
CLS.    ETC.    IF66    MNET    PAGE    SCP.    UNSP    INIT    SRB.
COPY    FDEV    IF77    MNOP    PCP.    SDS.    VMXA    RSTR    WSG.
COUN    FICS    IG$.    MNTR    PFIO    SFIL    V370    SEG2    W013
It seems that most system accounts have the default password (aardvarks), which should obviously be changed if ever one planned to make a MTS system public again. And STnn passwords are by default the same as the userid.

Checking the queues

(source, p. 29)

At the operator’s console:

$*  Job   Uid   Q        Time-Day Cdsin Extm Prnt  CpyPnch Py    Name
$*        Delivery Waituntil         Forms
$*600002  SYS. PRNT W    02:51-08     0    3  142X  0    0
$*        NONE                       AnyStandard
How does this work?

The MTS D6.0A distribution comes with a 142-page print job queued, which I wanted to cancel. But I couldn’t figure out who started the job (SYS.) or its job number (600002). The job was cancelled with:

$DELETE JOB 600002
$*Job 600002   Cancelled by OPER

Responding to CMDSTAT mount requests

(source, pp. 471–475 [PDF pp. 477–481])

From time to time, you may see something like the following at the operator’s console:

00052 MTS  *DWB: The CMDSTAT file to tape program has been started. ********
00052 MTS  *DWB has been started to dump the CMDSTAT file(s), if any, to tape.
00052 MTS  A tape, labeled as indicated, should be mounted when requested.
00052 MTS  See component 531 for a description of CMDSTAT.
00052 MTS SYS.:  F (1 9TP) M001 on 9TP, ring IN, 'CMDSTAT' ********************

In other words,

How do I handle this?

First, make sure the tape (cmd001.aws) is loaded via Hercules:

Command ==> devinit 18a
HHCTA101I 018A: AWS Tape Tapes/cmd001.aws closed
HHCTA004I 018A: Tapes/cmd001.aws is a AWS Format tape file
HHCPN098I Device 0:018A initialized

Then, back at the operator’s console, indicate that you have loaded the tape:

OK M001 T90A
00052 MTS Mount check OK.Mount M001 on T90A Ring In
00052 MTS SYS., M001:Accepted on T90A
00052 MTS **** Remove tape M001 from T90A (6250 BPI)
What is this process all about?

Rupert Lane has already put together an excellent page on CMDSTAT, *DWB, etc which I won’t redo here.

What to do with those CMDSTAT-generated tapes

I spent many hours attempting to coax W030:SCANX into giving up some secrets from the CMDSTAT tapes, but without success. The biggest mystery to me is the begintime field, as I don’t know what format it wants. The writeup for SCANX (item 403 on tape 3, W030:SCAN#WX) says:

"fromtime" and "totime" specify the range of signon times of statistics records. SCAN will add a fudge factor to "totime" (currently 12 hours), and scan thru signoff times up to that time. "fromtime" and "totime" are currently in UBCDATE (JVCT) format--this will be changed when I get to it. "TO" is required only when the two consecutive times would be ambiguous. If the time of day is omitted from "fromtime", the beginning of the day is assumed; if "totime" is also omitted, the entire day is used as the range. If the time of day is omitted from "totime", the end of the day is assumed.

I don‘t know what a UBCDATE (JVCT) date looks like. I tried many different inputs without success. Here are some of my attempts:

% sig w030
# Enter password.
# No Charges
# Last signon was at 19:54:23, Mon Jan 28/18
# User W030 signed on at 18:17:30, Tue Jan 29/18
# run scanx
# Execution begins   18:17:54
* sta
? MTS. 0
+ Operation exception at 000708 in section SCAN

I had marginally better results if I set statscan=*statistics(3) as suggested by the operator’s manual – at least it didn’t crash:

# rerun
# $Run scanx
# Execution begins   18:45:21
* set statscan=*statistics(3)
* sta
? MTS. 0

Not shown here, but I did try many other things in place of 0, including various text date formats, numeric dates in decimal and hex, blank, etc.

No joy from the tape, either:

Command ==> devinit 18a Tapes/cmd001.aws ro
HHCTA004I 018A: Tapes/cmd001.aws is a AWS Format tape file
HHCTA066I 018A: option 'ro' accepted.
HHCPN098I Device 0:018A initialized
00053 MTS W030:  T (1 9TP) M001 on 9TP, ring OUT, 'CMDSTAT' *******************
OK M001 T90A
00053 MTS Mount check OK.Mount M001 on T90A Ring Out
00053 MTS W030, M001:Accepted on T90A
# M001 9TP *T* VOL=CMD001 'CMDSTAT'
# *T* (M001): Mounted on T90A
# rerun
# $Run scanx
# Execution begins   19:07:51
* set statscan=*T*
* sta
? MTS.
+ Data exception at 174DF4
# release *T*
# "*T*": (M001) T90A released.
00053 MTS **** Remove tape M001 from T90A (6250 BPI)

The next step would be to pull the source for SCAN and see what it does, but that has so far been beyond my available time.

System internals

CKID and sigfiles

(source, PDF pp. 54–55)

When one signs into shared system userids (eg, MTS or ACC), a second-level userid and password is required. (You can imagine this as a “reverse su”.) The exchange looks somewhat like this:

# Enter password.
? aardvarks
# No Charges 
# Last signon was at 01:09:05, Sat Mar 15/13
# User ACC. signed on at 01:38:32, Sat Mar 15/13
ID? st00
PW? st00
How does this work?

*CLS? files (Command language subsystem)

Startup trace

Feel free to contact me with any questions, comments, or feedback.