Files
Landon Curt Noll a1c86c8a7a add original C links to entry navigation bars
The navigation bar for a winning entry now has a "_Original C_" link
(between the ✅ and the Inventory on the right hand side) so that one
may easily view the original C code that was submitted for IOCCC judging.

Ran `make www timestamp` to perform the above.
2025-08-10 12:46:23 -07:00

949 lines
44 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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:wght@100..900&display=swap" rel="stylesheet">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>2013/cable3 - Largest small system emulator</title>
<link rel="icon" type="image/x-icon" href="../../favicon.ico">
<meta name="description" content="2013 IOCCC entry cable3 - Largest small system emulator">
<meta name="keywords" content="IOCCC, 2013, IOCCC 2013, IOCCC entry, cable3, Largest small system emulator">
</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: 2013/cable3/README.md -->
<!-- -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2013/cable3/README.md !!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2013/cable3/README.md !!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2013/cable3/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/rules.html" class="sub-item-link">
IOCCC rules
</a>
</div>
<div class="outfit-font">
<a href="../../next/guidelines.html" class="sub-item-link">
IOCCC 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="../../quick-start.html#enter" class="sub-item-link">
Enter the IOCCC
</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="../../social.html" class="sub-item-link">
IOCCC social media
</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/rules.html">
IOCCC rules
</a>
<a class="mobile-submenu-item" href="../../next/guidelines.html">
IOCCC 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="../../quick-start.html#enter">
Enter the IOCCC
</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="../../social.html">
IOCCC social media
</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>2013/cable3 - Largest small system emulator</h2>
<h3>IBM PC emulator</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="../cable2/index.html">&larr; 2013/cable2</a>
<a class="Left" href="../index.html">&uarr; 2013 &uarr;</a>
<a class="Left" href="../dlowe/index.html">2013/dlowe &rarr;</a>
<a class="Right" href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/cable3.c">C code</a>
<a class="Right" href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/Makefile">Makefile</a>
<a class="Right" href="#inventory">Inventory</a>
<a class="Right" href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/cable3.orig.c">Original C</a>
<a class="Right" href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fwww.ioccc.org%2F2013%2Fcable3%2Findex.html">&#x2713;</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#Adrian_Cable">Adrian Cable</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: 2013/cable3/README.md -->
<h2 id="to-build">To build:</h2>
<pre><code> make</code></pre>
<p>An alternate version that should compile in Windows/MS Visual Studio is
available. See the <a href="#alternate-code">Alternate code</a> section below.</p>
<h2 id="to-use">To use:</h2>
<pre><code> ./cable3 bios-image-file floppy-image-file [harddisk-image-file]</code></pre>
<h2 id="try">Try:</h2>
<pre><code> ./cable3.sh</code></pre>
<p><strong>NOTE</strong>: to quit the program type <code>QUITEMU</code>. You might have to be at the top level
directory of the drive, <code>A:</code> or <code>C:</code>.</p>
<p>To send an <code>Alt+XXX</code> key combination, press (<code>^A</code> / <code>Ctrl+A</code>) then the key, so
for example to type <code>Alt+F</code>, press (<code>^A</code> / <code>Ctrl+A</code>) then <code>F</code>.</p>
<p>To send an <code>Fxx</code> key, press <code>^F</code> / <code>Ctrl+F</code> then a number key. For example, to
get the <code>F4</code> key, press <code>^F</code> / <code>Ctrl+F</code> then <code>4</code>. To get <code>F10</code>, press <code>^F</code> /
<code>Ctrl+F</code> then <code>0</code>.</p>
<p>To send a <code>Page Down</code> key, press <code>^F</code> / <code>Ctrl+F</code> then <code>O</code> (letter O, not digit
zero). To send a <code>Page Up</code> key, press <code>^F</code> / <code>Ctrl+F</code> then <code>E</code>. Other key
combinations are left for the discovery of the user.</p>
<h2 id="alternate-code">Alternate code:</h2>
<p>An alternate version, which should compile in Windows, is provided.</p>
<h3 id="alternate-build">Alternate build:</h3>
<p>Assuming <code>make</code> is available and will function:</p>
<pre><code> make alt</code></pre>
<h3 id="alternate-use">Alternate use:</h3>
<p>Use <code>cable3.alt</code> as you would <code>cable3</code> above.</p>
<h2 id="judges-remarks">Judges’ remarks:</h2>
<p>This entry weighs in at a magical 4043 bytes (8086 nibbles, 28,301
bits). It manages to implement most of the hardware in a 1980’s era
IBM-PC using a few hundred fewer bits than the total number of
transistors used to implement the original 8086 CPU.</p>
<p>If you are using macOS, the included <a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/sc-ioccc.terminal">sc-ioccc.terminal</a>
configuration file will correctly display console applications that use ANSI
graphics.</p>
<p><strong>NOTE</strong>: the author remarked that in some systems one might need to <code>#include &lt;unistd.h&gt;</code>. This has been done in the entry but not the alternate version. This
should not affect the usability of the program but will trigger a warning which
we have disabled in the Makefile.</p>
<p>Update: This entry now has its own website:
<a href="https://github.com/adriancable/8086tiny" class="uri">https://github.com/adriancable/8086tiny</a></p>
<h2 id="authors-remarks">Author’s remarks:</h2>
<h3 id="a-tiny-but-highly-functional-pc-emulatorvirtual-machine">A tiny but highly functional PC emulator/virtual machine</h3>
<p>The author hereby presents, for the delectation (?) of the judges, a portable PC
emulator/VM written specifically for the IOCCC which runs DOS, Windows 3.0,
Excel, MS Flight Simulator, AutoCAD, Lotus 1-2-3 …</p>
<p>In just 4043 bytes of C source, you get a complete mid-late 1980s-era
IBM-compatible PC, consisting of:</p>
<ul>
<li>Intel 8086/186 CPU</li>
<li>1MB RAM</li>
<li>8072A 3.5” floppy disk controller (1.44MB/720KB)</li>
<li>Fixed disk controller (supports a single hard drive up to 528MB)</li>
<li>Hercules graphics card with 720x348 2-color graphics (64KB video RAM), and
<a href="https://en.wikipedia.org/wiki/Color_Graphics_Adapter">CGA</a>
80x25 16-color text mode support</li>
<li>8253 programmable interval timer (PIT)</li>
<li>8259 programmable interrupt controller (PIC)</li>
<li>8042 keyboard controller with 83-key XT-style keyboard</li>
<li>MC146818 real-time clock</li>
<li>PC speaker</li>
</ul>
<p>The emulator uses the <a href="https://www.libsdl.org">SDL graphics library</a> for
portability, and compiles for Windows, macOS, Linux and probably most other
32-bit/64-bit systems too.</p>
<p>If you like living on the edge you can try building the emulator on a big endian
machine, and you will get an emulation of a big endian 8086, a rather bizarre
and somewhat useless beast. For everyone else, please run the emulator on a
little endian machine.</p>
<h3 id="rule-2-abuse-disclaimer">RULE 2 ABUSE DISCLAIMER</h3>
<ul>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/cable3.c">cable3.c</a> is 4043 bytes in length (half an 8086).</li>
<li><code>iocccsize -i &lt; cable3.c</code> returns 1977 (the year the 4.77 MHz 8086 CPU was announced)</li>
<li>Therefore, any suspicions the judges may have regarding rule 2 non-compliance
might be well-intentioned but are groundless.</li>
<li>Nonetheless, the author would like to apologise to the judges for the
one-big-block-of-code nature of this entry, which turned out to be unavoidable.
Hopefully the joys of this entry will make up for its shortcomings.</li>
</ul>
<h3 id="why-is-this-entry-obfuscatedinteresting">Why is this entry obfuscated/interesting?</h3>
<ul>
<li>First of all the 8086 is a nightmare processor to emulate. Instruction codings
are complex and irregular in size and structure, with multiple addressing modes
and no consistent memory placement for operands, very often multiple possible
encodings for the same instruction, and the bizarre segment:offset memory model.
In addition, the 8086 has a number of bugs (e.g. PUSH SP), undocumented
behaviours and instructions (e.g. AAM/AAD + imm8, SALC, flag behaviour for
MUL/DIV, etc. etc.), and archaic features (e.g. parity/auxiliary flags) which
all need to be emulated properly. Here we emulate every feature of the CPU
pretty exactly (in fact better than most commercial clones of the processor e.g.
the NEC V30), with the exception of the trap flag which no real software uses
except for debuggers (although support for the TF can be added if deemed
important, without exceeding the IOCCC size limit).</li>
<li>In addition to the CPU we also emulate all the standard PC peripheral
hardware. Parts of it are somewhat complete, much is rather dysfunctional (like
the 8253/8259) but enough to support most real software.</li>
<li>Nonetheless the source, while large for the IOCCC, is rather tiny for a
functional PC emulator - around 2% of the size of the source of other
open-source 8086 PC emulators with comparable functionality.</li>
<li>In fact, this entry is just like happy hour - at 4043 bytes long, you pay for
half the 8086, but you get served the whole one.</li>
<li>Getting the code down to &lt;= 4096 characters to meet the IOCCC rule 2 overall
size limit required a good deal of effort (and appreciable risk of divorce),
with obfuscation being a pretty unavoidable consequence in most places … for
the rest, I use short circuit operators whenever possible, mix <code>x[y]</code> and <code>y[x]</code>,
don’t use any flow control keywords except for <code>for</code>, use K&amp;R-style declarations
to honor the C language’s rich cultural heritage (plus it saves a byte), and
occasionally go overboard with nasty nested indexes to give things like this:
<code>--64[T=1[O=32[L=(X=*Y&amp;7)&amp;1,o=X/2&amp;1,l]=0,t=(c=y)&amp;7,a=c/8&amp;7,Y]&gt;&gt;6,g=~-T?y:(n)y,d=BX=y,l]</code>.</li>
<li>This entry highlights the importance of comments in C.</li>
<li>This entry might result in an adjustment to the IOCCC size tool for the 2014
competition (see above).</li>
</ul>
<h3 id="compiling-on-different-platforms">Compiling on different platforms</h3>
<p>This entry has been tested on Windows (compiled with MS Visual Studio 2010 and
2013), Mac OS X (clang and gcc), and Linux (clang and gcc). The Makefile
supplied is good for Mac OS X, Linux and probably other Unices. I have received
reports that the emulator works on Raspberry Pi/Android/ARM (you will need to
compile with <code>-fsigned-char</code>) and iOS. You will need to adjust the
<a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/Makefile">Makefile</a> if your system lacks <code>sdl-config</code> to correctly point to the
SDL libraries and header files.</p>
<p>On UNIX-based systems we can get raw keystrokes using <code>stty</code>. However Windows
has no <code>stty</code>. Therefore the Makefile includes a <code>-D</code> option to define a
“keyboard driver” <code>KB</code> which as it stands is suitable for Unices, but maybe not
non-UNIX platforms. For example, for Windows/MS Visual Studio, instead of the
Makefile definition of KB, use something slightly different - add the following
entry to the Preprocessor Definitions list in the Project Properties page:</p>
<pre><code> KB=(kb=H(8),kbhit())&amp;&amp;(r[1190]=getch(),H(7))</code></pre>
<p><strong>NOTE</strong>: this is done in the <a href="#alternate-code">Alternate code</a>.</p>
<h3 id="posix-portability-note">POSIX portability note</h3>
<p>The code as supplied uses implicit function declarations for POSIX file I/O and
in doing so assumes that file offsets are the same bit width as your
architecture. For some systems (e.g. 32-bit Mac OS X, which uses 64-bit file
offsets) this is not the case, and to run successfully on these systems, you
will need to explicitly declare these functions by adding the appropriate
include to the top of the source:</p>
<pre><code> #include &lt;unistd.h&gt;</code></pre>
<p><strong>NOTE</strong>: this has been done in <a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/cable3.c">cable3.c</a>.</p>
<h3 id="usage">Usage</h3>
<pre><code> ./cable3 bios-image-file floppy-image-file [harddisk-image-file]</code></pre>
<p><strong>PLEASE NOTE</strong> that under Unices the keyboard must be in raw mode for the emulator
to work properly. Therefore the emulator is best run from a shell script that
looks something like:</p>
<pre><code> stty cbreak raw -echo min 0
./cable3 bios floppy.img harddisk.img
stty cooked echo</code></pre>
<p>See the <a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/cable3.sh">cable3.sh</a> script.</p>
<h2 id="to-use-the-emulator---floppy-mode-only">To use the emulator - floppy mode only</h2>
<p>The simplest use of the emulator is with a single floppy boot disk image, like
the <code>fd.img</code> provided, which is a FreeDOS boot disk.</p>
<p>Before running the emulator on a Unix-type system, <code>stty</code> needs to be used to
put the keyboard into raw mode (and afterwards it needs to be put back to
cooked). So, run the emulator using something like this script (provided as
the <a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/cable3.sh">cable3.sh</a> file):</p>
<pre><code> stty cbreak raw -echo min 0
./cable3 bios fd.img
stty cooked echo</code></pre>
<h2 id="to-use-the-emulator---floppy-hd-mode">To use the emulator - floppy + HD mode</h2>
<p>Easiest to start with is to try a ready-made 40MB hard disk image containing a
whole bunch of software which is in the included file <code>hd.img</code>.</p>
<p>For the more adventurous, you can start off with (for example) a blank 40MB
image file called hd.img made using e.g. Makefile. Then use:</p>
<pre><code> stty cbreak raw -echo min 0
./cable3 bios fd.img hd.img
stty cooked echo</code></pre>
<p>Preparing the hard disk for use in the emulator is done just like a real PC.
Boot the emulator, and use <code>FDISK</code> to partition the hard disk. When it’s done
<code>FDISK</code> will reboot the emulator. Then you can use <code>FORMAT C:</code> and you are done. The
resulting disk image is in the right format to be mounted on a real Windows PC
using e.g. <code>OSFMount</code> (Windows), <code>hdiutil</code> (macOS), or <code>mount</code> (linux/unix), providing
an easy way to copy files and programs to and from the disk image. Or, you can
install programs from regular floppy disk images (see <a href="#floppy-disk-support">Floppy disk
support</a> below).</p>
<h3 id="keyboard-emulation">Keyboard emulation</h3>
<p>The emulator emulates an XT-style keyboard controlled by an Intel 8042 chip on
I/O port 0x60, generating IRQ1 and then interrupt 9 on each key press. This is
harder than it sounds because a real 8042 returns scan codes rather than the
ASCII characters which the C standard I/O functions return. Rather than make the
emulator less portable and use <code>ioctl(2)</code> or platform-dependent equivalents to obtain
real scan codes from the keyboard, the emulator BIOS does the reverse of a real
PC BIOS and converts ASCII characters to scan codes, simulating depress/release of
the modifier keys (e.g. shift) as necessary to work like a “real” keyboard. The
OS (DOS/Windows) then converts them back to ASCII characters and although this
process normally works seamlessly don’t be surprised if there are issues, for
example, with non-QWERTY e.g. international keyboards.</p>
<p>Most of the time you can just type normally, but there are special sequences to
get <code>Alt+xxx</code> and <code>Fxxx</code>.</p>
<p>To send an <code>Alt+XXX</code> key combination, press (<code>^A</code> / <code>Ctrl+A</code>) then the key, so
for example to type <code>Alt+F</code>, press (<code>^A</code> / <code>Ctrl+A</code>) then <code>F</code>.</p>
<p>To send an <code>Fxx</code> key, press <code>^F</code> / <code>Ctrl+F</code> then a number key. For example, to
get the <code>F4</code> key, press <code>^F</code> / <code>Ctrl+F</code> then <code>4</code>. To get <code>F10</code>, press <code>^F</code> /
<code>Ctrl+F</code> then <code>0</code>.</p>
<p>To send a <code>Page Down</code> key, press <code>^F</code> / <code>Ctrl+F</code> then <code>O</code> (letter O, not digit
zero). To send a <code>Page Up</code> key, press <code>^F</code> / <code>Ctrl+F</code> then <code>E</code>. Other key
combinations are left for the discovery of the user.</p>
<h3 id="text-mode-support">Text mode support</h3>
<p>The emulator supports both text output via the standard BIOS interrupt 0x10
interface, and also direct video memory access (one page, 4KB video RAM at
segment <code>B800</code>) in <code>80x25 CGA 16-color</code> text mode.</p>
<p>BIOS text output calls are converted to simple writes to <code>stdout</code>. Direct video
memory accesses for the <code>80x25 CGA color</code> text mode are converted to ANSI
terminal escape sequences. If you are using a terminal which does not support
ANSI (e.g. you are compiling the emulator with <code>MS VC++</code> and running in a
Windows console window) then PC applications that directly write to video memory
in text mode might be unusable.</p>
<p>Most <code>CGA I/O</code> ports are not supported except for the <code>CGA refresh</code> register at
<code>0x3DA</code>, which some applications use for timing or synchronisation.</p>
<p>The regular PC character code page (<code>437</code>) includes various extended ASCII
characters for things like line drawing. You might want to set the font in your
terminal program to something that includes these (e.g. on Mac OS X there is a
freeware font called <a href="https://www.dafont.com/perfect-dos-vga-437.font">Perfect DOS VGA
437</a> which does the trick).</p>
<p>Occasionally a DOS application on exit will leave the video hardware in an odd
state which confuses the emulator, resulting in subsequent text output being
invisible. If this happens, just use the DOS <code>CLS</code> command to clear the screen
and all will be well again.</p>
<h3 id="graphics-mode-support">Graphics mode support</h3>
<p><a href="https://en.wikipedia.org/wiki/Hercules_Graphics_Card">Hercules 720x348 monochrome graphics
mode</a> emulation is
implemented using SDL. Most Hercules features are supported via the normal I/O
interface on ports <code>0x3B8</code> and <code>0x3BA</code> including video memory bank switching
(segments <code>B000</code>/<code>B800</code>), which some games use for double-buffered graphics. CGA
graphics modes are not supported.</p>
<p>When an application enters graphics mode, the emulator will open an SDL window
(which will be closed when the application goes back to text mode). Including
code to redirect keystrokes from the SDL window to the main terminal window
would have busted the IOCCC size limits, so you need to keep the main emulator
terminal window in focus at all times even when you are doing graphics (sounds a
little odd but you will get used to it).</p>
<p>On Unices, SDL will automatically output graphics via X11 if the DISPLAY
environment variable is set up.</p>
<h3 id="dual-graphics-card-support">Dual graphics card support</h3>
<p>Some applications (e.g. AutoCAD) support a PC configuration with a CGA card and
a Hercules card, for simultaneous text and graphics output on different
displays. The emulator simulates this configuration, too, using separate windows
for the (terminal) text and (SDL) graphics displays.</p>
<h3 id="bios">BIOS</h3>
<p>Like a real PC, the emulator needs a BIOS to do anything useful. Here we use a
custom BIOS, written from scratch specifically for the emulator. Source code for
the BIOS (written in 8086 assembly language) which compiles with the
freely-available NASM x86 assembler is in <a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/bios.asm">bios.asm</a>.</p>
<p>The BIOS implements the standard interrupt interfaces for video, disk, timer,
clock and so on, much as a “real” PC BIOS does, and also a small
timer-controlled video driver to convert video memory formatting into ANSI
escape sequences when the emulator is in text mode.</p>
<h3 id="cpu-and-memory-emulation">CPU and memory emulation</h3>
<p>Memory map is largely as per a real PC, with interrupt vector table at <code>0:0</code>,
BIOS data area including keyboard buffer at <code>40:0</code>, CGA text video memory at
<code>B800:0</code>, Hercules dual-bank graphics memory at <code>B000</code>/<code>B800:0</code>, and BIOS at
<code>F000:100</code>. Unlike a real PC, in the emulator the CPU registers are
memory-mapped (at <code>F000:0</code>), which enables considerable optimisation of the
emulator’s instruction execution unit by permitting the unification of memory
and register operations, while remaining invisible to the running software.</p>
<p>The CPU supports the full 8086/186 instruction set. Due to the complexities of
the 8086’s arbitrary-length instruction decoding and flags, 8086 instructions
are first converted to a simpler intermediate format before being executed. This
conversion, along with instruction lengths and how each instruction modifies the
flags, is assisted by some lookup tables which form part of the BIOS binary.</p>
<p>The CPU also implements some “special” two-byte opcodes to help the emulator
talk with the outside world. These are:</p>
<ul>
<li><code>0F 00</code> - output character in register <code>AL</code> to terminal.</li>
<li><code>0F 01</code> - write real-time clock data (as returned by <code>localtime()</code>) to memory
location <code>ES:BX</code>.</li>
<li><code>0F 02</code> - read <code>AX</code> bytes from disk at offset <code>512*(16*SI+BP)</code> into memory
location <code>ES:BX</code>. Disk is specified in <code>DL</code> (<code>0</code> = hard disk, <code>1</code> = floppy
disk).</li>
<li><code>0F 03</code> - write <code>AX</code> bytes at memory location <code>ES:BX</code> to disk at offset
<code>512*(16*SI+BP)</code>. Disk is specified in <code>DL</code> as per <code>0F 02</code>.</li>
</ul>
<p>Emulator exit is triggered if <code>CS:IP == 0:0</code> (which would be nonsensical in real
software since this is where the interrupt vector table lives). The supplied
<code>fd.img</code> disk includes a small program <code>QUITEMU.COM</code> which contains a single
<code>JMP 0:0</code> instruction, to allow the user to easily quit the emulator without
shutting down the terminal.</p>
<h3 id="floppy-disk-support">Floppy disk support</h3>
<p>Emulates a 3.5” high-density floppy drive. Can read, write and format 1.44MB
disks (18 sectors per track, 2 heads) and 720KB disks (9 sectors per track, 2
heads).</p>
<p>If you want to install your own software from floppy images (downloaded from
e.g., vetusware.com at one time), the easiest way to “change disks” is
to copy each disk image in turn over the floppy image file you specify on the
command line. Don’t forget to put your original boot disk back at the end!</p>
<h3 id="hard-disk-support">Hard disk support</h3>
<p>Supports up to 1023 cylinders, 63 sectors per track, 63 heads for disks up to
528MB.</p>
<p>Disk image format used is a subset of the standard “raw” format used by most
disk image mount tools. In general, disk images prepared by the emulator will
work with disk image tools and other emulators, but not the other way around.</p>
<p>The emulator uses a particularly dumb algorithm to derive a simulated
cylinder/sector/head geometry from the disk image file’s size. This algorithm
often results in not all the space in the image file being available for disk
partitions. For example, creating a 40,000,000 byte image file results in <code>DOS FDISK</code> seeing only 31.9MB as the volume size.</p>
<p>Note that unlike a real PC, the emulator cannot boot from a hard disk (image).
Therefore, you will always need to use a bootable floppy image, even if after
boot everything runs from the HD.</p>
<h3 id="mouse">Mouse</h3>
<p>No mouse is emulated.</p>
<h3 id="real-time-clock">Real-time clock</h3>
<p>Reading the <a href="https://en.wikipedia.org/wiki/Real-time_clock">RTC</a> (both time and
date) is emulated via the standard BIOS clock interface, pulling the time/date
from the host computer. Setting the time or date is not supported.</p>
<h3 id="timers">Timers</h3>
<p>A countdown timer on I/O port <code>0x40</code> is simulated in a broken way which is good
enough for most software. On a real PC this has a default period of 55ms and is
programmable. No programmability is supported in the emulator and the period may
be about right or completely wrong depending on the actual speed of your
computer.</p>
<p>On a real PC, IRQ 0 and interrupt 8 are fired every 55ms. The emulator tries to
do the same but again, the delay period is not calibrated so you get what you
get.</p>
<h3 id="pc-speaker">PC speaker</h3>
<p>Beeps only, through the console.</p>
<h3 id="software-supported">Software supported</h3>
<p>The emulator will run practically any software a real PC (of the spec listed at
the top of this file) can. The author has tested a number of OSes/GUIs (MS-DOS
6.22, FreeDOS 0.82pl3, Windows 3.0, DESQview 2.8), professional software (Lotus
1-2-3 2.4 and AsEasyAs 5.7 for DOS, Excel 2.1 for Windows, AutoCAD 2.5, WordStar
4), programming languages (QBASIC, GWBASIC, Turbo C++), games (Carrier Command,
Police Quest, and a bunch of freeware Windows games), and diagnostic/benchmark
software (Manifest, Microsoft MSD, InfoSpot, CheckIt) and all of them run well.</p>
<p>Screenshots of some of these applications running (on Mac OS X) are provided for
the impatient:</p>
<p><img src="screenshot_autocad.png"
alt="screenshot image of autocad of St. Paul's Cathedral"
width=748 height=400></p>
<p><img src="screenshot_autocad.png"
alt="screenshot image from a Flight Simulator"
width=748 height=400></p>
<p><img src="screenshot_lotus123.png"
alt="screenshot image Lotus 123 color test"
width=748 height=400></p>
<p><img src="screenshot_qbasic.png"
alt="screenshot image of the welcome message from MS-DOS QBasic"
width=859 height=540></p>
<p><img src="screenshot_simcity.png"
alt="screenshot image from the Sim City game"
width=748 height=400></p>
<p><img src="screenshot_win3.png"
alt="screenshot image of Windows 3.00a under macOS"
width=748 height=400></p>
<h3 id="compiler-warnings">Compiler warnings</h3>
<p>A lot of compiler warnings are produced by clang. Missing type specifiers,
control reaching the end of functions without returning values, incompatible
pointer type assignments, and some precedence warnings, all necessary to keep
the source size down. Other compilers are likely to produce similar warnings.</p>
<!--
Copyright © 1984-2024 by Landon Curt Noll. All Rights Reserved.
You are free to share and adapt this file under the terms of this license:
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/
-->
<!-- AFTER: last line of markdown file: 2013/cable3/README.md -->
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
<div id="inventory">
<h1 id="inventory-for-2013cable3">Inventory for 2013/cable3</h1>
</div>
<h2 id="primary-files">Primary files</h2>
<ul>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/cable3.c">cable3.c</a> - entry source code</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/Makefile">Makefile</a> - entry Makefile</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/cable3.alt.c">cable3.alt.c</a> - alternate source code</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/cable3.orig.c">cable3.orig.c</a> - original source code</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/cable3.sh">cable3.sh</a> - script to run entry</li>
<li><a href="screenshot_autocad.png">screenshot_autocad.png</a> - screenshot of AUTOCAD running on macOS</li>
<li><a href="screenshot_flightsim4.png">screenshot_flightsim4.png</a> - screenshot of Flight Sim 4 running on macOS</li>
<li><a href="screenshot_lotus123.png">screenshot_lotus123.png</a> - screenshot of Lotus123 running on macOS</li>
<li><a href="screenshot_qbasic.png">screenshot_qbasic.png</a> - screenshot of QBasic running on macOS</li>
<li><a href="screenshot_simcity.png">screenshot_simcity.png</a> - screenshot of SimCity running on macOS</li>
<li><a href="screenshot_win3.png">screenshot_win3.png</a> - screenshot of Win3 running on macOS</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/sc-ioccc.terminal">sc-ioccc.terminal</a> - config for macOS to correctly display ANSI graphics apps</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/bios.asm">bios.asm</a> - BIOS source in assembly</li>
</ul>
<h2 id="secondary-files">Secondary files</h2>
<ul>
<li><a href="2013_cable3.tar.bz2">2013_cable3.tar.bz2</a> - download entry tarball</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/README.md">README.md</a> - markdown source for this web page</li>
<li><a href="bios">bios</a> - custom BIOS</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/.entry.json">.entry.json</a> - entry summary and manifest in JSON</li>
<li><a href="fd.img">fd.img</a> - FreeDOS boot disk</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
<li><a href="hd.img">hd.img</a> - disk image</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2013/cable3/.path">.path</a> - directory path from top level directory</li>
<li><a href="index.html">index.html</a> - this web page</li>
</ul>
<hr style="width:10%;text-align:left;margin-left:0">
<h4>
Jump to: <a href="#">top</a>
</h4>
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
<!-- END: this line ends content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
<!-- START: this line starts content from: inc/after-content.default.html -->
</div>
<!-- END: this line ends content from: inc/after-content.default.html -->
<!-- START: this line starts content from: inc/footer.inventory.html -->
<!--
Copyright © 1984-2025 by Landon Curt Noll. All Rights Reserved.
You are free to share and adapt this file under the terms of this license:
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/
-->
<div class="footer">
<div id="copyright"><h3>Copyright &copy; 1984-2025 by Landon Curt Noll:
<a href="https://creativecommons.org/faq/#what-does-some-rights-reserved-mean"
target="_blank"
rel="license noopener noreferrer">Some Rights Reserved</a></h3>
<p>
This work is <b>licensed by Landon Curt Noll</b> under
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1"
target="_blank"
rel="license noopener noreferrer"
style="display:inline-block;">CC BY-SA 4.0</a></b>.
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/cc.png"
alt="cc inside circle symbol">
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/by.png"
alt="person inside circle symbol">
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/sa.png"
alt="arrow looping back on itself inside circle symbol"><br>
You should <b>carefully review</b> the
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/legalcode.en"
target="_blank"
rel="license noopener noreferrer">CC BY-SA 4.0 LEGAL CODE</a></b>
before using the licensed material.<br>
You may wish to review the
<b><a href="../../license.html"
target="_blank"
rel="license noopener noreferrer">highlights of some of the key features and terms</a></b>
of <b>CC BY-SA 4.0</b>.<br>
</p>
</div>
<div id="coda"><h3>Coda</h3>
<p>
<a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fwww.ioccc.org%2F2013%2Fcable3%2Findex.html" rel="nofollow">Nu HTML check this web page</a><br>
<a href="#top">Jump to top</a> <a href="#content">Jump to Content</a> <a href="#inventory">Jump to Inventory</a><br>
</p>
</div>
</div>
<!-- END: this line ends content from: inc/footer.inventory.html -->
<!-- START: this line starts content from: inc/bottom.default.html -->
</body>
</html>
<!-- END: this line ends content from: inc/bottom.default.html -->