forked from ioccc-src/temp-test-ioccc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
1179 lines (1055 loc) · 55.4 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!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 -->
<!-- END: this line ends content from: inc/top.default.html -->
<!-- START: this line starts content from: inc/head.default.html -->
<head>
<link rel="stylesheet" href="../../ioccc.css">
<link href="https://fonts.googleapis.com/css2?family=Outfit:[email protected]&display=swap" rel="stylesheet">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>2018/mills - Best of Show</title>
<link rel="icon" type="image/x-icon" href="../../favicon.ico">
<meta name="description" content="2018 IOCCC entry mills - Best of Show">
<meta name="keywords" content="IOCCC, 2018, IOCCC 2018, IOCCC entry, mills, Best of Show">
</head>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- END: this line ends content from: inc/head.default.html -->
<!-- -->
<!-- This web page was formed via the tool: bin/readme2index.sh -->
<!-- The content of main section of this web page came from: 2018/mills/README.md -->
<!-- -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2018/mills/README.md !!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2018/mills/README.md !!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2018/mills/README.md !!! -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- Markdown content was converted into HTML via the tool: bin/md2html.sh -->
<!-- START: this line starts content from: inc/body.default.html -->
<body>
<!-- END: this line ends content from: inc/body.default.html -->
<!-- START: this line starts content from: inc/topbar.default.html -->
<div class="theader">
<nav class="topbar">
<div class="container">
<div class="logo">
<a href="../../index.html" class="logo-link">
IOCCC
</a>
</div>
<div class="topbar-items">
<div class="item">
<span class="item-header">
Entries
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../years.html" class="sub-item-link">
Winning entries
</a>
</div>
<div class="outfit-font">
<a href="../../authors.html" class="sub-item-link">
Winning authors
</a>
</div>
<div class="outfit-font">
<a href="../../location.html" class="sub-item-link">
Location of authors
</a>
</div>
<div class="outfit-font">
<a href="../../bugs.html" class="sub-item-link">
Bugs and (mis)features
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#fix_an_entry" class="sub-item-link">
Fixing entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#fix_author" class="sub-item-link">
Updating author info
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
Status
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../news.html" class="sub-item-link">
News
</a>
</div>
<div class="outfit-font">
<a href="../../status.html" class="sub-item-link">
Contest status
</a>
</div>
<div class="outfit-font">
<a href="../../next/index.html" class="sub-item-link">
Rules and guidelines
</a>
</div>
<div class="outfit-font">
<a href="../../markdown.html" class="sub-item-link">
Markdown guidelines
</a>
</div>
<div class="outfit-font">
<a href="../../SECURITY.html" class="sub-item-link">
Security policy
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
FAQ
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../faq.html" class="sub-item-link">
Frequently Asked Questions
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#submit" class="sub-item-link">
How to enter
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#compiling" class="sub-item-link">
Compiling entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#running_entries" class="sub-item-link">
Running entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#help" class="sub-item-link">
How to help
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
About
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../index.html" class="sub-item-link">
Home page
</a>
</div>
<div class="outfit-font">
<a href="../../about.html" class="sub-item-link">
About the IOCCC
</a>
</div>
<div class="outfit-font">
<a href="../../judges.html" class="sub-item-link">
The Judges
</a>
</div>
<div class="outfit-font">
<a href="../../thanks-for-help.html" class="sub-item-link">
Thanks for the help
</a>
</div>
<div class="outfit-font">
<a href="../../contact.html" class="sub-item-link">
Contact us
</a>
</div>
</div>
</div>
</div>
</div>
</nav>
<div class="header-mobile-menu">
<noscript>
<a href="../../nojs-menu.html" class="topbar-js-label">
Please Enable JavaScript
</a>
</noscript>
<button id="header-open-menu-button" class="topbar-mobile-menu">
<img
src="../../png/hamburger-icon-open.png"
alt="hamburger style menu icon - open state"
width=48
height=48>
</button>
<button id="header-close-menu-button" class="hide-content">
<img
src="../../png/hamburger-icon-closed.png"
alt="hamburger style menu icon - closed state"
width=48
height=48>
</button>
<div id="mobile-menu-panel" class="hide-content">
<div class="mobile-menu-container">
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
Entries
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../years.html">
Winning entries
</a>
<a class="mobile-submenu-item" href="../../authors.html">
Winning authors
</a>
<a class="mobile-submenu-item" href="../../location.html">
Location of authors
</a>
<a class="mobile-submenu-item" href="../../bugs.html">
Bugs and (mis)features
</a>
<a class="mobile-submenu-item" href="../../faq.html#fix_an_entry">
Fixing entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#fix_author">
Updating author info
</a>
<a class="mobile-submenu-item" href="../../thanks-for-help.html">
Thanks for the help
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
Status
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../news.html">
News
</a>
<a class="mobile-submenu-item" href="../../status.html">
Contest status
</a>
<a class="mobile-submenu-item" href="../../next/index.html">
Rules and guidelines
</a>
<a class="mobile-submenu-item" href="../../markdown.html">
Markdown guidelines
</a>
<a class="mobile-submenu-item" href="../../SECURITY.html">
Security policy
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
FAQ
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../faq.html">
Frequently Asked Questions
</a>
<a class="mobile-submenu-item" href="../../faq.html#submit">
How to enter
</a>
<a class="mobile-submenu-item" href="../../faq.html#compiling">
Compiling entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#running_entries">
Running entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#help">
How to help
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
About
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../index.html">
Home page
</a>
<a class="mobile-submenu-item" href="../../about.html">
About the IOCCC
</a>
<a class="mobile-submenu-item" href="../../judges.html">
The Judges
</a>
<a class="mobile-submenu-item" href="../../contact.html">
Contact us
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
var headerOpenMenuButton = document.getElementById("header-open-menu-button");
var headerCloseMenuButton = document.getElementById("header-close-menu-button");
var mobileMenuPanel = document.getElementById("mobile-menu-panel");
headerOpenMenuButton.addEventListener("click", () => {
headerOpenMenuButton.classList.remove("topbar-mobile-menu");
headerOpenMenuButton.classList.add("hide-content");
headerCloseMenuButton.classList.remove("hide-content");
headerCloseMenuButton.classList.add("topbar-mobile-menu");
mobileMenuPanel.classList.remove("hide-content");
mobileMenuPanel.classList.add("topbar-mobile-panel");
});
headerCloseMenuButton.addEventListener("click", () => {
headerCloseMenuButton.classList.remove("topbar-mobile-menu");
headerCloseMenuButton.classList.add("hide-content");
mobileMenuPanel.classList.add("hide-content");
mobileMenuPanel.classList.remove("topbar-mobile-panel");
headerOpenMenuButton.classList.add("topbar-mobile-menu");
headerOpenMenuButton.classList.remove("hide-content");
});
</script>
<!-- END: this line ends content from: inc/topbar.default.html -->
<!-- START: this line starts content from: inc/header.default.html -->
<div class="header">
<a href="../../2011/zucker/index.html">
<img src="../../png/ioccc.png"
alt="IOCCC image by Matt Zucker"
width=300
height=110>
</a>
<h1>The International Obfuscated C Code Contest</h1>
<h2>2018/mills - Best of Show</h2>
<h3>PDP-7/11 simulator</h3>
</div>
<!-- END: this line ends content from: inc/header.default.html -->
<!-- START: this line starts content from: inc/navbar.mid.html -->
<div class="navbar">
<a class="Left" href="../hou/index.html">← 2018/hou</a>
<a class="Left" href="../index.html">↑ 2018 ↑</a>
<a class="Left" href="../poikola/index.html">2018/poikola →</a>
<a class="Right" href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/mills/prog.c">C code</a>
<a class="Right" href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2018/mills/Makefile">Makefile</a>
<a class="Right" href="#inventory">Inventory</a>
<a class="Right" href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fioccc-src.github.io%2Ftemp-test-ioccc%2F2018%2Fmills%2Findex.html">✓</a>
</div>
<!-- END: this line ends content from: inc/navbar.mid.html -->
<!-- START: this line starts content from: inc/before-content.default.html -->
<div class="content" id="content">
<!-- END: this line ends content from: inc/before-content.default.html -->
<!-- START: this line starts content for HTML phase 20 by: bin/output-index-author.sh via bin/md2html.sh -->
<!-- START: this line starts content generated by: bin/output-index-author.sh -->
<h2 id="author">Author:</h2>
<ul>
<li>Name: <a href="../../authors.html#Christopher_Mills">Christopher Mills</a><br>
Location: <a href="../../location.html#US">US</a> - <em>United States of America</em> (<em>United States</em>)</li>
</ul>
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
<!-- END: this line ends content for HTML phase 20 by: bin/output-index-author.sh via bin/md2html.sh -->
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- BEFORE: 1st line of markdown file: 2018/mills/README.md -->
<h2 id="to-build">To build:</h2>
<pre><code> make</code></pre>
<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>
<pre><code> make clobber SAVE=1 all</code></pre>
<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>
<blockquote>
<p><strong>STATUS: known bug - please help us fix</strong><br>
<strong>STATUS: INABIAF - please DO NOT fix</strong></p>
</blockquote>
<p>For more detailed information see <a href="../../bugs.html#2018_mills">2018/mills in bugs.html</a>.</p>
<h2 id="to-use">To use:</h2>
<pre><code> ./prog</code></pre>
<h2 id="try">Try:</h2>
<pre><code> ./prog</code></pre>
<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>
<pre><code> cat > prog.c
main(){ printf("Hello, world!\n"); }
^D
cc prog.c
a.out</code></pre>
<p>where <code>^D</code> is EOF.</p>
<p>Next try:</p>
<pre><code> cc mullender.c
a.out</code></pre>
<p>… and enjoy the classic <a href="../../1984/mullender/index.html">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><strong>NOTE</strong>: 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>
<pre><code> ./v0</code></pre>
<p><strong>NOTE</strong>: 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>
<pre><code> @ ln dd dmr .</code></pre>
<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>
<pre><code> ./prog</code></pre>
<p>At the <code>>boot</code> prompt, type return.</p>
<p>At the “:” prompt, type <code>rk(0,0)rkunix</code>.</p>
<p><strong>NOTE</strong>: 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/index.html">1984/mullender</a>, as
shown earlier.</p>
<p>But wait, there is even more! Try:</p>
<pre><code> ./v6</code></pre>
<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><strong>NOTE</strong>: 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>
<pre><code> # ls
.cshrc .profile boot hkunix mnt tmp
.login 2.9stamp dev lib mullender.c unix
.msgsrc bin etc lost+found rkunix usr
# df
Filesystem Mounted on kbytes used free % used
/dev/rk0 / 1958 1688 270 86%
# bin/cc mullender.c
# ./a.out</code></pre>
<p>The program you’ve just run was the <a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/1984/mullender/mullender.c" title="mullender.c">winning entry of the first IOCCC contest from
1984</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
<a href="http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.9BSD" title="2.9 BSD">available online</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
<a href="https://www.bell-labs.com/usr/dmr/www/kbman.html" title="B Language">B language</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><a href="https://www.bell-labs.com/usr/dmr/www/hist.html" title="UNIX history">The story</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 <a href="https://www.bell-labs.com/usr/dmr/www/spacetravel.html" title="Space Travel"><em>Space Travel</em></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 <a href="https://www.bell-labs.com/usr/dmr/www/kbman.html" title="B Language">B programming language</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 <a href="https://www.bell-labs.com/usr/dmr/www/chist.html" title="C History">wrote</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/index.html">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="https://github.com/ioccc-src/temp-test-ioccc/blob/master/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 <a href="http://www.tuhs.org/Archive/Distributions/Research/McIlroy_v0/" title="V0 Scans">printouts of assembly-language source for the
original version of UNIX</a>. With what was a <a href="https://web.archive.org/web/20180826162445/https://minnie.tuhs.org//Y5/wkt_hapop_paper.pdf" title="UNIX v0">huge amount of work</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 <a href="https://github.com/DoctorWkt/pdp7-unix" title="PDP-7 UNIX">available on GitHub</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 <a href="http://bitsavers.trailing-edge.com/pdf/dec/pdp7/F-75P_PDP7prelimUM_Dec64.pdf" title="PDP-7 Manual">PDP-7</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
<a href="https://en.wikipedia.org/wiki/Binary-coded_decimal" title="BCD">packed BCD</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 <a href="http://www.tuhs.org/Archive/Caldera-license.pdf" title="Caldera Licence">permissive BSD-like license</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 <a href="https://groups.google.com/forum/?hl=en#!msg/net.lang.c/lx-TAuEyeRI/HdOOnNx6LC0J" title="First annual IOCCC announcement">original runtime environment used for the first IOCCC</a>.</p>
<h3 id="compile-time-options">Compile-time Options:</h3>
<p>The following command flags control the compilation:</p>
<ul>