build index.html for all winners
Updated manifest as per recent file changes. Updated winner `.winner.json` to reflect the manifest changes. Added [bin/all_run.sh](bin/all_run.sh) tool to run a command over all winning entries. These tools had slight improvements in the help usage message: * bin/gen-author.sh VERSION="1.3.1 2024-01-16" * bin/gen-inventory.sh VERSION="1.0.1 2024-01-16" * bin/pandoc_wrapper.sh VERSION="1.3.1 2024-01-16" * bin/subst.default.sh VERSION="1.1.1 2024-01-16" * bin/subst.winner-index.sh VERSION="1.1.1 2024-01-16" The `bin/readme2index.sh` tool was improved so that if the `index.html` file exists and the tool forms the exact same content, then the file `index.html` file is NOT touched. * bin/readme2index.sh VERSION="1.1 2024-01-16" We used the following command to generate `index.html` files for all winning entries: ```sh bin/all_run.sh -v 3 bin/readme2index.sh ``` NOTE: We have not (yet) built HTML files above the winner directory level (e.g., no year level nor top level HTML), nor have be built non-index HTML files for winners. NOTE: By default we are running `pandoc(1)` with: ``` --fail-if-warnings=true ``` This means that any problems with markdown to HTML generates an error. This is done to be sure that the HTML conversion is clean. We had to fix the following `README.md` files: * `2000/rince/README.md` The reference [^2] was never used. We made a guess that [^2] applies to the same spot as [^1]. Perhaps there is a better spot where [^2] applies? NOTE: For every reference, there MUST be some place where that reference is used. * 2012/vik/README.md The string "$...$" is assumed to be a TeX encoded string. NOTE: Every "$..$" needs to be backslashed as in "\$..\$". * 2018/burton1/README.md The reference [2] was duplicated. We changed the second [2] to [3]. NOTE: Every reference needs to have a unique number. * 2020/carlini/README.md The string "$...$" is assumed to be a TeX encoded string. NOTE: Every "$..$" needs to be backslashed as in "\$..\$". We also found 2 errors in the `author/author_handle.json` file set: * author/Anonymous_2001.json The `author/Anonymous_2001.json` file was missing. * author/Jari_Arkko.json The winner ID for `1989_jar.1` had a typo.
This commit is contained in:
1 parent
893cd915b6
commit
c1466f5165
350 files changed
+95242
-4217
No files matched your search
+897
-13
@@ -1,4 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<!-- START: two lines up starts content from: inc/top.default.html -->
|
||||
<!-- -->
|
||||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
|
||||
@@ -6,27 +8,909 @@
|
||||
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
|
||||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||
<!-- -->
|
||||
<!-- file: 2018/mills/index.html created by: fake.gen_index.sh version: 1.0.5 2023-10-31 -->
|
||||
<html lang="en">
|
||||
<!-- END: this line ends content from: inc/top.default.html -->
|
||||
<!-- -->
|
||||
<!-- This file was formed by the tool: bin/readme2index.sh version: 1.1 2024-01-16 -->
|
||||
<!-- -->
|
||||
<!-- START: this line starts content from: inc/head.default.html -->
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>2018 mills</title>
|
||||
<meta name="description" content="IOCCC year: 2018 IOCCC winner: mills winner index page">
|
||||
<meta name="keywords" content="IOCCC,2018,mills,winner index page">
|
||||
<link rel="stylesheet" href="/temp-test-ioccc/ioccc.css">
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
<title>2018/mills</title>
|
||||
<meta name="description" content="2018 IOCCC winner mills">
|
||||
<meta name="keywords" content="IOCCC, 2018, IOCCC 2018, IOCCC winner, mills">
|
||||
</head>
|
||||
|
||||
<!-- END: this line ends content from: inc/head.default.html -->
|
||||
<!-- START: this line starts content from: inc/body.default.html -->
|
||||
|
||||
<body>
|
||||
|
||||
<h1>2018 mills</h1>
|
||||
<!-- END: this line ends content from: inc/body.default.html -->
|
||||
<!-- START: this line starts content from: inc/header.default.html -->
|
||||
|
||||
<p>XXX - fake content until readme2index is working - XXX</p>
|
||||
<div class="header">
|
||||
<img src="/temp-test-ioccc/png/ioccc.png" alt="IOCCC image by Matt Zucker" width=300 height=110>
|
||||
<h1>The International Obfuscated C Code Contest</h1>
|
||||
<h2>2018/mills</h2>
|
||||
</div>
|
||||
|
||||
<hr style="width:50%;text-align:left;margin-left:0">
|
||||
<!-- END: this line ends content from: inc/header.default.html -->
|
||||
<!-- START: this line starts content from: inc/topnav.mid.html -->
|
||||
|
||||
<!-- Start Nu Html Checker -->
|
||||
<p><a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fioccc-src.github.io%2Ftemp-test-ioccc%2F2018%2Fmills%2Findex.html">Nu Html check https://ioccc-src.github.io/temp-test-ioccc/2018/mills/index.html</a></p>
|
||||
<!-- End Nu Html Checker -->
|
||||
<div class="topnav">
|
||||
<a class="Left" href="../hou/index.html">← hou</a>
|
||||
<a class="Left" href="../index.html">↑ 2018 ↑</a>
|
||||
<a class="Left" href="../poikola/index.html">poikola →</a>
|
||||
<a class="Right" href="#inventory">Inventory</a>
|
||||
</div>
|
||||
|
||||
<!-- END: this line ends content from: inc/topnav.mid.html -->
|
||||
<!-- START: this line starts content from: inc/begin-row.default.html -->
|
||||
|
||||
<div class="row">
|
||||
|
||||
<!-- END: this line ends content from: inc/begin-row.default.html -->
|
||||
<!-- START: this line starts content from: inc/begin-leftcolumn.default.html -->
|
||||
|
||||
<div class="leftcolumn">
|
||||
|
||||
<!-- END: this line ends content from: inc/begin-leftcolumn.default.html -->
|
||||
<!-- START: this line starts content from: inc/sidenav.default.html -->
|
||||
|
||||
<div class="sidenav">
|
||||
<a href="#content">Jump to contents</a>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="sidenav">
|
||||
<a href="/temp-test-ioccc/index.html">IOCCC Home</a>
|
||||
<a href="/temp-test-ioccc/years.html">Winning Entries</a>
|
||||
<a href="/temp-test-ioccc/winners.html">People who have won</a>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="sidenav">
|
||||
<a href="/temp-test-ioccc/news.html">IOCCC News</a>
|
||||
<a href="/temp-test-ioccc/faq.html#submit">How to enter the IOCCC</a>
|
||||
<a href="/temp-test-ioccc/faq.html">FAQ</a>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="sidenav">
|
||||
<a href="/temp-test-ioccc/bugs.html">Bugs & (mis)features</a>
|
||||
<a href="/temp-test-ioccc/faq.html#fix_a_winner">Fixing IOCCC winners</a>
|
||||
<a href="/temp-test-ioccc/faq.html#fix_web_site">Fixing the web site</a>
|
||||
<a href="/temp-test-ioccc/faq.html#fix_author">Fixing winner info</a>
|
||||
<a href="/temp-test-ioccc/thanks-for-help.html">Thanks for the help</a>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="sidenav">
|
||||
<a href="/temp-test-ioccc/judges.html">The IOCCC Judges</a>
|
||||
<a href="/temp-test-ioccc/contact.html">Contacting the IOCCC</a>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="sidenav">
|
||||
<a href="#top">Jump to top</a>
|
||||
</div>
|
||||
|
||||
<!-- END: this line ends content from: inc/sidenav.default.html -->
|
||||
<!-- START: this line starts content from: inc/end-leftcolumn.default.html -->
|
||||
|
||||
</div>
|
||||
|
||||
<!-- END: this line ends content from: inc/end-leftcolumn.default.html -->
|
||||
<!-- START: this line starts content from: inc/begin-rightcolumn.default.html -->
|
||||
|
||||
<div class="rightcolumn">
|
||||
|
||||
<!-- END: this line ends content from: inc/begin-rightcolumn.default.html -->
|
||||
<!-- START: this line starts content from: inc/before-content.default.html -->
|
||||
|
||||
<a name="content"></a>
|
||||
|
||||
<!-- END: this line ends content from: inc/before-content.default.html -->
|
||||
<!-- START: this line starts content generated by: bin/gen-author.sh -->
|
||||
|
||||
<p><a name="author"><strong>Author:</strong></a> <br><br>Name: <a
|
||||
href="/temp-test-ioccc/winners.html#Christopher_Mills">Christopher
|
||||
Mills</a><br> Location: <a
|
||||
href="/temp-test-ioccc/location.html#US">US</a></p>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/gen-author.sh -->
|
||||
<h2 id="to-build">To build:</h2>
|
||||
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span></span></code></pre></div>
|
||||
<p>If you wish to save state so that you can run the program and keep
|
||||
files changed (for instance you don’t want to compile
|
||||
<code>mullender.c</code> again) you can compile it like:</p>
|
||||
<div class="sourceCode" id="cb2"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> clobber SAVE=1 all</span></code></pre></div>
|
||||
<p>Make sure that if you do add a file (including by compiling code)
|
||||
that before you exit (ctrl-e) you type in <code>sync</code>! Otherwise
|
||||
the file might not exist or it will be corrupt if it does.</p>
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: known bug - please help us fix
|
||||
STATUS: INABIAF - please **DO NOT** fix</code></pre>
|
||||
<p>For more detailed information see <a href="/bugs.md#2018-mills">2018
|
||||
mills in bugs.md</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span></span></code></pre></div>
|
||||
<h2 id="try">Try:</h2>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span></span></code></pre></div>
|
||||
<p>At the <code>>boot</code> prompt, type return.</p>
|
||||
<p>At the <code>:</code> prompt, type <code>rk(0,0)rkunix</code> and
|
||||
wait for it to initialise itself. Now try typing:</p>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">cat</span> <span class="op">></span> prog.c</span>
|
||||
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="fu">main()</span><span class="kw">{</span> <span class="bu">printf</span><span class="er">(</span><span class="st">"Hello, world!\n"</span><span class="kw">);</span> <span class="kw">}</span></span>
|
||||
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="ex">^D</span></span>
|
||||
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="fu">cc</span> prog.c</span>
|
||||
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="ex">a.out</span></span></code></pre></div>
|
||||
<p>where <code>^D</code> is EOF.</p>
|
||||
<p>Next try:</p>
|
||||
<div class="sourceCode" id="cb7"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">cc</span> mullender.c</span>
|
||||
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ex">a.out</span></span></code></pre></div>
|
||||
<p>… and enjoy the classic <a
|
||||
href="/1984/mullender/README.md">1984/mullender</a> entry as it would
|
||||
have been in 1984 with a VAX-11/PDP-11! Once it reaches the end of the
|
||||
line, hit enter and see what happens again. When you’re tired of it hit
|
||||
ctrl-c.</p>
|
||||
<p>But there is much more to this entry! See below.</p>
|
||||
<p>NOTE: To quit, press Control-E.</p>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>Do small machines only need small programs? This program weighs in at
|
||||
just 3636 bytes, which is considerably lighter than the original machine
|
||||
it can replace.</p>
|
||||
<p>This program can take you back to the start of everything, it is
|
||||
possible to run v0. Just type:</p>
|
||||
<div class="sourceCode" id="cb8"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./v0</span></span></code></pre></div>
|
||||
<p>NOTE: To quit v0, press Control-E.</p>
|
||||
<p>You will be greeted with a familiar prompt of “login”. The username
|
||||
and password are “dmr” and “dmr”. To make things more familiar you’ll
|
||||
need to create ‘.’ as it hasn’t been invented yet on this image!</p>
|
||||
<div class="sourceCode" id="cb9"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ex">@</span> ln dd dmr .</span></code></pre></div>
|
||||
<p>An <code>ls</code> will reveal that C hasn’t been invented yet! IOBCC
|
||||
anyone? The compiler is <code>bc</code>. It produces assembly, which
|
||||
will then need to be assembled together like
|
||||
<code>ops.s bl.s hello.s bi.s</code> (in that order) to produce
|
||||
a.out!</p>
|
||||
<p>But wait, we said this was the start of it all! This program can also
|
||||
run a program that replaces an even larger machine that can run BSD 2.9.
|
||||
To start this,</p>
|
||||
<div class="sourceCode" id="cb10"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span></span></code></pre></div>
|
||||
<p>At the <code>>boot</code> prompt, type return.</p>
|
||||
<p>At the “:” prompt, type <code>rk(0,0)rkunix</code>.</p>
|
||||
<p>NOTE: To quit prog, press Control-E.</p>
|
||||
<p>This should now be very familiar and it is possible to compile and
|
||||
run one of the very first IOCCC entries <a
|
||||
href="/1984/mullender/mullender.c">mullender.c</a>, as shown
|
||||
earlier.</p>
|
||||
<p>But wait, there is even more! Try:</p>
|
||||
<div class="sourceCode" id="cb11"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./v6</span></span></code></pre></div>
|
||||
<p>At the <code>@</code> prompt, type <code>rkunix</code>. You might
|
||||
want to type <code>stty -lcase</code> as otherwise the output will be in
|
||||
all caps.</p>
|
||||
<p>NOTE: To quit v6, press Control-E.</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3
|
||||
id="this-ioccc-entry-is-dedicated-to-the-late-dennis-m.-ritchie"><em>This
|
||||
IOCCC entry is dedicated to the late Dennis M. Ritchie</em></h3>
|
||||
<h3 id="the-program">The Program:</h3>
|
||||
<p>Since this is the 25th “annual” IOCCC, I thought I should mark the
|
||||
occasion with a look back to its earliest roots. At the same time the
|
||||
contest enters its 34th year of providing a safe forum for poor C code,
|
||||
the C language itself is fast approaching its 50th anniversary, along
|
||||
with the UNIX operating system whose history is so entwined with.</p>
|
||||
<p>The program delivered here is both a full machine emulation of the
|
||||
original PDP-7 that Ken Thompson used to write the first version of UNIX
|
||||
and a full machine emulation of the PDP-11/40 used by subsequent UNICES.
|
||||
The <code>Makefile</code> can build versions that can run each of the
|
||||
following:</p>
|
||||
<ol type="1">
|
||||
<li>UNIX v0 for the PDP-7 (circa 1969)</li>
|
||||
<li>Research UNIX Version 6 (circa 1975)</li>
|
||||
<li>BSD 2.9 (circa 1983)</li>
|
||||
</ol>
|
||||
<p>For reasons to be described in a bit, the last (BSD 2.9) is the
|
||||
default.</p>
|
||||
<h3 id="building-and-running-bsd-2.9">Building and Running BSD 2.9:</h3>
|
||||
<p>To run BSD 2.9, do <code>make</code> to build <code>prog</code> and
|
||||
then <code>./prog</code> to run it.</p>
|
||||
<p>You should see a prompt from the first-stage bootloader that looks
|
||||
like</p>
|
||||
<pre><code>>boot</code></pre>
|
||||
<p>Hit enter/return at this point and you will get to the second-stage
|
||||
boot loader that looks like</p>
|
||||
<pre><code>40Boot
|
||||
:</code></pre>
|
||||
<p>The 40 in the prompt indicates that the bootloader has correctly
|
||||
determined that we are running on a PDP-11/40.</p>
|
||||
<p>At this point, type the rather cryptic command
|
||||
<code>rk(0,0)rkunix</code> – this tells the system to look at the first
|
||||
partition on the first <code>RK05</code> fixed disk, find the
|
||||
<code>rkunix</code> file and load it. You should eventually see the
|
||||
following:</p>
|
||||
<pre><code>>boot
|
||||
|
||||
40Boot
|
||||
: rk(0,0)rkunix
|
||||
|
||||
Berkeley UNIX (Rev. 2.9.1) Sun Nov 20 14:55:50 PST 1983
|
||||
mem = 135872
|
||||
|
||||
CONFIGURE SYSTEM:
|
||||
xp ? csr 176700 vector 254 skipped: No CSR
|
||||
rk 0 csr 177400 vector 220 attached
|
||||
hk ? csr 177440 vector 210 skipped: No CSR
|
||||
rl ? csr 174400 vector 160 skipped: No CSR
|
||||
rp ? csr 176700 vector 254 skipped: No CSR
|
||||
ht 0 csr 172440 vector 224 skipped: No CSR
|
||||
tm 0 csr 172520 vector 224 skipped: No CSR
|
||||
ts 0 csr 172520 vector 224 skipped: No CSR
|
||||
dh ? csr 160020 vector 370 skipped: No CSR
|
||||
dm ? csr 170500 vector 360 skipped: No autoconfig routines
|
||||
dz ? csr 160110 vector 320 skipped: No CSR
|
||||
dz ? csr 160110 vector 320 skipped: No CSR
|
||||
dn 0 csr 175200 vector 300 skipped: No autoconfig routines
|
||||
vp ? csr 177500 vector 174 skipped: No autoconfig routines
|
||||
lp ? csr 177514 vector 200 skipped: No CSR
|
||||
Erase=^?, kill=^U, intr=^C
|
||||
#</code></pre>
|
||||
<p>Congratulations, you are running BSD UNIX 2.9 in single-user mode as
|
||||
root.</p>
|
||||
<p>On the other hand, if you did a typo somewhere, the boot loader has
|
||||
probably crashed and halted – if so, type Control-E to quit the emulator
|
||||
and try again. If you did really badly, you might have corrupted the
|
||||
virtual disk. If so, consider a <code>make clean</code> to start from
|
||||
scratch.</p>
|
||||
<p>Assuming you managed to type 15 characters correctly, you should be
|
||||
at the root prompt. Most of the commands you are familiar with work here
|
||||
(this was only a quarter of a century ago – how much could things have
|
||||
changed?). Let’s try some:</p>
|
||||
<div class="sourceCode" id="cb15"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="co"># ls</span></span>
|
||||
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="ex">.cshrc</span> .profile boot hkunix mnt tmp</span>
|
||||
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="ex">.login</span> 2.9stamp dev lib mullender.c unix</span>
|
||||
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a><span class="ex">.msgsrc</span> bin etc lost+found rkunix usr</span>
|
||||
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a><span class="co"># df</span></span>
|
||||
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a><span class="ex">Filesystem</span> Mounted on kbytes used free % used</span>
|
||||
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a><span class="ex">/dev/rk0</span> / 1958 1688 270 86%</span>
|
||||
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a><span class="co"># bin/cc mullender.c</span></span>
|
||||
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a><span class="co"># ./a.out</span></span></code></pre></div>
|
||||
<p>The program you’ve just run was the [winner of the first IOCCC
|
||||
contest from 1984] <a
|
||||
href="https://www.ioccc.org/1984/mullender/mullender.c"
|
||||
title="mullender.c">1</a> (or was it 1894?), a personal favorite of
|
||||
mine. It is rather tightly bound to running on either a PDP-11 or a
|
||||
VAX-11. Now you have one.</p>
|
||||
<p>Hitting Control-C will return you to the BSD UNIX prompt. Hitting
|
||||
Control-D will log you out of the single-user session and get you back
|
||||
to the <code>:login:</code> prompt. Here you can log in as
|
||||
<code>root</code> and get a full time-sharing session. Feel free to try
|
||||
things like <code>vi</code>. I’ve taken the liberty of editing the
|
||||
<code>.login</code> and <code>.profile</code> files to set the console
|
||||
to a less traditional setup so that you don’t have to wait for the Model
|
||||
33 KSR teletype to move its carriage. I’ve also predefined
|
||||
<code>TERM</code> to <code>vt100</code>, which will probably work well
|
||||
enough with whatever sort of ANSI terminal emulation you are using.</p>
|
||||
<p>Note that I have not mounted the <code>/usr</code> disk here, so some
|
||||
commands from <code>/usr/bin</code> will be missing, along with all of
|
||||
the <code>man</code> pages. They are [available online] <a
|
||||
href="http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.9BSD"
|
||||
title="2.9 BSD">2</a> if you need them. Adding a second RK05 disk was
|
||||
possible, but I didn’t get around to it… As the Judges can no doubt
|
||||
attest, “Mid 2017” creeps up on you quicker than you expect. :)</p>
|
||||
<p>Once you’ve had enough fun in BSD 2.9, type Control-E to exit the
|
||||
emulation.</p>
|
||||
<h3 id="building-and-running-research-unix-v6">Building and Running
|
||||
Research UNIX v6:</h3>
|
||||
<p>Research UNIX v6 and BSD 2.9 use the same executable, but require a
|
||||
different disk image. Type <code>make v6</code> to build it, then type
|
||||
<code>./prog</code> to run it.</p>
|
||||
<p>You should see the boot loader prompt which is a single
|
||||
<code>@</code>:</p>
|
||||
<pre><code>@</code></pre>
|
||||
<p>At this point, you again must type a special incantation:
|
||||
<code>rkunix</code>. After that you should see:</p>
|
||||
<pre><code>@rkunix
|
||||
mem = 1035
|
||||
RESTRICTED RIGHTS
|
||||
|
||||
Use, duplication or disclosure is subject to
|
||||
restrictions stated in Contract with Western
|
||||
Electric Company, Inc.
|
||||
#</code></pre>
|
||||
<p>You are now running a single-user session of v6 UNIX. You might want
|
||||
to start with <code>stty -lcase</code> because otherwise everything will
|
||||
be IN ALL CAPS.</p>
|
||||
<p>Again, if you failed typing seven characters without making a
|
||||
mistake, you may need to use Control-E to quit the emulation.</p>
|
||||
<p>Assuming you’re more careful than that, we can try a few
|
||||
commands:</p>
|
||||
<pre><code>@rkunix
|
||||
mem = 1035
|
||||
RESTRICTED RIGHTS
|
||||
|
||||
Use, duplication or disclosure is subject to
|
||||
restrictions stated in Contract with Western
|
||||
Electric Company, Inc.
|
||||
# STTY -LCASE
|
||||
# ls
|
||||
bin
|
||||
dev
|
||||
etc
|
||||
hpunix
|
||||
lib
|
||||
mnt
|
||||
rkunix
|
||||
rpunix
|
||||
tmp
|
||||
unix
|
||||
usr
|
||||
# cat > foo.c
|
||||
main()
|
||||
{
|
||||
printf("Hello, World!\n");
|
||||
}
|
||||
^D
|
||||
# cc foo.c
|
||||
# ./a.out
|
||||
Hello, World!</code></pre>
|
||||
<p>Why is Version 6 interesting? Well, it was the oldest version that I
|
||||
could find a boot image of that had a C compiler… This C compiler is
|
||||
recognizably C, but not quite the same syntax as we have today. It’s
|
||||
much closer to the [B language] <a
|
||||
href="https://www.bell-labs.com/usr/dmr/www/kbman.html"
|
||||
title="B Language">3</a> from which it is derived. In particular, this C
|
||||
compiler would not be able to compile <code>mullender.c</code> (as
|
||||
simple as it is), because the following syntax features don’t exist
|
||||
yet:</p>
|
||||
<ul>
|
||||
<li>The <code>short</code> data type doesn’t exist yet. Only
|
||||
<code>int</code> (<code>short</code> will show up when <code>long</code>
|
||||
comes, and the port to the Interdata 7/32 starts to make the idea of
|
||||
portability become important).</li>
|
||||
<li>Hexadecimal constants don’t exist yet. Digital’s computers all used
|
||||
octal.</li>
|
||||
<li>The array initializer syntax hasn’t yet moved to using
|
||||
<code>=</code>. It still uses the older form taken from B, which looks
|
||||
like <code>array[] { 1, 2, 3 };</code></li>
|
||||
</ul>
|
||||
<p>It can still compile “Hello World!” (note that you must type a
|
||||
Control-D after you finish entering the code, to let <code>cat</code>
|
||||
see an end-of-file).</p>
|
||||
<p>This version of UNIX doesn’t go into multi-user mode if you do a
|
||||
Control-D. Single-user mode was entered because the front-panel console
|
||||
switches were set to the magic number 0173030 (this can be changed with
|
||||
a recompile).</p>
|
||||
<p>Once you are done with Version 6, Type Control-E to exit the
|
||||
emulation.</p>
|
||||
<p>Note that since both BSD 2.9 and UNIX v6 use the same PDP-11/40
|
||||
emulation code, and they use the same name for the disk
|
||||
(<code>rk05.fs</code>), if you want to go back to the BSD emulation, you
|
||||
should either delete <code>rk05.fs</code> or do a
|
||||
<code>make clean</code> before you do a <code>make</code>.</p>
|
||||
<h3 id="building-and-running-unix-v0">Building and Running UNIX v0:</h3>
|
||||
<p>We now set the Wayback Machine to the very start of it all, 1969.</p>
|
||||
<p>[The story] <a href="https://www.bell-labs.com/usr/dmr/www/hist.html"
|
||||
title="UNIX history">4</a> here is interesting and well worth a read.
|
||||
Bell Labs was pulling out of the Multics project and Ken Thompson and
|
||||
his colleagues had become accustomed to the relatively nice programming
|
||||
environment. They also enjoyed the early computer game [<em>Space
|
||||
Travel</em>] <a
|
||||
href="https://www.bell-labs.com/usr/dmr/www/spacetravel.html"
|
||||
title="Space Travel">5</a> and wanted another system to run it on. They
|
||||
found a PDP-7 which was already obsolete at the time to port <em>Space
|
||||
Travel</em> to. The primitive programming environment influenced
|
||||
Thompson to recreate parts of the Multics experience in the much more
|
||||
hardware-constrained PDP-7 environment. In the summer of 1969, with his
|
||||
wife out on a month-long vacation, Thompson rewrote a filesystem
|
||||
emulation he had been experimenting with to include an assembler, a
|
||||
shell, an editor and an operating system kernel and hence created the
|
||||
first version of UNIX (although it hadn’t been named that yet).</p>
|
||||
<p>You can try out this version by typing <code>make v0</code>. Since
|
||||
this version is a native PDP-7 emulation, it gets its own binary. Type
|
||||
<code>./v0</code> to run it. You should see the login prompt.</p>
|
||||
<pre><code>login:</code></pre>
|
||||
<p>There are two user accounts <code>ken</code> and <code>dmr</code>,
|
||||
with the passwords <code>ken</code> and <code>dmr</code> respectively.
|
||||
Let’s try the Dennis Richie’s <code>dmr</code> account:</p>
|
||||
<pre><code>login: dmr
|
||||
password: dmr
|
||||
@ ls
|
||||
. ?</code></pre>
|
||||
<p>Even though this is not Ken’s doing, I feel this gives me licence to
|
||||
include this quote from the BSD <code>fortune</code> program:</p>
|
||||
<blockquote>
|
||||
<p>Ken Thompson has an automobile which he helped design. Unlike most
|
||||
automobiles, it has neither speedometer, nor gas gauge, nor any of the
|
||||
numerous idiot lights which plague the modern driver. Rather, if the
|
||||
driver makes any mistake, a giant “?” lights up in the center of the
|
||||
dashboard. “The experienced driver”, he says, “will usually know what’s
|
||||
wrong.”</p>
|
||||
</blockquote>
|
||||
<p>What’s the deal here? Well, that’s a slightly long story. The short
|
||||
version is we have gone so far back in the history of UNIX that <em>we
|
||||
don’t have filesystem paths yet</em>. In other words, we can’t say
|
||||
something like <code>/bin/ls</code> yet, and the shell can’t store that
|
||||
path in <code>$PATH</code> to search for it. We also haven’t invented
|
||||
<code>.</code> or <code>..</code> yet. In fact, the filesystem isn’t
|
||||
even the traditional UNIX tree structure, it’s a directed graph of hard
|
||||
links…</p>
|
||||
<p><code>ls</code> needs to be able to read <code>.</code>, the current
|
||||
directory. <code>dmr</code>’s home directory doesn’t have that yet, but
|
||||
we can make it, because the home directory has a hard link to
|
||||
<code>dd</code>, which is the directory that holds all of the user home
|
||||
directories (this will eventually become <code>/</code>, the root path).
|
||||
We can do</p>
|
||||
<pre><code>@ ln dd dmr .</code></pre>
|
||||
<p>To make the new link (note that <code>ln</code> doesn’t support paths
|
||||
either, so you have to give it three arguments – a directory in the
|
||||
current dir, a file in that directory, and the new name).</p>
|
||||
<p>Now <code>ls</code> will work, and we can try some other things while
|
||||
we are here:</p>
|
||||
<pre><code>login: dmr
|
||||
password: dmr
|
||||
@ ln dd dmr .
|
||||
@ ls
|
||||
dd
|
||||
system
|
||||
as.s
|
||||
b_readme
|
||||
bi.s
|
||||
bl.s
|
||||
db.s
|
||||
hello.b
|
||||
ops.s
|
||||
.
|
||||
@ cat b_readme
|
||||
Here is how to compile and run hello.b:
|
||||
|
||||
@ bc hello.b hello.s
|
||||
@ as ops.s bl.s hello.s bi.s
|
||||
I
|
||||
II
|
||||
ops.s
|
||||
bl.s
|
||||
hello.s
|
||||
bi.s
|
||||
@ a.out
|
||||
Hello, World!
|
||||
|
||||
|
||||
@ bc hello.b hello.s
|
||||
@ as ops.s bl.s hello.s bi.s
|
||||
I
|
||||
II
|
||||
ops.s
|
||||
bl.s
|
||||
hello.s
|
||||
bi.s
|
||||
@ a.out
|
||||
Hello, World!
|
||||
@</code></pre>
|
||||
<p>The last command is invoking the compiler for an extremely early
|
||||
version of the [B programming language] <a
|
||||
href="https://www.bell-labs.com/usr/dmr/www/kbman.html"
|
||||
title="B Language">3</a>, the predecessor to C. Thompson missed the
|
||||
convenience of writing code in a high-level language – Multics was
|
||||
written in a version of PL/1 – and wanted the same convenience in UNIX.
|
||||
He preferred BCPL (a typeless language) to PL/1. As Dennis Ritchie
|
||||
[wrote] <a href="https://www.bell-labs.com/usr/dmr/www/chist.html"
|
||||
title="C History">6</a>:</p>
|
||||
<blockquote>
|
||||
<p>B can be thought of as C without types; more accurately, it is BCPL
|
||||
squeezed into 8K bytes of memory and filtered through Thompson’s
|
||||
brain.</p>
|
||||
</blockquote>
|
||||
<p>A look at the B reference manual will show the strong correlation
|
||||
with C, and shows the source of a lot of C’s mysteriousness – some of
|
||||
which is preserved simply so that C could compile the <em>dozens</em> of
|
||||
lines of existing B code…</p>
|
||||
<p>Thompson’s assembler was also extremely simple. It didn’t even know
|
||||
about opcodes – these need to be defined in the first assembly file,
|
||||
with the assembler OR-ing the opcode fields together (space was the
|
||||
“operator” for logical OR). There is no link step – all files are
|
||||
provided to the assembler on the command line, concatenated together and
|
||||
assembled, producing a single <code>a.out</code> (assembler output)
|
||||
file. Even after UNIX got a linker, <code>a.out</code> remained the
|
||||
default name of the binary generated by the linker (and hence also by
|
||||
<code>cc</code>).</p>
|
||||
<p>This system still has the familiarity of UNIX, with all the two and
|
||||
three letter commands, device files, shell redirection and the same core
|
||||
system calls (<code>read(2)</code>, <code>write(2)</code>,
|
||||
<code>open(2)</code>, <code>close(2)</code>, <code>creat(2)</code>,
|
||||
<code>fork(2)</code>, etc.). There are a number of differences
|
||||
still:</p>
|
||||
<ul>
|
||||
<li>As noted, there are no file paths.</li>
|
||||
<li><code>read(2)</code> and <code>write(2)</code> do I/O on (18-bit)
|
||||
words. Character I/O on files need to unpack those bytes, and of course
|
||||
deal with <code>NUL</code> characters.</li>
|
||||
<li><code>exec(2)</code> was performed by the shell directly. Arguments
|
||||
are passed as four words (eight bytes), and space padded. This matches
|
||||
the format for file names for <code>open(2)</code> and
|
||||
<code>creat(2)</code>.</li>
|
||||
<li><code>wait(2)</code> does not yet exist. A more complicated
|
||||
mechanism for sending and receiving messages (<code>smes</code> and
|
||||
<code>rmes</code>) are used instead.</li>
|
||||
<li>File permission bits are all different, since groups don’t exist
|
||||
yet.</li>
|
||||
<li>User programs are not allowed to run during disk I/O. This is
|
||||
because the disk controller’s “data break” (DMA) accesses were so fast
|
||||
relative to the CPU that transfers would be dropped if an instruction
|
||||
that used “deferred” mode (indirection) was executed. This also meant
|
||||
that the “program break” (interrupt) routine in the kernel had to
|
||||
specifically avoid deferred accesses by using self-modifying code to do
|
||||
indirection through pointers.</li>
|
||||
<li>Although the PDP-7 supported a “trap mode” (a primitive supervisor
|
||||
mode), the UNIX kernel doesn’t use it. This means that user programs
|
||||
could alter or crash the kernel at will (in fact, there is a system call
|
||||
that returns addresses of useful kernel routines so that user code can
|
||||
call them directly).</li>
|
||||
</ul>
|
||||
<p>As usual, when you are done exploring UNIX v0, type Control-E to exit
|
||||
the emulator.</p>
|
||||
<h3 id="about-the-program">About the Program:</h3>
|
||||
<p>The program came about when I was looking for something to honor the
|
||||
pending 50th anniversary of the C language (because of the mercurial
|
||||
nature of IOCCC contest scheduling, I chose not to wait for the actual
|
||||
50th anniversary). I had thought of writing self-hosting compilers for a
|
||||
stripped-down version of C, or maybe even a version of the B language…
|
||||
At the same time, I was obsessed with the idea of allowing <a
|
||||
href="/1984/mullender/README.md">mullender.c from 1984</a> to run.
|
||||
Although that was still a possibility on an interpreted version of B or
|
||||
a stripped-down version of C, it felt cheap, as it would be <a
|
||||
href="/1984/mullender/mullender.c">mullender.c</a> only in spirit.</p>
|
||||
<p>It was during this time that I discovered that in 2016, members of
|
||||
the Unix Heritage Society got access to [printouts of assembly-language
|
||||
source for the original version of UNIX] <a
|
||||
href="http://www.tuhs.org/Archive/Distributions/Research/McIlroy_v0/"
|
||||
title="V0 Scans">7</a>. With what was a [huge amount of work] <a
|
||||
href="https://web.archive.org/web/20180826162445/https://minnie.tuhs.org//Y5/wkt_hapop_paper.pdf"
|
||||
title="UNIX v0">8</a>, they scanned in the printouts, fixed up the OCR
|
||||
translations, built assembler and file system tools from scratch and
|
||||
made an accurate emulation of Thompson’s PDP-7 that allowed them to get
|
||||
the system up and running. Although source for the entire kernel and
|
||||
about half of the user-space commands were present (including the
|
||||
runtime and libraries for the B compiler), the remainder needed to be
|
||||
written from scratch, including the shell. The final results of the
|
||||
project are [available on GitHub] <a
|
||||
href="https://github.com/DoctorWkt/pdp7-unix"
|
||||
title="PDP-7 UNIX">9</a>.</p>
|
||||
<p>None of this was remotely easy (as I was to discover myself). The
|
||||
PDP-7 is long gone, and the documentation for it is less complete than
|
||||
one would like. In addition, the devices attached for it were a bit of a
|
||||
mystery. The disk system is referenced only in an old price list. It was
|
||||
a RB09 fixed disk, probably made by Burroughs. It is close to what was
|
||||
called the RC10 for the PDP-10, but with a different interface. And the
|
||||
system also included a custom display device called Graphics-2, which
|
||||
had been built in-house by AT&T. It can’t be completely ignored,
|
||||
because the kernel itself pokes at it (the UNIX crew used it as a second
|
||||
terminal – a “glass TTY”).</p>
|
||||
<p>I decided that implementing this PDP-7 would be possible as an IOCCC
|
||||
entry.</p>
|
||||
<p>The emulator emulates the full machine:</p>
|
||||
<ul>
|
||||
<li>PDP-7 Central Processor.</li>
|
||||
<li>Core Memory Module Type 147 – extends the core to 8,192 18-bit
|
||||
words.</li>
|
||||
<li>Extended Arithmetic Element Type 177 – adds one’s-complement
|
||||
multiplication, division and shifting.</li>
|
||||
<li>Real Time Clock.</li>
|
||||
<li>Teletype Model 33 KSR.</li>
|
||||
<li>Perforated Tape Reader Type 444.</li>
|
||||
<li>RB09 Fixed Disk Controller.</li>
|
||||
</ul>
|
||||
<p>The [PDP-7] <a
|
||||
href="http://bitsavers.trailing-edge.com/pdf/dec/pdp7/F-75P_PDP7prelimUM_Dec64.pdf"
|
||||
title="PDP-7 Manual">10</a> is an odd duck by modern computer
|
||||
standards:</p>
|
||||
<ul>
|
||||
<li>18 bit words, with no byte addressing.</li>
|
||||
<li>Both one’s and two’s complement math (there is <code>ADD</code> for
|
||||
one’s complement and <code>TAD</code> for two’s complement). The EAE is
|
||||
entirely one’s-complement.</li>
|
||||
<li>“Microcoded” instructions.</li>
|
||||
<li>Auto-increment memory locations.</li>
|
||||
<li>Non-reentrant function calls (the return address is stored at the
|
||||
indicated address and the PC jumps to the location after it).</li>
|
||||
<li>The <code>XCT</code> instruction, that executes the word loaded from
|
||||
memory as an instruction.</li>
|
||||
<li>An instruction <code>LAW</code> that loads the instruction opcode
|
||||
into the accumulator.</li>
|
||||
<li>Heavy use of <code>inline</code> operands. For instance the
|
||||
<code>MUL</code> instruction expects the second operand to be stored in
|
||||
memory after the instruction. This pretty much requires the use of
|
||||
self-modifying code.</li>
|
||||
<li>No immediates. Almost all constants have to live in memory locations
|
||||
and be referenced by address.</li>
|
||||
<li>Common operations, like “subtract” and “inclusive OR” are not
|
||||
directly supported on the machine and require multiple instructions and
|
||||
some spare memory locations to support. Being clever also helps.</li>
|
||||
<li>Single accumulator architecture. No direct support for things like
|
||||
stacks.</li>
|
||||
<li>I/O is done with dedicated I/O instructions (which are also
|
||||
microcoded).</li>
|
||||
<li>The RB09 disk controller gets a special mention here because of its
|
||||
particularly annoying encoding of track and sector offsets in [packed
|
||||
BCD] <a href="https://en.wikipedia.org/wiki/Binary-coded_decimal"
|
||||
title="BCD">11</a>. A non-trivial amount of code space in the simulator
|
||||
is needed to convert into and out of BCD, along with an equivalent
|
||||
amount of code in the UNIX kernel itself.</li>
|
||||
</ul>
|
||||
<p>The emulation handles everything I was able to discover about the
|
||||
PDP-7, even things that the UNIX code itself doesn’t use. For instance,
|
||||
it correctly implements the “trap mode” feature (a primitive form of
|
||||
supervisor mode) even though the kernel does not enable it. It also
|
||||
implements the microcoding of the EAE instructions even though the UNIX
|
||||
environment uses only the standard encodings. If you wanted to do a
|
||||
11-bit multiply instead of an 18-bit one, it will probably work.</p>
|
||||
<p>The emulation starts by loading a boot program off of the virtualized
|
||||
paper tape, which is in a modified version of the RIM boot loader
|
||||
format. The RIM format encodes each 18-bit word as three six-bit
|
||||
characters, using one bit to denote the final word (which is executed
|
||||
directly and is usually a <code>JMP</code> or <code>HLT</code>
|
||||
instruction). The load address comes from the console address switches.
|
||||
Both of these are controlled by compile-time flags.</p>
|
||||
<p>The emulator continues emulating instructions until it sees a
|
||||
<code>HLT</code> instruction which will cause it to exit. Console I/O is
|
||||
emulated by setting the terminal into raw mode and polling via
|
||||
<code>read(2)</code>. Line-clock ticks (at 60 Hz) are done by polling
|
||||
<code>gettimeofday(2)</code>. Dynamic frequency code arranges to reduce
|
||||
the polling interval to a few polls per tick, so that emulation remains
|
||||
responsive. Since we use the real wall-clock time, this means that the
|
||||
emulated system will see time advance at the correct rate.</p>
|
||||
<h3 id="licencing-fun">Licencing Fun</h3>
|
||||
<p>So now I have a system that can run UNIX v0. One problem remains… I
|
||||
don’t have permission to submit UNIX v0 to the IOCCC. It is not my code
|
||||
and the copyright for it remains the property of whoever owns that part
|
||||
of what was once Bell Labs – I believe it is Nokia at this point. I have
|
||||
worked around this problem in two ways:</p>
|
||||
<p>First, I didn’t submit the source code or binary image for v0 UNIX as
|
||||
part of my IOCCC entry. I merely submitted a <code>Makefile</code> that
|
||||
can issue a <code>curl</code> command to fetch a pre-built v0 disk image
|
||||
from the GitHub repository. I am hoping this is considered part of
|
||||
“Legal abuse of the rules” which is supposed to be “somewhat
|
||||
encouraged”. As per RULE 12, I am justifying said abuse here, in the
|
||||
remarks file.</p>
|
||||
<p>Secondly, the choice to run the UNIX v0 code is optional. If you are
|
||||
worried about Nokia’s lawyers running you to the ground for running a
|
||||
50-year old copy of a binary image for a machine that is almost
|
||||
completely non-existent, you can just not do so. Delete the lines from
|
||||
the <code>Makefile</code> and sleep well. You still have two other
|
||||
UNICES to play with.</p>
|
||||
<p>What about the other two UNIX variants? These are both covered by
|
||||
licences that allow me to use them. Back in 2002, Caldera International
|
||||
released Research Unix versions 1-7 and 32V under a [permissive BSD-like
|
||||
license] <a href="http://www.tuhs.org/Archive/Caldera-license.pdf"
|
||||
title="Caldera Licence">12</a>. BSD UNIX is based off of v7 UNIX, and of
|
||||
course has its own permissive BSD licence. And in 2017, Nokia also
|
||||
released versions 8-10 under the condition that it will not assert
|
||||
copyright rights for non-commercial use.</p>
|
||||
<p>So the newer UNICES are in the clear. I doubt anyone actually cares
|
||||
about version 0 either, but technically it’s still under copyright.</p>
|
||||
<h3 id="pdp-1140">PDP-11/40</h3>
|
||||
<p>So if I have a PDP-7 emulator, how do I run operating systems that
|
||||
expect a PDP-11? Simple… <em>I emulate a PDP-11/40 on the PDP-7</em>. I
|
||||
have written PDP-7 assembler code to emulate a PDP-11/40 with the
|
||||
following equipment:</p>
|
||||
<ul>
|
||||
<li>PDP-11/40 (KD11-A).</li>
|
||||
<li>EIS instruction set (KE11-E).</li>
|
||||
<li>Memory management unit (KJ11-A).</li>
|
||||
<li>Line time clock (KT11-D).</li>
|
||||
<li>124 Kwords of memory (244 Kbytes).</li>
|
||||
<li>RK05 fixed disk drive (RK11).</li>
|
||||
<li>Console TTY (DL11).</li>
|
||||
</ul>
|
||||
<p>This required a few tweaks to the emulator. The first problem is that
|
||||
the RK05 disk is about 2.5 MB, but the RB09 is only about 2 MB. That’s
|
||||
easily solvable – just add more tracks to the RB09. UNIX v0 is unlikely
|
||||
to notice (although the number of tracks is a compile time parameter,
|
||||
and the <code>v0</code> build commands set it to the correct value).</p>
|
||||
<p>The second problem is that we are emulating a system that can have up
|
||||
to 124K words of memory on a system with only 8K words total. That meant
|
||||
I needed to virtualize the PDP-11/40’s physical memory (and add a few
|
||||
more tracks to the disk to hold the virtualization).</p>
|
||||
<p>A large amount of time was spent tuning this code to be efficient.
|
||||
The memory virtualization uses part of the 8 Kword memory as an LRU
|
||||
cache, and uses a number of first-level microcaches to avoid having to
|
||||
do the LRU updates. This also serves to offload the complexity of the
|
||||
PDP-11’s segmentation logic from a large number of memory accesses (the
|
||||
PDP-11 does as many as eight accesses per instruction). Despite the
|
||||
super fast emulated disk, the PDP-7 code in the emulator is slow, mostly
|
||||
because it has to do a bunch of divides to convert the linear disk
|
||||
offset into a BCD-coded track and sector for the emulated RB09. I/O
|
||||
polling is again used, except this time it uses the PDP-7’s “skip on
|
||||
flag set” I/O instructions. As with the PDP-7 emulator itself, the
|
||||
PDP-11 emulator dynamically measures the instruction throughput relative
|
||||
to the line-clock tick, so that it only polls for I/O a few times per
|
||||
tick.</p>
|
||||
<p>The one remaining problem is building the disk images themselves.
|
||||
Since the PDP-11’s disk is 16-bit, but the PDP-7’s is 18-bit (which the
|
||||
emulator stores in 32-bit <code>int</code>s), a conversion program is
|
||||
needed to unpack the binary disk images from 16 bits per word to 32.
|
||||
This in turn needs to be done in the Makefile using standard POSIX
|
||||
tools, which aren’t exactly good with binary. I had a weirdly clever way
|
||||
to do this with <code>od(1)</code>, <code>awk(1)</code> and
|
||||
<code>uudecode(1)</code> that I will leave as an exercise for the
|
||||
curious, but I decided it would be easier to do it with the PDP-7
|
||||
emulator itself, feeding a simple program in on its boot tape. This
|
||||
required an additional tweak to the emulator, since by default its
|
||||
console TTY is not eight-bit clean (in fact, UNIX v0 expects to see the
|
||||
MSB set on the terminal reads, and sets it on writes, what is called
|
||||
“mark” parity). This is also enabled by a compile-time setting (used
|
||||
only for the <code>builddisk</code> program).</p>
|
||||
<p>Despite the complexity of the PDP-11 instruction set and its emulated
|
||||
I/O devices and the corresponding primitiveness of the PDP-7’s
|
||||
instruction set, the emulation itself is a surprisingly small amount of
|
||||
code, not really taxing the 8K word memory, with about 2.25 Kwords of
|
||||
actual code and a similar amount of space for the memory virtualization
|
||||
cache and disk block buffer, leaving nearly half (3.5 Kwords) of the
|
||||
memory unused. The simulator executes somewhere around 250 PDP-7
|
||||
instructions per PDP-11 instruction. On my laptop, the PDP-7 is running
|
||||
somewhere in the neighborhood of 70 MIPS, which means the PDP-11 is
|
||||
running at about 0.3 MIPS, which is probably not too far off of its
|
||||
actual speed (the cycle time of an 11/40 was around a microsecond for
|
||||
simple instructions, but could be proportionally larger for instructions
|
||||
that did multiple memory accesses, which many did).</p>
|
||||
<p>As an aside, although the idea of emulating the PDP-11 on an emulated
|
||||
PDP-7 came about from the realization that I needed a response to the
|
||||
late-discovered licence issue, I’m quite pleased with the result – it
|
||||
enables an interesting window on the dawn of the UNIX era. I feel that
|
||||
someone should complete the circle here by emulating a VAX 780 on the
|
||||
PDP-11 and run 4.2BSD on it, so that we can get the [original runtime
|
||||
environment used for the first IOCCC] <a
|
||||
href="https://groups.google.com/forum/?hl=en#!msg/net.lang.c/lx-TAuEyeRI/HdOOnNx6LC0J"
|
||||
title="First annual IOCCC announcement">13</a>.</p>
|
||||
<h3 id="compile-time-options">Compile-time Options:</h3>
|
||||
<p>The following command flags control the compilation:</p>
|
||||
<ul>
|
||||
<li><code>-DI="image.fs"</code>: Name of the disk image file. This must
|
||||
be created offline, and be of the correct size to avoid segmentation
|
||||
violations.</li>
|
||||
<li><code>-DA=4096</code>: Setting of the console address switches. This
|
||||
tells the RIM bootloader where to load the boot image.</li>
|
||||
<li><code>-DS=0</code>: Setting of the console data switches. The PDP-7
|
||||
emulation can read these with the microcoded <code>OAS</code> (OR
|
||||
switches into AC) instruction. By proxy, the PDP-11 emulation can read
|
||||
them via the <code>CSW</code> device.</li>
|
||||
<li><code>-DW=MAP_PRIVATE</code>: This sets the memory mapping for
|
||||
<code>mmap(2)</code>. Setting to <code>MAP_PRIVATE</code> makes the disk
|
||||
image be copy-on-write. Setting it to <code>MAP_SHARED</code> makes the
|
||||
disk image be shareable. Do the latter if you want to preserve the disk
|
||||
contents between sessions.</li>
|
||||
<li><code>-DT=</code>: List of initializers for the <code>termios</code>
|
||||
structure. The v0 UNIX expects the terminal to be in half-duplex mode,
|
||||
echoing its input, with swapped CR and NL. The PDP-11 UNICES don’t.</li>
|
||||
<li><code>-DX=5</code>: The ASCII code of the control character that
|
||||
causes the emulation to abort. If set to 0, there is no abort code.</li>
|
||||
<li><code>-DY=128</code>: Controls console I/O parity. If set to zero,
|
||||
the console is eight-bit clean. If set to 128, the high bit is set on
|
||||
keyboard reads and masked off on printer output (“mark” parity). UNIX v0
|
||||
expects the latter.</li>
|
||||
<li><code>-DV=270</code>: The size of the disk, in tracks. The UNIX v0
|
||||
disk has 200 tracks (each has 80 sectors of 64 18-bit words). The PDP-11
|
||||
UNICES increase this to 270, to allow for the larger RK05 disk emulation
|
||||
(406 tracks of twelve 256-word sectors), plus the space for the 124K
|
||||
words of virtualized memory and the 8K words of emulator code.</li>
|
||||
<li><code>-DP="xxx"</code>: RIM bootstrap program paper tape image. Be
|
||||
careful with the quoting here – there are at least three levels going
|
||||
on. In particular, you will need to escape <code>$</code> as
|
||||
<code>$$</code> to protect it from <code>make</code>.</li>
|
||||
</ul>
|
||||
<h3 id="what-is-the-ascii-art-supposed-to-be">What is the ASCII art
|
||||
supposed to be?</h3>
|
||||
<p>The ASCII art represents a torn piece of [paper tape] <a
|
||||
href="https://en.wikipedia.org/wiki/Punched_tape"
|
||||
title="Paper Tape">14</a>.</p>
|
||||
<h3 id="acknowledgements">Acknowledgements</h3>
|
||||
<p>None of this could have been possible without the hard work of</p>
|
||||
<ul>
|
||||
<li>Warren Toomey and the other members of the [The Unix Heritage
|
||||
Society] <a href="http://www.tuhs.org"
|
||||
title="The Unix Heritage Society">15</a></li>
|
||||
<li>Robert M. Supnik and the other contributors to [SimH] <a
|
||||
href="http://simh.trailing-edge.com" title="SimH">16</a>, the simulator
|
||||
for historic computer architectures. The number of times I needed to
|
||||
“Use the Source, Luke” on SimH to unravel some dark corner of these
|
||||
machines was uncountable.</li>
|
||||
<li>[Bitsavers] <a href="http://bitsavers.trailing-edge.com"
|
||||
title="Bitsavers.org">17</a>, which acquired, scanned and preserved all
|
||||
the manuals I spent many hours squinting at.</li>
|
||||
<li>Ken Thompson, Dennis Ritchie, Brian Kernigan, M. D. McIlroy, J. F.
|
||||
Osssanna, Rudd Canaday and the other members of the Bell Labs Computing
|
||||
Science Research Center who were responsible for the invention of UNIX,
|
||||
the C programming language, and the innumerable other innovations that
|
||||
we now take for granted as part of the modern software landscape. In
|
||||
particular, the [home page of the late Dennis Ritchie] <a
|
||||
href="https://www.bell-labs.com/usr/dmr/www/"
|
||||
title="DMR Homepage">18</a> contained a trove of useful information on
|
||||
the evolution of UNIX and C and is recommended for perusal by others who
|
||||
share my peculiar retro computing passion.</li>
|
||||
</ul>
|
||||
<p>Finally, thanks to my spouse for putting up with the many hours I
|
||||
spent on this nonsense, and treating “I’m working on my IOCCC entry” as
|
||||
an acceptable answer to queries about how I was spending my free time.
|
||||
Similarly, I apologise to those friends and coworkers who had to listen
|
||||
to me complain about obscure corner-case bugs in my code. The obsession
|
||||
is over, at least until next time…</p>
|
||||
<hr />
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<!-- START: this line starts content generated by: bin/gen-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2018mills"><a name="inventory"></a>Inventory for
|
||||
2018/mills</h1>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - winner home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/mills/prog.c">prog.c</a>
|
||||
- winning source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/mills/Makefile">Makefile</a>
|
||||
- winner Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/mills/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a href="2018_mills.tar.bz2">2018_mills.tar.bz2</a> - download
|
||||
winning source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/mills/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/mills/.winner.json">.winner.json</a>
|
||||
- description of winner in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/mills/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="boot.dat">boot.dat</a> - binary support file</li>
|
||||
<li><a href="bsd.img.bz2">bsd.img.bz2</a> - bz2 compressed BSD disk
|
||||
image</li>
|
||||
<li><a href="v0.image.fs">v0.image.fs</a> - filesystem image</li>
|
||||
<li><a href="v6.tape.gz">v6.tape.gz</a> - compressed filesystem
|
||||
image</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/gen-inventory.sh -->
|
||||
<!-- START: this line starts content from: inc/after-content.default.html -->
|
||||
|
||||
<!-- END: this line ends content from: inc/after-content.default.html -->
|
||||
<!-- START: this line starts content from: inc/end-rightcolumn.default.html -->
|
||||
|
||||
</div>
|
||||
|
||||
<!-- END: this line ends content from: inc/end-rightcolumn.default.html -->
|
||||
<!-- START: this line starts content from: inc/end-row.default.html -->
|
||||
|
||||
</div>
|
||||
|
||||
<!-- END: this line ends content from: inc/end-row.default.html -->
|
||||
<!-- START: this line starts content from: inc/footer.default.html -->
|
||||
|
||||
<div class="footer">
|
||||
<hr>
|
||||
<h2>Coda</h2>
|
||||
<p><a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fioccc-src.github.io%2Ftemp-test-ioccc%2F2018%2Fmills%2Findex.html">Nu HTML check this web page</a></p>
|
||||
<p><a href="#top">Jump to top</a> <a href="#content">Jump to Content</a> <a href="#inventory">Jump to Inventory</a></p>
|
||||
</div>
|
||||
|
||||
<!-- END: this line ends content from: inc/footer.default.html -->
|
||||
<!-- START: this line starts content from: inc/bottom.default.html -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- END: this line ends content from: inc/bottom.default.html -->
|
||||
Reference in new issue
Block a user