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

last update: 12/06/03

Introduction

This describes a BETA release of a program which emulates a Digital Equipment PDP-11 running the RT11SJ monitor. 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. 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 potential 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 sit, but if you are interested feel free to contact me. The executable is still freely available on reguest, but you have to give me some feedback if you want it. As described below, its up to Version 0.95, 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 MSDOS file system, NOT a disk image. The current version, 0.95, maps device specifications to local sub-directories. 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 passed to RTEMU on the command line. 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 or call one of the CSI EMTs to access files. If RTEMU is executed with no arguements you get the following usage message:
RTEMU Version 0.90 Beta
usage: rtemu *.sav [-d#] [-nkb] [-t] [-b[d]#] [-bi#] [-h] [-l{e|i}]
 load named file into system
 -nkb clears default VT100 emulation flag
 -d# sets debug: 2 disp macro | 4 disp regs in odt | 20 odt @ exit
 -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
 -h# 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. The others are left over from the development cycle. 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, 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). Under MSDOS VT100 emulation is in effect 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. The -t and -d# command line options set bits in this flag. Use -t to start in a single step trace mode and -d20 if you want to exit to my "ODT" debugger when the program terminates. You can also set multiple octal break points with the -b# option. I frankly don't remember what -bd# does! -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 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 untill 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'.

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.

This only runs one program at a time. It wouldn't be to hard to add a top level loop that looked something like KMON but I don't have the energy at the moment and it does what I need it to do now.

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.

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.

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 RT11 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. 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 added an optional simplistic monitor loop to process some simple commands like dir, copy, and run, bringing it to version 0.95 but this is not a direction I plan to continue. Version 0.95 also allows mapping disk devices to different sub-directories. Basically this will remain a program to emulate a single stand-alone RT11 executable.

I spend 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.