PDP-11‎ > ‎


RTEMU Emulates a PDP-11/23 (KDF11-AX) Running RT11SJ

last update: 03/15/10


This describes a BETA release of a program which emulates a Digital Equipment PDP-11 running the RT11SJ monitor without floating point support. My motivation was to be able to run a program created with Digitals Fortran IV compiler in a demonstration on any MSDOS machine without the concern that I was violating DEC operating system licensing laws. It is my understanding that DEC licenses are machine specific, and not having a laptop PDP-11 I thought an emulation that included the operating system was worth concidering. This has been accomplished by writing code that emulates the PDP-11 instruction set, a VT100, and most (NOT ALL) of the RT11SJ EMT calls. It was originally written in 16 bit Microsoft C, with almost no attempt at optimization. It has since been ported to Linux. It supports Fortran IV virtual memory arrays and emulates 256 kb of memory on a PDP-11.

There are a number of PDP-11 emulators available for hobby use which are more robust than this one. Both sites below have extensive lists by machine type:

DEC machines emulation
The DEC Emulation Website
My personal favorite is John Wilson's Ersatz-11 . John's FTP pages, contain a lot of useful PDP11 information. Through out this document I will be making comparisons to John Wilson's E11 program. In summary it is at least four times faster than mine, will run ANY PDP-11 code, and emulates most of the hardware. Although my emulation is more restrictive in most areas, it does emulate the operating system so I believe it eliminates and potential RT11 license conflicts as long as you have rights to the program you are executing. I have not done much in the way of timing tests, but have done some with my target Fortran IV generated program which does a lot of work with virtual arrays. My Pentium 75 MHz MSDOS development system seems similar to the performance of a real PDP-11, so todays machines should be significantly faster.

Version 0.9B was available at my earthlink site for several years without much interest. I no longer maintain the distribution on this web site, but if you are interested feel free to contact me. The executable is still freely available on request, but you have to give me some feedback if you want it. As described below, its up to Version 0.96, which contains some bug fixes and runs under both MSDOS and Linux.

Implimentation and Operating Instructions

The RTEMU program will execute a single program in a simulated RT11SJ environment. It uses the local file system, NOT a disk image container file. The current version, 0.96, maps each physical disk to a local sub directory on the host machine at startup via link commands in the initialization file. RT11 files are read and written to these sub-directories. RT11 assumes six characters in the file node name while DOS allows eight. I append "_T" to temporary files created with ENTER commands, and make them permanent by removing this suffix when the file is closed. The standard distribution assumes you are running a single *.sav file which is loaded and executed at startup. The path to the executable can be included in the initialization file as a RUN command or optionally passed to RTEMU as the first argument on the command line. Note the command line argument overrides an initialization file entry. In both cases a full path to the executable, *.sav, on the local machine is required, target link directories are not searched.

None of the optional command line arguements shown below are passed to the *.sav file to be executed, they are all used by the emulator. Your program must explicitly open its own files from the emulated disk directories or call one of the CSI EMTs to access files. If RTEMU is executed with the optional "-h" command line flag you get the following usage message:

