ITS Midas system calls

104 views
Skip to first unread message

Francis King

unread,
Oct 23, 2025, 4:13:36 PMOct 23
to PiDP-10
What I want to do is to understand PDP-10 Midas assembler system calls.This is a real nest of thorns. It looks easy until you start asking awkward questions.

A simple example:

Hello world.png
So, I can sort of see what it's trying to do. We set the channel to be 1, and use .open to open the channel to the terminal screen (.uao,,'tty). If it succeeds then it skips the next line. If it fails, it runs .lose and stops.

We read in 7-bit ASCII from the text at hello:, if the character is zero (end of text) we jump to .logout 2, which ends the program. Otherwise we print the character and loop back. (By the way, why is it 7 bits, when DEC uses six-bit text?)

This is a simple program, and is replicated in the PDP-10 book. Some of the details are a bit odd, though. For starters, there appears to be many ways to code this. We have .open, we have .call, and we have syscal (please see ITS, folder LARS, program BACKUP 23). Why one rather than the other?

The device is 'TTY, but if I want to open a file I need to supply a filename, and it is not easy to see how we could do that with .open.

If the device opening fails, it calls .lose. However, sometimes .lose is followed by another parameter, %lsfil, sometimes a different parameter, and sometimes there is no parameter at all.

Finally, we exit the program by calling .logout. Sometime we use .logout 1,  and sometimes we use .logout 2, and again it's not obvious why.

Thoughts please.

Eric Swenson

unread,
Oct 23, 2025, 5:38:08 PMOct 23
to Francis King, PiDP-10
I’m sure Lars or someone else will jump in here with many more details, but I thought it might be good to point out a few things about your message:

These are not “PDP-10 Midas assembler system calls”, really. The .open, .lose, and .logout you see there are called UUOs.  These are undefined processor opcodes that, when executed, cause a trap to a UUO handler, and are executed by it.  See the file SYSDOC;UUOS > for a list of all of these and their function and parameters.  Some of these UUOs are actually handled by ITS as system calls.  The .call UUO, for example, will make a system call to ITS.  See the file SYSDOC;.CALLS > for a list of all system calls and their function and parameters.

MIDAS is an assembler.  There could be other assemblers.  And there are compilers (lisp, muddle, C, etc.). All of these produce programs in machine code, which can make these calls.  So these UUOs are not really related to MIDAS — EXCEPT that MIDAS, as a convenience knows how to translate symbolic UUOs (e.g. .logout) to a processor opcode — a UUO opcode, so that a trap will be taken upon executing them.

Note also that a UUO need not be implemented in ITS or DDT.  Any program can set up a UUO handler and can handle UUOs as well.  This allows you to define your own “opcodes” and “handlers”.

It doesn’t “run” .lose (nor any of the other UUOs).  It executes the “undefined” opcode (the UUO opcode), which invokes the UUO handler, which performs the function associated with the mnemonic.  The documentation on the .lose UUO starts out this way (see SYSDOC;UUOS >):

.LOSE lossage-code                      report lossage

        The job's Program Counter is set to the address of the
        .LOSE minus one, the job's .VAL user variable is set
        to the new PC,,the magic bits, and the
        job is given a %PILOS interrupt.  If the job does not
        enable this interrupt, and it's superior is DDT, a
        helpful error message will be printed.

        The magic bits are documented in DDT ORDER.
        The most useful ones are 0 for a random error,
        1000 to ask DDT to type the error message corresponding
        to the most recent system call error return, and
        1400 if DDT should attempt to print the names of
        the file that the call was opening/referring to.

You asked about the parameter to the .lose UUO.  That is the lossage-code (above).  Read the further documentation in SYSDOC;UUOS > for details on lossage codes, such as %LSFIL.

You asked about the parameter to the .logout UUO.  Here is the doc (again from SYSDOC;UUOS >):

.LOGOUT                                 log out

        The executing job and all direct inferiors are killed,
        providing that it is the top-level job of its job tree.
        All resources used by such jobs are freed.  If the job
        tree was console-controlled, the system job will print
        a "console free" message on the freed console.

        If the executing job is not top-level, .LOGOUT with zero
        in the AC field merely returns without skipping.
        (An inferior job may not commit suicide without the consent
        of its superior.)  .LOGOUT with a nonzero AC field will
        cause a fatal %PIBRK interrupt which will inform the superior
        that the job wants to be killed.  If the superior is DDT,
        it will kill the job.  Here is how a program should exit:

                SKIPE DEBUG             ;optional debugging aid:
                 .VALUE                 ; job hangs if being debugged
                .LOGOUT 1,              ;log out or be killed.

