In order to really learn how to program in assembler, it is necessary to learn about the IRIS environment and the tools that are available. We hope this is a good starting point.
Understanding IRIS Subroutines
IRIS provides an extensive set of callable routines that do a lot common tasks like “Get a Byte” and “Write a Block”. Knowing what these are and how to call them gives us a lot of tools to make programming easier.
The vast majority of these routines are available through three main approaches:
- JSR’s (indirect) through page zero pointers. Most of these have readable labels defined for them. For example, GETBYTE assembles as JSR @116 and returns the byte addressed by the contents of AC1 (which the program loads before executing GETBYTE).
- CALL statement (followed by a subroutine number) for both memory resident and disk resident subroutines.
- CHANNEL statement (followed by subroutine number) for channel I/O
Since there are so many of these, each with its own calling sequence, they will be summarized in a download document (see downloads). Most of these are described in the Manager Reference Manual as well, but it can be hard to find what you are looking for there.
Please refer to the document for details on how to use all of these IRIS support routines.
The CALL statement actually assembles as a JSR @100, which runs a REX routine that looks up the subroutine # (after the CALL stmt) and jumps there with all AC’s intact. The CHANNEL statement assembles as a JSR @105, which runs a REX routine that requires AC0 to contain a user channel#, which it converts to a memory address in the user’s Data File Table (DFT), sets AC0 to that address, and then jumps into the REX code for a CALL stmt.
Extending IRIS Capabilities
IRIS is an extensible operating system. We can add new features at any time. That’s what makes it fun to work with! Here are the primary areas for adding new capabilities. Over time, each of these will be documented with all the info available to us.
1. New processors
Most of the major utilities such as COPY, FORMAT, KILL, BASIC, and so on are written as “system processors” which have special privileges and capabilities. For example, they can easily manage the user sessions, interact with user terminals, and safeguard information when users are swapped in and out of memory, These programs can also be quite large by the standards of the time. This means they can perform fairly complex tasks which can take multiple time slices to complete.
2. New Device Drivers
Device drivers are written as relocatable programs that can interact with specific devices that are supported by the hardware — or in our case here, with whatever “hardware” is supported by the SimH nova simulator.
At first glance it might seem that this area has been fully taken care of, but a little imagination might produce some interesting items. For one, we could use a Kermit or Xmodem driver to make it easier to transfer files in and out of the IRIS environment. We could also use a few improvements in existing device drivers ( $LPT.SIM could be modified to provide exports for hosts other than Windows). In any case, it is good to know how to write these types of drivers.
3. New System Support Drivers
IRIS can load relocatable bits of software that can do almost anything. Some existing examples are:
$DEC which simulates all of the decimal arithmetic.
$PHA which supports phantom ports for background tasks.
$TERMS which manages terminal translation, along with various translation modules, all of which are specially designed drivers.
Of course, there is only so much executable memory available for these routines, so they are only used for features that must remain memory resident at all times.
4. New Disc Resident Subroutines
The DISCSUBS file consists entirely of disc resident routines that perform various functions. For example, the support for indexed files that Basic can access via the SEARCH command is all contained within a set of routines included in DISCSUBS. The most commonly used routines can optionally be made memory resident (see Manager Reference Manual).
These subroutines are all accessed via either a CALL statement or a CHANNEL statement in assembly. They must be less than two blocks in length (max is around 509 words), and most are less than a single block in length. They are intended to provide functions and processes to higher level programs, usually ‘System Processors’ as noted above.
Some ideas for future routines might be:
— Parsing XML files into an array (for BASIC).
— Comparing a string to a “general expression” to see if there is a match.
5. Patching Existing IRIS Software
Given the nature of software, there is always something else that can be added to an existing routine. For example, for those familiar with DSP, you can see that we have already patched the R7.5 version to provide features that were not available then, such as telling the dump command ( ‘D’ ) how many words per line to print.
The sky is the limit here. What if some of our commands allowed wild card characters? Imagine being able to type, “# KILL DOC%” and any file beginning with the letters “DOC” would be killed. Or perhaps you are tired of looking at file charges in the LIBR listing (since no one will ever use them). LIBR could be patched to drop those and shorten the print line a bit. (actually we did this one).
6. Writing System Utilities in BASIC
While this area is technically about Basic and not Assembly, it is included here because Basic provides some interesting tools for writing utilities that require some knowledge of internal IRIS structures. It is possible to view memory locations, modify disc blocks, chain through processes (similar to a Unix pipe), and so on. With a little imagination, new utilities could offer such things as a Batch processing tool (similar to .bat files in DOS).
7. New Stand-Alone Routines
It is also possible to write new stand-alone routines which take full control of the Nova machine. These routines are run by means of the SHUTDOWN command, which loads the referenced program and turns execution over to it. The program dictates where it will be loaded into memory, and can even overwrite IRIS in the process.
This is how the original backup routines were written, and many of the hardware diagnostic tools as well.
For us, it would mean the ability to write anything we want to, which may not have anything to do with IRIS at all. Just for the fun of it.