RTEMU Version 0.96 Beta
usage: rtemu [*.sav] [-d#] [-i] [-nkb] [-t] [-b[d]#] 
                     [-bi#] [-h[i]] [-l{e|i}]
 1st argument optionally loads named file into system (overrides *.ini)
 -d# sets debug: 2 disp macro | 4 disp regs in odt | 20 odt @ exit
 -h displays this command line help and terminates program
 -i specifies alternate init, default rtemu.ini
 -nkb clears default VT100 emulation flag
 -t sets trace bit
 -b# sets break at octal #, -bd# also sets disp macro at octal #
 -bi sets break at macro id = dec #, see rtmacro.h
 -hi# enables histogram of instruction written to 'histo.dat'
 -le opens filename and outputs all EMT calls
 -li opens filename and outputs all iopage access
 -lm opens filename and outputs all disassembled macro instructions

In most cases you won't need any other argument than the file name of the RT11SJ program you wish to execute, and this can be embedded in the initialization file if you are often running the same program. The others options are left over from the development cycle and are potentially useful when testig new programs. Some may be of interest if you are attempting to find out what a program is doing. In particular the -l options open various log files. Its often instructive to see which EMT calls are made and their order. The -h option writes a binary histo.dat file which is 102 bytes long. Each byte contains the number of times <= 255 the instruction (by index in rtmacro.h) was used. I doubt this will be of interest now, but it was during the debug phase.

I couldn't resist adding VT100 emulation. The ansi.sys included with most MSDOS distributions just isn't enough. Note this isn't required under linux (recent versions 2.2 or later work fine in ansi mode) unless your program still uses the older VT52 escape sequences. Under MSDOS VT100 emulation is in effect by default, but you can disable it with the -nkb command line option (suggested for ODT debug options).

VT100 emulation is similar to what you get in E11. It assumes a fairly new keyboard where you have a set of arrow keys AND a numeric keypad. The function keys F1-F4 map to the VT100 PF1-PF4. The top row of the the four gray numeric keypad keys {NumLock,'/','*','-'} also map to PF1-PF4 as they are in the equivalent positions on the VT100. When VT100 emulation is in effect the keypad state is controlled by the escape sequences seen by the program, NOT the NumLock key. The separate bank of gray arrow keys map to the VT100 arrow keys. It differs from E11 in that the PC keypad only has 3 keys in the right hand column and the VT100 has 4. The gray '+' key on the PC keypad maps to the VT100 ',' unless shift is also depressed in which it maps to the VT100 '-'. I believe E11 handles this with an additional function key. Not all the special graphics characters on a VT100 map to what's available in the PC bios, I did the best I could. I leave it as an exercise for the reader to see what I used. Space invaders looks ok, so I didn't do too bad a job.

I reserve a small block of memory at the top, but could probably eliminate this to make the system act like the XM monitor. No device drivers are required or loaded so there really isn't a USR area. I honor swap/noswap requests as an RT11 system would require this, but they don't do much. You can get more space via SETTOP than you might expect.

The other options control the built in debug capabilities which are some sort of ugly cross between ODT and Microsoft's MSDOS DEBUG program. As mentioned above it is probably wise to turn off VT100 emulation if one is using the debug options. With -nkb in effect all console output is done in tty mode which is what the debugger assumes.

There is an internal debug flag which is a bitmap. With the -d# command line option you can set 3 bits {0x2,0x4, and 0x20) in this flag. You can set them individually or all at once. Use -d2 to start the program in macro display mode (PC and instruction mnemonic displayed on screen at each step) or -di# to turn this mode on at a specific PC in the emulated program. -d4 forces the display of the CPU registers when a break point is reached and -d20 switches to my "ODT" debugger when the program terminates (useful to examine system state if the program is halting unexpectedly). You can also set up to 10 octal break points by repeating the -b# option on the command line. If the PC reaches the a point location the program drops into single step mode controlled by my ODT style debugger. -bi# will cause a break when a particular instruction code is encountered (again the # is the defined index in rtmacro.h). In practice I found creating an EMT log file with -le and then setting break points in areas of interest was quite effective. On entry to the debugger the system flushes the io buffer and prints the ODT '@' prompt followed by the current PC. At this point any of the following commands may be entered.

 B# - set another break point
 BC# - clear this break point (by address)
 BD - display current break points
 C  - display subroutine call nesting level
 D[#] - default octal dump of address
 DH[#] - hex dump
 DR[#] - rad 50 dump
 G#    - sets PC to octal address and resumes execution
 M[#]  - macro disassembly
 JO - jump over subroutine
 O     - toggle output to file
 Q     - graceful exit closing all debug files
 R     - display contents of all registers
 S# # [#]  - set word @ memory address to value, may have 5 words
 SC#   - set condition codes PSW = (PSW &177760) | (# & 17)
 SD#   - set a subset of DEBUG flag bits MACRO_MSK | REGS_MSK | BOUNDS
 SR# # - set register(0-7) to value
 T     - toggle trace  {single step on/off}
   An empty line, ie pressing Enter resumes execution

The dump and macro instructions work on the current IP location or the last address accessed if an octal address is not specified. If the output log file, RTODT.log, is opened with the 'O' command all debug output is appended to the file until it is closed again. Thus one can build up snapshots of the program state by opening and closing this file.

The subroutine nesting and associated JO commands don't always work as expected. JO assumes the subroutine will return to the next IP (so it sets a temporary break point here), I've found a lot of code does not return normally, but instead adjusts the stack and goes somewhere else causing JO to fail. This same logic will fool my call level trace, 'C'.

Initialization file Syntax

The initialization file controls system configuration and operating system options. By default "RTEMU.ini" will be used, but you can override this with the "-i" command line options if you want several different initialization files available.
rest needs to be fleshed out.

Limitations and possible Extensions

The biggest problem is that I don't deal with any character devices except terminal service via ttinr and ttoutr, ie there is no printer. Specifications for output to TT: or LP: will fail while file oriented block device specifications will work. I'll correct this eventually. As stated above, all block oriented devices write to the current directory. I could add a mapping system by unit number to other directories or the floppy drive(s) but not right away. I'd also like to add the multi-terminal MT* emt's to connect to the serial ports at a future date.

Note: haven't I done some of this now??? what is link TT: COM1 in *.ini
doesn't link DL0: do the mapping above?

If you are doing floating point operations you are out of luck. The Floating Point instruction set is not supported

RTEMU only runs one program at a time. I have expairmented with RTKMON which adds a top level loop that looks a bit like KMON. It adds a top level loop which will display device directories, and allow executing programs from these directories as if they are run from RTEMU without any debug options. This isn't a direction I intend to pursue, but it was fun.

I have not implemented all the EMTs for RT11SJ. I know that I left out CMKT, and SCCA. A listing for an EMT call via the -le log file does NOT mean I am handling it, just that it occured! Amoung other things this means you should be careful with ^C, it is likely to abort the program when it shouldn't, especially if you happen to be in my "ODT" debugger.

Although I currently support FORTRAN IV virtual arrays via an MMU emulation I do not support XM monitor operations/programs. I'm currently looking at this, but not sure how far I'll take it. See the comments in the Development History.

Questions for you to answer

If this is neither useful nor interesting I assume I won't hear from you. On the other hand if you find a bug or need a feature please be in touch. I wrote the list of questions below in 2000. I got very little feedback and have gone on to other things. Before putting it on the back burner I did port it to Linux, but am no longer actively working on RTEMU.
  • Are you a hobbist, or do you have a commercial use? If the latter how can I extort some money from you?
  • What do you still use RT11 for anyway?
  • Which if any enhancements would be useful to you (priority order) and why?
  • Which is your operating system of choice MSDOS, Linux or Win32, other? One of the issues here is getting to more memory. 256 kb fits nicely in the MSDOS space, one can get at more in MSDOS but its easier in other environments, ie Linux with more space directly available.
  • If the VT100 emulation is useful, I think it can be split out and run as a stand alone TSR or *.exe to modify behavior of other PC programs. I got a big thread going about this on the PDP-11 newsgroup and apparently Fansi-Console did this fairly well, but although I found it in an archive the documentation for configuring VT100 emulation isn't available in the public release. If anyone can tell me how to get it or a related product to work I won't bother with is anymore. I also find current versions of Linux do this pretty nicely.
  • This is currently only available as a stand alone program. I've got a lot of time invested, and am not yet ready to make the source code available. If it would be useful as a linkable library I would concider that although its currently compiled with the MSC V6.00A 16 bit compiler which means you need to deal with the renaming per OLDLIBS if you use a newer version of this compiler.
  • If you have an RT11SJ application you'd like to run and RTEMU fails to do the job, get in touch. If time allows I'll look at it if you are willing to send me the offending *.sav file and some info on what goes wrong.

Development History

I did about two thirds of the development work in 1994. I was just interested in how RT11 worked, and attempting to write an emulator seemed like a good way to find out. At this time I developed my disk image manipulation routines. RTEMU ran a few very simple programs, but needed a lot of debugging. I may have put something on Compuserve (my only link to the world) at that time, but if so I never got any feedback. Then I found John Wilson's E11 program (don't think Simh was even available). E11 did everything I wanted and more so RTEMU went onto a back shelf. I stumbled across my original code in the spring of 2000 and was surprised how much of it seemed to work. The original concept of emulating the EMTs so one didn't need RT11 still looked valid and I hadn't seen anyone else try this approach. It took another 3 months to get out enough bugs that I was willing to release the 0.90 Beta version. I have since ported the code to Linux, primarily as a learning curve for that operating system. I believe RTEMU works on most of the RT11SJ distribution utilities, but these are part of the licensed package. If you have and run these you might as well use Digital's RT11 operating system with E11. I've also tested RTEMU with a number programs I created over the years using MACRO 11 and Fortran IV. Finally I found Tim Shoppa's PDP-11 Freeware Collecton to be a useful test suite (although as of 2017 it no longers appears to be available). I've successfully executed Runoff, Advent, and Spcinv from this distribution with RTEMU 0.90. Version 0.90 did all disk IO from a single default directory ignoring drive specifications.

Since releasing 0.90 in Sept of 2002, I've periodically done updates and testing. Especially as I had someone interested in using it commercially, however I was not able to add enough of the TSX enhancements he needed to make it viable. In the process during 4/01, I found a signifcant bug in my handling of the SOB instruction which was never corrected in the publically available release. During the summer of 2003 I created Version 0.95 which allows mapping disk devices to different sub-directories in the *.ini file. I also created a companion program, RTKMON, containing a monitor loop to process some simple commands like dir, copy, and run, but this is not a direction I plan to continue. Basically expect RTEMU to remain a program to emulate a single stand-alone RT11 executable.

The current version of RTEMU is 0.96 created in the spring of 2010. It contains some minnor VT100 emulation enhancements, including emulation of the VT52 specific escape codes for MSDOS executables. My interest in this was refreshed by an inquiry as to whether it could be used to emulate Guenter Dotzel's RT11 emulation of the Lilith Graphics Workstation. I worked on this a bit, but it turned out XM monitor support was required. I discovered in 2003 that Ian Hammond was doing something similar which had more features, although this project appears to have been abandoned also. I stopped development when I saw Ian's work. There is a PC emulation of the ETH Lilith, ie the original system as opposed to an RT11 based clone.

I spent a lot of time doing VT100 emulation for DEC ESC sequences in the original MSDOS release. I was originally disappointed when I ported to Linux as my 2.0.36 didn't handle the DEC graphics character set correctly. However with newer Linux versions, 2.2 and above this works perfectly on a standard PC without any effort on my part. Nice. Linux doesn't seem to do VT52 extensions or some of VT100 ansi extensions, but works well with most applications. For the moment I'm content to use what native Linux provides.

Programs Available

There are currently three related programs available:

RTEMU RT11SJ emulator, runs one *.sav program at a time.
Includes various test and debug options documented above. Available for MSDOS and Linux.

RTKMON contains a top level KMON loop that provides RT11 link commands for changing and listing directories and repeated calls execute the RTEMU emulator code allowing selection of different executables from the target directories. Uses the same *.ini fail system as RTEMU. Available for MSDOS and Linux.

PDPMON This uses the VT100 emulation code developed for RTEMU to allow a PC to emulate a VT100. Nothing very special about this, telnet would do this also. However PDPMON also includes my TU58 emulator code. This allows an MSDOS PC equiped with two serial ports to simulaneously act as the VT100 monitor and the TU58 tape drive. Since I have more old PCs than VT100s I often use PDPMON to boot and test my PDP equipment. PDPMON runs in a polling loop (input can be interrupt driven) accessing the two serial ports. One port services the TU58 requests using emulated tapes on the PC hard drive, the other port acts as a VT100 displaying text on the screen and sending keyboard input to the PDP-11. I've never had an overrun when using a 386 cpu and suspect a 286 would work for most applications. Only available for MSDOS as under linux you can easily run simultaneous processes to accomplish this.