Note the discussion about the UUO parameter (which is really just the accumulator (AC) field of the instruction.  0 means don’t skip if it fails.  Non-zero means that it will cause the job to get an interrupt that will let the superior, DDT, kill it.

If you say “.logout”, it is the same as “.logout 0,”.  In general, if you don’t specify an accumulator value in a PDP-10 machine instruction, it will be set to 0.

You asked about 7-bit ascii versus 6-bit.  Both ASCII and SIXBIT are supported.  The byte pointer (loaded by moving 440700 into the LF or A (which becomes the byte pointer to the string starting at the HELLO label) basically specifies a mask and size for “bytes”.  The 07 there is specifying 7-bit (I think).  Other byte sizes are possible depending on the byte pointer.  See the LDB and ILDB instructions in the processor manual.

And yes, there are many way to code this.  Using the .logout UUO, for example, can be replaced by making a .call to the SIXBIT/LOGOUT/ ITS system call.  In general, UUOs that invoke system calls are “deprecated” (although still very much in use), and use of .CALL is recommended.

To see how you might change this program to open a file, look at the OPEN system call (preferred over the .open UUO) and read about how to specify files.

On Oct 23, 2025, at 1:13 PM, Francis King <francis...@gmail.com> wrote:

What I want to do is to understand PDP-10 Midas assembler system calls.This is a real nest of thorns. It looks easy until you start asking awkward questions.

A simple example:

<Hello world.png>
So, I can sort of see what it's trying to do. We set the channel to be 1, and use .open to open the channel to the terminal screen (.uao,,'tty). If it succeeds then it skips the next line. If it fails, it runs .lose and stops.

We read in 7-bit ASCII from the text at hello:, if the character is zero (end of text) we jump to .logout 2, which ends the program. Otherwise we print the character and loop back. (By the way, why is it 7 bits, when DEC uses six-bit text?)

This is a simple program, and is replicated in the PDP-10 book. Some of the details are a bit odd, though. For starters, there appears to be many ways to code this. We have .open, we have .call, and we have syscal (please see ITS, folder LARS, program BACKUP 23). Why one rather than the other?

The device is 'TTY, but if I want to open a file I need to supply a filename, and it is not easy to see how we could do that with .open.

If the device opening fails, it calls .lose. However, sometimes .lose is followed by another parameter, %lsfil, sometimes a different parameter, and sometimes there is no parameter at all.

Finally, we exit the program by calling .logout. Sometime we use .logout 1,  and sometimes we use .logout 2, and again it's not obvious why.

Thoughts please.


--
You received this message because you are subscribed to the Google Groups "PiDP-10" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pidp-10+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/pidp-10/dd145b4f-6246-4066-84d1-f088db0c6ecbn%40googlegroups.com.
<Hello world.png>

Lars Brinkhoff

unread,
Oct 24, 2025, 12:33:02 AMOct 24
to PiDP-10
This is a real nest of thorns. It looks easy until you start asking awkward questions.

There are some quirks, but in this example it's quite straightforward.  Ask away!

I think Eric answered most of your questions.  Regarding UUO versus .CALL: If you check the ITS 1.4 or 1.5 Reference Manual you'll only find the UUOs.  They are pretty much like most other operating system calls.  The .CALLs came a little later and are unique to ITS.  Calls are identified by name rather than by number, and the arguments have a very regular structure.  I think the rule of thumb is: use a UUO when it's convenient or conventional, like .OPEN, .LOSE, .IOT.  Use a .CALL for more advanced situations, where there often is no UUO that can do the job.  For example, if you want to open a device with a long name, .OPEN can't do that; same if you want to supply a directory (SNAME).

If you want to .OPEN a file name, those go after the first argument word, i.e. .OPEN CH,[.UAO,,DSK ? SIXBIT/FN1/ ? SIXBIT/FN2/]  But no SNAME.  The old style is to set SNAME before .OPEN.

SYSCAL is just a conventional macro to make .CALL a little easier.  Sometimes I don't bother with it.

Jali

unread,
Oct 28, 2025, 6:55:59 PM (12 days ago) Oct 28
to PiDP-10
Maybe my question is related to this topic:  I am still struggling with the syntax of the system calls, and the explanation in SYSDOC;CALLS was no real help.  I have successfully tried to access a file with .CALL following this example:
CALL [ SETZ ? SIXBIT/OPEN/ [.UAO,,CHDSKI] ? [SIXBIT/DSK/] [SIXBIT /FOO/] ? 400000,,[SIXBIT/BAR/]].
But in my code, I am fetching the filenames as parameters, using JCL. I successfully stored them as SIXBIT in a memory area I designated FNAME1 and FNAME2. However, I don't know how to pass them to the call. Every example I have found so far, has used literals such as SIXBIT/FOO/. I have tried passing the addresses as byte pointers stored in accumulators, or directly as an  addresses by passing FNAME1 and FNAME2 as parameters. But I  always get a FILE NOT FOUND ERROR, and the file names are just jumbled data. I am pretty sure I am missing the obvious here, but I don't see it.  I'd be ever so grateful for a nudge in the right direction.

Ric Werme

unread,
Oct 29, 2025, 1:00:42 AM (12 days ago) Oct 29
to PiDP-10

Re: (By the way, why is it 7 bits, when DEC uses six-bit text?)

DEC uses sixbit, ascii (7 bit only in those days), and  RAD50 (for program symbols - three characters in 16 bits).

You wrote:  asciz  /hello, world/

The Z in asciz says to emit a zero byte after the string.  It commonly is used to mark the end of a string.  Had you used sixbit:

1) Lower case is not in sixbit.
2) a zero byte codes for a space - you need a different mechanism to note the end of the string or track the length of the string.
3) if you wanted a CRLF at the end of the strings, you'd be out of luck - sixbit has no control characters.

