Initial commit (a clone of the jsmachines project as of v1.15.3)

This commit is contained in:
jeffpar 2014-09-27 14:52:57 -07:00
commit a5e3e6a59d
714 changed files with 130602 additions and 0 deletions

50
blog/2013/11/README.md Normal file
View file

@ -0,0 +1,50 @@
A Blog That's Not A Blog
---
As you may have noticed (or not), the [JSMachines](http://jsmachines.net/) website had a very modest makeover
recently.
Originally, the site was a smattering of HTML files, along with some XML files that I was rendering as HTML
using some simple XSL stylesheets. However, I was tired of having one set of files for the website to explain
things and a different set of files on [GitHub](http://github.com) that explained other things -- many
of those things being the SAME things.
So this month, I decided to eliminate all the HTML files. As you browse the site, you're simply navigating
folders from the **GitHub** project and reading the project's **README.md** files.
There's a single PHP script responsible for transforming a folder's default document (either **README.md**
or **machine.xml**) to HTML, as well as displaying the current directory across the top and a directory listing
down the left-hand side.
The same script provides support for a subset of the [Markdown](http://daringfireball.net/projects/markdown/)
syntax, which is more than sufficient to handle all the site's **README.md** files. I probably should
have used a third-party Markdown library, but this was more educational, and it was easy to add extra features,
like the ability to embed JavaScript machines with a single Markdown-style link; eg:
[IBM PC](/configs/pc/machines/5150/mda/64kb/ "PCjs:ibm5150")
The script takes care of the rest, adding the appropriate stylesheets and PCjs scripts automatically.
I had more grandiose plans, including a command-line prompt written in JavaScript that would allow you to
navigate the site exactly as you would an IBM PC hard drive from a "DOS prompt", and I may try something
like that later, but don't hold your breath.
I've tried to improve the organization of all the [Machine Configuration Files](/configs/pc/machines/) as well.
The variety of configurations was getting out of hand. It's a bit tidier now, but there's still room for
improvement.
My workflow is improving, too. I'm more comfortable with [GitHub](http://github.com) now,
and I recently switched from Eclipse to JetBrains' [WebStorm](http://www.jetbrains.com/webstorm) (well,
actually [PhpStorm](http://www.jetbrains.com/phpstorm), since it's a superset of WebStorm, although I did start
with WebStorm), and the new development environment is feeling pretty good now. I've had zero problems with
[JetBrains](http://www.jetbrains.com) products and I'm seriously impressed with their quality and completeness,
so I have no qualms about moving from the "free" Eclipse platform to the $99 PhpStorm IDE.
The nice thing about the new GitHub-centric approach is that it's easy to "push" changes to both the repository
and the website. I update one or more **README.md** files, "Commit and Push" from the IDE, then "pull" from GitHub
on the web server.
This so-called blog is more of the same: **README.md** files in a series of folders. The only question now:
will this actually evolve into a series...?
*[@jeffpar](http://twitter.com/jeffpar)*
*November 20, 2013*

13
blog/2014/01/README.md Normal file
View file

@ -0,0 +1,13 @@
New Year, New Directions
---
Initial goals for 2014 include:
- Setting up a new web server running node.js, using either AWS, Google Compute Engine or Windows Azure;
- Porting this project to work with node.js, which includes rewriting all the PHP code as server-side JavaScript;
- Deciding whether to separate PCjs from C1Pjs for the new web site, or simply make PCjs.org a mirror of jsmachines.net;
- Deciding how best (or even whether) to accomodate PCjs running from both **node** and **non-node** web servers.
I guess we'll learn more as the year progresses.
*[@jeffpar](http://twitter.com/jeffpar)*
*January 20, 2014*

50
blog/2014/03/30/README.md Normal file
View file

@ -0,0 +1,50 @@
Running on Azure
---
Publishing a Node-based site to [Azure](http://azure.com) was painless, thanks to their friendly web portal and
GitHub integration. Getting a fully operational site, however, took a bit more time.
Unfortunately, because Azure's underlying server technology is Windows-based (IIS), some of the same Windows/Unix
portability problems that have plagued us for decades still plague us today: **carriage returns** and **backslashes**.
Even though all PCjs text files in my project contain only linefeeds, IIS would serve them up with CR/LF
instead. I first noticed this on the client side, when an XML file retrieved via *XMLHttpRequest()* came back
full of CR/LFs, and later on the server side, when *fs.readFile()* returned a Markdown file filled with CR/LFs.
I wondered if the CR/LF transformation had happened when Azure pulled all my files from GitHub, because
while I can understand some whitespace inconsistencies across web servers, I would never expect file system calls
on the server to modify file contents.
I finally confirmed that the files were indeed modified on the server, by using Azure's FTP browser. For example,
[minimal.xml](/configs/pc/keyboards/minimal.xml) is currently 622 bytes locally, but on the Azure server, the
reported size is 632 bytes -- one extra CR for each of the file's 10 lines. After a little more digging, I
[learned something new](http://git-scm.com/book/ch7-1.html#Formatting-and-Whitespace) about **Git**: it has a
setting called `core.autocrlf` which, for me on OS X, defaults to `input` (meaning "convert CR/LF to LF on commit
but do NOT convert LF back to CR/LF on check-out"). But Azure apparently sets this to `true`, causing all LFs to be
converted to CR/LF.
Regarding slashes, even when path components contained only slashes, *path.join()* would return paths with
backslashes. And unfortunately, this behavior varies from Node module to module. For example, I use the NPM
[glob](https://www.npmjs.org/package/glob) module, and even when the input path to *glob()* contains backslashes,
its output paths do not.
In the process of fixing those portability issues, I also had some trouble getting Azure logging to work as
documented. Setting `loggingEnabled: true` in **/IISNode.yml** would generate logs in **/site/wwwroot/iisnode/**,
but the logs were numerous and poorly organized.
And the Azure command-line tool that was *supposed* to enable real-time log-streaming to the console:
azure site log tail pcjs
would happily report:
Welcome, you are now connected to log-streaming service
but it would NEVER display anything but deployment information. Instead, I had to browse the log files using Azure's
"FTP DIAGNOSTIC LOGS" link on the web portal -- which presents the logs as one big, ugly, fragmented mess:
![Azure Logs](iisnode_logs.png)
Sigh. But at least the site is up and fully operational now.
*[@jeffpar](http://twitter.com/jeffpar)*
*March 30, 2014*

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

41
blog/2014/03/31/README.md Normal file
View file

@ -0,0 +1,41 @@
Browser Compatibility Woes
---
While JavaScript has been doing a good job of delivering on the old "write once, run everywhere" promise that its
[unrelated namesake](http://www.java.com) coined, the "hook once, deliver everywhere" promise seems less fulfilled.
Not that anyone ever made such a promise.
Specifically, I'm talking about DOM events. Take the HTML5 <canvas> element, for example. If I give
it a `contenteditable="true"` attribute, it will play nicely with my JavaScript app in a Mobile Safari browser,
by popping up the device's soft keyboard in response to the canvas element receiving focus (ie, when you tap on it).
The Silk browser on a Kindle Fire, however, is another story -- it acts like it has no idea what `contenteditable`
means. Even if I display an actual <input> text field alongside the <canvas>, and attach all the same
input event handlers to the text field instead of the canvas, the Kindle Fire's soft keyboard will pop up, but my
input event handlers still won't fire.
I've done what testing I can with the Android SDK and the "Android Virtual Device Manager", and in general, support
looks fine -- you click/tap on the PC's screen, the soft keyboard pops up, and typing works. So I guess Silk is just
an outlier. I'm not sure what I'll do about it yet (or even what I can do).
![PCjs in AVD](avd_tablet.png)
---
Here's another issue I've yet to resolve.
When Apple released iOS 7.0, PCjs went from being a rock-solid web application on
2nd/3rd/4th-generation iPads to a very flaky web application. It's still rock-solid on 5th-generation iPads
(the iPad Air and iPad Mini w/Retina Display), and so I suspect a bug in Apple's JavaScript engine that's specific
to their older A5 processor.
It may be possible to work around the bug, but I haven't yet isolated exactly what code
sequence(s) are failing. For now, this is the most serious unresolved PCjs bug I'm aware of.
---
If you're having a problem (or trouble with a device) that I've not already mentioned, [let me know](mailto:Jeff@pcjs.org).
Thanks.
*[@jeffpar](http://twitter.com/jeffpar)*
*March 31, 2014*

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

17
blog/2014/04/01/README.md Normal file
View file

@ -0,0 +1,17 @@
The Latest in Emulator Technology
---
Announcing **InternetJS: The Internet Emulator**, the world's smallest JavaScript application capable of emulating the entire Internet.
And like all PCjs applications, there's nothing to install. It runs safely and securely from any web browser.
Check out the ALPHA release demo below.
<iframe width="720" height="512" src="http://bing.com/" style="border-webkit-transform:scale(0.5);-moz-transform-scale(0.5);border:1px solid black;border-radius:15px;overflow:auto;width:100%;background-color:#FAEBD7;"></iframe>
Disclaimer: InternetJS may not be suitable for everyone. Ask your doctor if InternetJS is right for you. Side-effects may include:
- Increased awareness
- Loss of appetite after eating large meals
- Inability to forget things you never wanted to remember
*[@jeffpar](http://twitter.com/jeffpar)*
*April 1, 2014*

20
blog/2014/04/12/README.md Normal file
View file

@ -0,0 +1,20 @@
What's New in 1.13.0
---
The latest version adds support for "software manifests", which you can read more about [here](/apps/). Basically, manifests
are simple XML files that describe a piece of software (an application, an operating system, whatever). They can also
link to a PCjs machine configuration capable of running the software, along with a "ready-to-run" machine state file.
Conversely, a PCjs machine XML file can refer back to the manifest, to obtain a list of disk images.
Here are some [demos](/apps/pc/) of "ready-to-run" apps on [PCjs](/docs/about/pcjs/).
There have been lots of server-side changes recently, including API improvements that make it easy (well, *easier*)
to dynamically create diskette images from a list of files, or even an entire folder (including all subfolders),
as long as the total size of all the files will fit on a PCjs-supported diskette image. Support for creating hard disk
images is still on the "TODO" list (the original **convdisk** PHP script supported hard disk images, but that functionality
hasn't been ported to the newer **diskdump** Node module yet).
Almost nothing has changed in the PCjs client-side code (which is where the emulator runs), except for changes to use
the new **diskdump** API.
*[@jeffpar](http://twitter.com/jeffpar)*
*April 12, 2014*

148
blog/2014/04/14/README.md Normal file
View file

@ -0,0 +1,148 @@
Node + Express != Safari
---
There's something very odd going on with between Node+Express and Safari, resulting in blank web pages.
Don't believe me? Just ask [Google](https://www.google.com/#q=node+express+safari+blank+page).
[pcjs.org](http://www.pcjs.org/) contains a lot of XML files that are rendered as web pages using XML
stylesheets. And occasionally Safari -- and ONLY Safari -- will render those XML files as blank pages.
For example, here's the
[machine.xml](/configs/pc/machines/5150/mda/64kb/machine.xml) file that's also embedded on the
[pcjs.org](http://www.pcjs.org/) home page.
When Safari fetched that XML file from an Apache web server (what I used before switching to Node),
the request would look like:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14
and the response would look like:
Date: Mon, 14 Apr 2014 22:11:20 GMT
Last-Modified: Sun, 13 Apr 2014 01:59:06 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.24 mod_ssl/2.2.26 OpenSSL/0.9.8y
Etag: "37a10b3-492-4f6e2e96b2e80"
Content-Type: text/xml
Connection: Keep-Alive
Accept-Ranges: bytes
Keep-Alive: timeout=5, max=100
Content-Length: 1170
with a status code of 200 ("OK"). And no matter how many times I hit Safari's Reload button, the response was the same.
Now with Node+Express, the same exact request would look like:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14
with a response of:
Date: Mon, 14 Apr 2014 22:16:42 GMT
Etag: "1170-1397354346000"
Last-Modified: Sun, 13 Apr 2014 01:59:06 GMT
X-Powered-By: Express
Content-Type: application/xml
Cache-Control: public, max-age=0
Connection: keep-alive
Accept-Ranges: bytes
Content-Length: 1170
HOWEVER, as soon as I used Safari's Back button to return to the home page, and then pressed the Forward button to return to
the XML file, the XML request changed to:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Cache-Control: max-age=0
If-None-Match: "1170-1397354346000"
If-Modified-Since: Sun, 13 Apr 2014 01:59:06 GMT
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14
with a response of 304 ("Not Modified") and the following response headers:
Date: Mon, 14 Apr 2014 22:18:26 GMT
Cache-Control: public, max-age=0
Etag: "1170-1397354346000"
Last-Modified: Sun, 13 Apr 2014 01:59:06 GMT
Connection: keep-alive
Accept-Ranges: bytes
X-Powered-By: Express
And here's where the "blank page" problem occurs: pressing Safari's Reload button. Again, the request looks the same as before,
and the response is still be 304 ("Not Modified"), but the page is blank, and the response now looks like:
Date: Mon, 14 Apr 2014 22:21:15 GMT
Cache-Control: public, max-age=0
Last-Modified: Sun, 13 Apr 2014 01:59:06 GMT
Connection: keep-alive
Accept-Ranges: bytes
X-Powered-By: Express
Etag: "1170-1397354346000"
and no matter how many times I press Reload, the response is the same (except for an updated *Date*), and the page is still blank.
So, here's the kludge I've added to my Express server code, to prevent Safari from displaying blank pages for those XML files:
/*
* The Safari "blank page" problem continues to plague us. Our first work-around was for directory
* "index.html" documents, which we resolved by always sending the document ourselves, along with an
* "ok" (200) response, instead of letting next() handle it, which would result in a "not modified"
* (304) response.
*
* However, the problem also extends to any XML files that we serve to an initial Safari request
* (eg, the machine.xml and manifest.xml files that we style as web pages). Safari includes
* "Cache-Control max-age=0" in the request, and if the response is "Cache-Control public, max-age=0"
* along with a 304 response code, Safari may once again display a blank page.
*
* This problem appears limited to the initial resource request for a particular URL. When these XML
* files are requested by Safari while loading another web page, Safari's caching logic is different
* (eg, it doesn't include the same "Cache-Control" setting).
*/
if (sBaseName == "machine.xml" || sBaseName == "manifest.xml") {
var sAgent = req.headers['user-agent'];
if (sAgent && sAgent.indexOf("Safari/") >= 0 && sAgent.indexOf("Chrome/") < 0 && sAgent.indexOf("OPR/") < 0) {
var sCacheControl = req.headers['cache-control'];
if (sCacheControl && sCacheControl.indexOf("max-age=0") >= 0) {
fs.readFile(sPath, {encoding: "utf8"}, function doneReadFile(err, sData) {
if (err) {
next(); // alternatively: res.status(404).send("Cannot GET " + req.path);
} else {
/*
* HACK: Express may still modify our response, turning our 200 status code into a 304
* and adding an Etag, unless we ALSO change the req.method from "GET" to something else.
* Supposedly, we could also use app.disable('etag'), but I'm not sure that would prevent
* Express from changing the status code, and I'm tired of testing work-arounds for this
* irritating behavior in Safari.
*/
req.method = "NONE";
res.set("Content-Type", "application/xml");
res.status(200).send(sData);
}
});
return;
}
}
}
I should add that this problem wasn't limited to XML files. It's a problem for the first resource requested by
Safari for any URL on the site (eg, URLs that default to "index.html" files).
I'm also rather surprised that no one yet seems to have figured out exactly what's going on here between Node+Express
and Safari. Or maybe they have, and I haven't been keeping my Node.js config up-to-date. I've tried to avoid changing
too many variables.
Lots of people have run into this problem. For example, on
[StackOverflow](http://stackoverflow.com/questions/18811286/nodejs-express-cache-and-304-status-code), someone
concluded that the [node-fresh](https://github.com/visionmedia/node-fresh) module should be changed. And for a while,
it was changed, until the change was [reverted](https://github.com/visionmedia/node-fresh/issues/8) -- along with a
lengthy discussion about why the change was wrong and that this was really a bug in Safari.
This "blank page" behavior may well be a bug in Safari, but that doesn't mean Express server components can't
or shouldn't provide a work-around for that behavior in the meantime. It also seems that some people who decided
this was a bug in Safari did not actually reproduce the bug themselves.
I don't know the right answer, but I do know that the current situation adversely affects users of other Node-powered
websites, who will probably get blank pages when they shouldn't, and other developers, who must all discover/debug/work-around
this problem on their own.
*[@jeffpar](http://twitter.com/jeffpar)*
*April 14, 2014*

39
blog/2014/04/30/README.md Normal file
View file

@ -0,0 +1,39 @@
Heading to New York
---
Lots of tinkering has been going on here at pcjs.org the past couple of weeks, but with nothing substantial to show for it.
Fixing lots of little problems requires only small bits of time, whereas buckling down and tackling "the next BIG thing" for
PCjs requires a much more serious time commitment, with limited interruptions.
And I certainly can't start on "the next BIG thing" now, because I'm heading to New York tomorrow, for [EmpireJS](http://2014.empirejs.org),
my first JavaScript conference *and* my first trip to New York in about 20 years.
I'm going to the conference partly because it was a great excuse to finally visit New York again (and with the whole family,
since all three of us are computer nerds), but also to get a more up-close-and-personal sense of where this whole JavaScript
renaissance is headed.
Is it headed for a fiery crash? This recent blog post
("[you have ruined javascript](http://codeofrob.com/entries/you-have-ruined-javascript.html)")
suggests it already has for some people. Is it drowning in the Sea of Endless Proliferation, as this still-relevant two-year-old
[parody](http://www.webmonkey.com/2012/05/jokes-for-nerds-html9-responsive-boilerstrap-js/) implies? Excerpt:
> *If youre feeling overwhelmed by the endless proliferation of responsive grids, adaptive images, HTML boilerplates,
CSS frameworks and JavaScript whirligigs then what you need is the HTML9 Responsive Boilerstrap JS.*
> *To install HTML9 Responsive Boilerstrap JS just “attackclone the grit repo pushmerge, then rubygem the lymphnode js shawarma
module — and presto!”*
> *If youre wondering what H9RBS.js actually is, well, you can abandon any hopes of one day being hip. But if you must know,
H9RBS.js is a “flexible, dependency-free, lightweight, device-agnostic, modular, baked-in, component framework MVC library
shoelacestrap to help you kickstart your responsive CSS-based app architecture backbone kitchensink tweetybirds.”*
Seriously, I'm concerned about how the JavaScript language (rather than the endless procession of frameworks) is going to evolve,
and whether it even can. Two examples: at a high-level, we have Microsoft pushing [TypeScript](http://www.typescriptlang.org/),
and at a much lower level, we have Mozilla pushing [asm.js](http://asmjs.org). And while I like aspects of both those efforts,
I'm relunctant to go very far down either of those paths right now, because I don't want to get suckered. Inevitably, someone will
see a *different* shiny object along another fork in the road, and everyone will chase after that instead.
Will [EmpireJS](http://2014.empirejs.org) answer any of these big questions? It doesn't really matter. I just expect to learn stuff,
and learning is fun!
*[@jeffpar](http://twitter.com/jeffpar)*
*April 30, 2014*

27
blog/2014/05/12/README.md Normal file
View file

@ -0,0 +1,27 @@
Chrome Kicks Butt
---
I haven't been closely monitoring the performance of PCjs across various browsers. Most of my browser testing has
been limited to "Does the latest version still work in all current web browsers?"
However, at some point during the last couple months, Chrome's performance suddenly jumped through the roof. On my
2.8GHz Intel Core i7 MacBook Pro, Chrome v34.0.1847.131 easily punches through the 120Mhz barrier on a PCjs machine
running PC-DOS 2.00.
That's roughly a 3x-4x increase over previous versions of Chrome. Safari used to be the performance champ, capable
of running a PCjs machine at a top speed of around 70-80MHz, while Chrome was less than half that, and Firefox was
slower still.
Chrome has now leap-frogged Safari in a big way, almost doubling Safari's speed. And with Chrome's superior
Developer Tools, Chrome is clearly the "Browser of Choice," whether you're just playing with PCjs or actually
debugging it.
Firefox is a bit of a disappointment, given all the hoopla over [asm.js](http://asmjs.org/) and other investments
that Mozilla is making. I've taken a "wait-and-see" attitude toward asm.js, because PCjs is hand-coded JavaScript,
and I'm not prepared to build a preprocessor that converts the code to asm.js semantics solely for the benefit of a
single browser.
Chrome's approach to making regular JavaScript run faster seems to be a winning strategy so far, at least for apps
like PCjs.
*[@jeffpar](http://twitter.com/jeffpar)*
*May 12, 2014*

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

75
blog/2014/06/14/README.md Normal file
View file

@ -0,0 +1,75 @@
Halt and Catch Liar
---
I had high hopes for the new AMC series "[Halt and Catch Fire](http://www.amctv.com/shows/halt-and-catch-fire),"
but it has proven to be an utter disappointment. I think I can suspend my disbelief as well as anyone, but this
show requires you to completely turn your brain off in order to be believed. I'm also baffled by the show's
high [IMDb score](http://www.imdb.com/title/tt2543312/), which is currently 8.4 (out of 10). Either AMC has figured
out how to game the system, or viewers are easily turned on by clichés, like the know-it-all Hot Programmer,
the self-assured Sales Guy, and the non-plot-advancing sex that they almost instantly engage in.
The premise: ex-IBM Sales Guy waltzes into a fictional computer company, smooth-talks his way into a top
marketing position without so much as a resumé, and then immediately risks all, including a huge potential lawsuit
with IBM, because he has dreams of building IBM clones that are "2x fast" at "1/2 price" -- with *handles*!
And the first thing they must do to achieve this dream is clone the IBM PC ROM BIOS, which the show pretends
was so secret that you couldn't even tell which chips on the IBM PC motherboard contained the ROM. Never mind
that IBM published the entire ROM BIOS listing in their Technical Reference Manual, which also included system
diagrams identifying every chip in the machine. I think if you're going to weave facts into your fiction,
the least you can do is get your facts right.
And centerpiece of this whole conceit -- the cloning of the IBM PC ROM BIOS. What a farce! Check out this
scene from Episode 2, where Brilliant Engineer looks at Hot Programmer's whiteboard in awe. Apparently, he
is easily awed, because he did the same thing when Sales Guy wrote "2x fast, 1/2 price" on an earlier whiteboard.
!["Halt and Catch Fire" Scene from Episode 2](Halt_and_Catch_Liar-thumbnail.jpg "link: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:
![Googlewhack](googlewhack.jpg)
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*

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

13
blog/2014/06/26/README.md Normal file
View file

@ -0,0 +1,13 @@
More Under-The-Hood Changes
---
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/]() directory for old documents, and [/disks/pc/]() 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. I have managed to streamline the process somewhat, however, as discussed in
[/disks/pc/personal/]().
*[@jeffpar](http://twitter.com/jeffpar)*
*June 26, 2014*

38
blog/2014/07/30/README.md Normal file
View file

@ -0,0 +1,38 @@
EGA Support
---
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](/configs/pc/machines/5160/ega/640kb/win101/) in color. Check out our
[Windows 1.01 "Server Array"](/configs/pc/machines/5160/ega/640kb/array/) demo.
![Windows 1.01 "Server Array" Demo](/blog/2014/07/30/win101-array-demo-small.jpg "link:/blog/2014/07/30/win101-array-demo.jpg")
EGA support is added to a **machine.xml** file using two XML elements; eg:
<video id="videoEGA" model="ega" memory="0x20000" screenwidth="640" screenheight="350"/>
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
&lt;machine&gt; element.
The second required XML element is a &lt;rom&gt; element to load the EGA ROM; eg:
<rom id="romEGA" addr="0xc0000" size="0x4000" file="/devices/pc/video/ibm-ega.json" notify="videoEGA"/>
The *notify* attribute must match the *id* of the &lt;video&gt; element, so that the Video component can load
the initial 8x14 and 8x8 fonts from the ROM. Support for dynamic loading of fonts from plane 2 of the EGA's memory
will be added later; however, current support works well enough to allow switching from 25-line mode to 43-line mode,
which essentially switches from the 8x14 font to the 8x8 font.
The &lt;video&gt; element also supports a *switches* attribute to specify the type of monitor connected to the EGA;
this attribute corresponds to the actual switch settings on the EGA card; our default *switches* setting is "0110",
which selects an Enhanced Color Monitor, enabling the EGA's maximum resolution of 640x350.
*[@jeffpar](http://twitter.com/jeffpar)*
*July 30, 2014*

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

26
blog/2014/08/01/README.md Normal file
View file

@ -0,0 +1,26 @@
PC Tech Journal, 1987
---
As part of an ongoing effort to make classic PC technical literature more accessible, I just finished
scanning and posting the 12 issues of [PC Tech Journal](/pubs/pc/magazines/pctj/) from 1987.
![PC Tech Journal, Jan 1987](http://static.pcjs.org/pubs/pc/magazines/pctj/PCTJ-1987-01/thumbs/PCTJ-1987-01 1.jpeg "link:/pubs/pc/magazines/pctj/PCTJ-1987-01/:200:260")
Future PC Tech Journal postings will include:
- Vol. 1, No. 1, July-August 1983
- Vol. 3, No. 12, December 1985
- Vol. 4, Nos. 1-12, 1986
- Vol. 6, Nos. 1-12, 1988
I'm missing the rest of 1983, all of 1984, most of 1985, and all of 1989 (well, through April 1989, which was
apparently the last issue).
For a nice overview and brief history of PC Tech Journal, check out the [OS/2 Museum](http://www.os2museum.com/wp/?p=2478).
In the meantime, if you have old PC Tech Journal issues that would fill any of the above holes, let me know.
I'd be happy to buy them, scan them, and recycle them.
Thanks.
*[@jeffpar](http://twitter.com/jeffpar)*
*August 1, 2014*

45
blog/2014/08/28/README.md Normal file
View file

@ -0,0 +1,45 @@
Supporting the 80286
---
The next milestone for PCjs is complete 80286 emulation. My hope is to have it working by the end of the year.
PCjs version 1.15.0 is the first step on the path to full 80286 support. It includes changes to the physical
memory manager and separate real-mode and protected-mode address evaluators. The Debugger supports physical
addresses (eg, %FE05B is the same as F000:E05B, assuming real-mode operation), along with breakpoint commands that
stop execution on port input/output operations. And the ChipSet component now contains "infrastructure" (a
fancy way of saying "partial support") for multiple PICs, DMA controllers, the 8042 keyboard controller (including
A20 support), and a bit more -- but not much.
One of the challenges is creating a single "universal" version of PCjs that can adapt itself to different machine
types without impacting performance. There will not be a **pc8088.js** or a **pc80286.js** or whatever. There will
only be **pc.js**.
Up until now, all PCjs machine XML files assumed an 8088 CPU with a 20-bit bus and a model 5150 or 5160 motherboard.
But now, a machine XML file can specify:
<computer name="IBM PC AT" buswidth="24"/>
<cpu model="80286"/>
<chipset model="5170"/>
...
Conventional emulators are usually NOT able to run original BIOS images, or simulate original PC hardware,
or even run at the same speed as the original PC, making some software difficult or impossible to use. PCjs takes a
different approach, by attempting to simulate an entire PC as it originally existed. Which is why a PCjs simulation
of an IBM PC does NOT run at whatever speed your modern PC happens to run in V86-mode or whatever speed your
browser's JavaScript engine tops out at.
No, a PCjs simulation of a 4.77Mhz IBM PC runs at 4.77Mhz. And a PCjs simulation of a 6Mhz IBM PC AT will run at
6Mhz. If you want to run the simulation faster, you have that option, but that's not the default. And I'm not saying
that PCjs is *exact* -- exactness is an exercise I'm leaving for another day and/or to other developers who are even
more obsessive than I am. I'm just saying that original PCs represent the targets that PCjs is shooting for.
PCjs 1.15.0 can now load and run the IBM 5170 ROM BIOS up to the first 80286-specific opcode, so it's off and running.
Although "running" isn't quite the right metaphor, because the process of bringing a new machine simulation to
completion is a *very* long series of baby steps.
Also, in preparation for this new phase, I recently dug up a variety of old [80286 CPU Documentation](/pubs/pc/reference/intel/80286/)
and posted excerpts. I'm sure none of this information is "new" at this point, but it might have some historical interest.
Enjoy.
*[@jeffpar](http://twitter.com/jeffpar)*
*August 28, 2014*

27
blog/2014/09/02/README.md Normal file
View file

@ -0,0 +1,27 @@
Minor Fixes and Additions
---
The following fixes were made in PCjs v1.15.1:
1. Using the "User-defined URL" option when loading a disk image from a 3rd-party server was broken if the URL
contained certain special characters; that should be fixed now, but be aware that only web servers (ie, URLs
using the HTTP protocol) are supported. URLs that trigger a redirect may also not work (more testing required).
2. Any errors that occur during the call to either *embedPC()* or *embedC1P()* should be properly displayed on the
caller's page now.
3. Two embedding helper functions have been added to provide more control over the machine startup
and shutdown process:
+ *enableEvents(boolean)*: pass *false* to disable delivery of all page events to all machines on the page,
or *true* to re-enable;
+ *sendEvent(string)*: pass *"init"*, *"show"* or *"exit"* to simulate the corresponding browser event
(*onload*, *onpageshow* or *onbeforeunload*, respectively).
If a page calls *enableEvents(false)* before calling *embedPC()*, all machine layouts will be instantiated
but the machines themselves will not be initialized. When the page is ready, call *enableEvents(true)* to restore
normal event processing, and if the browser has already sent the *onload* event, then call *sendEvent("init")*
to manually initialize the machine(s).
These two new functions are designed to assist in testing the starting up, shutting down and restarting of machines,
by allowing scripts to control the overall process, without requiring use of the browser's back/forward/close controls.
*[@jeffpar](http://twitter.com/jeffpar)*
*September 2, 2014*

66
blog/2014/09/13/README.md Normal file
View file

@ -0,0 +1,66 @@
The IBM PC AT: Alive and Booting
---
My first IBM PC AT (Model 5170) [Test Configuration](/configs/pc/machines/5170/ega/640kb/debugger/) finally
boots to a PC-DOS prompt. The configuration uses the original [IBM Model 5170 ROM BIOS](/devices/pc/bios/5170/),
dated January 10, 1984.
Getting through the BIOS "POST" (Power-On Self Test) diagnostics was like running an obstacle course, with various
tests derailing the simulation at every turn.
Sometimes the problems were as simple as missing hardware. For example, I knew that the PC AT contained two DMA
controllers, for a total of 8 DMA channels, but what I didn't know (or had forgotten) is that it also contained 16
DMA page registers, some of which the BIOS uses as scratch registers. Since DMA page registers are accessed with
I/O instructions that work identically in both real-mode and protected-mode, they obviously offer some advantages
over RAM, especially when the BIOS hasn't yet tested all the RAM, or determined how much RAM is installed, or set up
descriptors that allow the RAM to be accessed from protected-mode.
Aside from the additional DMA Controller, other major new motherboard components on the PC AT included a second
8259 Interrupt Controller, an 8042 Keyboard ("Kitchen Sink") Controller, and an MC146818 Real-Time Clock/CMOS chip.
The Keyboard Controller and Real-Time Clock/CMOS components required the most tinkering to pass through the ROM BIOS
gauntlet.
For example, at one point, the BIOS ("[TEST.21](../../../../pubs/pc/reference/ibm/static/5170/techref/pages/IBM-5170-TECHREF 202.pdf)")
reset the keyboard ("[KBD_RESET](../../../../pubs/pc/reference/ibm/static/5170/techref/pages/IBM-5170-TECHREF 212.pdf)"),
which unmasked the keyboard IRQ and waited for an interrupt, using a loop where CX was initialized to zero and then
decremented until either CX wrapped around to zero again *or* an interrupt occurred. The "TEST.21" code then assumed
that if "KBD_RESET" returned zero in CX, no interrupt had occurred.
Unfortunately, my Keyboard Controller was a bit too fast: it generated an interrupt as soon as the keyboard IRQ was
unmasked; as a result, CX was never decremented, leaving it at zero.
---
Most of the effort getting to this point involved adding support for 80286 protected-mode. That work is still far
from complete, but getting through multiple real-mode/protected-mode round trips in the BIOS was an important
milestone. Some of the work was outside the CPU component, such as A20 support and processor reset via the 8042
controller. Work inside the CPU component included:
- New 80286 general-purpose instructions (eg, ENTER, LEAVE, new PUSH SP behavior, etc)
- New protected-mode instructions (eg, ARPL, LGDT, LIDT, LAR, LSL, VERR, VERW, etc)
- Protected-mode segment loading, addressing, and fault handling
Another "feature" I spent considerable time on was ensuring that 80286 protected-mode support did not adversely
real-mode performance, so that the PC and PC XT simulations still run (almost) as fast as before. PCjs dynamically
reconfigures itself according to the requirements of the processor and platform it's emulating.
---
There's still no support for [LOADALL](/pubs/pc/reference/intel/80286/loadall/) or triple-fault resets, nor for
call gates or task gates, nor for conforming code segments or expand-down data segments. 80286-specific cycle
counts haven't been incorporated yet, either. The list of remaining 80286 features is long.
And there's plenty of hardware support left to do: I haven't looked at the AT hard disk controller yet (which
I believe is significantly different from the XT hard disk controller), and the keyboard *barely* works; the 8042
Keyboard Controller and AT keyboard had a number of features that older PC/XT keyboards did not (like LEDs and
programmable repeat rate).
And there are plenty of issues to investigate. For example, PC-DOS is picking up the correct RTC time, but not the
date (PCjs initializes the RTC to the browser's current date/time, unless a hard-coded date/time is specified in the
machine XML). And diskette I/O seems a bit slow; I'm concerned that the BIOS is spinning its wheels somewhere
unnecessarily. And even though the test machine is configured with 640Kb of RAM, the BIOS is reporting only 64Kb.
Hmmmm.
*[@jeffpar](http://twitter.com/jeffpar)*
*September 13, 2014*