Bringing up V6 Unix on the Ersatz-11 PDP-11 Emulator


The moderately early
PDP-11 versions of Unix such as V6 Unix packed an incredible amount of power into a extemely small amount of space - for V6, a mere 20KB of code (not including device drivers) for the permanently resident kernel - a bang/buck ration that will almost certainly never be exceeded.

It's relatively easy to bring up a V6 PDP-11 Unix under the Ersatz-11 PDP-11 emulator. This page (and ancillaries) tell you how to do it, and provide a number of useful tools to go with V6 Unix. (I ran into a number of pitfalls on the way to getting V6 running, using RK05 disk images from the TUHS archive, but this short writeup will tell you how to avoid them all.)

If all you want to do is bring it up so you can say you've done it, you only need this page, and read the first three sections or so. The rest of the page, along with a companion page, Improving V6 Unix, provides what may be useful information to people who want to do more. The latter covers a range of topics, including how to get the Standard I/O Library into V6, and the 'tar' command (both of which require system mods).

Much of this (e.g. how to build a new copy of the system after adding a device) may be something people with early Unix experience already know - if so, just skip it, it's there for novices, not you! :-)

Note: I have only done all this on a Windoze box, but the Ersatz-11 emulator has a Linux version available, and this should all work equally well there.

Getting the emulator and setting it up

I picked the Ersatz-11 emulator because I wanted an emulator that runs under Windoze, and also the
FAQ on the Unix Archive and Unix on the PDP-11 page said it was the fastest. I have been very pleased with this emulator; it it is indeed fast (my simulated 11/70 runs at about 100 MIPS on a relatively elderly Athlon, which is about 30 times as fast as a real one used to :-), and it has lots of nice features (e.g. you can TELNET in to a terminal port on the simulated PDP-11).

Getting the emulator, and setting it up, is extremely easy. Simply go to the demo download page, download the appropriate version of the self-extracting archive, and run it; it will unpack itself and it's ready to go.

The documentation is fairly comprehensive, but you don't really need to read it; this page tell you everything you need to know (to begin with, at least). There is also a configuration file you may eventually want to set up, but you don't need it to start with either.

To start the emulator, simply click on the E11.EXE icon. It will pop up two windows; the first (empty) one I have not figured out any use for, and you can kill it (it won't kill the emulator). The second is the PDP-11 console, and is used for both giving commands to the emulator, and as the PDP-11 console device.

One you start the PDP-11, type-in on it goes to the 11; it you need to get back to the emulator for any reason, type "Shift-Enter" and you're at an emulator prompt. To get back to the PDP-11, just hit a plain "Enter".

Getting your initial Unix disk

You can, if you'd like, simply download a bootable root disk image from TUHS: the original Research distribution is
here, and an almost-identical copy (except for an important tweak) is here. (Note that even though the file names end in .GZ, for me at least, when I save the targets, I get uncompressed V6 disk images.)

The difference between the two is that in the Wellsch versions i) a Western Electric rights notice has been added to the Unix bootable images (which prints on booting); ii) the RK images in the Research version don't have an RK bootstrap in block 0, and thus won't boot directly.

However, you probably don't want to use either (although you can), because those disk images are all only 4000 blocks long (to leave space for a 872-block swap area at the end of the disk), not the 4872 blocks of a complete RK05 pack. This has important consequences when running on Ersatz-11.

Ersatz-11 emulates disk packs with ordinary Windows files of the appropriate size. E.g. create a file 4872 blocks long, and you can 'mount' that file as an RK05 pack. On Ersatz-11 (at least, on E11 V7.0), to 'play nice' with packs which have bad block tables at the end of the pack which sometimes aren't included in a copy of the pack, reads to parts of the disk which aren't in the file which emulates the pack return all 0's, not an error; writes to that area of the disk appear to the PDP-11 to succeed, but don't actually do anything.

So if you start Unix under Ersatz-11 on one of the 4000-block pack images, it will eventually try to swap a process out - to the part of the disk that doesn't exist in those 4,000 block disk images, and later read it back in and get all zeros - and promptly crash.

So you need to extend those pack image files to the full 4872 blocks before you can use them. I wrote some tools to do that (below), but to save you the trouble there is an extended version of the root pack (the only one that's critical to have full length, since the initial RK-based Unix swaps to the root RK disk) from the Wellsch set here which you can download.

Alternatively, there is an RK pack image there with a driver for the emulator's very useful "DOS device" (see below) already added; you might prefer to just retrieve this, to the having to do all the (painful) work to add the DOS device yourself the first time (see below). You can download that here.

You will probably also want the source pack (called "usr" in the Wellsch folder), and the documentation pack may also be useful. You can either put the image(s) in the same directory as E11, or you can put it/them elsewhere (see below for how to proceed if you do).

Booting Unix

Now that you have Ersatz-11, and the root pack, you're ready to go.

First, tell the emulator what kind of PDP-11 you have. You can boot the distributed V6 Unix images with an 11/40, in which case say to the emulator (you don't have to type this, copy-and-paste works fine with Ersatz-11 - just right-click to paste):

set cpu 40 eis
(The "eis" is important because the basic 11/40 does not include the MUL instruction, which Unix uses everywhere - including in the bootstrap. Leave that out, and the bootstrap will croak - as I found out the hard way!)

Now set the switch register for single-user boot (this is not strictly necessary, but it's a good habit to get into):

set switch 173030
Next, tell the emulator it doesn't need to run in a tight loop:
set idle delay=10
(Again, not strictly necessary, but why heat up your CPU chip when you don't need to?)

Next, mount the RK pack image you just downloaded on drive zero:

mount dk0: UnixRoot. /rk05
(Note that you can in fact have disk image files under Ersatz-11 which don't end in ".DSK" - just make sure to have that terminal '.' there.)

If you put your disk image somewhere other than in the same directory as Ersatz-11, just give the complete path name, e.g:

mount dk0: C:\Unix\UnixRoot. /rk05
If you're trying to boot the DOS Unix, you need to configure the DOS device:
mount do:
Now start the bootstrap:
boot dk0:
and you should get the usual '@' prompt from the V6 bootstrap. Type the file to load ("rkunix" in this case, or "dosunix" if you want the one with the DOS device and have that pack), and hit 'Enter', and your Unix should boot in single-user mode.

First things to do on Unix

(Note: Up until this point, all typein has been directed to the emulator. You're now talking to Unix, and commands below are Unix commands. If you need to give the emulator a command, use Shift-Return/Return to get back to the emulator, and then return to Unix.)

The first think you'll probably notice is that all typing is in upper-case, which can be trying. Say "stty -lcase" to suppress this.

Note that on V6 Unix, the 'change directory' command is 'chdir', not 'cd'. To fix this, you'll have to tweak the shell and recompile it (which is best done once you have the DOS device installed, see below, to avoid having to do this with the line editor, 'ed'), but for the moment, best to just live with it. When you get to it, a modified version which has the short alternative is here.

Unix V6 as distributed uses '#' for the character erase, and '@' for the line kill. DELETE is the interrupt character. The latter is quite hard to change (you'll need to edit a file and then re-build the operating system, see the Improving V6 Unix page for more), but you can fix the former by saying "stty erase X" and "stty kill Y" (where X and Y are your choice of characters - e.g. ^U for line kill; give the actual character, not the printing equivalent, i.e. "^U").

Setting your erase character to '^H' (backspace) has the added advantage that erased characters are overwritten, making it easier to be sure of what you've actually typed into Unix.

Unix as distributed includes almost no special files (in /dev). In particular, there are no special files for any disks. So one of the first things to do is create them (this has already been done on the DOS Unix disk image):

/etc/mknod /dev/rk0 b 0 0
/etc/mknod /dev/rrk0 c 9 0
You can now say:
icheck /dev/rrk0
dcheck /dev/rrk0
to verify that your root pack is OK.

To shut down Unix, type "sync", and then immediately go to the emulator command level, and type HALT. With the PDP-11 halted, you can then type "exit" or "quit" to terminate the emulator.

More disks, more devices, etc

Here are some details on how to do various other things, once you have your Unix running.

Mounting other disks

To mount the source/documentation disk packs, you will first need to tell the emulator (after switching to its command level :-) to mount the pack, e.g:
mount dk2: C:\Unix\UnixSrc. /rk05
You will then need to tell Unix to create the appropriate special files for the disk device, and also the mount point. (Hint: make the mount point a file, not a directory, then commands like 'cpall foo* /mnt' will give an error message if the pack is not mounted.) Also, it's wise to always run 'icheck' on a disk pack:
icheck /dev/rrk2
before mounting it, to make sure there's no damage to the file-system. You can then tell Unix to mount the pack, e.g.:
mount /dev/rk2 /src
If you're doing things on the emulated system, it's also wise to either start multi-user operation, which will automatically (depending on the contents of /etc/rc) start the automatic disk synchronizer (/etc/update), or start it manually in the background (i.e. "/etc/update &"). This will reduce the chances of disk damage if the system crashes unexpectedly (although panic() does a sync() internally, so if you see a panic message you should be OK).

Adding devices, etc

The Unixes in the basic pack have only a single type of disk driver (I think; I know that 'rkunix' has only an RK driver), although they support up to 8 drives of each type, and a single tty. If you want to change any of that (or anything else about the kernel), you will need to go to /usr/sys/conf, and compile 'mkconf':
cc -s -n -O mkconf.c
mv a.out mkconf
(No, there is no "-o" option in this version of "cc"!)

Note: If you're running the DOS Unix, a lot of this has already been done - and in particular, you have hand-edited copies of l.s and c.c which have the DOS device added. (I was too lazy to modify mkconf.c to add that device. So shoot me! :-) So, if you run mkconf, if will overwrite those versions. So if you do any of this, you need to carefully save them away somewhere first! You'll then need to hand-edit the DOS device info into any new l.s/c.c files you produce (or edit the new stuff in them back to the hand-edited l.s/c.c which include the DOS device.)

Then run 'mkconf' to produce the appropriate c.c and l.s files. (The document Setting Up Unix - Sixth Edition has instructions on how to use 'mkconf', but note that to end the input, and tell it to produce the files, a line with "done" on it is the last line of input.)

Note that for no reason that I can understand, mkconf doesn't support the 'my teletype' indirect device, /dev/tty. If you want that, you'll have to add it manually; in c.c, use 'ed' to add a line like this to 'cdevsw':

	&syopen,   &nulldev,  &syread,   &sywrite,  &sysgtty,	/* tty = MM */
(where MM is the correct major device number, so you don't have to count the entries in c.c every time you need to make a new device :-). Next, after you build the new system (below) and boot it, you'll have to create the /dev/tty entry:
/etc/mknod /dev/tty c MM 0
(replacing the MM with the correct number, of course). (This has all already been done on the DOS system.)

Once you have l.s and c.c all set, compile/assemble them:

cc -c c.c
as l.s
mv a.out l.o
and then you're ready to build a new Unix (note the use of a different file name for this system image; that way, if you make a mistake, you can go back and boot the original system):
ld -x l.o m40.o c.o ../lib1 ../lib2
mv a.out /nunix
Note that to increase the number of KL11/DL11 lines, you'll have to i) edit kl.c (found in the sys/dmr directory), ii) re-compile it, and then iii) add the modified version to the library:
ar r ../lib2 kl.o
Note also that the free demo version of Ersatz-11 doesn't support DH-11s, etc, so if you want more than one tty you have to use KL11's. The demo version does support the DZ-11, but there is no DZ-11 driver in the 'vanilla' V6 distribution. I do have a DZ driver for V6 (see
below), but before you try and add that, add the DOS device (below) first.

Some disk problems to avoid

If you try to add an RP11 controller, note that Ersatz-11 reports the default CSR location for that as 010 lower than the DEC manuals, i.e. 176700. Ignore this! The DEC manuals say the registers start at 176710, but actually the device responds from 176700 on up, and only 176710-37 are meaningful; the base address in E11 is the address at which the device starts responding (which it dutifully emulates exactly), not the first useful register.

Note also that Unix uses all 406 cylinders of an RP03, but Ersatz-11 by default assumes the size stated by DEC, i.e. 400 cylinders. So you need to say something like:

mount dp0: C:\Unix\UnixLarge. /RP03 /Cylinders:406
otherwise you'll get odd errors.

Finally, note that in Ersatz-11, when you dismount the last drive on a controller, it automatically deletes the controller. If you then (forgetfully) try and touch a disk (e.g. 'icheck' or 'mount' or something) on that controller, the system will crash with a kernel NXM fault when it tries to touch the controller. For that reason I habitually mount a null pack as the last drive on all the controllers, e.g.:

mount dk7: null:
mount dp7: null:
to prevent the controller being deleted when the last real pack is dismounted.

The Emulator's DOS Device

The Ersatz-11 emulator has this nice virtual device called the "DOS device" ("the name is left over from the DOS version of Ersatz-11"), which allows a program running on the emulated PDP-11 i) access to files in the Windows file system, and ii) to issue commands to the emulator.

I have written a V6 driver for it, and a suite of Unix commands which allow you to i) grab a file off the Windows file system (both binary and text mode), and ii) issue various commands to the emulator. Since getting files into the Unix filesystem is painful (at best) without this, I recommend adding this as step #1 once you have your Unix running.

[The thing I use this for the most is editing files. 'Vanilla' V6 Unix only has a line editor ('ed'), and while it's usable, it's truly painful compared to even a poor visual editor. We did have a nice Emacs on the PDP-11 V6+ at MIT, but while have located a copy, I have yet to make it run on vanilla V6, and make it available; I think there's a 'vi' available for V6 too.

So to edit a file, I almost always (except for tiny changes) I tend to keep the master copy on the Windoze computer, edit it there (I myself use, and swear by, Epsilon, which is small, fast, very customizable, and allows me to run a Windows command line interpreter in a buffer), and move the edited result to the Unix machine; the command I have to do this is so short/simple that it's very painless to do this.

If I do edit a file a bit on the Unix machine, and then want to edit it more significantly, I slurp it over to the Windows filesystem, using the 'filex' command (below), and then copy it back as above when I'm done.]

The driver is available here, and the header file it (and the Unix commands which interact with the DOS device) use is here. To get them into the Unix, I used the following kludge (which is another reason to get this running ASAP :-) - perhaps you can think of a better one!

[In fact, it's so painful that I decided to make a system/disk pack image with the DOS device (and the 'hostrd' command) all pre-loaded (see above), so unless you're a masochist, you can ignore the rest of this section, and just go there instead!]

Anyway, here's the whole gory procedure I used to get files into the Unix (before I had the DOS device working!):

(In theory, the second and third steps above are unnecessary: you should just be able to say:
mount dk2: dos.c
to the emulator, and be able to read the file out of the pack, but for some reason that doesn't work, so you have to add these two additional steps.)

You can now move them to the right place (/usr/sys for dos.h, and /usr/sys/dmr for dos.c), and compile the DOS driver and add it to the device library:

cc -c -O dos.c
ar r ../lib2 dos.o
rm dos.o
Next, you have to edit l.s and c.c (in /usr/sys/conf) to add the appropriate code to call the DOS driver (see above on how to create l.s and c.c); in c.c, use 'ed' to add a line like this to 'cdevsw':
	&dosopen,  &dosclose, &dosread,  &doswrite, &dossgtty,	/* DOS: = NN */
(again, where NN is the correct major device number) and in l.s add this to the vector area:
. = 110^.
	dosio; br4
and this to the linkage area:
.globl	_dosintr
dosio:	jsr	r0,call; _dosintr
(If you've never done this before, don't worry, it's easy to see, looking at the file, where they need to go.) You can now build a new Unix (see above for how to do that) with the DOS device driver in it, and boot it.

As your penultimate step, you need to create the DOS special device file in /dev; if your major device number for the DOS device is X, you need to say:

/etc/mknod /dev/dos c X 0
(Now, can you see why I provided a pack with this all pre-loaded? :-)

Finally, configure the DOS device on the emulator (remember you need to exit to the emulator command level to give this command):

mount do:
Now you're ready for the commands which use it...

Commands to go with the DOS device

There are a bunch of Unix commands which go with the DOS device.


Most important is 'hostrd', which picks a file off the host (Windows in my case) file system, and copies it onto the Unix file system.

This command is pre-loaded in the 'DOS' pack; the source is in /usr/src, and the binary is in /bin. You may wish to rename the binary to something shorter, since it gets used a lot: I call mine 'hrd'. If you have to download it, the source is available here. This (and a bunch of the other commands below) also need strlen(), there's a copy of that here.

To use it, just say:

hrd {host-name} {unix-name}
if you don't provide {unix-name}, it will try to write the file to {host-name} on the Unix filesystem; if that fails, it will try a filename of just the last component of the host-name in the current directory of Unix. I.e. if you say:
hrd ../windows/desktop/foo
you'll wind up with a file 'foo' in your Unix current directory.

It has several flag arguments; the first is "-a", which tells it that the file being transferred is an ASCII text file (e.g. C source), and that it should do Windows->Unix text conversion (i.e. replace CRLF newline sequences with just the plain LF Unix expects - the V6 C compiler will barf on CRLF's). This flag defaults to on (since I mostly use this command for transferring text files in the edit/compile/test loop), you don't actually need to give it.

The "-b" flag disables that behaviour (i.e. it transfers the file as a raw file). (If you're trying to read a binary file into the machine, don't forget to give this one, or the file will likely be roached.)

The -t flag suppresses printing of the total amount transferred (given in blocks+bytes).


This (which I rename to the short "hc"), source
here, allows you to give arbitrary commands to the emulator from inside Unix:
hc dismount dk2:
What's the point of that, you say? I mean, you can just exit to the emulator and give the command. Well, you might be logged in on a non-console tty (more on this below below - although on those 'hc' can't show you the output of the emulator). Also, it allows me to have shell command files which e.g. tell the emulator to mount up a pack, and then do a Unix 'mount' of the pack.


This (which I rename to the short "hcd"), source
here, allows you to change the working directory of the emulator on the host system from inside Unix. Tired of typing the /unix/sys part of:
hrd /unix/sys/foo.c
Just do:
hcd /unix/sys
and then you can:
hrd foo.c
as you go around the edit/compile/test loop. Plain 'hcd' on the command console will print the emulator's current working directory.


This (which I rename to the short "sc"), source
here, allows you to change the contents of the PDP-11 switch register (e.g. to go from single-user to multi-user).
sc 0
login: root
sc 173030
(The sc 173030 is because if you don't do it right away, you'll probably forget to do it before rebooting! :-) Yes, yes, I know this is the same as "hc set switch X", which I could easily put in a Unix shell run file, but it was written before "hc" was.

Issues with V6 Unix

V6 as distributed is strictly a 20th Century operating system. Literally. You can't set the date to anytime in the 21st century, for two reasons.

First, the 'date' command only take a 2-digit year number. Second, even if you fix that, the ctime() library routine has a bug in it that makes it stop working in the closing months of 1999. (IIRC, the bug is that the number of 8-hour blocks since the epoch - January 1, 1970 - overflows a 15-bit integer at that point. 'Vanilla' V6 C doesn't have unsigneds.)

I have 'fixed' copies of date.c and ctime.c; here and here. You can download them and install them; ctime.o goes in /lib/libc.a:

ar r /lib/libc.a ctime.o
The 'date' command has been extended to support 2- and 4-digit year numbers (to be upwardly compatible, the 2-digit ones assume 19xx). It has also been extended (for forgetful people like me :-) so that if you type:
date -
it will tell you what order the arguments go in.

The 'fix' in ctime() is really kludgy - sorry, I was in a hurry! It will also break in another 15 years or so (when the number of 8-hour periods overflows 16 bits). Someone else can fix that one!

There are a number of programs that are linked with ctime.o, and will produce bogus results unless they are linked with the fixed one. I don't have a complete list, but one major one is 'ls'.

Useful new (to V6) Unix tools

Unix V6 is not too bad an environment, modulo not having a video editor. (I do miss "!" and "^" in the shell, though.) One thing was really missing, though, and I added a couple more for hacks.


This version of Unix pre-dates video terminals. Issue a command that produces a lot of output (e.g. "nm /unix"), and it will scroll off your screen - and this version of Unix does not have 'more'. So I have written a 'more' for vanilla V6; the source is available
here. (And trust me, you will want to download and add this right away! I add (via a hard link - no aliases in the V6 shell :-) the short alias 'p'; not sure how common that is for you all.)

It also needs strlen(), there's a copy of that here; and a couple of header files - stat.h, sgtty.h and sig.h - which are available here, here, and here. I honestly don't recall where the header files came from: I don't know if I edited them out of V6 kernel header files (it looks like that might be where stat.h and sig.h came from), or if they came from the Shoppa disks, or if I created them from scratch (possibly for sgtty.h). Anyway, it doesn't matter - I needed them, and here they are now!

(Why does the source call for them to be in "/lib/h" (of all non-standard places)? Well, feel free to put them whereever you want, but as to why I have them there.... I always felt the whole /usr thing for files which aren't actually user files was... confused. So I generally frown on /usr/{anything} - although some things, like /usr/bin, I just have to live with. But why "h" instead of "include"? Less characters, of course! Duhhh!)

It has one bug (which I'm still trying to work out how to solve): it opens the terminal in 'raw' mode (so you can hit 'Space' for each new screen), and it is also useable as a filter (e.g. "nm /unix | more"), but as a result it you say just 'more' (with no arguments) you can't escape its clutches (no EOF in raw mode, right)? If you're running single-user, you'll have to reboot the system!


Want to see how fast your simulated PDP-11 is? Try
this. It basically does the fastest single instruction (think "CLR R0") many, many, many times over (in big blocks to get rid of loop overhead), and checks the clock time to do so. For reference, on an idle PDP-11/70, this used to return '3'. On a relatively elderly Athlon, I see '100'. :-)


Sort of like 'ps' on steroids, this requires Unix mods. See the
Improving V6 Unix, page.

Other useful Unix stuff

Here are some useful commands from later Unix versions, and some tweaked versions of V6 ones.


Although V6 includes 'cpall', it does not (for no goood reason I can see) include 'mvall'; but that's easy to add; it's a minor tweak to cpall.c. The source is
here; put the binary in /usr/bin, like 'cpall'.


Although V6 is distributed with man pages, it is missing the 'man' command. The one from BSD1 needed almost no changes to work in V6, other than a mild tweak to get rid of the backspace-_ stuff so the output is useful on a video terminal. The source is
here, and you will also need the 'ssp' command (a slightly tweaked version to handle the backspace-_ stuff) here; put them both in /usr/bin.


A modified version of 'nm' (source
here) which has a couple of extra flags:


A modified version of 'cmp' (source
here) which has a couple of extra flags: It needs a new library routine, loocv.s, available here.


An enhanced version of 'file' (source
here) tells you whether object files have a symbol table, and relocation info; it also handles old and new archives.


A modified version which has the short alternative "cd" for "chdir" is
here. Note: Be very careful when replacing /bin/sh! That, /etc/init and /dev/tty8 all have to be working properly or your Unix won't boot! So try it out for a bit as /bin/nsh or something, before you replace /bin/sh.

Other useful Unix drivers

I also have a couple of V6 drivers which might be useful.

DZ serial line driver

This is actually somewhat useful, because of a neat feature of Ersatz-11. It includes a built in TELNET server (I know, I know - totally insecure - so hide it behind a firewall and only use TELNET inside your site), which it can connect up to any simulated terminal line. So you can run your PDP-11 on one machine, and log into it from another.

I personally use the TELNET line mostly, because I prefer the look of the Windows TELNET client - black letters (font selectable) on a white background I much prefer to the VT100 emulation on the Ersatz-11 consoles! And you can't use a DH or anything else, because the free (demo) version of Ersatz-11 doesn't support them.

Anyway, here is the driver source (goes in dmr, see instructions above on how to compile a driver and add it to lib2), and here are the l.s and c.c. entries:

. = 270^.
	dzin; br5
	dzou; br5
.globl	_dzrint
dzin:	jsr	r0,call; _dzrint
.globl	_dzxint
dzou:	jsr	r0,call; _dzxint
	&dzopen,   &dzclose,  &dzread,   &dzwrite,  &dzsgtty,	/* dz = XX */
Note that this does not use the standard DZ-11 CSR and vector address in Ersatz-11; you will need to configure it there thusly:
assign yza0-7: telnet:
set yza: csr=770000 vector=270
And don't forget that these lines will only operate i) when Unix is running multi-user, ii) there have to be /dev/tty? special files for them, and iii) you have to edit /etc/ttys to enable them for login listeners.

RL disk driver

This turns out to be pretty much useless; it's completely subsumed, for the purposes of emulation, by the RP driver - which can read RL images just fine. (Trust me - this works, I have tried it!) Why an RP driver to read an RL pack? I didn't realize this at first, and actually got an RL driver running in V6 to read those packs. Later on, the penny dropped, and I realized that all Ersatz-11 used was a flat file image, which you could plug into any disk device that E11 emulates (or even tape, if that floats your boat :-).

You just need a device that's big enough to gain access to the complete image file. Unix will read the disk size (in the superblock) and not try and go any further than that (just like it ignores the swap area on an RK-based system). Since an RP pack is far larger than an RL, it fits the bill nicely (but make sure to use minor device 0 or 4; the others aren't large enough to cover a whole RL02 pack, or don't start at cylinder 0). (See above for how to build new Unix loads with different devices, to add the RP driver to your Unix.)

Unless you have a real need for an RL driver (why, I can't imagine), you can skip the rest of this section. Anyway, if you have some use for a V6 RL driver, it's here. Here are the lines to add to l.s for it:

. = 160^.
	rlio; br5
.globl	_rlintr
rlio:	jsr	r0,call; _rlintr
and for c.c (two lines, since it's a block device: one for bdevsw, and one for the raw device in cdevsw):
	&nulldev,	&nulldev,	&rlstrategy,	&rltab,	/* rl = X */
	&nulldev,  &nulldev,  &rlread,   &rlwrite,  &nodev,	/* rl = XX */
I also have an RL bootstrap (from the Shoppa disk; the source was lost, but I disassmbled the actual bootstrap and re-created the source, checking that the assembler output matched the binary I started with); it's available here.

Actually, there were two different ones; the source for the other (also retrieved by disassembly) is here. I guess I ought to comment the latter a little better; I read through the code in order to be able to turn the magic numbers in the disassembled code into named constants, but I didn't do much more than that to make it readable.

Useful Windows tools

I have a number of Windows commands to do various useful things, such as read a file off a Unix V6 file system (hosted in a Windows file), including ports of a number of Unix commands. Not all of them will be useful to you, but some will (e.g. the command to create a blank disk file).

All of them were compiled with, and run under CygWin. If you don't already have this (it's pretty cool), or feel like dealing with it, all you need to do is download the executable versions (below), and also the CygWin library DLL, and put that somewhere the commands can find it (e.g. in the same directory as the commands).


This (short name 'fx') reads a file off a V6 disk image stored as a file under Windoze. (I didn't realize it until after I'd written it, but this is a duplicate of a bunch of
other utilities in the TUHS archives. Oh well! This one runs under Windoze, though...) It's a command line things (these all are), so you'll have to start a Windoze 'Command Prompt' window to run it. (Do the latest versions of Windows even have that any more? ;-)

Source is here, Windows binary here. It requires a couple of hacked header files (to produce the right types in the Intel GCC compiler), wino.h and wfilsys.h, available here and here.

To run it, as follows:

fx {filesysfile} {hostname} {unixname}
Note that unixname is relative to the filesystem the file is in; i.e. if you have UnixSrc up on RK2, and mounted as /src, to read the file /src/foo/bar.c, you'd say:
fx UnixSrc bar.c /foo/bar.c
There's also a mode to read given only the inode number (for roached disks). 'Use the source, Luke!'

One nice feature is that it will share access to the disk image with Ersatz-11 - i.e. you don't have to 'unmount' a drive from Ersatz-11 before you can read it with this. So that make it really convenient to go around the edit/compile/test loop on Unix (compiling) and Windows (editing): 'fx' it to the Windoze box, edit it, 'hrd' it back to Unix.


This (short name 'mke') makes a large, empty file (suitable for mounting as a drive image under Ersatz-11). Source is
here, Windows binary here. To run it, as follows:
mke {filesysfile} {nblocks}
Note that before you can mount the resulting disk pack under Unix, you need to create a Unix file-system on it with mkfs.


This (short name 'ins') inserts one file into another (hopefully larger :-) existing file (usually one suitable for mounting as a drive image under Ersatz-11). Source is
here, Windows binary here. To run it, as follows:
ins {targetfile} {sourcefile} {offset} {nblocks}
If the {nblocks} argment is given as zero, the entire file is inserted. This command is useful for things like i) inserting a bootstrap program in block zero, ii) extending a 4000 block RK disk image file to 4872 blocks so Unix can swap off of it, etc.


This (no short name) converts a file in Windows ASCII (CRLF newlines) to one in Unix ASCII (LF newlines). Source is
here, Windows binary here. To run it, as follows:
stripcr {sourcefile} {outputfile}
Note: The code is really simplistic, and won't grok CRs that aren't paired with LFs. For more sophisticated CR stripping, use 'hrd'.


This (short name 'bex') extracts specified block(s) in a file into another file. (Think poor man's 'dd' on Unix.) Source is
here, Windows binary here. To run it, as follows:


This (short name 'dmf') dumps a specific block in a file in octal/etc. (Think 'od' on Unix.) Source is
here, Windows binary here. To run it, as follows:
dmf [flags] {sourcefile} {blkno}
Flag arguments: -a dumps in ASCII bytes, -d in decimal words (default is octal words), -o prints the addresses in decimal (default is octal).

Useful Unix tools under Windows

I have ported a number of Unix commands to Windoze to do various useful things, such as read TAR files from the
TUHS archive (since the version of WinZip on my machine doesn't grok some really old TAR files).


As mentioned, some of the older TAR files in the TUHS archive (e.g.
the Spencer V7 distribution) can't be read with newer archiving tools. A version of V7 'tar' modified (very minimally) to run under Windows solves that. Source is here, Windows binary here.

To compile, tar needs a couple of tweaked header files, available here, here, and here.

Note: The functionality of this program is suspect; the changes made to get it running were so minimal. E.g. simply saying:

tar tvf v7.tar
gives a directory checksum error. However, if the blocksize is specified as 1, i.e.:
tar tvfb v7.tar 1
it works - even though it's a file, not a tape! It may be that something about file reading under Windows (where, with the Standard I/O package, one has to specify whether to open files in the ASCII or binary modes) doesn't work properly.

Also, the date-setting functionality doesn't seem to work, so if you extract the things from an archive, their 'last-write' date isn't set properly. Feel free to fix either of these, and let me know how!


(Short name 'wnc'); useful for producing a list of the files on a pack image you want to poke around in. Source is
here, Windows binary here. (It also needs wino.h and wfilsys.h, see above.)


(Short name 'wnm'); useful for looking at the symbol table of some file you have extracted. Source is
here, Windows binary here. It includes the same extra flags as the Unix one.


Want to see how fast your PC actually is, compared to the simulated PDP-11, using the exact same tool? Try this:
source and binary.

Auto-configuration of Ersatz-11

Finally (at last, you're no doubt thinking :-), if you do more than just try this once or twice, you'll get sick of configuring Ersatz-11 each time. Not to worry, it has an init configuration file. There is a sample one
here; you will want to tweak this to adjust to i) which emulated disks you have, ii) where they are on your machine, etc, etc, but this will give you a good start.

Back to JNC's home page

© Copyright 2014-2015, 2019-2020 by J. Noel Chiappa

Last updated: 18/September/2020