When you note that DEC uses sixbit,  note that it's often for things like file names (six or three characters fitting in a word or half word).  Ascii (asciz), is used for messages, especially those with lowercase, more punctuation, and formatting characters (backspace, tab, line feed, vertical tab, form feed, carriage return) and other control characters.

Lars Brinkhoff

unread,
Oct 30, 2025, 12:17:57 AM (11 days ago) Oct 30
to PiDP-10
Jali wrote:
Maybe my question is related to this topic:  I am still struggling with the syntax of the system calls, and the explanation in SYSDOC;CALLS was no real help.  I have successfully tried to access a file with .CALL following this example:
CALL [ SETZ ? SIXBIT/OPEN/ [.UAO,,CHDSKI] ? [SIXBIT/DSK/] [SIXBIT /FOO/] ? 400000,,[SIXBIT/BAR/]].
But in my code, I am fetching the filenames as parameters, using JCL. I successfully stored them as SIXBIT in a memory area I designated FNAME1 and FNAME2. However, I don't know how to pass them to the call.

This is explained in SYSDOC;.CALLS.  A very condensed version is that your example above already passes in arguments stored in memory.  I.e. the four bracketed expressions are addresses to the arguments.  So you can replace e.g. [SIXBIT /FOO/] with FNAME1.  If you want to be more explicit about the type of argument, you would say %CLIN,,FNAME1.  But %CLIN is 0 so you can leave it out, which is convenient for this common situation.  An argument can equally well go in an accumulator, since it has an address.  So e.g. %CLIN,,A or just A if you want to pass something in A.
 
But I  always get a FILE NOT FOUND ERROR, and the file names are just jumbled data.as I am pretty sure I am missing the obvious here, but I don't see it.  I'd be ever so grateful for a nudge in the right direction.

If you use DDT to step your program to the .CALL, you can run the :CALPRT program to get some information about the system call.  Then you can see if the information agrees with your view or not.

And after an error, you can run the DDT command :ERR to get some information about the problem.  See DDT ORDER for details.

Side note here: Isn't it amazing how full featured the ITS development environment is?  Most of the things you want for convenient programming are in there, somewhere.  You just have to find them, and get used to the fact that they may not be quite like what you are used to from typical environments today.

Francis King

unread,
Nov 2, 2025, 12:49:30 PM (7 days ago) Nov 2
to PiDP-10
I would like to thank everyone for their input. I am working through your comments now.

Lars, please could you explain more about the comments on SNAME.

F.

Eric Swenson

unread,
Nov 2, 2025, 12:58:15 PM (7 days ago) Nov 2
to Francis King, PiDP-10
The .open UUO doesn’t allow specification of the SNAME; the .CALL OPEN system call does.

The SNAME is the directory of the file.

On Nov 2, 2025, at 09:49, Francis King <francis...@gmail.com> wrote:

I would like to thank everyone for their input. I am working through your comments now.
--
You received this message because you are subscribed to the Google Groups "PiDP-10" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pidp-10+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages