diff --git a/404.md b/404.md deleted file mode 100644 index 5e3d75792..000000000 --- a/404.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: page -title: Page Not Found -permalink: /404.html ---- - -{% include random-publication.html text="This is not the page you are looking for. You found a piece of paper instead." %} diff --git a/CNAME b/CNAME deleted file mode 100644 index 6283f0c5a..000000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -www.pcjs.org diff --git a/Gemfile b/Gemfile deleted file mode 100644 index b002ff5fd..000000000 --- a/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source 'https://rubygems.org' -gem 'github-pages' -gem 'jekyll-sitemap' -gem 'jekyll-redirect-from' diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 141fb80be..000000000 --- a/_config.yml +++ /dev/null @@ -1,128 +0,0 @@ -# Site settings - -title: "PCjs Machines" -email: Jeff@pcjs.org -description: > - PCjs: Home of the original IBM PC emulator in a browser. - Classic computer simulations in JavaScript, including the IBM PC and other x86-based machines, 6502-based - machines such as the Ohio Scientific Challenger 1P, and 8080-based machines such as Space Invaders. - Includes an archive of historical PC software and publications. -baseurl: "" # "/pcjs" when using http://jeffpar.github.io or "" when using http://www.pcjs.org -url: "http://www.pcjs.org" # "http://jeffpar.github.io" or "http://www.pcjs.org" -twitter_username: jeffpar -github_username: jeffpar - -left_brace: "{" -right_brace: "}" -encoding: UTF-8 - -# Build settings - -exclude: ["**/index.html", "**/archive", "**/c64", "logs", "node_modules", "projects", "src", "**/src", "tmp", "**/tmp", "videos", "web", ".git", ".idea"] -markdown: kramdown -kramdown: - input: GFM - hard_wrap: false - -gems: - - jekyll-sitemap - - jekyll-redirect-from - -# Custom site settings - -pcjs: - domain: pcjs.org # whereas site.url is used for linking purposes, site.pcjs.domain is used for display purposes - version: 1.23.2 # IMPORTANT: keep pcjs.version in sync with package.json:version - compiled: true # by default, the compiled pcjs.version scripts will be used (eg, pcx86.js or pcx86-dbg.js) - c1p_scripts: # if pcjs.compiled is false, the following scripts will be included instead, in the order listed - - /modules/shared/lib/defines.js - - /modules/shared/lib/nodebug.js - - /modules/shared/lib/dumpapi.js - - /modules/shared/lib/reportapi.js - - /modules/shared/lib/strlib.js - - /modules/shared/lib/usrlib.js - - /modules/shared/lib/weblib.js - - /modules/shared/lib/component.js - - /modules/c1pjs/lib/defines.js - - /modules/c1pjs/lib/panel.js - - /modules/c1pjs/lib/cpu.js - - /modules/c1pjs/lib/rom.js - - /modules/c1pjs/lib/ram.js - - /modules/c1pjs/lib/keyboard.js - - /modules/c1pjs/lib/video.js - - /modules/c1pjs/lib/serial.js - - /modules/c1pjs/lib/disk.js - - /modules/c1pjs/lib/debugger.js - - /modules/c1pjs/lib/computer.js - - /modules/shared/lib/embed.js - pcx86_scripts: - - /modules/shared/lib/defines.js - - /modules/shared/lib/nodebug.js - - /modules/shared/lib/diskapi.js - - /modules/shared/lib/dumpapi.js - - /modules/shared/lib/reportapi.js - - /modules/shared/lib/userapi.js - - /modules/shared/lib/strlib.js - - /modules/shared/lib/usrlib.js - - /modules/shared/lib/weblib.js - - /modules/shared/lib/component.js - - /modules/pcx86/lib/defines.js - - /modules/pcx86/lib/x86.js - - /modules/pcx86/lib/interrupts.js - - /modules/pcx86/lib/messages.js - - /modules/pcx86/lib/panel.js - - /modules/pcx86/lib/bus.js - - /modules/pcx86/lib/memory.js - - /modules/pcx86/lib/cpu.js - - /modules/pcx86/lib/x86seg.js - - /modules/pcx86/lib/x86cpu.js - - /modules/pcx86/lib/x86fpu.js - - /modules/pcx86/lib/x86func.js - - /modules/pcx86/lib/x86help.js - - /modules/pcx86/lib/x86mods.js - - /modules/pcx86/lib/x86ops.js - - /modules/pcx86/lib/x86op0f.js - - /modules/pcx86/lib/chipset.js - - /modules/pcx86/lib/rom.js - - /modules/pcx86/lib/ram.js - - /modules/pcx86/lib/keyboard.js - - /modules/pcx86/lib/video.js - - /modules/pcx86/lib/parallelport.js - - /modules/pcx86/lib/serialport.js - - /modules/pcx86/lib/mouse.js - - /modules/pcx86/lib/disk.js - - /modules/pcx86/lib/fdc.js - - /modules/pcx86/lib/hdc.js - - /modules/pcx86/lib/debugger.js - - /modules/pcx86/lib/state.js - - /modules/pcx86/lib/computer.js - - /modules/shared/lib/embed.js - - /modules/shared/lib/save.js - pc8080_scripts: - - /modules/shared/lib/defines.js - - /modules/shared/lib/dumpapi.js - - /modules/shared/lib/reportapi.js - - /modules/shared/lib/userapi.js - - /modules/shared/lib/strlib.js - - /modules/shared/lib/usrlib.js - - /modules/shared/lib/weblib.js - - /modules/shared/lib/component.js - - /modules/pc8080/lib/defines.js - - /modules/pc8080/lib/cpudef.js - - /modules/pc8080/lib/messages.js - - /modules/pc8080/lib/panel.js - - /modules/pc8080/lib/bus.js - - /modules/pc8080/lib/memory.js - - /modules/pc8080/lib/cpu.js - - /modules/pc8080/lib/cpustate.js - - /modules/pc8080/lib/cpuops.js - - /modules/pc8080/lib/chipset.js - - /modules/pc8080/lib/rom.js - - /modules/pc8080/lib/ram.js - - /modules/pc8080/lib/keyboard.js - - /modules/pc8080/lib/video.js - - /modules/pc8080/lib/debugger.js - - /modules/pc8080/lib/state.js - - /modules/pc8080/lib/computer.js - - /modules/shared/lib/embed.js - - /modules/shared/lib/save.js diff --git a/_developer.yml b/_developer.yml deleted file mode 100644 index 5e7352f02..000000000 --- a/_developer.yml +++ /dev/null @@ -1,4 +0,0 @@ -developer: true -url: "http://localhost:4000" -pcjs: - compiled: false diff --git a/_includes/breadcrumbs.html b/_includes/breadcrumbs.html deleted file mode 100644 index 522446d67..000000000 --- a/_includes/breadcrumbs.html +++ /dev/null @@ -1,11 +0,0 @@ -{% capture page_url_without_index_html %}{{ page.url | remove: "/index.html" | remove: "/404.html" }}{% endcapture %} -{% assign splitted_url_parts = page_url_without_index_html | split: '/' %} -{% capture forLoopMaxInt %}{{ splitted_url_parts.size | minus:1 }}{% endcapture %} -{% for i in (1..forLoopMaxInt) %} - {% capture url %}{{ url }}{{ splitted_url_parts[i] }}/{% endcapture %} - {% capture path %}{{ path }}\{{ splitted_url_parts[i] | upcase }}{% endcapture %} - {% if splitted_url_parts[i] == "blog" %} - {% break %} - {% endif %} -{% endfor %} -
subscribe via RSS
- -
](/blog/images/halt-and-catch-liar.jpg)
-
-So if you deconstruct the code on this whiteboard, you quickly notice that while it IS assembly language, it is
-NOT the sort of assembly language you would find in a ROM BIOS, let alone ANYTHING that would leave you in awe.
-
-Here are some excerpts:
-
- Initialization
- MOV AX,CX ; set up DS
- MOV DS,AX
- MOV SS,AX ; and SS
- LEA AX,BEGINSTACK
- MOV SP,AX
- MOV AL,OUTINT
- ...
- TSTART
- LEA AX,BEGTRACE
- MOV POINT,AX
- MOV AL,YES ; TURN TRACE ON
- MOV TFLAG,AL
- MOV AL,NO ; NOT WRAPPED
- MOV WRAP,AL
- MOV AX,CS ; CONVERT ADDRESS FOR OUTPUT
- LEA SI,LOADCS
- CALL HEXPRT
- MOV AX,100H
- LEA SI,LOADIP
- CALL HEXPRT
- LEA DX,SIGNIN
- MOV AH,9
- INT DOSINT
- LEA DX,OUTPUT
- MOV AL,OUTPUT (?)
- MOV AH,25H ; Set Interrupt Vector
- INT DOSINT ; Have DOS place the interrupt...
- ...
-
-This is clearly **NOT** code for a PC ROM BIOS, because no PC BIOS would ever issue a DOS interrupt.
-A BIOS is designed to be called *by* DOS, not the other way around.
-
-This turns out to be code largely copied from a file I found online: [PCTRACE.ASM](http://ftpmirror.your.org/pub/misc/dos/RbbsInABoxVol1No2_640/files/007P/PCTRACE.ZIP-contents/PCTRACE.ASM)
-
-Another curiosity is that searching for this resulted in a "[Googlewhack](http://en.wikipedia.org/wiki/Googlewhack)"
-of sorts:
-
-
-
-Technically, a Googlewhack (a two-word search that yields exactly one result) must use two words found in an actual
-dictionary. But dictionaries are so passé.
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*June 14, 2014*
diff --git a/_posts/2014-06-26-more-under-the-hood-changes.md b/_posts/2014-06-26-more-under-the-hood-changes.md
deleted file mode 100644
index e6d718aa9..000000000
--- a/_posts/2014-06-26-more-under-the-hood-changes.md
+++ /dev/null
@@ -1,18 +0,0 @@
----
-layout: post
-title: More Under-The-Hood Changes
-date: 2014-06-26 11:00:00
-category: Releases
-permalink: /blog/2014/06/26/
----
-
-v1.13.7 of PCjs contains a few minor improvements, mostly in terms of rendering video modes a little more
-efficiently. The rest of the changes to the website involved beefing up support for both "software manifests"
-and "document manifests."
-
-To that end, there's a new [/pubs/](/pubs/) directory for old documents, and [/disks/pcx86/](/disks/pcx86/) contains
-more disk images, with more on the way. I have a TON of old diskette images, and it has taken more time to organize
-them and create manifests than I would like.
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*June 26, 2014*
diff --git a/_posts/2014-07-30-ega-support.md b/_posts/2014-07-30-ega-support.md
deleted file mode 100644
index 2425209e2..000000000
--- a/_posts/2014-07-30-ega-support.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-layout: post
-title: EGA Support
-date: 2014-07-30 11:00:00
-category: Video
-permalink: /blog/2014/07/30/
----
-
-PCjs v1.14.0 now includes basic EGA support. It emulates the EGA hardware well enough to pass the IBM EGA BIOS
-diagnostics and run [Windows 1.01](/devices/pcx86/machine/5160/ega/640kb/win101/) in color. Check out our
-[Windows 1.01 "Server Array"](/devices/pcx86/machine/5160/ega/640kb/array/) demo.
-
-[
](/blog/images/win101-array-demo.jpg)
-
-EGA support is added to a **machine.xml** file using two XML elements; eg:
-
-```xml
-
-```
-
-The *model* attribute must be set to "ega" and the *memory* attribute should be set to the amount of memory
-desired on the card; valid memory sizes are:
-
-- 0x10000 (64Kb)
-- 0x20000 (128Kb)
-- 0x40000 (256Kb)
-
-As with the MDA and CGA video cards, the *screenwidth* and *screenheight* attributes specify the size of display
-window, which the browser will then scale up or down, unless a specific overall size has been specified on the
-<machine> element.
-
-The second required XML element is a <rom> element to load the EGA ROM; eg:
-
-```xml
-
](/disks/pcx86/os2/misc/1.0/88286/)
-
-As an added bonus, the Model 5170 machines feature two serial ports, with COM1 connected to a simulated serial
-mouse and COM2 connected to the **Control Panel** output window.
-
-Once you've booted the [OS/2 1.0 Debugger Disk](/disks/pcx86/os2/misc/1.0/88286/) from the assortment of
-[OS/2 Prototype Disks](/disks/pcx86/os2/misc/), you can click on the **Control Panel** output window, press Ctrl-C, and
-find yourself magically transported into the OS/2 Kernel Debugger. The **Control Panel** display is functioning
-as both the output window for all PCjs messages and PCjs Debugger commands, as well as a serial input/output device
-(aka "Dumb Terminal") for any software inside the machine communicating via COM2: in this case, the OS/2 Kernel Debugger.
-
-> SIDEBAR: You can perform similar tricks with DOS in these machines. Boot any DOS disk (version 2.00 and up)
-and type "CTTY COM2" at the DOS prompt. All DOS input/output will now be routed to the **Control Panel** display.
-To restore control to the the machine's keyboard and video display, type "CTTY CON".
-
-Type "?" for a list of all OS/2 Kernel Debugger commands. Type "g" to continue running OS/2. Make sure you type all
-OS/2 Kernel Debugger commands into the **Control Panel** output window. Commands typed into the input box *beneath*
-the output window are processed only by the PCjs Debugger.
-
-When a fault occurs, OS/2 normally displays a "TRAP" message; however, when the Kernel Debugger is running, it
-intercepts the fault and displays the faulting instruction. But the PCjs Debugger has ultimate control: using
-the "m fault on" and "m halt on" commands, the PCjs Debugger will display and halt on any fault first. If you want
-PCjs to deliver the fault to OS/2, single-step over the faulting instruction and then continue.
-
-There are still a number of known issues running OS/2. For example, when attempting to install OS/2 1.0 from the
-installation diskette images onto a hard disk image, OS/2 successfully formats the hard disk and copies the files from
-the first two diskettes, but usually while copying files from either the second or third diskette, the process stops.
-There's no crash -- it simply stops copying files and never finishes. My best guess at this point is that some
-interrupts are being dropped.
-
-Similarly, if a machine running OS/2 1.0 is left unattended for a few minutes, it may stop responding. Again, there's
-no crash or other indication of a problem. The machine simply appears hung. "Ctrl-Alt-Del" and "Reset" buttons still
-work.
-
-The journey continues.
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*December 4, 2014*
diff --git a/_posts/2014-12-05-canvas-performance-and-contenteditable.md b/_posts/2014-12-05-canvas-performance-and-contenteditable.md
deleted file mode 100644
index f4df0f7ff..000000000
--- a/_posts/2014-12-05-canvas-performance-and-contenteditable.md
+++ /dev/null
@@ -1,71 +0,0 @@
----
-layout: post
-title: Canvas Performance and ContentEditable
-date: 2014-12-05 11:00:00
-category: HTML5
-permalink: /blog/2014/12/05/
----
-
-From the beginning of the [JavaScript Machines](/docs/about/) Project, I've always used an HTML5
-[Canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) object for both machine output
-and input. It's the obvious choice for output, because the Canvas provides a 2D drawing API that's
-essential both for drawing bitmappped graphics and for faithfully rendering individual characters
-using the machine's original bitmapped fonts.
-
-The Canvas is perhaps a less obvious choice for input, but the theory was that by adding a
-"[contenteditable](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_Editable)" attribute
-to the Canvas object, the user could simply click (or tap) the Canvas to give it focus, and then all the
-usual *onkeydown*, *onkeyup*, and *onkeypress* event handlers would work as expected. The advantage of
-this approach is that it eliminated the need for another on-screen control that would no serve no visual
-purpose.
-
-The "contenteditable" attribute had some issues, but mainly only on mobile devices, so I left those
-issues for another day. For example, using PCjs on an Android device is problematic, in part because
-it doesn't honor the "contenteditable" attribute on a Canvas, but also because Android's built-in
-"soft keyboard" doesn't deliver any keys to the application until you press Enter. So for now, you
-have to use PCjs machines that come with their own "soft keyboard".
-
-However, today I noticed an oddity with Safari on the desktop. For the most part, Safari and Chrome
-perform comparably, and are generally the best browsers to use with PCjs. Firefox used to be a great
-option a couple years ago, but ever since Mozilla started focusing heavily -- perhaps *too* heavily -- on
-[asm.js](http://asmjs.org/) performance, they seem to have fallen behind in overall performance.
-
-But I digress. What I noticed in Safari was that text-scrolling in both DOS and OS/2 was significantly
-slower than Chrome. This seemed very odd -- they should have been almost equally fast. Then I made
-an important discovery: while the machine was scrolling, if I clicked on some other part of the page,
-taking focus *away* from the Canvas, scrolling dramatically sped up. When I clicked on the Canvas
-again, it slowed way down again.
-
-Long story short: when I removed the "contenteditable" attribute from the Canvas, drawing performance
-was consistently fast. The only problem, of course, is that I couldn't type anything into the machine.
-
-So I resurrected some old code I'd written that creates a transparent
-<[textarea](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea)> on top of the Canvas,
-and now I use the <textarea> to provide all keyboard, mouse, and touch events (and pointer locking,
-for the handful of browsers that support it).
-
-That seemed to work well, until I tested Safari on an iPad, where I noticed a blinking cursor in the top
-left corner of the machine's screen; that is, the top left corner of the transparent <textarea>. I tried
-all sorts of work-arounds suggested online -- setting the textarea's "color" attribute to "transparent",
-on the theory that the cursor used the same color, or setting the "cursor" attribute to "none" -- but none
-of those work-arounds seemed to, um, work.
-
-I had almost settled on adding iOS detection code, and reverting to the old Canvas input code for iOS only,
-when I noticed that even a Canvas on iOS displayed a blinking cursor -- it was just slightly less annoying
-because the cursor was flush with the left edge of the Canvas. More importantly, it was also as tall as
-the full height of the Canvas.
-
-At this point, it seemed clear that iOS was trying to display the cursor based on what it believed the
-line height to be (ie, the full height of the Canvas). So I switched back to the transparent <textarea>
-again, set its "line-height" attribute to zero, and viola: no more blinking cursor.
-
-So that, in a nutshell, is why v1.16.2 of PCjs comes one day after v1.16.1: because I happened to noticed
-that drawing performance in desktop Safari was suffering, and that there was a fairly straightforward solution.
-
-Safari's behavior should probably be considered a bug, as it's probably doing something it shouldn't,
-like trying to account for an "invisible" blinking cursor. Chrome certainly doesn't have this problem,
-so unless I was the only person in the world who used "contenteditable" Canvases, this is probably something
-Safari will want to fix.
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*December 5, 2014*
diff --git a/_posts/2015-01-17-pcjs-uncompiled.md b/_posts/2015-01-17-pcjs-uncompiled.md
deleted file mode 100644
index f22c6b315..000000000
--- a/_posts/2015-01-17-pcjs-uncompiled.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-layout: post
-title: PCx86 Uncompiled
-date: 2015-01-17 11:00:00
-category: Features
-permalink: /blog/2015/01/17/
-machines:
- - type: pcx86
- id: at-ega-1152k-rev3
- debugger: true
- uncompiled: true
- config: /devices/pcx86/machine/5170/ega/1152kb/rev3/debugger/machine.xml
----
-
-Most PCx86 machines on [{{ site.pcjs.domain }}](/) run with a compiled version of PCx86, which is produced
-by running the PCx86 JavaScript source code through Google's Closure Compiler, yielding a smaller (minified)
-version that loads and runs much faster than the original source code.
-
-However, certain features are disabled in the compiled versions, including a new BACKTRACK feature that
-makes it possible to track the contents of memory locations and registers back to their source (eg, to a ROM
-or file location). Once the BACKTRACK feature is finished, it will be folded into the compiled code, but until
-then, the only way to experiment with it is by running the uncompiled code.
-
-To make it easier to launch machines with uncompiled code, a PCx86 machine definition can now set `uncompiled`
-to *true*, overriding the value of `site.pcjs.compiled` in **_config.yml**.
-
-Here's what a typical Markdown file would look like:
-
-{% raw %}
- ---
- ...
- machines:
- - type: pcx86
- id: at-ega-1152k-rev3
- debugger: true
- uncompiled: true
- config: /devices/pcx86/machine/5170/ega/1152kb/rev3/debugger/backtrack/machine.xml
- ---
- ...
- {% include machine.html id="at-ega-1152k-rev3" %}
-{% endraw %}
-
-In fact, that's what we've done in the Markdown file you are reading right now.
-
-{% include machine.html id="at-ega-1152k-rev3" %}
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*January 17, 2015 (Updated December 10, 2015 to reflect the new `uncompiled` property)*
diff --git a/_posts/2015-01-28-new-pcjs-control-panel.md b/_posts/2015-01-28-new-pcjs-control-panel.md
deleted file mode 100644
index e93ff21ce..000000000
--- a/_posts/2015-01-28-new-pcjs-control-panel.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-layout: post
-title: New PCx86 Control Panel
-date: 2015-01-28 11:00:00
-category: Control Panel
-permalink: /blog/2015/01/28/
-machines:
- - type: pcx86
- id: at-ega-1152k-rev3
- debugger: true
- uncompiled: true
- config: /devices/pcx86/machine/5170/ega/1152kb/rev3/debugger/backtrack/machine.xml
----
-
-A new PCx86 Control Panel is under development, featuring a new "Display Panel" that will provide a variety of
-information about the machine, in real-time, and operate more efficiently than previous DOM-based Control Panels.
-
-A preview of the layout is shown below. There's not much to see yet, as this is very much a work-in-progress.
-
-{% include machine.html id="at-ega-1152k-rev3" %}
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*January 28, 2015*
diff --git a/_posts/2015-02-22-compaq-deskpro-386.md b/_posts/2015-02-22-compaq-deskpro-386.md
deleted file mode 100644
index be644ef22..000000000
--- a/_posts/2015-02-22-compaq-deskpro-386.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-layout: post
-title: COMPAQ DeskPro 386
-date: 2015-02-22 11:00:00
-category: 80386
-permalink: /blog/2015/02/22/
-machines:
- - type: pcx86
- id: deskpro386
- debugger: true
- uncompiled: true
- config: /devices/pcx86/machine/compaq/deskpro386/ega/2048kb/debugger/machine.xml
----
-
-I finally dumped the [COMPAQ DeskPro 386/16 ROMs](/devices/pcx86/rom/compaq/deskpro386/) from the motherboard I bought
-on ebay last year, so I'm ready to begin adding 80386 support to PCx86.
-
-I'd also like to locate a copy of the "COMPAQ DeskPro 386 Technical Reference Guide, Volumes 1 and 2". It's not hard
-to find COMPAQ Maintenance and Service guides online, but their Technical Reference guides are much rarer, perhaps because
-they were expensive ($149) and not many were sold. Anyway, I'm hoping to either borrow or buy a copy, and then scan and
-post it.
-
-A [COMPAQ DeskPro 386](/devices/pcx86/machine/compaq/deskpro386/ega/2048kb/debugger/) test configuration is displayed below.
-The configuration doesn't run, and the debugger can't disassemble 80386-specific code yet, but this is what I will be
-using to test and debug my changes over the next few months.
-
-{% include machine.html id="deskpro386" %}
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*February 22, 2015*
diff --git a/_posts/2015-02-23-early-80386-cpus.md b/_posts/2015-02-23-early-80386-cpus.md
deleted file mode 100644
index ae5dc2e97..000000000
--- a/_posts/2015-02-23-early-80386-cpus.md
+++ /dev/null
@@ -1,116 +0,0 @@
----
-layout: post
-title: Early 80386 CPUs
-date: 2015-02-23 11:00:00
-category: 80386
-permalink: /blog/2015/02/23/
----
-
-Assembling a detailed and accurate history of the Intel 80386 CPU, including a complete listing of all the
-"steppings" (revisions), when they were released, what "errata" (problems) each stepping suffered from, and
-which of those problems were fixed by a later stepping, seems virtually impossible at this late date.
-
-See [Intel 80386 CPU Information](/pubs/pc/reference/intel/80386/) for what the PCjs Project has been able to
-collect about 80386 steppings so far, including how some of them were externally marked and internally identified,
-along with lists of associated errata, much of it based on Intel's own documents.
-
-Of course, there's also an eclectic mix of information about early 80386 processors available from various online
-sources. A few of those are highlighted below.
-
----
-
-Excerpt from "Inside Track", [PC Magazine, February 24, 1987](https://books.google.com/books?id=phxlBt4dX3oC&lpg=PA67&pg=PA67#v=onepage),
-by John C. Dvorak:
-
-> **80386 Bug Stopper Dept.**: If you buy an 80386 machine, card, or chip, make sure you **get the B1 revision of
-the chip** or something newer (B2, B3, and so on). There are **far too many bugs** in the A1 and A2 versions of the
-chip to be acceptable. Here's what to look for: On the top line of the chip you'll see the designation A80386-16.
-If it says A80386-16ES, then it's an engineering sample and the vendor is a *cheapskate*. The samples have the revision
-number on the top line as A1, A2, or B1. Look no further.
-
-> For the rest of you, look at the second line on the chip. If it's S40344 then you have a B1 chip. S40334 is the
-A2 revision and S40276 is the A1 revision....
-
----
-
-Excerpt from "Tutor", [PC Magazine, October 15, 1991](https://books.google.com/books?id=tSLe3yMjc-AC&pg=PT438&hl=en&sa=X&ved=0ahUKEwjR9MH4gOHJAhVT0mMKHc4tD0YQ6AEIKjAA#v=onepage),
-by Jeff Prosise:
-
-> You can tell if you have a B0 or B1 Step level 386 by looking at the markings on the chip. If it has the ID number
-S40336 or S40337 stamped on it, then it's a Step B0; if it's marked with S40343, S40344, or S40362, it's a Step B1.
-Some B0 and B1 chips were marked B0 or B1 rather than with an ID number.
-
----
-
-Excerpt from "[CPU Identification by the Windows Kernel](http://www.geoffchappell.com/studies/windows/km/cpu/index.htm)", by Geoff Chappell:
-
-> Finer identification of 80386 processors is largely academic. Whatever the model or stepping, the 80386 processor
-is unsupported since [Windows NT] version 4.0, and soon causes the bug check UNSUPPORTED_PROCESSOR (0x5D), though not
-without the kernel having worked its way through more tests for defects to identify models and steppings. For any 80386
-processor that passes all tests, the model and stepping leap ahead to 3 and 1. Version 3.51, which was the last to
-support the 80386 (and only then in a single-processor configuration), rejects any 80386 that does not pass all these
-tests.
-
- Family Model Stepping Test
- ------ ----- -------- ----
- 3 0 0 32-bit MUL not reliably correct
- 3 1 0 supports XBTS instruction
- 3 1 1 set TF bit (0x0100) in EFLAGS causes Debug exception (interrupt 0x01) only at completion of REP MOVSB
- 3 3 1
-
-> The particular multiplication that distinguishes model 0 is of 0x81 by 0x0417A000. This same test was used by Microsoft
-at least as far back as Windows 3.10 Enhanced Mode, to advise:
-
- The Intel 80386 processor in this computer does not reliably execute 32-bit
- multiply operations. Windows usually works correctly on computers with this
- problem but may occasionally fail. You may want to replace your 80386 processor.
- Press any key to continue...
-
-> The instruction whose support is tested for model 1 stepping 0 has opcode bytes 0x0F 0xA6 followed by a Mod R/M byte
-and by whatever more this byte indicates is needed for the operand. This opcode is disassembled as XBTS by Microsoft’s
-DUMPBIN utility from Visual C++, and has been since at least the mid-90s. However, the same opcode was apparently reused
-for the CMPXCHG instruction on some 80486 processors. The confusion seems to have left a lasting mark: Intel’s opcode
-charts leave 0x0F 0xA6 unassigned even now. The specific test performed by the Windows kernel is to load EAX and EDX
-with zero and ECX with 0xFF00. If executing XBTS ECX,EDX does not cause an Invalid Opcode exception and clears ecx to
-zero (which CMPXCHG ECX,EDX would not), then XBTS is deemed to be supported and the processor is model 1 stepping 0.
-This case of 80386 processor also was known to Windows 3.10 Enhanced Mode, and was rejected as fatal:
-
- Windows may not run correctly with the 80386 processor in this computer.
-
- Upgrade your 80386 processor or start Windows in standard mode by typing
- WIN /s at the MS-DOS prompt.
-
-> When string instructions such as MOVSB are repeated because of a REP prefix, each operation is ordinarily interruptible.
-As Intel says (for REP in the [Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 2B: Instruction Set Reference N-Z](http://www.intel.com/design/processor/manuals/253667.pdf)),
-this “allows long string operations to proceed without affecting the interrupt response time of the system.” It ordinarily
-applies also to the Debug exception, such as raised by the processor at the end of executing an instruction for which the TF
-bit is set in the EFLAGS when the instruction started. Programmers may have noticed this in the real world of assembly-language
-debugging. If the debugger actually does implement its trace command as a trace, as opposed to setting an INT 3 breakpoint
-where the instruction is calculated to end, then a two-byte REP MOVSB may take many keystrokes to trace through! That
-model 1 stepping 1 traces through a REP MOVSB without interruption may be helpful when debugging, but it is surely a defect.
-
----
-
-More examples of problems with early 80386 CPUs are posted in "[The Old New Thing](http://blogs.msdn.com/b/oldnewthing/)"
-blog. Here are some highlights from "[My, what strange NOPs you have!](http://blogs.msdn.com/b/oldnewthing/archive/2011/01/12/10114521.aspx)",
-by Raymond Chen:
-
-> [I]f the instruction following a string operation (such as movs) uses opposite-sized addresses from that in the string
-instruction (for example, if you performed a movs es:[edi], ds:[esi] followed by a mov ax, [bx]) or if the following
-instruction accessed an opposite-sized stack (for example, if you performed a movs es:[edi], ds:[esi] on a 16-bit stack,
-and the next instruction was a push), then the movs instruction would not operate correctly....
-
-> [T]here was one bug that manifested itself in incorrect instruction decoding if a conditional branch instruction
-had just the right sequence of taken/not-taken history, and the branch instruction was followed immediately by a selector load,
-and one of the first two instructions at the destination of the branch was itself a jump, call, or return. The easy workaround:
-Insert a NOP between the branch and the selector load....
-
-> [T]he B1 stepping did not support virtual memory in the first 64KB of memory. Fine, don't use virtual memory there....
-
-> If virtual memory was enabled, if a certain race condition was encountered inside the hardware prefetch, and if you executed
-a floating point coprocessor instruction that accessed memory at an address in the range 0x800000F8 through 0x800000FF,
-then the CPU would end up reading from addresses 0x000000F8 through 0x0000000FF instead. This one was easy to work around:
-Never allocate valid memory at 0x80000xxx.
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*February 23, 2015*
diff --git a/_posts/2015-03-26-javascript-idiosyncrasies.md b/_posts/2015-03-26-javascript-idiosyncrasies.md
deleted file mode 100644
index 59e692470..000000000
--- a/_posts/2015-03-26-javascript-idiosyncrasies.md
+++ /dev/null
@@ -1,210 +0,0 @@
----
-layout: post
-title: JavaScript Idiosyncrasies
-date: 2015-03-26 11:00:00
-category: JavaScript
-permalink: /blog/2015/03/26/
----
-
-Time to mention a few JavaScript idiosyncrasies, and how I deal with them.
-
-Also, see my previous posts on [PCjs Coding Conventions](/blog/2014/09/30/) and [JavaScript Negativity](/blog/2014/10/26/).
-
-### Strict Equality
-
-Many JavaScript websites will advise you to *never* use the "==" and "!=" JavaScript operators, because when they compare
-variables containing different data types, JavaScript will coerce one of the operands to a matching type, sometimes in
-unexpected ways. We can thank the early days of JavaScript for this feature, when it was trying to be extraordinarily
-forgiving of sloppy code. I'm not going to list all the odd results that can arise from JavaScript's operand coercion,
-because there are more than enough examples on the web already.
-
-To avoid unexpected type coercion, and thus unexpected matches and/or mismatches, the usual advice is to *always* use
-strict equality operators ("===" and "!==").
-
-I disagree.
-
-In well-written code, the variable data types should always be clear. In fact, the more you're able to
-use [JSDoc](http://developers.google.com/closure/compiler/docs/js-for-compiler) types to declare the data types
-of all your parameters, return values, and other variables, the fewer errors you'll have. As long as you're always
-comparing variables with matching types, there shouldn't be any unexpected coercions.
-
-Obviously, there will be times when a polymorphic variable is required, especially when dealing with APIs that can
-return multiple types. But those should be the exception, not the rule.
-
-Another exception is optional parameters. When I write a method with optional parameters, I generally allow those
-parameters to either be omitted (ie, *undefined*) or set to *null*. Using "==", you can check for either value with
-a single comparison:
-
-``` javascript
-if (parameter == null) { ... }
-```
-
-whereas strict equality requires more work:
-
-``` javascript
-if (parameter === undefined || parameter === null) { ... }
-```
-
-This is one of those times when coercion (of *undefined* to *null*), and the use of "non-strict" operators, is beneficial.
-Here's another:
-
-``` javascript
-if (!b) { ... }
-```
-
-Coercing a value to *boolean* is a popular way of checking for all "falsy" values (ie, *undefined*, *null*,
-0, false, "", NaN, etc). It is shorthand for:
-
-``` javascript
-if (b == false) { ... }
-```
-
-yet I suspect the proponents of strict equality would embrace the former while rejecting the latter.
-
-However, I don't recommend "falsy" checks for optional parameters:
-
-``` javascript
-if (!parameter) { ... }
-```
-
-because often a valid numeric parameter might include 0, or a valid string parameter might include "", so it's better
-to do this:
-
-``` javascript
-if (parameter == null) { ... }
-```
-
-and obviously if *null* is also a acceptable value, then you should definitely use strict equality:
-
-``` javascript
-if (parameter === undefined) { ... }
-```
-
-Problems with type coercion are **NOT** problems caused by a poor choice of operators, so trying to make
-those problems go away by artificially limiting your choice of operators seems like the wrong solution.
-Type coercion problems are, by definition, problems involving mismatched types. Solutions include:
-
-- Avoid comparing variables of different types; or
-- Convert your variables to matching types first; or
-- Use strict equality operators (just don't use them mindlessly)
-
-Explicitly convert variables to a single type whenever possible. For example, I might define a method
-that accepts an optional numeric parameter, with a documented default value when it's omitted. I think it's
-important make that parameter unambiguously numeric as soon as possible; eg:
-
-``` javascript
-/**
- * foo(n)
- *
- * Performs a mathematical operation on n and returns a result.
- *
- * @param {number} [n] is an optional parameter (defaults to zero if omitted)
- * @return {number}
- */
-function foo(n) {
- n = n || 0;
- ...
-}
-```
-
-The expression `n || 0` might seem pointless, because *undefined* and *zero* are equivalent in a "falsy" sense, but
-*undefined* is not a number, and there will be fewer problems downstream if you ensure that n is *always* a number.
-
-### Enumerating Array or Object Properties
-
-When using *for*...*in* loops like this:
-
-``` javascript
-var a = [100, 200, 300];
-for (var i in a) { ... }
-```
-
-the type of variable *i* will be **string** rather than **number**; that is, it will contain "0", "1", and "2" rather
-than 0, 1, and 2. If you then use *i* to set a matching element in another array, that element will not be stored in
-the same (numeric) position as the original array.
-
-One solution is to convert *i* to a **number**:
-
-``` javascript
-parseInt(i, 10);
-```
-
-However, a more elegant solution is to use the unary "+" operator to coerce the **string** to a **number**:
-
-``` javascript
-+i;
-```
-
-The same problem arises with objects using numeric properties. And watch out for JavaScript's automatic base
-conversion of numeric properties. For example, when you enumerate the properties of object "o":
-
-``` javascript
-var o = {
- 0x20: ' ',
- 0x41: 'A'
-};
-```
-
-you will get the strings "32" and "65", not "0x20" and "0x41". You must quote your property names to prevent
-any conversion; eg:
-
-``` javascript
-var o = {
- "0x20": ' ',
- "0x41": 'A'
-};
-```
-
-Numeric properties can always be safely converted using the unary "+" operator, regardless whether they were quoted
-or not.
-
-The unary "+" is a great alternative to parseInt(), but be mindful of their differences. One important difference
-is that parseInt() will stop when it encounters an invalid digit, returning whatever value was parsed up to that point,
-whereas unary "+" conversion will return *NaN* if there are any invalid digits in the string.
-
-### Shift Counts For Bitwise Shifts
-
-It turns out that shifting an integer value by more than 31 bits in either direction may not shift as many bits as
-you'd expect. For example:
-
-``` javascript
-n = 0x10000000;
-n >>>= 33;
-```
-
-will shift n by only *one* bit, not 33 bits, and the result will be 0x08000000, not zero. This is because,
-just like the shift instructions on 32-bit Intel processors, JavaScript converts the shift count to a *mod 32* value
-(in other words, it truncates the shift count to a 5-bit value).
-
-So the above example is equivalent to:
-
-``` javascript
-n >>>= 1;
-```
-
-If you really need larger shift counts to work in a consistent manner, you can perform multiple shifts, where each
-shift count is in the range 0-31. Here's one way to shift a number 33 bits:
-
-``` javascript
-n = (n >>> 31) >>> 2;
-```
-
-Also, it's not quite correct to say that a shift count of zero has *no* effect on a number:
-
-``` javascript
-n = 0x88888888|0; // n is displayed as -2004318072
-n >>>= 0; // n is displayed as 2290649224
-```
-
-It's true that the bottom 32 bits of the number were not changed, but a side-effect of the unsigned shift operator
-is that all the upper sign bits are stripped from the (64-bit) result.
-
-Similarly, as soon as you perform any other bitwise operation on the number, even one that does not modify the low
-32 bits, the upper bits will revert to the sign of the lower 32-bit value:
-
-``` javascript
-n |= 0; // n is displayed as -2004318072 again
-```
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*March 26, 2015*
diff --git a/_posts/2015-04-16-compaq-deskpro-386-update.md b/_posts/2015-04-16-compaq-deskpro-386-update.md
deleted file mode 100644
index 7f18051ea..000000000
--- a/_posts/2015-04-16-compaq-deskpro-386-update.md
+++ /dev/null
@@ -1,154 +0,0 @@
----
-layout: post
-title: COMPAQ DeskPro 386 Update
-date: 2015-04-16 11:00:00
-category: 80386
-permalink: /blog/2015/04/16/
-machines:
- - type: pcx86
- id: deskpro386
- debugger: true
- uncompiled: true
- config: /devices/pcx86/machine/compaq/deskpro386/ega/2048kb/debugger/machine.xml
----
-
-PCx86 can now boot the [COMPAQ DeskPro 386/16 ROM BIOS](/devices/pcx86/rom/compaq/deskpro386/).
-
-There's still a problem with the Hard Drive Controller, which I haven't looked into yet,
-but booting from a floppy works.
-
-While working through issues with this ROM BIOS, I created some lightly-annotated
-[source code](/devices/pcx86/rom/compaq/deskpro386/1988-01-28/1988-01-28.asm) that can be re-assembled
-with [NASM](http://www.nasm.us/). The initial process of creating the source code is
-explained [here](/devices/pcx86/rom/compaq/deskpro386/#recreating-rom-source-code).
-
-At the top of the source code, I explain a few important details about ROM addresses that
-are worth recapping here:
-
-> This 32Kb ROM image is ORG'ed at 0x8000, because most of its code is designed to run
-at real-mode addresses F000:8000 through F000:FFFF.
-
-> And even though the 80386 resets with CS:IP set to F000:FFF0, the physical base address
-of CS is set to %FFFF0000, which means the ROM must also be mapped at physical addresses
-%FFFF8000 through %FFFFFFFF.
-
-> Additionally, DeskPro 386 systems mirror this 32Kb ROM at real-mode address F000:0000
-through F000:7FFF. Once again, that region is mirrored at physical addresses %FFFF0000
-through %FFFF7FFFF.
-
-> In other words, both 32Kb halves of the last 64Kb of both the first and last megabyte
-of the 80386's 4Gb address space are physically mapped to this ROM image.
-
-> Finally, the DeskPro 386 has a "RAM Relocation" feature that allows 128Kb of RAM at
-%00FE0000 through %00FFFFFF to be mapped to %000E0000 through %000FFFFF, effectively
-replacing the ROM in the first megabyte with write-protected RAM; the top 64Kb of that
-RAM must first be initialized with the 64Kb at %000F0000 prior to remapping. It's also
-possible to copy external ROMs from %000C0000 through %000EFFFF into the bottom 64Kb of
-that RAM, but this is only done for ROMs known to contain relocatable code; eg, a COMPAQ
-Video Graphics Controller (VGC) Board.
-
-> Every DeskPro 386 system must have a MINIMUM of 1Mb of RAM, of which either 256Kb,
-512Kb, or 640Kb can be physically mapped as conventional memory (at the bottom of the
-first megabyte), with the remainder (either 768Kb, 512Kb, or 384Kb) physically mapped
-to the top of the 16th megabyte (ending at address %00FFFFFF), the last 128Kb of which
-is used by the "RAM Relocation" feature. The remaining memory immediately below that
-128Kb (ie, below %00FE0000) can only be accessed by special system software, such as CEMM.
-
-> COMPAQ refers to that remaining memory as "Compaq Built-in Memory".
-
-So there you have it. Once the ROM has relocated itself to RAM at the top of the 16th
-megabyte, there are no less than THREE physical address ranges where ROM code and data
-structures can be accessed:
-
- 1. %000F0000 through %000FFFFF (aka real-mode adresses F000:0000 through F000:FFFF)
- 2. %00FF0000 through %00FFFFFF (the relocated copy)
- 3. %FFFF0000 through %FFFFFFFF (the physical alias of %000F0000 through %000FFFFF)
-
-As you would expect, most of the ROM's code and data references are to first megabyte,
-since most of the code is designed to run in real-mode. But there are portions that
-run in protected-mode, and those portions are much less consistent about which address
-range to use -- no doubt, in part, because it makes no difference. The ROM does
-not run with paging enabled, so any physical address is as easy to access as any other.
-
-Unless, of course, the A20 line is disabled. In that case, only the first range is
-accessible; the other two are not.
-
-April 19, 2015 Update
----
-Thanks to some sleuthing by [Michal Necasek](http://os2museum.com/), it turns out that my
-assumptions about A20 management on the COMPAQ DeskPro 386 were incorrect.
-
-He noted that, on page 398 of "DOS Internals" by Geoff Chappell, (c) 1994, the author says:
-
-> On a machine that controls the A20 by passing the address line through an AND gate with a
-signal from some bit at an I/O port, the A20MAP program should produce a map similar to:
-
- Memory mapping with disabled A20 line:
-
- 0MB -> 0MB
- 1MB -> 0MB
- 2MB -> 2MB
- 3MB -> 2MB
- 4MB -> 4MB
- 5MB -> 4MB
- 6MB -> 6MB
- 7MB -> 6MB
-
-> showing wrap-around for every second megabyte. It is also possible to include other address lines
-in the controlling mechanism, which may reduce the incidence of wrap-around, as with a Compaq
-DeskPro:
-
- 0MB -> 0MB
- 1MB -> 0MB
- 2MB -> 2MB
- 3MB -> 3MB
- 4MB -> 4MB
-
----
-
-This means that the DeskPro ROM BIOS can, in fact, access its own code and data at ANY of the above
-three physical address ranges at any time, regardless whether A20 is disabled or not.
-
-Which is a good thing, because I came across at least one code sequence in the ROM BIOS that enters
-protected-mode with A20 disabled -- an unwise thing to do on most machines:
-
- ;
- ; When we arrive here, the A20 line has been disabled; on most systems, that would
- ; mean that the ROM's GDT would only be accessible at the "low" ROM address (%0F0730),
- ; not the "high" address (%FF0730). But fortunately, A20 management on COMPAQ
- ; DeskPros affects wrap-around only from the 1st to the 2nd megabyte; no other address
- ; range is affected.
- ;
- ; FYI, it seems this code doesn't do anything if bits 6 and 7 of the RAM Settings
- ; register are set to anything other than 0x40 (ie, it returns to real-mode almost
- ; immediately after entering protected-mode).
- ;
- lgdt [cs:0x077e] ; 0000F498 2E0F01167E07; load [gdtr_hi] into GDTR
- mov eax,cr0 ; 0000F49E 0F2000
- or ax,0x1 ; 0000F4A1 0D0100
- mov cr0,eax ; 0000F4A4 0F2200
- jmp 0x28:xf4ac ; 0000F4A7 EAACF42800
-
-Before fully understanding the DeskPro's unusual A20 management, PCx86 worked around it by
-redirecting all A20 changes from the Bus component to the CPU component, giving the CPU first
-crack at any changes to A20. If the CPU was in real-mode, it would simply pass the A20 request
-on to the Bus. However, if the CPU was in protected-mode, it would maintain the requested
-"logical" A20 state but ensure that the "physical" state of A20 was always enabled. In short,
-it was no longer possible for the CPU to be in protected-mode AND for the A20 line to be disabled;
-when one was enabled, the other was enabled as well.
-
-I'm in the process of replacing that work-around with a much more compatible change, at least
-on 32-bit bus configurations, which involves changing the physical address map for the 2nd megabyte
-to match that of the 1st megabyte whenever A20 is disabled. I could probably get away with remapping
-only the first 64Kb of the 2nd megabyte, but until I'm actually able to run some tests on a real
-DeskPro 386, I'm going to assume COMPAQ's A20 implementation affected the entire 2nd megabyte.
-
-Here's my [COMPAQ DeskPro 386/16](/devices/pcx86/machine/compaq/deskpro386/ega/2048kb/debugger/) test
-configuration. Set a breakpoint at F000:F498 ("bp f000:f498") in the Debugger panel to see the above
-code in action. When the machine is operating in real-mode, you can use the "rp" command to dump all
-the registers, including the current base and limit values loaded into the segment registers.
-
-{% include machine.html id="deskpro386" %}
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*April 16-19, 2015*
diff --git a/_posts/2015-05-20-pc-tech-journal-collection.md b/_posts/2015-05-20-pc-tech-journal-collection.md
deleted file mode 100644
index 87e50d8d6..000000000
--- a/_posts/2015-05-20-pc-tech-journal-collection.md
+++ /dev/null
@@ -1,26 +0,0 @@
----
-layout: post
-title: PC Tech Journal Collection
-date: 2015-05-20 11:00:00
-category: PC Tech Journal
-permalink: /blog/2015/05/20/
----
-
-This is an update to my 2014 [post](/blog/2014/08/01/) on the PCjs online collection of old
-[PC Tech Journal](/pubs/pc/magazines/pctj/) magazine issues.
-
-Our collection is much more complete now. We have the first issue, the last issue, and almost all the issues
-in between. All we're currently missing are the April 1988 issue and the first three issues of 1989, at least in
-terms of regular issues.
-
-We also have the [1987 Editorial Index and Comprehensive Product Guide](/pubs/pc/magazines/pctj/PCTJ-1987-00/);
-however, even though it identifies itself as a 1987 issue, the editorial index only covers issues through
-October 1986, so "technically" it should be considered a late 1986 issue. It is officially Vol. 4, No. 13, which,
-numerically, puts it squarely between the December 1986 and January 1987 issues.
-
-[
](/blog/images/ipad-solitaire.jpg){% endcomment %}
-{% include screenshot.html src="/blog/images/ipad-solitaire-small.jpg" title="iPad running Solitaire on Windows 3.10" link="/blog/images/ipad-solitaire.jpg" %}
-
-The basic touch events are:
-
- - `touchstart`
- - `touchmove`
- - `touchend`
-
-which roughly correspond to `mousedown`, `mousemove`, and `mouseup` events, except that your finger isn't
-exactly like a mouse -- it doesn't have *buttons* for one thing -- so there are several usability problems
-that must be solved.
-
-One of the problems is how to deal with the *default behaviors* of touch events. For example, tapping on a
-PCjs screen is normally how you trigger the iPad's soft keyboard, and dragging your finger across the screen
-normally scrolls the page up and down. However, you don't want *either* of those behaviors when you're
-trying to move the machine's mouse pointer around or click on things.
-
-PCjs attempts to resolve the tapping problem by disabling default behaviors most of the time, except when
-two taps occur more than 1/2 second apart. This allows a quick *double-tap* to be treated as a double-click,
-while a pair of slower taps allows the soft keyboard to activate.
-
-Another problem is how to differentiate between *moving the mouse* (ie, without any buttons pressed) and
-*dragging the mouse* (ie, with the left button pressed). Newer devices offer the option of relying on "3D Touch"
-(aka Force Touch), and using pressure to determine the user's intent, but most devices don't have that feature,
-and I'm not sure I'd want to rely on that anyway.
-
-The PCjs solution: if you *tap and hold* for more than 200ms, and then start moving, your movements become the
-equivalent of a *mouse drag* operation.
-
-This is my first stab at touch-to-mouse conversion, and it's not perfect, but it's already fairly usable,
-as my Solitaire experiment demonstrates. And there are still some open questions, such as how to intuitively
-support operations like *right drag*, since the current *mouse drag* operation is inherently *left drag*;
-one solution would be to rely on multi-touch and use two fingers to trigger right-button operations.
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*March 6, 2016*
diff --git a/_posts/2016-03-12-demos-of-windows386-and-windows-3x.md b/_posts/2016-03-12-demos-of-windows386-and-windows-3x.md
deleted file mode 100644
index 245c89fca..000000000
--- a/_posts/2016-03-12-demos-of-windows386-and-windows-3x.md
+++ /dev/null
@@ -1,34 +0,0 @@
----
-layout: post
-title: Demos of Windows/386 and Windows 3.x
-date: 2016-03-12 14:00:00
-permalink: /blog/2016/03/12/
----
-
-I recently added some more demos to the PCjs Project, to showcase its ability to run old 80286-based and
-80386-based software, such as [Windows/386](/disks/pcx86/windows/2.0x/), [Windows 3.0](/disks/pcx86/windows/3.00/),
-[Windows 3.1](/disks/pcx86/windows/3.10/), and [Windows 95](/disks/pcx86/windows/win95/4.00.950/).
-
-{% include screenshot.html src="/disks/pcx86/windows/2.0x/thumbnail.jpg" width="200" height="120" title="COMPAQ DeskPro 386, Windows/386 2.01" link="/disks/pcx86/windows/2.0x/" %}
-{% include screenshot.html src="/disks/pcx86/windows/3.00/thumbnail.jpg" width="200" height="120" title="IBM PC AT w/EGA, Windows 3.00" link="/disks/pcx86/windows/3.00/" %}
-{% include screenshot.html src="/disks/pcx86/windows/3.10/thumbnail.jpg" width="200" height="120" title="IBM PC AT w/VGA, Windows 3.10" link="/disks/pcx86/windows/3.10/" %}
-{% include screenshot.html src="/disks/pcx86/windows/win95/4.00.950/thumbnail.jpg" width="200" height="120" title="COMPAQ DeskPro 386, Windows 95" link="/disks/pcx86/windows/win95/4.00.950/" %}
-
-As the [OS/2 Museum](http://www.os2museum.com/wp/windows386-2-01/) points out, [Windows/386 2.01](/disks/pcx86/windows/2.0x/)
-was the first Microsoft product to specifically target the 80386. However, not only was it *not* a 32-bit operating
-system, it didn't even run Windows applications in protected-mode. Windows apps ran in V86-mode, and even then, *only*
-if you started Windows by running `WIN386.EXE`.
-
-There may have been some incidental protection advantages to running Windows in V86-mode instead of real-mode,
-but the primary advantages were the ability to simulate expanded memory (EMS) using the 80386's paging capabilities,
-and the ability to run multiple DOS applications simultaneously.
-
-Alternatively, you could start Windows/386 with `WIN86.COM`, which reverted to the older Windows 1.x memory model,
-where all Windows applications ran in real-mode and only one DOS application could be run at a time.
-
-Strangely, unlike all previous and subsequent versions of Windows, there was no `WIN` command in Windows/386.
-
-At least there was no `LOSE` command.
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*March 12, 2016*
diff --git a/_posts/2016-04-30-the-intel-8080-cpu.md b/_posts/2016-04-30-the-intel-8080-cpu.md
deleted file mode 100644
index 8f4006a6a..000000000
--- a/_posts/2016-04-30-the-intel-8080-cpu.md
+++ /dev/null
@@ -1,56 +0,0 @@
----
-layout: post
-title: Introducing the Intel 8080 CPU
-date: 2016-04-30 14:00:00
-permalink: /blog/2016/04/30/
----
-
-Or rather, introducing [PC8080](/modules/pc8080/), a new 8080-based machine emulator recently added to the
-PCjs Project.
-
-Our first [8080 Test Machine](/devices/pc8080/machine/exerciser/) loads a copy of the
-[8080 Exerciser](https://web.archive.org/web/20151006085348/http://www.idb.me.uk/sunhillow/8080.html)
-(specifically, [8080EX1](/devices/pc8080/rom/exerciser/8080EX1.MAC)) and intercepts the exerciser's CP/M console
-calls so that you can see its progress in the Control Panel window. It's a "headless" test machine
-(no keyboard or display), so that's all you get.
-
-The good news: PC8080 passes all the 8080 Exerciser tests. And it doesn't do it by using all sorts of weird
-"flags tables" that most other 8080 emulators seem to fall back on.
-
-Like all the other CPU emulations in the PCjs Project, PC8080 never "calculates" the flags unless/until they are
-actually required, which considerably speeds up arithmetic operations.
-
-Of particular note are the 8080's subtract, compare, and decrement operations, which actually perform addition,
-not subtraction, by using two's complement arithmetic in "stages": the first stage (inverting the source operand)
-occurs *before* the addition, and the second stage (incrementing the inverted operand) occurs *after* the addition.
-And it appears to be the result of the *first* stage, not the second, that determines the state of the Auxiliary
-Carry flag (AF).
-
-The behavior of the Auxiliary Carry flag (AF) and the associated DAA instruction are probably the most significant
-(and least understood) *arithmetic* differences between the 8080 and all later x86-based CPUs. Well, there's also
-the fact that the 8080 doesn't provide an Overflow flag (OF). Internally however, PC8080 retains the ability to
-calculate overflow (since PC8080 was a fork of PCjs), which should be useful when we add Z80 support to PC8080.
-
-On a related note, [Ken Shirriff](http://www.righto.com/) has some fascinating blog posts on the 8085 that also
-provide clues as to how the 8080 likely operates:
-
-* [Inside the ALU of the 8085 microprocessor (January 2013)](http://www.righto.com/2013/01/inside-alu-of-8085-microprocessor.html)
-* [Silicon reverse engineering: The 8085's undocumented flags (February 2013)](http://www.righto.com/2013/02/looking-at-silicon-to-understanding.html)
-* [The 8085's register file reverse engineered (March 2013)](http://www.righto.com/2013/03/register-file-8085.html)
-* [Reverse-engineering the 8085's ALU and its hidden registers (July 2013)](http://www.righto.com/2013/07/reverse-engineering-8085s-alu-and-its.html)
-* [Reverse-engineering the flag circuits in the 8085 processor (July 2013)](http://www.righto.com/2013/07/reverse-engineering-flag-circuits-in.html)
-* [Reverse-engineering the 8085's decimal adjust circuitry (August 2013)](http://www.righto.com/2013/08/reverse-engineering-8085s-decimal.html)
-
-The idea is to make [PC8080](/modules/pc8080/) sufficiently configurable so that it will work with a variety of
-8080-based systems, including those with memory-mapped video displays (like
-[Space Invaders](/devices/pc8080/machine/invaders/)), as well as simpler terminal-based systems, like the CP/M-based
-systems of old.
-
-In fact, as soon as [Space Invaders](/devices/pc8080/machine/invaders/) is working, my next planned adaptation
-is a DEC VT100 terminal emulator (itself an 8080-based machine) which can then be "wired up" to other PCjs machine
-simulations. This will not be yet-another VT100-compatible emulation -- which, like 8080 emulators, has been done to
-death -- but rather a simulation of the original VT100 hardware, building on [Adam Mayer's](https://github.com/phooky)
-work [reverse-engineering the VT100](https://github.com/phooky/VT100-Hax).
-
-*[@jeffpar](http://twitter.com/jeffpar)*
-*April 30, 2016*
diff --git a/_posts/2016-05-04-the-sharpening.md b/_posts/2016-05-04-the-sharpening.md
deleted file mode 100644
index c584acb08..000000000
--- a/_posts/2016-05-04-the-sharpening.md
+++ /dev/null
@@ -1,95 +0,0 @@
----
-layout: post
-title: The Sharpening
-date: 2016-05-04 08:00:00
-permalink: /blog/2016/05/04/
----
-
-This was the week of The Sharpening.
-
-A while back, I updated most of the machines to use higher-resolution "screens". For example, a typical
-[EGA video configuration](/devices/pcx86/video/ibm/ega/1984-09-13/128kb-autolockfs.xml) now specifies a *screenWidth*
-of 1280 and *screenHeight* of 700, dimensions which are exactly twice the standard EGA resolution.
-
-That change had no effect on the machine's operation, but it did improve the machine's appearance, because
-most people are using much higher resolution monitors today, so by using a higher-resolution "screen" (canvas),
-less interpolation is happening when a machine's screen image is scaled up to fill your browser window.
-
-The amount of scaling *also* depends on whether the machine allows itself to be stretched to fill the browser window.
-For example, this [machine](/devices/pcx86/machine/5160/ega/640kb/array/machine.xml) (used by the
-[EGA Machine Array Demo](/devices/pcx86/machine/5160/ega/640kb/array/)) is limited to an overall *width* of 680 pixels,
-no matter how large you make your browser window:
-
-```xml
-