Merge branch 'next-release'
This commit is contained in:
commit
ce9b8f12be
97 changed files with 4416 additions and 336 deletions
56
_posts/2013-11-20-a-blog-thats-not-a-blog.md
Normal file
56
_posts/2013-11-20-a-blog-thats-not-a-blog.md
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
layout: post
|
||||
title: "A Blog That's Not A Blog"
|
||||
date: 2013-11-20 11:00:00
|
||||
category: News
|
||||
permalink: /blog/2013/11/20/
|
||||
---
|
||||
|
||||
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](/devices/pcx86/machine/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](/devices/pcx86/machine/) 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*
|
||||
19
_posts/2014-01-01-new-year-new-directions.md
Normal file
19
_posts/2014-01-01-new-year-new-directions.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
layout: post
|
||||
title: New Year, New Directions
|
||||
date: 2014-01-01 11:00:00
|
||||
category: Goals
|
||||
permalink: /blog/2014/01/01/
|
||||
---
|
||||
|
||||
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*
|
||||
56
_posts/2014-03-30-running-on-azure.md
Normal file
56
_posts/2014-03-30-running-on-azure.md
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
layout: post
|
||||
title: Running on Azure
|
||||
date: 2014-03-30 11:00:00
|
||||
category: Web Servers
|
||||
permalink: /blog/2014/03/30/
|
||||
---
|
||||
|
||||
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,
|
||||
[us83-buttons-minimal.xml](/devices/pcx86/keyboard/us83-buttons-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:
|
||||
|
||||

|
||||
|
||||
Sigh. But at least the site is up and fully operational now.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*March 30, 2014*
|
||||
47
_posts/2014-03-31-browser-compatibility-woes.md
Normal file
47
_posts/2014-03-31-browser-compatibility-woes.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
layout: post
|
||||
title: Browser Compatibility Woes
|
||||
date: 2014-03-31 11:00:00
|
||||
category: JavaScript
|
||||
permalink: /blog/2014/03/31/
|
||||
---
|
||||
|
||||
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).
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
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*
|
||||
23
_posts/2014-04-01-the-latest-in-emulator-technology.md
Normal file
23
_posts/2014-04-01-the-latest-in-emulator-technology.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
layout: post
|
||||
title: The Latest in Emulator Technology
|
||||
date: 2014-04-01 11:00:00
|
||||
category: JavaScript
|
||||
permalink: /blog/2014/04/01/
|
||||
---
|
||||
|
||||
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*
|
||||
26
_posts/2014-04-12-whats-new-in-1.13.0.md
Normal file
26
_posts/2014-04-12-whats-new-in-1.13.0.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
layout: post
|
||||
title: "What's New in 1.13.0"
|
||||
date: 2014-04-12 11:00:00
|
||||
category: Releases
|
||||
permalink: /blog/2014/04/12/
|
||||
---
|
||||
|
||||
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/).
|
||||
|
||||
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*
|
||||
156
_posts/2014-04-14-node-express-safari.md
Normal file
156
_posts/2014-04-14-node-express-safari.md
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Node + Express != Safari"
|
||||
date: 2014-04-14 11:00:00
|
||||
category: Browsers
|
||||
permalink: /blog/2014/04/14/
|
||||
---
|
||||
|
||||
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).
|
||||
|
||||
[{{ site.pcjs.domain }}]({{ site.url }}/) 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](/devices/pcx86/machine/5150/mda/64kb/machine.xml) file that's also embedded on the
|
||||
[{{ site.pcjs.domain }}]({{ site.url }}/) 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 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:
|
||||
|
||||
{% highlight javascript linenos %}
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
{% endhighlight %}
|
||||
|
||||
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*
|
||||
45
_posts/2014-04-30-heading-to-new-york.md
Normal file
45
_posts/2014-04-30-heading-to-new-york.md
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
---
|
||||
layout: post
|
||||
title: Heading to New York
|
||||
date: 2014-04-30 11:00:00
|
||||
category: JavaScript
|
||||
permalink: /blog/2014/04/30/
|
||||
---
|
||||
|
||||
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 you’re 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 you’re 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*
|
||||
33
_posts/2014-05-12-chrome-kicks-butt.md
Normal file
33
_posts/2014-05-12-chrome-kicks-butt.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
layout: post
|
||||
title: Chrome Kicks Butt
|
||||
date: 2014-05-12 11:00:00
|
||||
category: JavaScript
|
||||
permalink: /blog/2014/05/12/
|
||||
---
|
||||
|
||||
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*
|
||||
81
_posts/2014-06-14-halt-and-catch-liar.md
Normal file
81
_posts/2014-06-14-halt-and-catch-liar.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
---
|
||||
layout: post
|
||||
title: Halt and Catch Liar
|
||||
date: 2014-06-14 11:00:00
|
||||
category: TV Shows
|
||||
permalink: /blog/2014/06/14/
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
[<img src="/blog/images/halt-and-catch-liar-small.jpg" alt='"Halt and Catch Fire" Scene from Episode 2'/>](/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*
|
||||
18
_posts/2014-06-26-more-under-the-hood-changes.md
Normal file
18
_posts/2014-06-26-more-under-the-hood-changes.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
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*
|
||||
48
_posts/2014-07-30-ega-support.md
Normal file
48
_posts/2014-07-30-ega-support.md
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
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.
|
||||
|
||||
[<img src="/blog/images/win101-array-demo-small.jpg" alt='Windows 1.01 "Server Array" Demo'/>](/blog/images/win101-array-demo.jpg)
|
||||
|
||||
EGA support is added to a **machine.xml** file using two XML elements; eg:
|
||||
|
||||
```xml
|
||||
<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
|
||||
<machine> element.
|
||||
|
||||
The second required XML element is a <rom> element to load the EGA ROM; eg:
|
||||
|
||||
```xml
|
||||
<rom id="romEGA" addr="0xc0000" size="0x4000" file="/devices/pcx86/video/ibm-ega.json" notify="videoEGA"/>
|
||||
```
|
||||
|
||||
The *notify* attribute must match the *id* of the <video> 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 <video> 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*
|
||||
32
_posts/2014-08-01-pc-tech-journal-1987.md
Normal file
32
_posts/2014-08-01-pc-tech-journal-1987.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
layout: post
|
||||
title: PC Tech Journal, 1987
|
||||
date: 2014-08-01 11:00:00
|
||||
category: PC Tech Journal
|
||||
permalink: /blog/2014/08/01/
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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*
|
||||
53
_posts/2014-08-28-supporting-the-80286.md
Normal file
53
_posts/2014-08-28-supporting-the-80286.md
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
---
|
||||
layout: post
|
||||
title: Supporting the 80286
|
||||
date: 2014-08-28 11:00:00
|
||||
category: 80286
|
||||
permalink: /blog/2014/08/28/
|
||||
---
|
||||
|
||||
The next milestone for PCx86 is complete 80286 emulation. My hope is to have it working by the end of the year.
|
||||
|
||||
PCx86 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 PCx86 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 **pcx86.js**.
|
||||
|
||||
Up until now, all PCx86 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:
|
||||
|
||||
```xml
|
||||
<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. PCx86 takes a
|
||||
different approach, by attempting to simulate an entire PC as it originally existed. Which is why a PCx86 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 PCx86 simulation of a 4.77Mhz IBM PC runs at 4.77Mhz. And a PCx86 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 PCx86 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 PCx86 is shooting for.
|
||||
|
||||
PCx86 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*
|
||||
32
_posts/2014-09-02-minor-fixes-and-additions.md
Normal file
32
_posts/2014-09-02-minor-fixes-and-additions.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
layout: post
|
||||
title: Minor Fixes and Additions
|
||||
date: 2014-09-02 11:00:00
|
||||
category: Releases
|
||||
permalink: /blog/2014/09/02/
|
||||
---
|
||||
|
||||
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*
|
||||
71
_posts/2014-09-13-the-ibm-pc-at-alive-and-booting.md
Normal file
71
_posts/2014-09-13-the-ibm-pc-at-alive-and-booting.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
---
|
||||
layout: post
|
||||
title: "The IBM PC AT: Alive and Booting"
|
||||
date: 2014-09-13 11:00:00
|
||||
category: Releases
|
||||
permalink: /blog/2014/09/13/
|
||||
---
|
||||
|
||||
My first IBM PC AT (Model 5170) [Test Configuration](/devices/pcx86/machine/5170/ega/640kb/rev1/debugger/) finally
|
||||
boots to a PC-DOS prompt. The configuration uses the original [IBM Model 5170 ROM BIOS](/devices/pcx86/rom/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](http://archive.pcjs.org/pubs/pc/reference/ibm/5170/techref/1984-03/pages/IBM-5170-TECHREF 202.pdf)")
|
||||
reset the keyboard ("[KBD_RESET](http://archive.pcjs.org/pubs/pc/reference/ibm/5170/techref/1984-03/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 drive controller yet (which
|
||||
I believe is significantly different from the XT hard drive 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*
|
||||
246
_posts/2014-09-30-pcjs-coding-conventions.md
Normal file
246
_posts/2014-09-30-pcjs-coding-conventions.md
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
---
|
||||
layout: post
|
||||
title: PCjs Coding Conventions
|
||||
date: 2014-09-30 11:00:00
|
||||
category: JavaScript
|
||||
permalink: /blog/2014/09/30/
|
||||
---
|
||||
|
||||
Here are a few highlights of the (evolving) JavaScript coding conventions used in PCjs.
|
||||
|
||||
### Tabs vs. Spaces
|
||||
|
||||
I've configured my IDE ([WebStorm](http://www.jetbrains.com/webstorm/)) to NEVER use tab characters in .js files
|
||||
(spaces only) and to ALWAYS use tab characters in almost every other type of text file. This is largely because
|
||||
when a web browser displays a JavaScript file (either in the main window or in the Developer Tools window), tabs
|
||||
usually screw up the formatting, which I find annoying when I'm debugging. XML files, on the other hand,
|
||||
are usually reformatted by the browser anyway, so in those cases, I opt for smaller files and use real tabs.
|
||||
|
||||
Note that most of the JavaScript delivered by a PCjs production server will have been compiled by Google's
|
||||
Closure Compiler, which completely eliminates all non-essential whitespace, so this is just a development
|
||||
preference, with little to no impact on production files.
|
||||
|
||||
Regardless of the choice of tab character however, I almost always use 4-column tab stops, except in legacy .asm
|
||||
files, where 8-column tab stops were the norm.
|
||||
|
||||
I've noticed that 2-column tab stops have recently become popular, especially in Node projects; NPM, for example,
|
||||
will rewrite package.json files, replacing my 4-column spacing with 2-column spacing. I don't fight that trend -- I
|
||||
just ignore it.
|
||||
|
||||
### Constants
|
||||
|
||||
Property names with all UPPER-CASE letters (with optional numbers and/or underscores) represent constants.
|
||||
|
||||
I originally adopted this rule in part because it's a popular C language convention, but also because it
|
||||
made it easy to write a preprocessing script (see the PCjs Grunt task **prepjs** in /modules/grunts/prepjs/)
|
||||
that replaced all such property references with the corresponding property values and then removed the original
|
||||
property definitions. Of course, this convention also depended on the properties never being modified *or* enumerated.
|
||||
|
||||
I later discovered that Google's Closure Compiler does an excellent job of automatically inlining properties
|
||||
that are never modified or enumerated, so the **prepjs** preprocessing script is no longer used, but I've stuck
|
||||
with the UPPER-CASE convention.
|
||||
|
||||
I don't bother with JSDoc *@const* annotations, because 1) the project contains far too many constants, 2)
|
||||
all the constants are already effectively annotated by virtue of being UPPER-CASE, and 3) there is no noticeable
|
||||
improvement in the Closure Compiler's inlining capability with the addition of *@const*.
|
||||
|
||||
All constants associated with a component are normally attached to the component's constructor; ie, as properties of
|
||||
the constructor. If you think of a JavaScript constructor as a "class', then constants attached to the constructor
|
||||
can be thought of as "class constants".
|
||||
|
||||
For example, the ChipSet component, which manages (among other things) Programmable Interrupt Controllers or PICs,
|
||||
*could* define the constant for an EOI command like this:
|
||||
|
||||
``` javascript
|
||||
ChipSet.EOI = 0x20; // non-specific EOI (end-of-interrupt)
|
||||
```
|
||||
|
||||
but since the EOI command is actually one of a number Operation Command Words (specifically, OCW2), I include an
|
||||
"OCW2_" prefix in the constant name:
|
||||
|
||||
``` javascript
|
||||
ChipSet.OCW2_EOI = 0x20; // non-specific EOI (end-of-interrupt)
|
||||
```
|
||||
|
||||
and since I also like to group constants that are associated with a particular register or port, and since I don't
|
||||
want the ChipSet constructor becoming littered with property constants, I first define a constant object; in this
|
||||
case, **PIC_LO**:
|
||||
|
||||
``` javascript
|
||||
ChipSet.PIC_LO = {};
|
||||
ChipSet.PIC_LO.OCW2_EOI = 0x20; // non-specific EOI (end-of-interrupt)
|
||||
ChipSet.PIC_LO.OCW2_EOI_SPEC = 0x60; // specific EOI
|
||||
ChipSet.PIC_LO.OCW2_EOI_ROT = 0xA0; // rotate on non-specific EOI
|
||||
ChipSet.PIC_LO.OCW2_EOI_ROTSPEC = 0xE0; // rotate on specific EOI
|
||||
```
|
||||
|
||||
By using fully-qualified property names for each constant, the code has a more C-like appearance (think *#define*)
|
||||
that's also easier to preprocess.
|
||||
|
||||
However, I've gradually switched to the more conventional JavaScript object notation for class constants:
|
||||
|
||||
``` javascript
|
||||
ChipSet.PIC_LO = {
|
||||
OCW2_EOI: 0x20, // non-specific EOI (end-of-interrupt)
|
||||
OCW2_EOI_SPEC: 0x60, // specific EOI
|
||||
OCW2_EOI_ROT: 0xA0, // rotate on non-specific EOI
|
||||
OCW2_EOI_ROTSPEC: 0xE0 // rotate on specific EOI
|
||||
};
|
||||
```
|
||||
|
||||
because, again, the Closure Compiler does an excellent job inlining such constants (or indeed any property that is
|
||||
never modified *or* enumerated).
|
||||
|
||||
### DEBUG vs. RELEASE
|
||||
|
||||
While we're talking about constants, it's important to be aware of constants that are not scoped to
|
||||
any particular component.
|
||||
|
||||
In [/modules/shared/lib/defines.js](/modules/shared/lib/defines.js), **DEBUG** is set to **TRUE**,
|
||||
enabling all debug-only code by default. It is also declared as a *@define* so that the Closure Compiler can
|
||||
override it, setting it to **FALSE** and disabling debug-only code.
|
||||
|
||||
To ensure that debug-only code is not simply *disabled* but also *removed*, the code should be wrapped with:
|
||||
|
||||
``` javascript
|
||||
if (DEBUG) {
|
||||
[code to be removed by the Closure Compiler]
|
||||
}
|
||||
```
|
||||
|
||||
In many cases, the compiler is able to completely remove calls to debug-only class methods; eg:
|
||||
|
||||
``` javascript
|
||||
Component.assert(off >= 0 && off < this.cb);
|
||||
```
|
||||
|
||||
However, calls to debug-only instance methods seem to be more problematic, so all such calls are wrapped; eg:
|
||||
|
||||
``` javascript
|
||||
if (DEBUG) this.log('load("' + sFileURL + '")');
|
||||
```
|
||||
|
||||
There are a number of other important shared constants in [/modules/shared/lib/defines.js](/modules/shared/lib/defines.js)
|
||||
and PCjs-specific constants in [/modules/pcx86/lib/defines.js](/modules/pcx86/lib/defines.js); refer
|
||||
to those files for more information.
|
||||
|
||||
### Braces and Parentheses
|
||||
|
||||
Most opening braces appear at the end of the line containing the associated "if", "while", "for", "switch",
|
||||
"function", etc, preceded by a single space. And most opening parentheses are also preceded by a single space,
|
||||
except when following "function" or a function name, in which case there is NO space.
|
||||
|
||||
There's always the occasional exception. For example, the opening brace of all the top-level (documented)
|
||||
functions in a module may appear on its own line, because the extra whitespace can make the code a bit more
|
||||
readable.
|
||||
|
||||
It's also important to be aware of JavaScript's automatic semicolon insertion feature and the associated danger of
|
||||
putting an opening brace below a *return* statement that wants to return an object literal. As long as you (and
|
||||
your IDE) are aware of that specific danger, there's no need to be dogmatic about opening braces.
|
||||
|
||||
### Variable Names
|
||||
|
||||
I still tend to follow Charles Simonyi's "[Hungarian](http://en.wikipedia.org/wiki/Hungarian_notation)" naming
|
||||
conventions -- or rather, a naming convention loosely inspired by Hungarian.
|
||||
|
||||
For example, if I need a string or numeric variable representing a "thing," I will name it "sThing" if it's a
|
||||
string or "iThing" if it's a number (or possibly "nThings" if it represents a total of Things or "cThings"
|
||||
if it's a counter of Things). If a string or numeric variable has a very short-term use, I'll probably just name
|
||||
it "s" or "i".
|
||||
|
||||
As I mention [below](./#quotation-marks), I still tend to distinguish single characters from strings too,
|
||||
which means I may sometimes prefix character variables with "ch" and character counters with "cch".
|
||||
|
||||
Of course, variable name prefixes like "s" and "n" are irrelevant if you've already given your variables meaningful
|
||||
names like "nameOfPerson" or "numberOfPeople". And that's fine -- I sometimes do that as well. But in general,
|
||||
I still prefer variable names like "sPerson" and "nPeople".
|
||||
|
||||
I don't try to come up with special prefixes for Objects. If there's a Person object, for example, I'll probably
|
||||
use colloquial names like "personHere" or "personThere". I am stricter with Arrays though: I prefix array variables
|
||||
with "a", arrays of strings and numbers with "as" and "ai" (or "an"), arrays of arrays with "aa", etc. As for Arrays
|
||||
of anything else, I usually don't bother with anything more than an "a" prefix.
|
||||
|
||||
### Quotation Marks
|
||||
|
||||
Because of my C background, I prefer to use double-quotes around multi-character strings and single quotes
|
||||
around single-character strings. While the reasons for doing so are largely historical and currently irrelevant,
|
||||
characters are STILL the building blocks of strings, and even the JavaScript String class contains methods that
|
||||
deal with individual characters (eg, charCodeAt() and fromCharCode()). So for any code that deals explicitly with
|
||||
individual characters, I like to reinforce that with single quotes.
|
||||
|
||||
Also, to emphasize that object property names aren't really strings (even though strings can be used as property
|
||||
names), I tend to use single quotes when quoting property names. That does make me somewhat inconsistent with
|
||||
the JSON standard, which insists that property names be double-quoted, but JSON.stringify() takes care of that, so
|
||||
it's not really a problem. Besides, I have a lot of quibbles with the JSON standard, like its "disapproval" of
|
||||
comments and hexadecimal constants, and its failure to faithfully serialize and deserialize uninitialized Array
|
||||
objects, but I'll leave my gripes about JSON for another post.
|
||||
|
||||
Generally speaking, the only time I quote property names is when I have to. I'll use the "dot" syntax; eg:
|
||||
|
||||
``` javascript
|
||||
obj.prop = true;
|
||||
```
|
||||
|
||||
instead of:
|
||||
|
||||
``` javascript
|
||||
obj['prop'] = true;
|
||||
```
|
||||
|
||||
unless the property name doesn't conform to variable name syntax (eg, if it starts with a digit) or if it's a
|
||||
"public" property and therefore I can't risk Google's Closure Compiler "minifying" the property name to something
|
||||
else.
|
||||
|
||||
I break my own quoting rules slightly when dealing with strings that *contain* double-quotes, since it's more readable
|
||||
to put double-quotes inside single-quoted strings than to "escape" every double-quote with a backslash.
|
||||
|
||||
For code that I originally wrote in PHP and later ported to JavaScript, there was a tendency in the original
|
||||
code to always use double-quotes around strings and "escape" double-quotes regardless, and that tendency may linger
|
||||
in code I didn't feel like rewriting much, but the tendency was due more to idiosyncrasies of PHP than any convention
|
||||
of mine; for example:
|
||||
|
||||
- single-quoted PHP strings may not include any escaped characters (except for single-quote and backslash)
|
||||
- single-quoted PHP strings cannot resolve references to string variables (eg, "the value of foo is {$foo}")
|
||||
|
||||
Because of PHP's restrictions on single-quoted strings, I tended to avoid them. However, in JavaScript, those
|
||||
restrictions/features don't exist.
|
||||
|
||||
### JSDoc
|
||||
|
||||
Most of the PCjs code is documented with [JSDoc](http://usejsdoc.org/) annotations -- not
|
||||
because I want to be able to generate documentation (although that's something to think about), but because
|
||||
it's the only way to tell both the Closure Compiler and my IDE exactly what data types are passed around.
|
||||
The goals are to minimize the number of "code inspection" warnings in the IDE and produce warning-free
|
||||
compilations.
|
||||
|
||||
In order to use the Closure Compiler's ADVANCED_OPTIMIZATIONS option and get maximum performance (and maximum
|
||||
"minification", a form of "uglification"), every function and its parameters needs to be fully typed; otherwise,
|
||||
the Compiler generates way too many warnings/errors -- at least, that was the case when I first started using
|
||||
it a couple of years ago.
|
||||
|
||||
I've adopted a zero-tolerance policy for warnings: nothing gets checked in if the Closure Compiler generates even
|
||||
a single warning.
|
||||
|
||||
And finally, speaking of warnings, I've had to tell [WebStorm](http://www.jetbrains.com/webstorm/) to "shut up"
|
||||
about a few:
|
||||
|
||||
- Unfiltered for…in loop
|
||||
- Bitwise operator usage
|
||||
- Comma expressions
|
||||
- loop statement that doesn't loop
|
||||
- “throw” of exception caught locally
|
||||
|
||||
I acknowledge those those features can introduce bugs if you're not careful, so I make sure I'm careful. I don't
|
||||
subscribe to the dogmatic approach that others (eg, the author of JSLint) take about so-called "risky" features.
|
||||
I agree that it's always a good idea to walk to the crosswalk before crossing a street, but I don't agree that it's
|
||||
*never* a good idea to cross in the middle sometimes, too.
|
||||
|
||||
I've also made the following "weak warnings" instead of "warnings":
|
||||
|
||||
- Unused JavaScript / ActionScript local symbol
|
||||
|
||||
because it's a useful warning, but I don't like being penalized for functions that have been "prototyped" a specific
|
||||
way but can't always be implemented exactly as prototyped.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*September 30, 2014*
|
||||
27
_posts/2014-10-12-pcjs-released-on-github.md
Normal file
27
_posts/2014-10-12-pcjs-released-on-github.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
layout: post
|
||||
title: PCjs Released on GitHub
|
||||
date: 2014-10-12 11:00:00
|
||||
category: Releases
|
||||
permalink: /blog/2014/10/12/
|
||||
---
|
||||
|
||||
I've decided the time has come to make the [PCjs Project](https://github.com/jeffpar/pcjs) an open source project on
|
||||
[GitHub](http://github.com/).
|
||||
|
||||
This doesn't mean PCjs is done -- not by a long shot. But I promised to release it on GitHub by the end of
|
||||
the year, which is fast approaching, and I didn't really want to do this in December.
|
||||
|
||||
I feel I've made pretty good progress on my goals for the year -- primarily EGA and PC AT support. PC AT machines
|
||||
can boot and run in real-mode now, but there's still a lot of protected-mode work to do. The big remaining goal for
|
||||
this year is to boot OS/2 1.0.
|
||||
|
||||
There are also a lot of rough edges left to polish. Holes in EGA emulation remain to be filled (support for dynamically
|
||||
loaded fonts is one of the bigger ones). And the PC AT Keyboard, along with the 8042 and Hard Drive controllers, are all
|
||||
just limping along at the moment.
|
||||
|
||||
Longer term, I'm looking forward to building some new tools, including an "IBM PC Configurator" that will take some
|
||||
of the pain out of building your own bootable PCjs machine configurations, and make them easier to share, embed, etc.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*October 12, 2014*
|
||||
34
_posts/2014-10-13-the-8mhz-ibm-pc-at-5170.md
Normal file
34
_posts/2014-10-13-the-8mhz-ibm-pc-at-5170.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
layout: post
|
||||
title: The 8Mhz IBM PC AT 5170
|
||||
date: 2014-10-13 11:00:00
|
||||
category: JavaScript
|
||||
permalink: /blog/2014/10/13/
|
||||
---
|
||||
|
||||
I just added my first [8Mhz IBM PC AT](/devices/pcx86/machine/5170/ega/1152kb/rev3/debugger/) machine configuration
|
||||
to the list of [IBM PC Machine Configurations](/devices/pcx86/machine/), and not surprisingly, the new machine
|
||||
fails to boot.
|
||||
|
||||
This machine uses the 3rd [ROM BIOS](/devices/pcx86/rom/5170/) that IBM released for the PC AT, a revision that
|
||||
included support for 3.5-inch 1.44Mb diskettes -- which will be nice, because I have a number of 1.44Mb diskette
|
||||
images I would like to be able to read in a PCjs machine.
|
||||
|
||||
Since machines with this BIOS also ran at 8Mhz, I've bumped the CPU speed up to 8,000,000 cycles/second.
|
||||
It'll be interesting to see whether this BIOS also increased any of its hard-coded timing delay-loops as a result.
|
||||
|
||||
Anyway, when I enabled ChipSet I/O port messages in the Debugger:
|
||||
|
||||
m chipset on
|
||||
m port on
|
||||
|
||||
I can see that the BIOS Power-On Self Test (POST) progresses nicely until it starts generating lots of port 0x61
|
||||
activity:
|
||||
|
||||
chipset.inPort(0x0061,8042_RWREG): 0x30 at F000:05A8
|
||||
chipset.inPort(0x0061,8042_RWREG): 0x20 at F000:05AE
|
||||
|
||||
I know what I'm going to be doing this afternoon now.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*October 13, 2014*
|
||||
58
_posts/2014-10-17-improved-support-for-pc-at-machines.md
Normal file
58
_posts/2014-10-17-improved-support-for-pc-at-machines.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
layout: post
|
||||
title: Improved support for PC AT machines
|
||||
date: 2014-10-17 11:00:00
|
||||
category: Releases
|
||||
permalink: /blog/2014/10/17/
|
||||
---
|
||||
|
||||
The [8Mhz IBM PC AT](/devices/pcx86/machine/5170/ega/1152kb/rev3/debugger/) machine configuration now boots in
|
||||
[PCjs v1.15.5](https://github.com/jeffpar/pcjs/releases/tag/v1.15.5), which includes the following fixes:
|
||||
|
||||
+ The BIOS expects memory refresh to occur roughly every 16us, which I've resolved by tying the state
|
||||
of the refresh bit in port 0x61 to bit 6 of the CPU cycle count (see *in8042RWReg()* in [chipset.js](/modules/pcx86/lib/chipset.js));
|
||||
the original AT BIOS was satisfied with a refresh bit that merely alternated, whereas the new AT BIOS
|
||||
is much more particular about the rate at which that bit changes, since many hard-coded delay-loops have
|
||||
now been replaced with code that waits for a specific number of refresh cycles.
|
||||
|
||||
+ The 8042 Keyboard Controller emulation needed a few more tweaks, mainly with respect to what happens
|
||||
when the keyboard's "clock" line is toggled (see *set8042CmdData()* in [chipset.js](/modules/pcx86/lib/chipset.js)).
|
||||
|
||||
+ The Floppy Drive Controller needed to add support for the "READ ID" command, in order for the BIOS
|
||||
"double-stepping" test to work (double-stepping is required on an 80-track drive when attempting to read
|
||||
a 40-track diskette).
|
||||
|
||||
+ The BIOS Diskette Reset function does something odd after resetting the Floppy Drive Controller: it
|
||||
issues not one but *four* "SENSE INTERRUPT STATUS" commands to the FDC, and expects each response to
|
||||
return an incrementally larger drive number. I found this a bit mystifying, considering that IBM's
|
||||
own FDC/HDC "combo card" supports a maximum of *two* diskette drives. But, there's no point arguing
|
||||
with a BIOS that's almost 30 years old.
|
||||
|
||||
+ The BIOS attempts to detect what its authors must have considered a common problem: the user's failure
|
||||
to run SETUP after installing a second hard drive. So, when the CMOS reports only one hard drive installed,
|
||||
the BIOS probes for a second hard drive anyway, and it does so by simply writing the drive number to the ATC's
|
||||
"DRVHD" register and then immediately reading the "STATUS" register, without issuing any intervening command.
|
||||
It was an easy fix to *outATCDrvHd()* in [hdc.js](/modules/pcx86/lib/hdc.js), but I was surprised
|
||||
to discover that the ATC had this behavior, and now I'm wondering if there are any other I/O operations
|
||||
that must immediately update the "STATUS" register.
|
||||
|
||||
This PCjs release also fixes a problem reported by a user: if you disable **localStorage** support in your
|
||||
browser, previous versions of PCjs would fault. While every browser that supports PCjs also supports
|
||||
**localStorage**, I didn't consider what might happen if a user decided to turn it off.
|
||||
|
||||
The only downside to turning off **localStorage** is that none of your PCjs machines will be able save/restore
|
||||
their state when you leave/return to the page; they will always reboot.
|
||||
|
||||
Browser's don't always refer to the **localStorage** feature by its actual name, either. For example, in
|
||||
Chrome, the setting that enables/disables **localStorage** is hidden under "Advanced Settings" => "Privacy" =>
|
||||
"Content Settings" => "Cookies" => "Allow local data to be set (recommended)". Which is somewhat misleading
|
||||
and a little annoying, because **localStorage** is *not* a **cookie**.
|
||||
|
||||
PCjs *never* sets any cookies. Cookies are bits of data that your browser saves and then automatically sends
|
||||
off to the server every time you make a request. **localStorage** is nothing more than local storage; it is
|
||||
*not* automatically sent anywhere. Granted, a JavaScript application could abuse it and send it out just like a
|
||||
cookie, but PCjs does *not* do that; the only exception is when PCjs detects a problem, and even then, you must
|
||||
first agree to submit your machine's state as part of the bug report.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*October 17, 2014*
|
||||
27
_posts/2014-10-23-improved-pc-dos-700-support.md
Normal file
27
_posts/2014-10-23-improved-pc-dos-700-support.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
layout: post
|
||||
title: Improved PC-DOS 7.00 Support
|
||||
date: 2014-10-23 11:00:00
|
||||
category: Releases
|
||||
permalink: /blog/2014/10/23/
|
||||
---
|
||||
|
||||
[PCjs v1.15.6](https://github.com/jeffpar/pcjs/releases/tag/v1.15.6) is a fairly minor update that fixes a few
|
||||
Floppy Drive Controller (FDC) issues and one CPU emulation bug that prevented [PC-DOS 7.00](/disks/pcx86/dos/ibm/7.00/)
|
||||
from working properly.
|
||||
|
||||
There are also some Debugger improvements; for example, if you turn on "fdc" and "int" messages in the
|
||||
Debugger using the "m fdc on" and "m int on" commands, all FDC (INT 0x13) software interrupts will be logged,
|
||||
including descriptions and register values.
|
||||
|
||||
PC-DOS 7.00 still can't be setup from its specially-formatted 1.84Mb
|
||||
[XDF](http://www.os2museum.com/wp/the-xdf-diskette-format/) distribution disk images, "PC-DOS 7.00 (Disk 2)"
|
||||
through "PC-DOS 7.00 (Disk 5)", so your best bet is to boot from the 1.44Mb "PC-DOS 7.00 (1.44M Boot)".
|
||||
|
||||
Note that you must also use a fairly new 80286 machine configuration, like this
|
||||
[8Mhz IBM PC AT](/devices/pcx86/machine/5170/ega/1152kb/rev3/debugger/),
|
||||
in order to use 1.44Mb diskette images; previous models did not support 3.5-inch diskette drives, unless they had been
|
||||
retrofitted with a newer [BIOS](/devices/pcx86/rom/5170/).
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*October 23, 2014*
|
||||
83
_posts/2014-10-26-javascript-negativity.md
Normal file
83
_posts/2014-10-26-javascript-negativity.md
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
---
|
||||
layout: post
|
||||
title: JavaScript Negativity
|
||||
date: 2014-10-26 11:00:00
|
||||
category: JavaScript
|
||||
permalink: /blog/2014/10/26/
|
||||
---
|
||||
|
||||
Coming from the C programming language, it's easy to be "negative" about how JavaScript deals with 32-bit integers.
|
||||
|
||||
As a newcomer, you quickly learn that JavaScript supports only one numeric data type -- 64-bit floats -- and you groan.
|
||||
|
||||
Then you learn that all the "bitwise" operators (**~**, **|**, **&**, **^**, **<<**, **>>** and
|
||||
**>>>**) treat their operands as 32-bit integer values and produce 32-bit integer results, and you breathe
|
||||
a sigh of relief.
|
||||
|
||||
But then you start noticing oddities. In C, you can take any 32-bit value, such as -1526726656 (which is equivalent
|
||||
to 0xA5000000), mask it with 0x80808080, and get 0x80000000. However, in JavaScript, you actually get -0x80000000,
|
||||
which, sadly, is not equal to 0x80000000.
|
||||
|
||||
To verify, type the following into any JavaScript REPL (eg, Node):
|
||||
|
||||
> n = -1526726656
|
||||
-1526726656
|
||||
> n &= 0x80808080
|
||||
-2147483648
|
||||
> n == 0x80000000
|
||||
false
|
||||
> n == -0x80000000
|
||||
true
|
||||
|
||||
The sign (bit 31) of every 32-bit result is always extended into the entire 52 "significand" bits of the underlying
|
||||
64-bit float. And it's impossible to simply "mask away" those additional sign bits, thanks to a fundamental
|
||||
restriction of JavaScript bitwise operators: they operate *only* on the low 32 bits.
|
||||
|
||||
With one exception: the unsigned right-shift operator. It does more than simply shift zero bits in from
|
||||
the left; it also zeros all the bits above the sign bit. This means that `n >>> 0`, while leaving the low 32 bits
|
||||
unchanged, also clears the upper bits, resulting in a value that is positive, albeit outside the signed 32-bit range.
|
||||
It is equivalent to adding the 33-bit value 0x100000000 to a negative 32-bit number:
|
||||
|
||||
> n = (n < 0? n + 0x100000000 : n)
|
||||
2147483648
|
||||
> n.toString(16)
|
||||
'80000000'
|
||||
|
||||
These operations work because JavaScript is perfectly capable of representing 0x80000000, or any other 32-bit value,
|
||||
as a positive number, but it must use a floating point value to do so. And be careful, because as soon as you perform
|
||||
*any* bitwise operation on a value with bit 31 set, even an operation as innocuous-looking as:
|
||||
|
||||
> n |= 0
|
||||
-2147483648
|
||||
> n.toString(16)
|
||||
'-80000000'
|
||||
|
||||
the result will be negative again. This is simply how all bitwise operators (except for unsigned right-shift) operate:
|
||||
they truncate the result to a signed 32-bit value.
|
||||
|
||||
This might tempt you to think that the right way to write negative 32-bit constants in hex is to simply precede
|
||||
them with a minus sign. But that would be wrong. For example, if you wrote the constant 0x80000080 as "-0x80000080",
|
||||
JavaScript would treat that as negation of 2147483776, resulting in a value whose low 32 bits are 0x7FFFFF80, not
|
||||
0x80000080.
|
||||
|
||||
The safest way to write a 32-bit constant like 0x80000080 is "0x80000080|0", which will produce -2147483520. If you
|
||||
write all your negative 32-bit constants that way, then you won't have to resort to using either unsigned right-shifts
|
||||
or 33-bit addition, which in turn avoids the use of floating point values.
|
||||
|
||||
To continue the fun, try setting bit 0 of 0x80000000, which should give you 0x80000001:
|
||||
|
||||
> n |= 1
|
||||
-2147483647
|
||||
> n.toString(16)
|
||||
'-7fffffff'
|
||||
|
||||
WTF? Have all the low 32 bits flipped instead?
|
||||
|
||||
Actually, no, this time, I'm pulling your leg. The low 32 bits of the internal value are exactly what you would
|
||||
expect: 0x80000001 (the internal representation is more like 0xFFFFF80000001). But as the
|
||||
[MDN Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString)
|
||||
explain, for a negative number, toString() returns the positive representation of the number, preceded by a - sign,
|
||||
*not* the "two's complement" of the number.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*October 26, 2014 (Updated September 8, 2015)*
|
||||
23
_posts/2014-10-28-limited-support-for-xdf-disk-images.md
Normal file
23
_posts/2014-10-28-limited-support-for-xdf-disk-images.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
layout: post
|
||||
title: Limited Support for XDF Diskettes
|
||||
date: 2014-10-28 11:00:00
|
||||
category: Releases
|
||||
permalink: /blog/2014/10/28/
|
||||
---
|
||||
|
||||
[PCjs v1.15.7](https://github.com/jeffpar/pcjs/releases/tag/v1.15.7) adds support for the
|
||||
[XDF Diskette Format](http://www.os2museum.com/wp/the-xdf-diskette-format/), which was used in
|
||||
[PC-DOS 7.00](/disks/pcx86/dos/ibm/7.00/).
|
||||
|
||||
However, this support is referred to as "fake" XDF support, because it requires using JSON disk images created
|
||||
by DiskDump *without* the experimental "--xdf" option, which is an option that attempts to encode XDF sectors as they
|
||||
existed on the original diskettes (ie, with varying lengths and non-standard sector IDs).
|
||||
|
||||
"Fake" XDF support works by using conventional 80-track disk images with 23 sectors/track. No standard PC floppy disk
|
||||
format ever used 23 sectors/track, but in this case, by distributing the XDF track data across 23 conventional 512-byte
|
||||
sectors, the PC-DOS 7.00 Setup code that reads XDF disks succeeds. This was probably one of several fall-back options
|
||||
built into the PC-DOS XDF code.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*October 28, 2014*
|
||||
55
_posts/2014-12-04-os2-10.md
Normal file
55
_posts/2014-12-04-os2-10.md
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
---
|
||||
layout: post
|
||||
title: OS/2 1.0
|
||||
date: 2014-12-04 11:00:00
|
||||
category: OS/2
|
||||
permalink: /blog/2014/12/04/
|
||||
---
|
||||
|
||||
Exciting news for OS/2 fans: PCjs (v1.16.1) is now able to run OS/2 1.0 on
|
||||
[IBM PC AT Machine Configurations](/devices/pcx86/machine/#model-5170-machine-configurations). This is the culmination
|
||||
of recent work in PCjs to fully emulate the Intel 80286 processor and 16-bit protected-mode, including undocumented
|
||||
features like [LOADALL](/pubs/pc/reference/intel/80286/loadall/) and triple-fault resets.
|
||||
|
||||
For a quick demo, try the [OS/2 1.0 Debugger Disk](/disks/pcx86/os2/misc/1.0/88286/). In a few seconds,
|
||||
you'll see a very rudimentary OS/2 shell (a slimmed-down version of the OS/2 Program Selector) that allows you to
|
||||
start the protected-mode command interpreter ("Start a Program") or the real-mode command interpreter ("command.com").
|
||||
|
||||
[<img src="/blog/images/os2-debugger.jpg" alt="OS/2 1.0 With Kernel Debugger"/>](/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*
|
||||
71
_posts/2014-12-05-canvas-performance-and-contenteditable.md
Normal file
71
_posts/2014-12-05-canvas-performance-and-contenteditable.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
---
|
||||
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*
|
||||
48
_posts/2015-01-17-pcjs-uncompiled.md
Normal file
48
_posts/2015-01-17-pcjs-uncompiled.md
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
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)*
|
||||
23
_posts/2015-01-28-new-pcjs-control-panel.md
Normal file
23
_posts/2015-01-28-new-pcjs-control-panel.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
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*
|
||||
30
_posts/2015-02-22-compaq-deskpro-386.md
Normal file
30
_posts/2015-02-22-compaq-deskpro-386.md
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
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*
|
||||
116
_posts/2015-02-23-early-80386-cpus.md
Normal file
116
_posts/2015-02-23-early-80386-cpus.md
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
---
|
||||
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*
|
||||
210
_posts/2015-03-26-javascript-idiosyncrasies.md
Normal file
210
_posts/2015-03-26-javascript-idiosyncrasies.md
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
---
|
||||
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*
|
||||
154
_posts/2015-04-16-compaq-deskpro-386-update.md
Normal file
154
_posts/2015-04-16-compaq-deskpro-386-update.md
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
---
|
||||
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*
|
||||
26
_posts/2015-05-20-pc-tech-journal-collection.md
Normal file
26
_posts/2015-05-20-pc-tech-journal-collection.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
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.
|
||||
|
||||
[<img src="http://archive.pcjs.org/pubs/pc/magazines/pctj/PCTJ-1983-07/thumbs/PCTJ-1983-07 1.jpeg" width="200" height="260" alt="PC Tech Journal, July-August 1983"/>](/pubs/pc/magazines/pctj/)
|
||||
|
||||
Happy reading!
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*May 20, 2015*
|
||||
142
_posts/2015-06-01-debugging-the-ibm-vga-rom.md
Normal file
142
_posts/2015-06-01-debugging-the-ibm-vga-rom.md
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
---
|
||||
layout: post
|
||||
title: Debugging the IBM VGA ROM
|
||||
date: 2015-06-01 11:00:00
|
||||
category: Video
|
||||
permalink: /blog/2015/06/01/
|
||||
---
|
||||
|
||||
The IBM VGA ("Video Graphics Array") standard was introduced as part of the IBM PS/2 line of computers;
|
||||
it was not a feature you could purchase or install in older PC, XT or AT-compatible machines. In fact, full VGA
|
||||
support was not even available in all PS/2 models.
|
||||
|
||||
Of the first four PS/2 models -- the 8086-based Model 30, the 80286-based Model 50 and Model 60, and the 80386-based
|
||||
Model 80 -- VGA support was available only in the three higher-end models. The Model 30 came with MCGA ("Multicolor
|
||||
Graphics Array") video hardware that supported a subset of VGA modes (eg, 640x480 2-color and 320x200 256-color graphics).
|
||||
|
||||
It wasn't until October 1987 that IBM finally introduced an 8-bit ISA card that brought VGA capability to older PCs.
|
||||
The card was called the **IBM PS/2 Display Adapter**. However, I think the name is a bit confusing, since the card
|
||||
could only be used in PC, XT, and AT-compatible systems. I'll refer to it here simply as the IBM VGA.
|
||||
|
||||
The VGA ROM used here is assumed to have come from an original IBM VGA. It's unknown if IBM ever made any
|
||||
revisions to the VGA ROM. With the introduction of the PS/2 family and the VGA, IBM decided to no longer publish
|
||||
the source code for its ROMs, so I've created some assemblable source code from the IBM VGA ROM
|
||||
[here](/devices/pcx86/video/ibm/vga/).
|
||||
|
||||
I've finally started debugging a machine configuration that uses the IBM VGA ROM. Since the VGA and the 80386 are
|
||||
contemporaries, I'm using an [80386 machine configuration](/devices/pcx86/machine/compaq/deskpro386/vga/2048kb/debugger/).
|
||||
However, I don't expect the IBM VGA ROM to require any 80386 support or PS/2-specific features.
|
||||
|
||||
The first problem I ran into was here:
|
||||
|
||||
;
|
||||
; Initialize the ROM BIOS Video Mode Options byte @40:0087 (default to color and 256Kb of RAM)
|
||||
;
|
||||
mov byte [0x487],0x60 ; 0000008D
|
||||
;
|
||||
; The x100 subroutine alternately enables port 0x3B? and 0x3D? decoding, verifying that there is
|
||||
; no response on opposing ports 0x3D? and 0x3B?, respectively; otherwise, it assumes that another
|
||||
; video card must exist and attempts to select co-existing settings for the VGA. For example, if
|
||||
; there is an unexpected response on the color ports, the VGA ROM will default to mono operation.
|
||||
;
|
||||
call x100 ; 00000092
|
||||
|
||||
The Video component installs I/O port handlers for all possible I/O ranges; when a range isn't being used, the
|
||||
associated I/O operations are redirected to a dummy Card, so that the active Card isn't affected. Here,
|
||||
however, that was insufficient. If the VGA is the only installed video card, the VGA ROM expects *NO RESPONSE*
|
||||
on inactive CRTC ports. So I've changed the CRTC I/O handlers to check the Card's fActive flag. This seems
|
||||
like a safe and logical change, but I still have to check for backward-compatibility issues with older ROMs.
|
||||
|
||||
Other problems included:
|
||||
|
||||
* Some bugs in Read Mode 1 that caused a memory test failure
|
||||
* Horizontal and vertical retrace timing issues (the ROM requires a specific number of intervals per second)
|
||||
* Differences between the EGA and VGA in the SWSENSE bit (bit 4) of Input Status Register 0
|
||||
|
||||
The last problem was the most puzzling, because the ROM programs a series of values into the first DAC register,
|
||||
and expects the SWSENSE bit of Input Status Register 0 to change in very specific ways, depending on the kind
|
||||
of monitor attached.
|
||||
|
||||
I've not found any hardware documentation that explains exactly how this should work. IBM's own Technical Reference
|
||||
material is extremely vague:
|
||||
|
||||
"Bit 4: Switch Sense Bit - This bit allows the system microprocessor to read the switch sense line.
|
||||
This bit allows the power-on self-test to determine if a monochrome or color display is connected to
|
||||
the system."
|
||||
|
||||
I've hard-coded a solution that assumes a color monitor. Support for using a monochrome monitor with an EGA was
|
||||
never completed, and this is another related issue that will have to be resolved for the VGA as well.
|
||||
|
||||
---
|
||||
|
||||
While debugging and fixing assorted IBM VGA issues, I made a table of all the register values for the video
|
||||
modes commonly used on the IBM VGA. Here's that table:
|
||||
|
||||
INT 0x10 Mode Requested: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x0D 0x0E 0x10 0x12 0x13
|
||||
|
||||
BIOSMODE: 0x01 0x01 0x03 0x03 0x04 0x04 0x06 0x0D 0x0E 0x10 0x12 0x13
|
||||
CRTC[0x00]: HTOTAL 0x2D 0x2D 0x5F 0x5F 0x2D 0x2D 0x5F 0x2D 0x5F 0x5F 0x5F 0x5F
|
||||
CRTC[0x01]: HDISP_END 0x27 0x27 0x4F 0x4F 0x27 0x27 0x4F 0x27 0x4F 0x4F 0x4F 0x4F
|
||||
CRTC[0x02]: HBLANK_START 0x28 0x28 0x50 0x50 0x28 0x28 0x50 0x28 0x50 0x50 0x50 0x50
|
||||
CRTC[0x03]: HBLANK_END 0x90 0x90 0x82 0x82 0x90 0x90 0x82 0x90 0x82 0x82 0x82 0x82
|
||||
CRTC[0x04]: HRETRACE_START 0x2B 0x2B 0x55 0x55 0x2B 0x2B 0x54 0x2B 0x54 0x54 0x54 0x54
|
||||
CRTC[0x05]: HRETRACE_END 0xA0 0xA0 0x81 0x81 0x80 0x80 0x80 0x80 0x80 0x80 0x80 0x80
|
||||
CRTC[0x06]: VTOTAL 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0x0B 0xBF
|
||||
CRTC[0x07]: OVERFLOW 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x1F 0x3E 0x1F
|
||||
CRTC[0x08]: PRESET_ROW 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
CRTC[0x09]: MAX_SCAN 0x4F 0x4F 0x4F 0x4F 0xC1 0xC1 0xC1 0xC0 0xC0 0x40 0x40 0x41
|
||||
CRTC[0x0A]: CURSOR_START 0x0D 0x0D 0x0D 0x0D 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
CRTC[0x0B]: CURSOR_END 0x0E 0x0E 0x0E 0x0E 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
CRTC[0x0C]: START_ADDR_HI 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
CRTC[0x0D]: START_ADDR_LO 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
CRTC[0x0E]: CURSOR_ADDR_HI 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x00
|
||||
CRTC[0x0F]: CURSOR_ADDR_LO 0x19 0x19 0x41 0x41 0x19 0x19 0x41 0x19 0x41 0x41 0xE1 0xA2
|
||||
CRTC[0x10]: VRETRACE_START 0x9C 0x9C 0x9C 0x9C 0x9C 0x9C 0x9C 0x9C 0x9C 0x83 0xEA 0x9C
|
||||
CRTC[0x11]: VRETRACE_END 0x8E 0x8E 0x8E 0x8E 0x8E 0x8E 0x8E 0x8E 0x8E 0x85 0x8C 0x8E
|
||||
CRTC[0x12]: VDISP_END 0x8F 0x8F 0x8F 0x8F 0x8F 0x8F 0x8F 0x8F 0x8F 0x5D 0xDF 0x8F
|
||||
CRTC[0x13]: OFFSET 0x14 0x14 0x28 0x28 0x14 0x14 0x28 0x14 0x28 0x28 0x28 0x28
|
||||
CRTC[0x14]: UNDERLINE 0x1F 0x1F 0x1F 0x1F 0x00 0x00 0x00 0x00 0x00 0x0F 0x00 0x40
|
||||
CRTC[0x15]: VBLANK_START 0x96 0x96 0x96 0x96 0x96 0x96 0x96 0x96 0x96 0x63 0xE7 0x96
|
||||
CRTC[0x16]: VBLANK_END 0xB9 0xB9 0xB9 0xB9 0xB9 0xB9 0xB9 0xB9 0xB9 0xBA 0x04 0xB9
|
||||
CRTC[0x17]: MODE_CTRL 0xA3 0xA3 0xA3 0xA3 0xA2 0xA2 0xC2 0xE3 0xE3 0xE3 0xE3 0xA3
|
||||
CRTC[0x18]: LINE_COMPARE 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
GRC[0x00]: SRESET 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
GRC[0x01]: ESRESET 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
GRC[0x02]: COLORCMP 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
GRC[0x03]: DATAROT 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
GRC[0x04]: READMAP 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
GRC[0x05]: MODE 0x10 0x10 0x10 0x10 0x30 0x30 0x00 0x00 0x00 0x00 0x00 0x40
|
||||
GRC[0x06]: MISC 0x0E 0x0E 0x0E 0x0E 0x0F 0x0F 0x0D 0x05 0x05 0x05 0x05 0x05
|
||||
GRC[0x07]: COLORDC 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0F 0x0F 0x0F 0x0F 0x0F
|
||||
GRC[0x08]: BITMASK 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
|
||||
SEQ[0x00]: RESET 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03 0x03
|
||||
SEQ[0x01]: CLOCKING 0x08 0x08 0x00 0x00 0x09 0x09 0x01 0x09 0x01 0x01 0x01 0x01
|
||||
SEQ[0x02]: MAPMASK 0x03 0x03 0x03 0x03 0x03 0x03 0x01 0x0F 0x0F 0x0F 0x0F 0x0F
|
||||
SEQ[0x03]: CHARMAP 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
SEQ[0x04]: MEMMODE 0x03 0x03 0x03 0x03 0x02 0x02 0x06 0x06 0x06 0x06 0x06 0x0E
|
||||
ATC[0x00]: PAL00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
ATC[0x01]: PAL01 0x01 0x01 0x01 0x01 0x13 0x13 0x17 0x01 0x01 0x01 0x01 0x01
|
||||
ATC[0x02]: PAL02 0x02 0x02 0x02 0x02 0x15 0x15 0x17 0x02 0x02 0x02 0x02 0x02
|
||||
ATC[0x03]: PAL03 0x03 0x03 0x03 0x03 0x17 0x17 0x17 0x03 0x03 0x03 0x03 0x03
|
||||
ATC[0x04]: PAL04 0x04 0x04 0x04 0x04 0x02 0x02 0x17 0x04 0x04 0x04 0x04 0x04
|
||||
ATC[0x05]: PAL05 0x05 0x05 0x05 0x05 0x04 0x04 0x17 0x05 0x05 0x05 0x05 0x05
|
||||
ATC[0x06]: PAL06 0x14 0x14 0x14 0x14 0x06 0x06 0x17 0x06 0x06 0x14 0x14 0x06
|
||||
ATC[0x07]: PAL07 0x07 0x07 0x07 0x07 0x07 0x07 0x17 0x07 0x07 0x07 0x07 0x07
|
||||
ATC[0x08]: PAL08 0x38 0x38 0x38 0x38 0x10 0x10 0x17 0x10 0x10 0x38 0x38 0x08
|
||||
ATC[0x09]: PAL09 0x39 0x39 0x39 0x39 0x11 0x11 0x17 0x11 0x11 0x39 0x39 0x09
|
||||
ATC[0x0A]: PAL0A 0x3A 0x3A 0x3A 0x3A 0x12 0x12 0x17 0x12 0x12 0x3A 0x3A 0x0A
|
||||
ATC[0x0B]: PAL0B 0x3B 0x3B 0x3B 0x3B 0x13 0x13 0x17 0x13 0x13 0x3B 0x3B 0x0B
|
||||
ATC[0x0C]: PAL0C 0x3C 0x3C 0x3C 0x3C 0x14 0x14 0x17 0x14 0x14 0x3C 0x3C 0x0C
|
||||
ATC[0x0D]: PAL0D 0x3D 0x3D 0x3D 0x3D 0x15 0x15 0x17 0x15 0x15 0x3D 0x3D 0x0D
|
||||
ATC[0x0E]: PAL0E 0x3E 0x3E 0x3E 0x3E 0x16 0x16 0x17 0x16 0x16 0x3E 0x3E 0x0E
|
||||
ATC[0x0F]: PAL0F 0x3F 0x3F 0x3F 0x3F 0x17 0x17 0x17 0x17 0x17 0x3F 0x3F 0x0F
|
||||
ATC[0x10]: MODE 0x0C 0x0C 0x0C 0x0C 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x41
|
||||
ATC[0x11]: OVERSCAN 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
ATC[0x12]: PLANES 0x0F 0x0F 0x0F 0x0F 0x03 0x03 0x01 0x0F 0x0F 0x0F 0x0F 0x0F
|
||||
ATC[0x13]: HPAN 0x08 0x08 0x08 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
|
||||
In addition, I've created a [VGA Tests](/tests/pc/vga/) directory to hold VGA test and sample code that PCjs can
|
||||
now successfully run (for the most part). See that directory for more details.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*June 1, 2015 (Updated July 9, 2015)*
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
---
|
||||
layout: post
|
||||
title: The Strange Case of the EGA Graphics Scroll Bug
|
||||
date: 2015-06-05 11:00:00
|
||||
category: Video
|
||||
permalink: /blog/2015/06/05/
|
||||
---
|
||||
|
||||
I was playing with different video modes using this [IBM PC AT w/EGA](/devices/pcx86/machine/5170/ega/640kb/rev1/debugger/),
|
||||
and I discovered an odd problem.
|
||||
|
||||
For example, when I ran this code:
|
||||
|
||||
A>b:debug
|
||||
-a
|
||||
0CE0:0100 mov ax,e
|
||||
0CE0:0103 int 10
|
||||
0CE0:0105 int 3
|
||||
0CE0:0106
|
||||
-g
|
||||
|
||||
the following "text" correctly appeared at the top of the screen, in 640x200 16-color graphics mode 0x0E:
|
||||
|
||||
AX=0B01 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
|
||||
DS=0CE0 ES=0CE0 SS=0CE0 CS=0CE0 IP=0105 NV UP EI PL NZ NA PO NC
|
||||
0CE0:0105 CC INT 3
|
||||
-
|
||||
|
||||
And when I typed "q", then "cls" and finally "dir", the screen filled with DOS directory contents.
|
||||
|
||||
But as soon as the screen started to scroll, the screen contents became garbled. Other EGA graphics modes,
|
||||
like 640x350 16-color mode 0x10, didn't have this problem.
|
||||
|
||||
To investigate, I set a breakpoint in the IBM EGA ROM where the scrolling starts, at 0xC000:12EA (see p.130 of the
|
||||
"IBM Enhanced Graphics Adapter" Technical Reference document):
|
||||
|
||||
CRANK_A:
|
||||
PUSH CX
|
||||
MOV CL,DL
|
||||
SUB CH,CH
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
REP MOVSB
|
||||
POP DI
|
||||
POP SI
|
||||
ADD SI,BX
|
||||
ADD DI,BX
|
||||
POP CX
|
||||
LOOP CRANK_A
|
||||
|
||||
CX contains 0xC0 (192), which is the number of scan-lines to move up, and BX contains 0x50 (80), the number
|
||||
of bytes per scan-line.
|
||||
|
||||
When the breakpoint was hit, I dumped the video hardware state, using the Debugger's "*d video*" command.
|
||||
For comparison purposes, I've pasted the corresponding video state for mode 0x10 on the right-hand side.
|
||||
|
||||
breakpoint hit: C000:12EA (exec)
|
||||
stopped (175707689 ops, 800060264 cycles, 133470 ms, 5994308 hz)
|
||||
AX=020F BX=0050 CX=00C0 DX=1950 SP=0B58 BP=0511 SI=0280 DI=0000
|
||||
SS=011F DS=A000 ES=A000 PS=0246 V0 D0 I1 T0 S0 Z1 A0 P1 C0
|
||||
C000:12EA 51 PUSH CX
|
||||
|
||||
BIOSMODE: 0x0E BIOSMODE: 0x10
|
||||
CRTC[0x00]: HORZ_TOTAL 0x70 CRTC[0x00]: HORZ_TOTAL 0x5B
|
||||
CRTC[0x01]: HORZ_DISP_END 0x4F CRTC[0x01]: HORZ_DISP_END 0x4F
|
||||
CRTC[0x02]: HORZ_BLANK_START 0x59 CRTC[0x02]: HORZ_BLANK_START 0x53
|
||||
CRTC[0x03]: HORZ_BLANK_END 0x2D CRTC[0x03]: HORZ_BLANK_END 0x37
|
||||
CRTC[0x04]: HORZ_RETRACE_START 0x5E CRTC[0x04]: HORZ_RETRACE_START 0x52
|
||||
CRTC[0x05]: HORZ_RETRACE_END 0x06 CRTC[0x05]: HORZ_RETRACE_END 0x00
|
||||
CRTC[0x06]: VERT_TOTAL 0x04 CRTC[0x06]: VERT_TOTAL 0x6C
|
||||
CRTC[0x07]: OVERFLOW 0x11 CRTC[0x07]: OVERFLOW 0x1F
|
||||
CRTC[0x08]: PRESET_ROW_SCAN 0x00 CRTC[0x08]: PRESET_ROW_SCAN 0x00
|
||||
CRTC[0x09]: MAX_SCAN_LINE 0x00 CRTC[0x09]: MAX_SCAN_LINE 0x00
|
||||
CRTC[0x0A]: CURSOR_START 0x00 CRTC[0x0A]: CURSOR_START 0x00
|
||||
CRTC[0x0B]: CURSOR_END 0x01 CRTC[0x0B]: CURSOR_END 0x01
|
||||
CRTC[0x0C]: START_ADDR_HI 0x00 CRTC[0x0C]: START_ADDR_HI 0x00
|
||||
CRTC[0x0D]: START_ADDR_LO 0x00 CRTC[0x0D]: START_ADDR_LO 0x00
|
||||
CRTC[0x0E]: CURSOR_ADDR_HI 0x07 CRTC[0x0E]: CURSOR_ADDR_HI 0x01
|
||||
CRTC[0x0F]: CURSOR_ADDR_LO 0x80* CRTC[0x0F]: CURSOR_ADDR_LO 0x41*
|
||||
CRTC[0x10]: VERT_RETRACE_START 0xE0 CRTC[0x10]: VERT_RETRACE_START 0x5E
|
||||
CRTC[0x11]: VERT_RETRACE_END 0x23 CRTC[0x11]: VERT_RETRACE_END 0x2B
|
||||
CRTC[0x12]: VERT_DISP_END 0xC7 CRTC[0x12]: VERT_DISP_END 0x5D
|
||||
CRTC[0x13]: OFFSET 0x28 CRTC[0x13]: OFFSET 0x28
|
||||
CRTC[0x14]: UNDERLINE 0x00 CRTC[0x14]: UNDERLINE 0x0F
|
||||
CRTC[0x15]: VERT_BLANK_START 0xDF CRTC[0x15]: VERT_BLANK_START 0x5F
|
||||
CRTC[0x16]: VERT_BLANK_END 0xEF CRTC[0x16]: VERT_BLANK_END 0x0A
|
||||
CRTC[0x17]: MODE_CTRL 0xE3 CRTC[0x17]: MODE_CTRL 0xE3
|
||||
CRTC[0x18]: LINE_COMPARE 0xFF CRTC[0x18]: LINE_COMPARE 0xFF
|
||||
STATUS1: 0x01 STATUS1: 0x01
|
||||
ATCDATA: true ATCDATA: true
|
||||
ATC[0x00]: PAL00 0x00 ATC[0x00]: PAL00 0x00
|
||||
ATC[0x01]: PAL01 0x01 ATC[0x01]: PAL01 0x01
|
||||
ATC[0x02]: PAL02 0x02 ATC[0x02]: PAL02 0x02
|
||||
ATC[0x03]: PAL03 0x03 ATC[0x03]: PAL03 0x03
|
||||
ATC[0x04]: PAL04 0x04 ATC[0x04]: PAL04 0x04
|
||||
ATC[0x05]: PAL05 0x05 ATC[0x05]: PAL05 0x05
|
||||
ATC[0x06]: PAL06 0x06 ATC[0x06]: PAL06 0x14
|
||||
ATC[0x07]: PAL07 0x07 ATC[0x07]: PAL07 0x07
|
||||
ATC[0x08]: PAL08 0x10 ATC[0x08]: PAL08 0x38
|
||||
ATC[0x09]: PAL09 0x11 ATC[0x09]: PAL09 0x39
|
||||
ATC[0x0A]: PAL0A 0x12 ATC[0x0A]: PAL0A 0x3A
|
||||
ATC[0x0B]: PAL0B 0x13 ATC[0x0B]: PAL0B 0x3B
|
||||
ATC[0x0C]: PAL0C 0x14 ATC[0x0C]: PAL0C 0x3C
|
||||
ATC[0x0D]: PAL0D 0x15 ATC[0x0D]: PAL0D 0x3D
|
||||
ATC[0x0E]: PAL0E 0x16 ATC[0x0E]: PAL0E 0x3E
|
||||
ATC[0x0F]: PAL0F 0x17 ATC[0x0F]: PAL0F 0x3F
|
||||
ATC[0x10]: MODE 0x01 ATC[0x10]: MODE 0x01
|
||||
ATC[0x11]: OVERSCAN 0x00 ATC[0x11]: OVERSCAN 0x00
|
||||
ATC[0x12]: PLANES 0x0F ATC[0x12]: PLANES 0x0F
|
||||
ATC[0x13]: HORZPAN 0x00 ATC[0x13]: HORZPAN 0x00
|
||||
GRC[0x00]: SRESET 0x00 GRC[0x00]: SRESET 0x00
|
||||
GRC[0x01]: ESRESET 0x00 GRC[0x01]: ESRESET 0x00
|
||||
GRC[0x02]: COLORCMP 0x00 GRC[0x02]: COLORCMP 0x00
|
||||
GRC[0x03]: DATAROT 0x00 GRC[0x03]: DATAROT 0x00*
|
||||
GRC[0x04]: READMAP 0x00 GRC[0x04]: READMAP 0x00
|
||||
GRC[0x05]: MODE 0x11* GRC[0x05]: MODE 0x00
|
||||
GRC[0x06]: MISC 0x05 GRC[0x06]: MISC 0x05
|
||||
GRC[0x07]: COLORDC 0x0F GRC[0x07]: COLORDC 0x0F
|
||||
GRC[0x08]: BITMASK 0xFF GRC[0x08]: BITMASK 0xFF
|
||||
SEQ[0x00]: RESET 0x03 SEQ[0x00]: RESET 0x03
|
||||
SEQ[0x01]: CLOCKING 0x01 SEQ[0x01]: CLOCKING 0x01
|
||||
SEQ[0x02]: MAPMASK 0x0F* SEQ[0x02]: MAPMASK 0x0F*
|
||||
SEQ[0x03]: CHARMAP 0x00 SEQ[0x03]: CHARMAP 0x00
|
||||
SEQ[0x04]: MEMMODE 0x06 SEQ[0x04]: MEMMODE 0x06
|
||||
FEAT: 0x02 FEAT: 0x02
|
||||
MISC: 0x23 MISC: 0xA7
|
||||
STATUS0: 0x10 STATUS0: 0x10
|
||||
LATCHES: 0x00000000 LATCHES: 0x00000000
|
||||
ACCESS: 0x1411 ACCESS: 0x0400
|
||||
|
||||
One of the apparent oddities is that, for mode 0x0E, the GRC Mode Register was programmed with 0x11, whereas
|
||||
for mode 0x10, it was programmed with 0x00. Why would mode 0x0E want to set the ODDEVEN bit during the scroll,
|
||||
when it hadn't been set during any other writes to the screen?
|
||||
|
||||
At this point, I dumped the instruction history buffer a bit ("*dh 100*"), and noticed this GRC write:
|
||||
|
||||
C000:1582 8BC5 MOV AX,BP ;history=33
|
||||
C000:1584 B603 MOV DH,03 ;history=32
|
||||
C000:1586 B2CE MOV DL,CE ;history=31
|
||||
C000:1588 E88AF7 CALL 0D15 ;history=30
|
||||
C000:0D15 86C4 XCHG AL,AH ;history=29
|
||||
C000:0D17 EE OUT DX,AL ;history=28
|
||||
C000:0D18 42 INC DX ;history=27
|
||||
C000:0D19 86C4 XCHG AL,AH ;history=26
|
||||
C000:0D1B EE OUT DX,AL ;history=25
|
||||
C000:0D1C 4A DEC DX ;history=24
|
||||
|
||||
So I looked farther back and saw where BP was set:
|
||||
|
||||
C000:1522 BA00A0 MOV DX,A000 ;history=97
|
||||
C000:1525 BD1105 MOV BP,0511 ;history=96
|
||||
|
||||
Here's the complete function:
|
||||
|
||||
GR_ST_1:
|
||||
MOV DX,A000
|
||||
MOV BP,0511
|
||||
CMP AH,0F
|
||||
JC 1535
|
||||
CALL 14F7
|
||||
JNC 1535
|
||||
MOV BP,0501
|
||||
RET
|
||||
|
||||
OK, so any (EGA) graphics mode below 0x0F is going to the trigger the use of Write Mode 1 with the ODDEVEN bit set.
|
||||
And sure enough, the scrolling bug also occurs when using 320x200 16-color mode 0x0D.
|
||||
|
||||
It's also worth noting that, whenever the ODDEVEN bit of the GRC Mode Register is set, the SEQUENTIAL bit in the Sequencer
|
||||
Memory Mode Register is supposed to be clear (and vice versa -- those two bits are supposed to always be oppositely set).
|
||||
But here, the IBM EGA BIOS hasn't done that. One wonders if that was a mistake....
|
||||
|
||||
Another bit of trivia: while dumping the frame buffer in a VGA text mode in a different emulator, I discovered that
|
||||
when I turned off the ODDEVEN bit in the GRC Mode Register, odd bytes would still appear from plane 1; it wasn't until I
|
||||
*also* turned off the CHAIN bit in the GRC Miscellaneous Register that the odd bytes would no longer appear. But,
|
||||
that could have just been an idiosyncrasy of that particular emulator.
|
||||
|
||||
As a result of all these observations, and more importantly, to make EGA scrolling work properly in modes 0x0D and 0x0E,
|
||||
I've changed the Video component to use odd/even memory functions *only* when the SEQUENTIAL bit (bit 2) of the
|
||||
Sequencer's Memory Mode Register is clear, instead of relying on the ODDEVEN bit (bit 4) of the Graphics Controller's Mode
|
||||
Register.
|
||||
|
||||
To be continued.... because I've barely scratched the surface of all the side-effects of EGA/VGA odd/even addressing,
|
||||
and I hope to do some testing on real hardware in the near future.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*June 5, 2015*
|
||||
204
_posts/2015-07-17-windows-95.md
Normal file
204
_posts/2015-07-17-windows-95.md
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
---
|
||||
layout: post
|
||||
title: Windows 95
|
||||
date: 2015-07-17 11:00:00
|
||||
category: Windows 95
|
||||
permalink: /blog/2015/07/17/
|
||||
machines:
|
||||
- type: pcx86
|
||||
id: deskpro386
|
||||
debugger: true
|
||||
state: /disks/pcx86/windows/win95/4.00.950/deskpro386.json
|
||||
config: /devices/pcx86/machine/compaq/deskpro386/vga/4096kb/debugger/machine.xml
|
||||
drives: '[{name:"68Mb Hard Disk",type:4,path:"http://archive.pcjs.org/disks/pcx86/fixed/68mb/win95.json"}]'
|
||||
autoMount: ''
|
||||
---
|
||||
|
||||
This week (July 14, 2015) was the 20th anniversary of Windows 95 RTM ("Release To Manufacturing"). So I decided to
|
||||
throw a PCjs party and try running Windows 95 Setup inside a PCx86 machine for the first time.
|
||||
|
||||
Sadly, it immediately failed:
|
||||
|
||||
Please wait while Setup initializes.
|
||||
Windows requires a computer with an 80386 processor or higher.
|
||||
|
||||
The failing code:
|
||||
|
||||
0E36:08FD 06 PUSH ES
|
||||
0E36:08FE 1E PUSH DS
|
||||
0E36:08FF 9C PUSHF
|
||||
0E36:0900 33C0 XOR AX,AX
|
||||
0E36:0902 50 PUSH AX
|
||||
0E36:0903 9D POPF
|
||||
0E36:0904 9C PUSHF
|
||||
0E36:0905 58 POP AX
|
||||
0E36:0906 A90080 TEST AX,8000
|
||||
0E36:0909 7517 JNZ 0922
|
||||
0E36:090B B80070 MOV AX,7000
|
||||
0E36:090E 50 PUSH AX
|
||||
0E36:090F 9D POPF
|
||||
0E36:0910 FB STI
|
||||
0E36:0911 9C PUSHF
|
||||
0E36:0912 58 POP AX
|
||||
0E36:0913 A90070 TEST AX,7000
|
||||
0E36:0916 7405 JZ 091D
|
||||
0E36:0918 B88603 MOV AX,0386
|
||||
0E36:091B EB08 JMP 0925
|
||||
0E36:091D B88602 MOV AX,0286
|
||||
0E36:0920 EB03 JMP 0925
|
||||
0E36:0922 B88600 MOV AX,0086
|
||||
0E36:0925 9D POPF
|
||||
0E36:0926 1F POP DS
|
||||
0E36:0927 07 POP ES
|
||||
0E36:0928 C3 RET
|
||||
|
||||
was easily fixed with a change to [x86cpu.js](/modules/pcx86/lib/x86cpu.js), allowing the IOPL bits to be
|
||||
modified in real-mode on an 80386. When I had previously tweaked setPS() to accomodate 80286/80386 discrimination
|
||||
logic in OS/2 1.0, there was no 80386 support in PCx86 at that time, so it was sufficient to *never* allow the
|
||||
IOPL bits to be altered in real-mode.
|
||||
|
||||
The next problem was triggered by Setup's CAB ("Diamond") decompression code, which uses all 32 bits
|
||||
of the 80386's 32-bit registers. That in itself was not a problem, but by leaving stray bits in the upper halves of
|
||||
registers like EDX, it exposed a bug in the PCx86 I/O instruction handlers, which neglected to mask EDX with 0xFFFF before
|
||||
performing port lookups, causing mysterious I/O failures that usually manifested themselves as hard disk I/O errors.
|
||||
|
||||
Then PCx86 crashed in the middle of the decompression of the first CAB file (MINI.CAB). It turned out the stack
|
||||
had been improperly adjusted because a "RETF n" instruction mistakenly believed that a stack switch had occurred.
|
||||
This was, in fact, a left-over condition from a protected-mode stack-switch. That was easily cleared.
|
||||
|
||||
Next, I discovered that I had never finished updating a handful of instructions to full 32-bit operation;
|
||||
namely, INC, DEC, NEG, NOT, TEST, MOVSB and MOVSW. Those are done now.
|
||||
|
||||
Then I ran into a couple of Windows 95 oddities. First, some kernel initialization code deliberately
|
||||
executed an invalid opcode (0x0F,0xFF) and expected its DPMI exception (0x06) handler to field the exception; that was
|
||||
fixed by flagging the opcode as genuinely invalid.
|
||||
|
||||
> SIDEBAR
|
||||
|
||||
> By default, PCx86 marks opcodes as invalid *only* if they have been confirmed invalid. PCx86 considers the vast
|
||||
majority of unused/undocumented opcodes to be merely "undefined" until I've seen them in the wild. An instruction will
|
||||
be marked invalid if I either discover that real hardware treats it as an Invalid Opcode (by throwing the exception)
|
||||
*or* that real software expects it to. For opcode 0x0F,0xFF, it was the latter.
|
||||
|
||||
> Don't be confused that Intel also refers to the Invalid Opcode exception (0x06) as the #UD ("Undefined")
|
||||
opcode exception. Every opcode that triggers that exception is, by definition, defined: it's defined as invalid.
|
||||
I consider it a misnomer to refer to any invalid instruction as "undefined".
|
||||
|
||||
The other recent Windows 95 oddity I ran into was an instruction with multiple address-override (0x67) prefixes; the
|
||||
first prefix changed the instruction's addressing mode from 16-bit to 32-bit, and the second prefix changed it back to
|
||||
16-bit. PCx86 should have simply ignored the second prefix.
|
||||
|
||||
With all of the above changes in place, PCx86 v1.18.4 is able to run Windows 95 Setup a bit farther, but still far from
|
||||
completion. If you want to give it a spin yourself, start the machine below (click the "Run" button) and once it has
|
||||
finished booting, run SETUP from drive B, where the first Windows 95 diskette is already loaded.
|
||||
|
||||
If, when it crashes (and it will), you're interested in examining the instructions that were executed prior to the
|
||||
crash, you can dump the instruction history buffer using the Debugger's "dh" command.
|
||||
|
||||
NOTE: The diskette images contain a pre-release version of Windows 95, as I don't currently have the RTM version on
|
||||
diskette.
|
||||
|
||||
---
|
||||
|
||||
August 13, 2015 Update
|
||||
---
|
||||
|
||||
PCx86 v1.18.8 has made a little more progress running Windows 95 Setup, but CAB decompression still fails almost
|
||||
immediately. To monitor DOS calls until the first 36-byte read of PRECOPY1.CAB, try setting the following
|
||||
breakpoint and then starting the machine, using the PCx86 Debugger *input* field next to the **Enter** button:
|
||||
|
||||
m dos off
|
||||
bp 1ED4:16B4 "set fn=ah;dos;if fn!=3f||cx!=24"
|
||||
g
|
||||
|
||||
Alternatively, you can hard-code those commands into the Debugger component of the machine.xml file; eg:
|
||||
|
||||
```xml
|
||||
<debugger id="debugger" messages="fault|tss|int" commands='m dos off;bp 1ED4:16B4 "set fn=ah;dos;if fn!=3f||cx!=24"'/>
|
||||
```
|
||||
|
||||
Once the 36-byte read is hit, you'll probably want to stop on the next instruction that examine those bytes,
|
||||
by using a memory read breakpoint:
|
||||
|
||||
br ds:dx
|
||||
|
||||
and you also might want to change the first breakpoint to stop on *any* file read, and add a second breakpoint
|
||||
to dump the initial contents of those reads:
|
||||
|
||||
bp 1ED4:16B4 "set fn=ah;dos;if fn!=3f"
|
||||
bp FDC8:422A "if fn==3f;di ds:dx;db ds:dx;h;else"
|
||||
|
||||
In the current machine, `1ED4:16B4` is the DOS INT 0x21 entry point and `FDC8:422A` is the corresponding IRET.
|
||||
The first breakpoint sets an internal variable, `fn`, to the value of the **AH** register on entry, so that the
|
||||
second breakpoint can check the value on exit.
|
||||
|
||||
Regarding the other Debugger commands shown above, the `dos` command describes the current DOS operation
|
||||
(alternatively, you could use the `m int on; m dos on` commands to turn on DOS interrupt messages). The `di`
|
||||
command dumps PCx86 BACKTRACK(tm) information, to help you visually confirm which INT 0x21 calls are reading
|
||||
PRECOPY1.CAB. Finally, the `if` command evaluates the given expression, and if the result is non-zero ("true"),
|
||||
all subsequent commands are executed, up to to any `else` command; otherwise, only commands after the `else`
|
||||
command will be executed, and if there is no `else` command, execution will stop.
|
||||
|
||||
Debugger expressions may contain the usual variety of arithmetic, bitwise and logical binary operators, and they
|
||||
are evaluated using traditional operator precedence (ie, the same as C or JavaScript); any other operators, such as
|
||||
parentheses, assignment operators, and unary or ternary operators, are not supported in expressions.
|
||||
|
||||
This test machine below has been updated to load WDEB386.EXE prior to starting B:SETUP.EXE, if you prefer using
|
||||
WDEB386. Make sure the machine is running (ie, click the **Run** button, or use the PCx86 Debugger "g" command),
|
||||
and then click on the Debugger *output* control to give it focus and press CTRL-C to trigger WDEB386.
|
||||
|
||||
The Debugger *input* field is used exclusively for PCx86 Debugger commands, whereas the *output* textarea combines
|
||||
all Debugger output *and* WDEB386 COM2 serial port I/O. You can even use the PCx86 Debugger to debug
|
||||
the WDEB386 debugger; just make sure the appropriate text control has focus before typing a command.
|
||||
|
||||
To help reduce confusion, the PCx86 Debugger displays a double-character command prefix, to differentiate its commands
|
||||
from WDEB386's single-character command prompt -- but it's still easy to get confused.
|
||||
|
||||
A quick recap of those command prefixes (which you won't see until AFTER you've typed a PCx86 command):
|
||||
|
||||
* `>>` indicates real-mode
|
||||
* `##` indicates protected-mode
|
||||
* `--` indicates V86-mode
|
||||
|
||||
80386 Debug register (DR0-DR7) support was recently added, so even WDEB386 read/write breakpoints should work now.
|
||||
|
||||
---
|
||||
|
||||
August 21, 2015 Update
|
||||
---
|
||||
|
||||
PCx86 v1.19.1 has finally solved a number of nagging bugs. The CAB decompression code itself was running
|
||||
fine; it would crash after loading a 32-bit value into EAX *and* a timer interrupt occurred. A path
|
||||
through the interrupt handler was trashing the upper bits of EAX. The culprit: any of the MOV instructions
|
||||
that move an immediate value into one of the "high" 8-bit registers (AH, BH, CH, or DH). Those instructions
|
||||
were failing to preserve the upper 16 bits of the entire register. Further proof that the most exasperating
|
||||
bugs sometimes have the most mundane causes.
|
||||
|
||||
Also recently fixed: the annoying VGA video glitch that would occur whenever the mouse was moved, improper
|
||||
updates to the ACCESSED bit in a selector's descriptor table entry, improper error codes when a selector load
|
||||
generated a fault, and the RETF instruction's failure to properly restart when the return address referred
|
||||
to a not-present segment.
|
||||
|
||||
The next problem appears to be timer-related. When Windows 95 Setup begins its hardware analysis, it
|
||||
gets "stuck" in code that's reading and writing timer ports (0x40 and 0x43). Turning on timer port messages
|
||||
with the `"m port on;m timer on"` Debugger commands reveals that the problem maybe an unsupported timer
|
||||
command:
|
||||
|
||||
chipset.outPort(0x0043,PIT1_CTRL,0xD2) @1847:DD02
|
||||
PIT1_CTRL: Read-Back command not supported (yet)
|
||||
|
||||
---
|
||||
|
||||
September 12, 2015 Update
|
||||
---
|
||||
|
||||
Lots of bugs have been squashed in the past few weeks -- not enough to finish setting up Windows 95, but it's getting
|
||||
closer. More details on recent releases can be found [here](https://github.com/jeffpar/pcjs/releases).
|
||||
|
||||
The machine below has been reconfigured with a hard disk image containing all the Windows 95 Setup files. The machine
|
||||
is at the point where Windows 95 SETUP has just rebooted.
|
||||
|
||||
{% include machine.html id="deskpro386" %}
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*July 17, 2015 (updated September 12, 2015)*
|
||||
39
_posts/2015-09-21-windows-95-in-your-web-browser.md
Normal file
39
_posts/2015-09-21-windows-95-in-your-web-browser.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
layout: post
|
||||
title: Windows 95 In Your Web Browser
|
||||
date: 2015-09-21 11:00:00
|
||||
category: Windows 95
|
||||
permalink: /blog/2015/09/21/
|
||||
machines:
|
||||
- type: pcx86
|
||||
id: deskpro386
|
||||
state: /disks/pcx86/windows/win95/4.00.950/deskpro386.json
|
||||
config: /devices/pcx86/machine/compaq/deskpro386/vga/4096kb/machine.xml
|
||||
drives: '[{name:"68Mb Hard Disk",type:4,path:"http://archive.pcjs.org/disks/pcx86/fixed/68mb/win95.json"}]'
|
||||
autoMount: ''
|
||||
---
|
||||
|
||||
Today, the last serious bug preventing a successful boot of Windows 95 was fixed. I won't bore you with
|
||||
the details.
|
||||
|
||||
OK, I will: three arithmetic instructions (specifically, **AND**, **OR** and **XOR**) include a variation that
|
||||
converts an immediate signed byte into a signed word. Those variations were failing to truncate the result when
|
||||
a 16-bit operand size was in effect, and if the destination was a register, the upper 16 bits of that register
|
||||
could become corrupted.
|
||||
|
||||
The [Windows 95 Test Machine](/disks/pcx86/windows/win95/4.00.950/) hard disk has been updated
|
||||
with a complete set of Windows 95 files from a "Compact" installation, and first boot has finished, so instead
|
||||
of the initial "Getting ready to run Windows 95 for the first time..." splash screen, you'll see the normal
|
||||
Windows 95 startup screen.
|
||||
|
||||
The machine is still a bit finicky. It easily gets confused about the state of its shift keys if you switch away
|
||||
from the browser and then back again. And Explorer windows don't open in the correct view; for example, both
|
||||
**My Computer** and **Recycle Bin** open the same (incorrect) view. In short, there are still some serious bugs
|
||||
to be resolved, but booting has been achieved.
|
||||
|
||||
The adventure continues.
|
||||
|
||||
{% include machine.html id="deskpro386" %}
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*September 21, 2015*
|
||||
218
_posts/2015-10-27-windows-95-and-early-80386-cpus.md
Normal file
218
_posts/2015-10-27-windows-95-and-early-80386-cpus.md
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
---
|
||||
layout: post
|
||||
title: Windows 95 and Early 80386 CPUs
|
||||
date: 2015-10-27 11:00:00
|
||||
categories: ['Windows 95', '80386']
|
||||
permalink: /blog/2015/10/27/
|
||||
---
|
||||
|
||||
Every time Windows 95 starts up, its real-mode loader performs the following CPU identification test.
|
||||
|
||||
&0654:121E 9C PUSHF
|
||||
&0654:121F 33C0 XOR AX,AX ; try to clear bit 15 of flags
|
||||
&0654:1221 50 PUSH AX
|
||||
&0654:1222 9D POPF
|
||||
&0654:1223 9C PUSHF
|
||||
&0654:1224 58 POP AX
|
||||
&0654:1225 A90080 TEST AX,8000 ; bit 15 of flags set anyway?
|
||||
&0654:1228 7543 JNZ 126D ; yes (must be an 8086/8086)
|
||||
&0654:122A B80070 MOV AX,7000 ; try to set bits 12-14 of flags
|
||||
&0654:122D 50 PUSH AX
|
||||
&0654:122E 9D POPF
|
||||
&0654:122F FB STI
|
||||
&0654:1230 9C PUSHF
|
||||
&0654:1231 58 POP AX
|
||||
&0654:1232 9D POPF
|
||||
&0654:1233 A90070 TEST AX,7000 ; any of bits 12-14 of flags set?
|
||||
&0654:1236 7436 JZ 126E ; no (must be an 80286)
|
||||
&0654:1238 51 PUSH CX
|
||||
&0654:1239 33C9 XOR CX,CX
|
||||
&0654:123B 8BC4 MOV AX,SP
|
||||
&0654:123D 83E003 AND AX,0003
|
||||
&0654:1240 7404 JZ 1246
|
||||
&0654:1242 8BC8 MOV CX,AX
|
||||
&0654:1244 2BE0 SUB SP,AX
|
||||
&0654:1246 669C PUSHFD
|
||||
&0654:1248 666800000400 PUSH 00040000 ; try to set the AC bit of flags
|
||||
&0654:124E 669D POPFD
|
||||
&0654:1250 669C PUSHFD
|
||||
&0654:1252 6658 POP EAX
|
||||
&0654:1254 669D POPFD
|
||||
&0654:1256 66A900000400 TEST EAX,00040000 ; AC bit set?
|
||||
&0654:125C 7508 JNZ 1266 ; yes (must be an 80486, or newer)
|
||||
&0654:125E 40 INC AX
|
||||
&0654:125F 03E1 ADD SP,CX
|
||||
&0654:1261 59 POP CX
|
||||
&0654:1262 0BC0 OR AX,AX
|
||||
&0654:1264 F9 STC ; return ZF clear and CF set to indicate 80386
|
||||
&0654:1265 C3 RET
|
||||
&0654:1266 03E1 ADD SP,CX
|
||||
&0654:1268 59 POP CX
|
||||
&0654:1269 660BC0 OR EAX,EAX ; return ZF clear and CF clear to indicate 80486
|
||||
&0654:126C C3 RET
|
||||
&0654:126D 9D POPF
|
||||
&0654:126E 33C0 XOR AX,AX ; return ZF set to indicate 80286 or older
|
||||
&0654:1270 C3 RET
|
||||
|
||||
If the above function returns ZF set, then the processor is an 80286 or older, so Windows 95 displays the
|
||||
following message and exits:
|
||||
|
||||
You need an 80386 processor to run Windows.
|
||||
|
||||
If the above function returns CF set, then the processor is an 80386, and if CF is clear, the processor is an
|
||||
80486 or newer.
|
||||
|
||||
When CF is set, Windows 95 proceeds to the following 80386 stepping check, which attempts to execute an
|
||||
XBTS (Extract Bit String) instruction -- an instruction that existed only on B0 and earlier 80386 steppings.
|
||||
|
||||
&0654:1299 53 PUSH BX
|
||||
&0654:129A 51 PUSH CX
|
||||
&0654:129B 52 PUSH DX
|
||||
&0654:129C B80635 MOV AX,3506 ; save the current "invalid opcode" handler (IVT entry #6)
|
||||
&0654:129F CD21 INT 21
|
||||
&0654:12A1 8CC0 MOV AX,ES
|
||||
&0654:12A3 66C1E010 SHL EAX,10
|
||||
&0654:12A7 8BC3 MOV AX,BX
|
||||
&0654:12A9 6650 PUSH EAX
|
||||
&0654:12AB 1E PUSH DS
|
||||
&0654:12AC BAE012 MOV DX,12E0
|
||||
&0654:12AF 8CCB MOV BX,CS
|
||||
&0654:12B1 8EDB MOV DS,BX
|
||||
&0654:12B3 B80625 MOV AX,2506 ; temporarily install a new "invalid opcode" exception handler
|
||||
&0654:12B6 CD21 INT 21
|
||||
&0654:12B8 1F POP DS
|
||||
&0654:12B9 33C0 XOR AX,AX
|
||||
&0654:12BB 8BD0 MOV DX,AX
|
||||
&0654:12BD B900FF MOV CX,FF00
|
||||
&0654:12C0 0FA6CA XBTS CX,DX,AX,CL ; attempt to execute an XBTS instruction
|
||||
&0654:12C3 6658 POP EAX
|
||||
&0654:12C5 8BD0 MOV DX,AX
|
||||
&0654:12C7 66C1E810 SHR EAX,10
|
||||
&0654:12CB 1E PUSH DS
|
||||
&0654:12CC 8ED8 MOV DS,AX
|
||||
&0654:12CE B80625 MOV AX,2506 ; restore the original "invalid opcode" exception handler
|
||||
&0654:12D1 CD21 INT 21
|
||||
&0654:12D3 1F POP DS
|
||||
&0654:12D4 B8B000 MOV AX,00B0
|
||||
&0654:12D7 0BC9 OR CX,CX ; did XBTS work (ie, did CX change)?
|
||||
&0654:12D9 7401 JZ 12DC ; yes, so we must have a B0 stepping or earlier
|
||||
&0654:12DB 40 INC AX ; no, so bump the stepping to B1
|
||||
&0654:12DC 5A POP DX
|
||||
&0654:12DD 59 POP CX
|
||||
&0654:12DE 5B POP BX
|
||||
&0654:12DF C3 RET ; returns AX == 0xB0 if B0 stepping or earlier, 0xB1 if B1 stepping or later
|
||||
|
||||
&0654:12E0 55 PUSH BP ; temporary "invalid opcode" handler
|
||||
&0654:12E1 8BEC MOV BP,SP
|
||||
&0654:12E3 83460203 ADD [BP+02],0003 ; advance IP past the 3-byte XBTS instruction
|
||||
&0654:12E7 5D POP BP
|
||||
&0654:12E8 CF IRET
|
||||
|
||||
If the above function returns 0xB0, then the 80386 is a B0 or earlier stepping, so Windows 95 displays the
|
||||
following message and aborts:
|
||||
|
||||
Windows may not run correctly with the 80386 processor that is installed in this computer.
|
||||
Upgrade your 80386 processor.
|
||||
|
||||
Otherwise, the 80386 is a B1 or later stepping, so Windows 95 next performs a multiplication test (a simplified
|
||||
version of the multiplication tests discussed in "[Early 80386 CPUs](/blog/2015/02/23/)"):
|
||||
|
||||
&0654:12E9 33C9 XOR CX,CX
|
||||
&0654:12EB 66BB81000000 MOV EBX,00000081
|
||||
&0654:12F1 66B800A01704 MOV EAX,0417A000
|
||||
&0654:12F7 66F7E3 MUL EBX
|
||||
&0654:12FA 6683FA02 CMP EDX,00000002
|
||||
&0654:12FE 750B JNZ 130B
|
||||
&0654:1300 663D00A0E70F CMP EAX,0FE7A000
|
||||
&0654:1306 7503 JNZ 130B
|
||||
&0654:1308 E2E1 LOOP 12EB
|
||||
&0654:130A C3 RET
|
||||
|
||||
If any of the 65,536 identical multiplications return an incorrect result, Windows 95 displays the following
|
||||
message:
|
||||
|
||||
WARNING: The 80386 processor in this computer may not reliably execute 32-bit
|
||||
multiplication. Windows may occasionally fail on this computer.
|
||||
|
||||
You may want to replace your 80386 processor.
|
||||
Press any key to continue...Press a key to continue
|
||||
|
||||
A multiplication failure implies that the 80386 stepping is B1, because later steppings resolved the problem.
|
||||
|
||||
You may have heard that Windows 95 [pulled support for the 80386 B1 stepping](http://blogs.msdn.com/b/oldnewthing/archive/2011/01/12/10114521.aspx),
|
||||
and that's true, but only insofar as Windows 95 SETUP is concerned. The following code is executed by WINSETUP.BIN,
|
||||
a 16-bit Windows component that manages the Windows 95 installation process:
|
||||
|
||||
#05C7:69E8 1E PUSH DS
|
||||
#05C7:69E9 07 POP ES
|
||||
#05C7:69EA 6657 PUSH EDI
|
||||
#05C7:69EC FD STD
|
||||
#05C7:69ED 66BF00000000 MOV EDI,00000000
|
||||
#05C7:69F3 678A07 MOV AL,[EDI]
|
||||
#05C7:69F6 67AA STOSB
|
||||
#05C7:69F8 33C0 XOR AX,AX
|
||||
#05C7:69FA 6681FFFFFF0000 CMP EDI,0000FFFF
|
||||
#05C7:6A01 7501 JNZ 6A04
|
||||
#05C7:6A03 40 INC AX
|
||||
#05C7:6A04 FC CLD
|
||||
#05C7:6A05 665F POP EDI
|
||||
#05C7:6A07 C3 RET
|
||||
|
||||
Ths above code checks for B1 stepping [Errata #7](/pubs/pc/reference/intel/80386/#b1-errata): "Wrong Register Size for
|
||||
String Instructions in Mixed 16/32-bit Addressing Systems." It returns AX == 0 if the STOSB instruction updated EDI
|
||||
correctly (0xFFFFFFFF) or AX == 1 if EDI is incorrect (0x0000FFFF).
|
||||
|
||||
If Errata #7 is detected, then Windows 95 SETUP displays the following message and aborts:
|
||||
|
||||
Setup Error B1: Setup has detected an 80386 processor that is not compatible with this version of Windows.
|
||||
Before you can run this version of Windows, you need to upgrade your processor.
|
||||
Contact your computer manufacturer for more information.
|
||||
|
||||
However, if you can get through SETUP, Windows 95 will still run on a B1 stepping. For example, if you installed
|
||||
Windows 95 using a newer 80386, and then later "downgraded" the CPU to a B1, Windows 95 would still run. If your B1
|
||||
suffered from the multiplication flaw, you would see the 32-bit multiplication warning on start-up, but you could
|
||||
still continue to run, and if there was no multiplication problem, you would not see any message at all.
|
||||
|
||||
---
|
||||
|
||||
PCjs v1.20.0 now supports a "stepping" attribute on the <cpu> element, which you can use to simulate specific
|
||||
stepping behavior. For example, a *machine.xml* file with the following CPU definition:
|
||||
|
||||
```xml
|
||||
<cpu id="cpu386" model="80386" stepping="b0"/>
|
||||
```
|
||||
|
||||
will cause Windows 95 to abort exactly as described as above. Similarly, selecting a 80386 B1 stepping:
|
||||
|
||||
```xml
|
||||
<cpu id="cpu386" model="80386" stepping="b1"/>
|
||||
```
|
||||
|
||||
will cause Windows 95 to display the 32-bit multiplication warning shown above (PCjs deliberately fails the exact
|
||||
multiplication test that Windows 95 performs).
|
||||
|
||||
If you want to simulate a B1 stepping that does *not* have the 32-bit multiplication flaw, set the stepping to B2:
|
||||
|
||||
```xml
|
||||
<cpu id="cpu386" model="80386" stepping="b2"/>
|
||||
```
|
||||
|
||||
B2 was not an actual 80386 stepping; it is a *pseudo-stepping* that provides a simple way of specifying a B1 80386 that
|
||||
passes all 32-bit multiplication tests.
|
||||
|
||||
As previously discussed, Windows 95 SETUP will refuse to install on any "A" or "B" stepping, but if it's already been
|
||||
installed, it *will* start up on a B1 stepping.
|
||||
|
||||
PCjs stepping support is extremely limited at this point. Here's a summary:
|
||||
|
||||
1. 80386 steppings A0-B0 provide *limited* support for the short-lived XBTS and IBTS instructions
|
||||
2. 80386 steppings A0-B1 enable [Errata #7](/pubs/pc/reference/intel/80386/#b1-errata) for STOSB (as tested by Windows 95; see above)
|
||||
3. 80386 stepping B1 enables 32-bit multiplication errors (as tested by Windows 95; see above)
|
||||
4. 80386 stepping B2 includes all supported B1 errata, but without 32-bit multiplication errors
|
||||
|
||||
In addition, on 80386 reset, we set the CPU revision number in DX to the appropriate value for the specified stepping.
|
||||
|
||||
Support for additional 80286 and 80386 errata may be added over time, as interesting scenarios or test cases are discovered.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*October 27, 2015*
|
||||
124
_posts/2015-12-10-rebuilding-the-pcjs-website.md
Normal file
124
_posts/2015-12-10-rebuilding-the-pcjs-website.md
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
---
|
||||
layout: post
|
||||
title: Rebuilding the PCjs Website
|
||||
date: 2015-12-10 11:03:00
|
||||
category: Website
|
||||
permalink: /blog/2015/12/10/
|
||||
---
|
||||
|
||||
It's been nice using Node.js to power the PCjs website, using Amazon's Elastic Beanstalk service, but that combination
|
||||
has also been a source of some frustrations.
|
||||
|
||||
+ When someone posts an article or a tweet linking to a PCjs page, the website bogs down, and while Amazon's Elastic
|
||||
Beanstalk service makes it easy to automatically scale up, each new instance automatically multiplies my expenses as well,
|
||||
which hover around $34/month for a single instance. With assorted S3 and transfer charges, my average monthly bill is
|
||||
over $55/month. That's a bit much for a site that generates zero revenue.
|
||||
|
||||
+ Once or twice a year, when I'm attempting to either update the server or upgrade my Node configuration, the update
|
||||
or upgrade will fail, and Amazon's web console provides virtually no details about why it failed. I get an error message
|
||||
like "**ERROR: Failed to deploy application**" and that is it. Literally.
|
||||
|
||||
Granted, there are some "simple" things I could do to improve performance, like adding an **nginx** proxy server to
|
||||
the configuration, but that feels like a band-aid solution, and as a software developer, the time spent fiddling with
|
||||
web server issues is time I'd much rather spend writing code.
|
||||
|
||||
Since PCjs is designed to do all its work in the user's web browser, and since the website can be completely built out
|
||||
as a set of static web pages, I've decided to stop using Node to power www.pcjs.org. I'm in the process of migrating
|
||||
the website to [GitHub Pages](https://pages.github.com/), and using [Jekyll](https://help.github.com/articles/using-jekyll-with-pages/)
|
||||
to convert all my existing Markdown files to HTML.
|
||||
|
||||
This new approach is *very* similar to what the PCjs custom Node modules did: every time someone visited a folder
|
||||
on the website that did not yet contain an "index.html", the PCjs Node server would create one, either by converting the
|
||||
README.md file in that folder to HTML or generating a default HTML document. The PCjs Markdown-to-HTML converter also
|
||||
contained some special logic that made it easy to embed PCjs machines on a page.
|
||||
|
||||
Thanks to GitHub Pages, all of that now happens ahead of time: whenever I update the PCjs "gh-pages" branch on GitHub,
|
||||
Jekyll automatically runs through the entire site and rebuilds a complete set of web pages.
|
||||
|
||||
The Node web server would automatically embed PCjs machines on web pages by looking for special Markdown links, such as;
|
||||
|
||||
[Embedded IBM PC](machine.xml "PCjs:ibm5150")
|
||||
|
||||
After migrating to GitHub Pages and Jekyll, that markup must now be written as:
|
||||
|
||||
{% raw %}
|
||||
{% include machine.html id="ibm5150" %}
|
||||
{% endraw %}
|
||||
|
||||
and the following "Front Matter" (YAML) must appear at the top of the Markdown file:
|
||||
|
||||
---
|
||||
...
|
||||
machines:
|
||||
- type: pcx86
|
||||
id: ibm5150
|
||||
---
|
||||
|
||||
Basically, the YAML at the top of the file lists all the machines that the page intends to use, and then
|
||||
{% raw %}`{% include ... %}`{% endraw %} is inserted in the text at the point where a machine should be embedded.
|
||||
|
||||
The `machine.html` include accepts only one parameter: the `id` of a machine listed at the top of the file.
|
||||
|
||||
The `machines` element at the top of the file must specify a `type` and `id` at a minimum. `type` should be one of
|
||||
the following values, depending on whether you want an IBM PC or Challenger 1P:
|
||||
|
||||
- pc
|
||||
- c1p
|
||||
|
||||
and `id` can be any identifier you want to use to embed the machine. If you want to include the machine's built-in
|
||||
debugger, set `debugger` to *true*; the older method of specifying *pc-dbg* or *c1p-dbg* instead of *pc* or *c1p* as the
|
||||
`type` still works, too.
|
||||
|
||||
You may also use `config` to specify a machine XML configuration file if not using the default *machine.xml*;
|
||||
`template` to specify an alternate XSL template file if not using the default *components.xsl*; `state` to specify
|
||||
a JSON-encoded machine state file if the machine requires a predefined state; and `uncompiled` may be set to *true*
|
||||
to force a machine to use uncompiled sources, overriding the value of `site.pcjs.compiled` in **_config.yml**.
|
||||
|
||||
For example, the PCjs home page contains two machines, so this appears at the top of the
|
||||
[Markdown file](https://raw.githubusercontent.com/jeffpar/pcjs/master/index.md):
|
||||
|
||||
machines:
|
||||
- type: pcx86
|
||||
id: ibm5150
|
||||
config: /devices/pcx86/machine/5150/mda/64kb/machine.xml
|
||||
- type: c1p
|
||||
id: demoC1P
|
||||
config: /devices/c1p/machine/8kb/large/machine.xml
|
||||
|
||||
If necessary, you can also override some of the settings in a machine XML file. Here's an example of overriding the
|
||||
FDC `autoMount` setting, making it easy to reuse the same machine XML file with different boot disks:
|
||||
|
||||
machines:
|
||||
- type: pcx86
|
||||
id: deskpro386
|
||||
debugger: true
|
||||
autoMount:
|
||||
A:
|
||||
path: /disks/pcx86/os2/misc/football/FOOTBALL-76817.json
|
||||
config: /devices/pcx86/machine/compaq/deskpro386/ega/4096kb/debugger/machine.xml
|
||||
|
||||
Other settings that can currently be overridden include:
|
||||
|
||||
+ `autoPower`
|
||||
+ `drives`
|
||||
+ `messages`
|
||||
+ `state`
|
||||
|
||||
Additional overrides will be added as needed. See the [Windows 95 Demo](/disks/pcx86/windows/win95/4.00.950/)
|
||||
machine and its associated [Markdown file](https://raw.githubusercontent.com/jeffpar/pcjs/master/disks/pcx86/windows/win95/4.00.950/README.md)
|
||||
for more override examples, including how to set `autoMount` to *not* mount any diskettes.
|
||||
|
||||
I will continue to include a Node web server with the PCjs Project, but it's now intended for development
|
||||
purposes only (not production servers). I've updated the PCjs MarkOut component to parse any "Front Matter"
|
||||
at the top of the PCjs Markdown files, and to convert all new Jekyll-style embedded machines and screenshots
|
||||
to the older Markdown-compatible formats, so pages generated by the Node web server should still function
|
||||
as before. But there are no guarantees.
|
||||
|
||||
WARNING: If you decide to run/alternate between Jekyll's web server (WEBrick) and the built-in Node web
|
||||
server (server.js), you should run "grunt clean" before starting either one, to remove any old **index.html**
|
||||
files. Node may inadvertently reuse old "index.html" files, and Jekyll may inadvertently propagate them
|
||||
to its "_site" folder. It's easy to tell when this happens, because you'll see the wrong color scheme: Node
|
||||
web server pages were designed to use *dark* colors, whereas Jekyll web server pages currently use *light* colors.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*December 10, 2015*
|
||||
48
_posts/2015-12-27-revisiting-os2.md
Normal file
48
_posts/2015-12-27-revisiting-os2.md
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
layout: post
|
||||
title: Revisiting OS/2
|
||||
date: 2015-12-27 11:00:00
|
||||
category: OS/2
|
||||
permalink: /blog/2015/12/27/
|
||||
machines:
|
||||
- type: pcx86
|
||||
id: ibm5170
|
||||
debugger: true
|
||||
config: /devices/pcx86/machine/5170/ega/2048kb/rev3/debugger/machine.xml
|
||||
drives: '[{name:"20Mb Hard Disk",type:2,path:"/disks/pcx86/fixed/20mb/IBMOS210-EGA.json"}]'
|
||||
automount: ''
|
||||
---
|
||||
|
||||
Just for fun (because I have a warped sense of fun), I decided to revisit some of the old OS/2 software I wrote
|
||||
almost 30 years ago. But first, I needed an OS/2 development environment.
|
||||
|
||||
So I started with a clean install of [IBM OS/2 1.0](/disks/pcx86/os2/ibm/1.0/) in the 8Mhz IBM PC AT machine
|
||||
below, by booting from the "IBM OS/2 1.0 (1.44M Install)" diskette in drive A and reformatting the machine's 20Mb
|
||||
drive C.
|
||||
|
||||
Next, I installed the [MS OS/2 SDK 1.02](/disks/pcx86/tools/microsoft/os2/sdk/1.02/). This SDK was released
|
||||
in December 1987 along with [Microsoft OS/2 1.0](/disks/pcx86/os2/microsoft/1.0/). I don't have any of the
|
||||
printed documentation that came with the SDK, such as the *Installation Guide*, but I do have the
|
||||
[Microsoft® Operating System/2 Programmer’s Toolkit](/pubs/pc/software/os2/microsoft/ptk10/) documentation
|
||||
from March 1988, thanks to the [OS/2 Museum](http://www.os2museum.com/wp/os2-history/os2-library/os2-1-x-programming/).
|
||||
|
||||
Aside from **Microsoft Macro Assembler 5.00A** (MASM) and **Microsoft C Compiler 5.10 (Beta)** (CL), the SDK
|
||||
included some other useful tools, such as the **SDK Editor** (SDKED), which was essentially an OS/2 port of
|
||||
Mark Zbikowski's full-screen editor (Z) that was used internally at Microsoft for many years. It was renamed
|
||||
to the **Microsoft Editor** (M or MEP) with the release of **Microsoft C Compiler 5.10**, and it was later integrated
|
||||
into **Programmer's Workbench** (PWB), the text-mode Integrated Development Environment (IDE) that came with
|
||||
**Microsoft C Compiler 6.0**.
|
||||
|
||||
With the introduction of graphical IDEs, such as Visual BASIC in 1991, Visual C++ in 1993, and Visual Studio in 1995,
|
||||
this stand-alone, text-mode editor became obsolete, but in the 1980s, it was a valuable tool. You can learn more
|
||||
about [SDKED](/disks/pcx86/tools/microsoft/os2/sdk/1.02/#using-sdked) on the
|
||||
[MS OS/2 SDK 1.02](/disks/pcx86/tools/microsoft/os2/sdk/1.02/) page.
|
||||
|
||||
Our [IBM OS/2 1.0](/disks/pcx86/os2/ibm/1.0/) demo machine (shown below) has the
|
||||
[MS OS/2 SDK 1.02](/disks/pcx86/tools/microsoft/os2/sdk/1.02/) pre-installed, so check out our copy of the
|
||||
[Microsoft® Operating System/2 Programmer’s Toolkit](/pubs/pc/software/os2/microsoft/ptk10/) and then write some code!
|
||||
|
||||
{% include machine.html id="ibm5170" %}
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*December 27, 2015*
|
||||
39
_posts/2016-01-23-early-os2-artifacts.md
Normal file
39
_posts/2016-01-23-early-os2-artifacts.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
layout: post
|
||||
title: Early OS/2 Artifacts
|
||||
date: 2016-01-23 14:00:00
|
||||
category: OS/2
|
||||
permalink: /blog/2016/01/23/
|
||||
---
|
||||
|
||||
Before OS/2 was named **OS/2** by IBM on April 2, 1987, the operating system was known by many different names at
|
||||
Microsoft as it evolved, including **DOS5**, **MT-DOS**, **CP-DOS**, and **ADOS**.
|
||||
|
||||
In late 1986, Microsoft began working on a couple different branches. One was called **SIZZLE**, where a variety of
|
||||
performance improvements were tested before being merged back into the main branch.
|
||||
|
||||
Another branch was **FOOTBALL** (aka **PIGSKIN**), an early 80386-based prototype intended to test the viability
|
||||
of the running multiple DOS applications in V86-mode. Sometimes this 80386 version was also called **386DOS**,
|
||||
to distinguish it from **286DOS**. More details are in this
|
||||
[FOOTBALL Design Document](/disks/pcx86/os2/misc/football/87058/#football-design-document).
|
||||
|
||||
To shed some light on those efforts, I recently added a few [OS/2 Prototype Disks](/disks/pcx86/os2/misc/): a small
|
||||
collection of early (mostly pre-1.0) OS/2 boot disks that provide a glimpse of what some of those early OS/2 builds
|
||||
looked like.
|
||||
|
||||
Getting these early versions of OS/2 to run in **PCjs** has been a bit of a challenge. There have been some successes
|
||||
but also some lingering issues. Debugging continues.
|
||||
|
||||
Part of the problem is that these pre-1.0 builds still contain a few bugs. Also, the original
|
||||
[OS/2 FOOTBALL Boot Disk](/disks/pcx86/os2/misc/football/87058/) from February 1987 was developed and
|
||||
tested exclusively on Compaq DeskPro 386 machines from late 1986, so it has some uncommon 80386 dependencies:
|
||||
|
||||
* The [80386 LOADALL](/pubs/pc/reference/intel/80386/loadall/) instruction
|
||||
* 32-bit segment register writes must modify only 16 bits of memory
|
||||
|
||||
**FOOTBALL** also had some specific video hardware requirements: CGA or EGA. Note that the VGA, which is what most
|
||||
emulators use by default these days, did not exist in 1986. The VGA was introduced in April 1987, when IBM
|
||||
unveiled their new PS/2 hardware line -- and announced OS/2.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*January 23, 2016*
|
||||
57
_posts/2016-02-08-super-bowl-winner-pcjs.md
Normal file
57
_posts/2016-02-08-super-bowl-winner-pcjs.md
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Super Bowl Winner: PCjs"
|
||||
date: 2016-02-08 14:00:00
|
||||
permalink: /blog/2016/02/08/
|
||||
---
|
||||
|
||||
The new release of PCjs (v1.20.8) is a fairly minor update, but it's an important one for **FOOTBALL** fans, resolving
|
||||
two annoying problems with the [OS/2 FOOTBALL Boot Disk](/disks/pcx86/os2/misc/football/87058/): mysterious hard-error popups
|
||||
and blank screens.
|
||||
|
||||
A hard-error popup would occur when FOOTBALL tried to initialize a non-existent PRN device. To resolve that, PCjs
|
||||
now provides basic parallel port emulation, in the form of a [ParallelPort](/docs/pcx86/parallel/) component that you
|
||||
include in a machine XML file with the <parallel> element, in much the same way you include the
|
||||
[SerialPort](/docs/pcx86/serial/) component with the <serial> element. This [Compaq DeskPro 386]
|
||||
(/devices/pcx86/machine/compaq/deskpro386/ega/4096kb/debugger/) machine used to run FOOTBALL has now been updated to
|
||||
include one parallel port.
|
||||
|
||||
The other problem was that switching between sessions with the **SysReq** key would often result in a blank screen;
|
||||
the new session was active, but you couldn't see it. This was a side-effect of how FOOTBALL reprograms the video
|
||||
controller when switching screens *and* the linear page mappings it creates to access video memory, which in turn
|
||||
exposed a PCjs memory-management bug. The upshot is that whenever the Video component moves the address of the video
|
||||
buffer (which is *physical* memory), it must tell the CPU to flush any linear-to-physical mappings that may still refer
|
||||
to the old physical memory.
|
||||
|
||||
With these changes, the [OS/2 FOOTBALL Boot Disk](/disks/pcx86/os2/misc/football/87058/) appears to be quite usable now.
|
||||
Feel free to give it a few kicks!
|
||||
|
||||
---
|
||||
|
||||
I've also tidied up a few things in the [Devices](/devices/) folder. ROM images used to be stored under
|
||||
`/devices/pcx86/basic/` and `/devices/pcx86/bios/`, but BASIC and BIOS ROM images aren't actually devices; they are the
|
||||
*contents* of ROM devices. So, with that in mind, I've made the following rearrangements:
|
||||
|
||||
* `/devices/pcx86/bios/5150/*` => `/devices/pcx86/rom/5150/*`
|
||||
* `/devices/pcx86/bios/5160/*` => `/devices/pcx86/rom/5160/*`
|
||||
* `/devices/pcx86/bios/5170/*` => `/devices/pcx86/rom/5170/*`
|
||||
* `/devices/pcx86/bios/compaq/*` => `/devices/pcx86/rom/compaq/*`
|
||||
* `/devices/pcx86/basic/ibm-basic-1.00.json` => `/devices/pcx86/rom/5150/basic/BASIC100.json`
|
||||
* `/devices/pcx86/basic/ibm-basic-1.10.json` => `/devices/pcx86/rom/5160/basic/BASIC110.json`
|
||||
|
||||
This structure mirrors what was done with Machine and Video devices, where the devices are organized
|
||||
first by manufacturer (IBM or COMPAQ) and then by type (MDA, CGA, EGA, etc).
|
||||
|
||||
Here, the first ROM subdivision is either a manufacturer or a machine model. A model implies a manufacturer;
|
||||
for example, models 5150 through 5170 refer to IBM PC models.
|
||||
|
||||
---
|
||||
|
||||
The project currently includes only two BASIC ROM versions, C1.00 and C1.10, which were initially released with the
|
||||
first model 5150 and 5160 machines, respectively. For more details, see [IBM PC ROMs](/devices/pcx86/rom/).
|
||||
|
||||
I believe there was also a BASIC ROM version 1.20 released for IBM PCjr, but since PCjs does not yet emulate the PCjr,
|
||||
it has not been added to the project.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*February 8, 2016*
|
||||
130
_posts/2016-02-17-saving-disks-and-machines.md
Normal file
130
_posts/2016-02-17-saving-disks-and-machines.md
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
---
|
||||
layout: post
|
||||
title: "Saving Disks and Machines"
|
||||
date: 2016-02-17 14:00:00
|
||||
permalink: /blog/2016/02/17/
|
||||
---
|
||||
|
||||
PCx86 (v1.20.9) now offers new, *much* easier ways to save disks and machines, thanks to the new
|
||||
[Save Disk](/blog/2016/02/17/#saving-disks) and [Save Machine](/blog/2016/02/17/#saving-machines) features.
|
||||
With one click, PCx86 can now generate a single download containing everything you need to embed any of our
|
||||
IBM PC demos on your own web page.
|
||||
|
||||
Saving Disks
|
||||
---
|
||||
|
||||
Floppy disk images can now be saved to your desktop computer by simply clicking the **Save** button next
|
||||
to the floppy disk controls. Select the drive first, and then whatever diskette is shown as being "loaded"
|
||||
in that drive will be saved in your local machine's Downloads folder when you click **Save**.
|
||||
|
||||
If you made any changes to that disk after it was loaded, those changes will be included, so if you want a pristine
|
||||
copy of the disk, click the **Load** button first. PCx86 will ask you to confirm that you really want to reload the
|
||||
disk and discard any changes.
|
||||
|
||||
Note that the disk *should* be downloaded as an **.img** file, which is nothing more than a sector-by-sector binary
|
||||
dump of the disk. For example, a 360Kb double-sided double-density (DSDD) disk contains 9 512-byte sectors in each
|
||||
of the 40 tracks on each of its 2 sides, so when you **Save** a 360Kb disk, the downloaded file should be exactly
|
||||
368,640 bytes large.
|
||||
|
||||
The Mac OS X operating system can automatically mount most **.img** files (from disks created by DOS 2.0 or later).
|
||||
Older DOS 1.x disks, along with most non-DOS disks, do not have a BIOS Parameter Block (BPB) in the boot sector, so
|
||||
most modern operating systems won't recognize the disk format. Other operating systems, like Windows, may require
|
||||
third-party software in order to mount an **.img** file, and some third-party software may prefer a different extension,
|
||||
such as **.ima** or **.bin**.
|
||||
|
||||
It's also recommended that you make your **.img** files *read-only*, so that if you do mount them on your desktop
|
||||
computer, neither you nor the operating system will inadvertently modify the contents of the disk. On OS X, this is
|
||||
easily done with the **chmod** utility.
|
||||
|
||||
For example, if you saved the disk named "PC-DOS 2.00 (Disk 1)", it should have been downloaded as "PCDOS200-DISK1.img"
|
||||
in your Downloads folder, so the OS X Terminal command `chmod -w PCDOS200-DISK1.img` will make it read-only, and
|
||||
`chmod +w PCDOS200-DISK1.img` will make it writable again.
|
||||
|
||||
**NOTE**: Some browsers, notably Safari, do not support named downloads, so any disks you download will end up
|
||||
with default names like "Unknown" or "download". PCx86 will still try to let you know what the original filename was,
|
||||
so that you can rename it appropriately.
|
||||
|
||||
Saving Machines
|
||||
---
|
||||
|
||||
Saving the entire state of any existing IBM PC machine is also much simpler now, using the new **Save Machine** link.
|
||||
You can choose to save a machine in its initial state, or make changes to any of the machine's disks and then save it.
|
||||
All your changes should be preserved.
|
||||
|
||||
Under the bottom-left corner of any IBM PC on the PCjs [website](/), you should now see a
|
||||
[**Save Machine**] link. When you click that link, PCx86 will generate a large chunk of JavaScript containing
|
||||
everything that machine needs to run, including:
|
||||
|
||||
* The machine XML configuration file (eg, "machine.xml")
|
||||
* The machine XSL transformation file (eg, "components.xsl")
|
||||
* The machine CSS stylesheet file (eg, "components.css")
|
||||
* The machine state file (eg, "state.json")
|
||||
* The PCx86 machine emulation script (eg, "pcx86.js")
|
||||
* Copies of all the disk images mounted by the machine
|
||||
|
||||
Let's say you want to save the IBM PC on the PCx86 [home page](/). When you click **Save Machine**, two things should
|
||||
happen:
|
||||
|
||||
* A file will be downloaded (eg, "pcx86.js")
|
||||
* A dialog box will appear with some markup to copy-and-paste
|
||||
|
||||
The dialog box should provide the following information:
|
||||
|
||||
Check your Downloads folder for "pcx86.js", copy it to your web server as "pcx86.js",
|
||||
and then add the following to your web page:
|
||||
|
||||
<div id="ibm5150"></div>
|
||||
...
|
||||
<script type="text/javascript" src="pcx86.js"></script>
|
||||
<script type="text/javascript">embedPC("ibm5150","machine.xml","components.xsl");</script>
|
||||
|
||||
The machine should appear where the <div> is located.
|
||||
|
||||
Copy the downloaded file to your own web server as **pcx86.js**, then create or edit a web page and insert the above text.
|
||||
If **pcx86.js** and your web page are in different folders, then you'll also need to update *src* to include the exact
|
||||
location of the script.
|
||||
|
||||
Some notes:
|
||||
|
||||
* PCx86 may attempt to name the downloaded file **pcx86.json** instead of **pcx86.js**, because a file with a ".js"
|
||||
extension could cause your web browser to block the download.
|
||||
|
||||
* For browsers that don't support named downloads, PCx86 will attempt to open a new window/tab instead. Make sure
|
||||
you copy the *entire* contents of that window into a file named to **pcx86.js** (or **pcx86-dbg.js** if the machine is
|
||||
using the built-in PCx86 debugger).
|
||||
|
||||
* Your browser may also impose size limitations on the download. If nothing happens, the machine data may be too
|
||||
large for your browser; try a different browser (eg, Firefox or Safari) or a different machine.
|
||||
|
||||
* If you have modified any floppy disks mounted by the machine *or* any of the machine's hard disks, those
|
||||
modifications should be saved along with the machine.
|
||||
|
||||
* Any floppy disks mounted during the lifetime of the machine will be added to the machine's state. So, for example,
|
||||
if you want your copy of the machine to include all the Windows 1.01 SDK disks, make sure you have loaded each disk
|
||||
once before clicking **Save Machine**.
|
||||
|
||||
* Any floppy disks *not* mounted during the lifetime of the machine will be *removed* from the machine's list of
|
||||
available disks; we don't want machines running on other websites to be consuming our bandwidth.
|
||||
|
||||
* The machine's current state, including memory and screen contents, are saved as part of the machine state.
|
||||
So, even if the original machine always powers on from scratch, the *copied* machine will always resume at the point
|
||||
it was saved. This behavior, however, can be disabled by passing a *parms* object as the 4th parameter to the
|
||||
*embedPC()* call, overriding the 'state' property:
|
||||
|
||||
```xml
|
||||
<script type="text/javascript">embedPC("ibm5150","machine.xml","components.xsl","{state:null}");</script>
|
||||
```
|
||||
|
||||
While the [PCx86 Documentation](/docs/pcx86/) explains how to create a *new* machine, by writing your own machine
|
||||
XML file and manually copying all the other pieces, the new **Save Machine** feature is the best way to save
|
||||
any *existing* IBM PC and embed it on any other website.
|
||||
|
||||
**WARNING**: While this feature is still "hot of the press," there will probably be some kinks to work out. Every
|
||||
browser seems to have its own idiosyncrasies in terms of what can be downloaded and/or how large it can be. It's
|
||||
also quite possible that certain machine features or modifications may not be properly preserved.
|
||||
|
||||
If you're having trouble with a particular browser or a particular machine, be sure to
|
||||
[let me know](mailto:Jeff@pcjs.org), and then try another browser and/or machine.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*February 17, 2016*
|
||||
95
_posts/2016-02-24-remembering-compaq.md
Normal file
95
_posts/2016-02-24-remembering-compaq.md
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
---
|
||||
layout: post
|
||||
title: Remembering COMPAQ
|
||||
date: 2016-02-24 14:00:00
|
||||
permalink: /blog/2016/02/24/
|
||||
---
|
||||
|
||||
IBM is obviously the company everyone thinks of first when we talk about the IBM PC -- after all, IBM is right
|
||||
there in the name. They designed the thing. So IBM, and in particular the folks who worked in Boca Raton at IBM's
|
||||
Entry Systems Division in the early 1980's, deserve all the credit for defining what eventually became known as the
|
||||
Industry Standard Architecture (ISA) PC platform.
|
||||
|
||||
However, the dawn of the PC era also saw the rise and fall of many other personal computer companies.
|
||||
One of the more exceptional companies from that era was COMPAQ. It would be a mistake to dismiss COMPAQ as just
|
||||
another company that set out to "copy" or "clone" IBM's design, because from the very beginning, COMPAQ's ambitions
|
||||
went beyond mere imitation. They were really in the *compatibility* business.
|
||||
|
||||
Innovation in the PC industry would not have been as rapid and diverse if IBM had been the only supplier of
|
||||
compatible machines and accessories. If IBM had been able to control the market, they probably would have continued
|
||||
some of the monopolistic practices they had perfected in the mainframe era. Market control might have been a win for
|
||||
IBM, but it almost certainly would *not* have been a win for customers.
|
||||
|
||||
In 1982, the founders of COMPAQ took a big gamble, by reportedly investing around a million dollars to create
|
||||
a system that mimicked IBM's without infringing on it. I don't know if COMPAQ pioneered the concept of "clean room"
|
||||
design, where the engineers designing and coding have no direct contact with the hardware and software they're cloning,
|
||||
but they were certainly successful.
|
||||
|
||||
But that wasn't COMPAQ's most important contribution. That was just the price they had to "pay to play." Armed with
|
||||
compatible hardware and software, COMPAQ proceeded to innovate in ways that IBM did not.
|
||||
|
||||
Look at COMPAQ's first product: the COMPAQ Portable. For starters, it was *portable*. And unlike
|
||||
IBM machines, it didn't force you to choose between a higher-quality text-only (MDA) display or a lower-quality
|
||||
graphics-capable (CGA) display. COMPAQ improved on IBM's mutually-exclusive display choices by creating a monochrome
|
||||
display that could display both high-quality text *and* graphics.
|
||||
|
||||
IBM released their own portable unit a year later, but it looked suspiciously COMPAQ-like, and it lacked COMPAQ's
|
||||
innovative display.
|
||||
|
||||
That tradition of innovation at COMPAQ continued for many years. Sometimes they even seemed *more* concerned about
|
||||
compatibility than IBM did. For example, faster machines sometimes broke speed-sensitive floppy-based copy protection
|
||||
schemes, which COMPAQ tried to avoid by automatically *slowing* the machine down whenever a floppy drive was spinning.
|
||||
|
||||
To my knowledge, IBM never bothered with such a feature -- maybe IBM was simply being pragmatic, or perhaps they were
|
||||
just a little arrogant, operating on the theory that if the universe revolves around IBM, then the planets will
|
||||
simply realign *themselves* (translation: software vendors will release new versions if they want to remain IBM-compatible).
|
||||
|
||||
Sadly, COMPAQ was ultimately absorbed by another behemoth -- Hewlett Packard -- and then simply disappeared. Today,
|
||||
all we have are the memories.
|
||||
|
||||
### Speaking of Memories
|
||||
|
||||
In particular, Read-Only Memories: we have precious few of those, too. I finally obtained
|
||||
a [ROM Dump](/devices/pcx86/rom/compaq/portable/) from COMPAQ's first machine, the COMPAQ Portable, but I had to buy
|
||||
a system board on ebay to get it. Considering all the effort (and money) that COMPAQ invested in writing that code,
|
||||
it's a bit depressing that these things haven't been properly preserved and memorialized.
|
||||
|
||||
Looking ahead to the day when PCjs will be able to simulate the original COMPAQ Portable, I thought it would be a good
|
||||
idea to create my own roughly chronological list of [COMPAQ Machines](/devices/pcx86/machine/compaq/) from the 1980s,
|
||||
since they are all machines I would like to see PCjs eventually support:
|
||||
|
||||
- COMPAQ Portable
|
||||
- COMPAQ [Portable] Plus
|
||||
- COMPAQ DeskPro
|
||||
- COMPAQ DeskPro 286
|
||||
- COMPAQ Portable 286
|
||||
- COMPAQ Portable II
|
||||
- [COMPAQ DeskPro 386](/devices/pcx86/machine/compaq/deskpro386/)
|
||||
- COMPAQ Portable III
|
||||
- COMPAQ DeskPro 386/20
|
||||
- COMPAQ Portable 386
|
||||
- COMPAQ DeskPro 386/25
|
||||
- COMPAQ DeskPro 386s
|
||||
- COMPAQ DeskPro 386/20e
|
||||
- COMPAQ SLT Series (SLT/286)
|
||||
- COMPAQ DeskPro 386/33
|
||||
- COMPAQ LTE Series (LTE and LTE/286)
|
||||
|
||||
It's hard to stop at this point, because COMPAQ produced other innovative 80386-based systems, like those in the LTE
|
||||
and LTE Lite series. But I think I need to stick to my original plan and draw a line at the end of the 1980s.
|
||||
|
||||
### Regarding The COMPAQ Name
|
||||
|
||||
As best I can tell, COMPAQ preferred to print its company name in all-caps, so that's my practice as well.
|
||||
|
||||
However, it seems that sometime between the release of [COMPAQ MS-DOS 3.10](/disks/pcx86/dos/compaq/3.10/) and
|
||||
[COMPAQ MS-DOS 3.31](/disks/pcx86/dos/compaq/3.31/), there may have been a shift in policy. Both products still
|
||||
called themselves `The COMPAQ Personal Computer MS-DOS`, but in 3.31, the copyright string changed to
|
||||
`Compaq Computer Corp.`
|
||||
|
||||
Their all-caps practice also extended to product names (eg, `COMPAQ DESKPRO`), at least in their marketing literature.
|
||||
Contemporary news stories, however, tended to lower-case the product name (eg, `COMPAQ Deskpro`). I've decided to
|
||||
split the difference and use mixed-case where it seems appropriate (eg, `COMPAQ DeskPro`).
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*February 24, 2016*
|
||||
48
_posts/2016-03-06-touching-windows.md
Normal file
48
_posts/2016-03-06-touching-windows.md
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
layout: post
|
||||
title: Touching Windows
|
||||
date: 2016-03-06 09:00:00
|
||||
permalink: /blog/2016/03/06/
|
||||
---
|
||||
|
||||
Yesterday, I fired up [Windows 3.1](/disks/pcx86/windows/3.10/) and played a complete game of
|
||||
[Windows Solitaire](https://en.wikipedia.org/wiki/Microsoft_Solitaire) on my iPad. It was a bit, um, touchy,
|
||||
but it worked.
|
||||
|
||||
{% comment %}[<img src="/blog/images/ipad-solitaire-small.jpg" alt="Windows Solitaire on iPad"/>](/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*
|
||||
34
_posts/2016-03-12-demos-of-windows386-and-windows-3x.md
Normal file
34
_posts/2016-03-12-demos-of-windows386-and-windows-3x.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
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*
|
||||
56
_posts/2016-04-30-the-intel-8080-cpu.md
Normal file
56
_posts/2016-04-30-the-intel-8080-cpu.md
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
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*
|
||||
95
_posts/2016-05-04-the-sharpening.md
Normal file
95
_posts/2016-05-04-the-sharpening.md
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
---
|
||||
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
|
||||
<machine id="ibm5160" class="pc" border="1" width="680px" float="left" background="#FAEBD7">
|
||||
```
|
||||
|
||||
but most machines don't specify a (maximum) overall width, so their screen canvas is allowed to stretch far beyond
|
||||
the initial *screenWidth* and *screenHeight*, thanks to some additional CSS settings.
|
||||
|
||||
Larger screens mean less interpolation, which is a good thing if you want the screens to look less "fuzzy."
|
||||
However, interpolation also happens at a deeper level, because internally, PCjs uses two canvases to move pixels
|
||||
from the machine's frame buffer to your browser: the screen canvas, which I've already discussed, and another
|
||||
canvas called the *buffer* canvas, where changes to the machine's frame buffer are, um, buffered.
|
||||
|
||||
The *buffer* canvas has the same dimensions as the machine's frame buffer, whereas the *screen* canvas
|
||||
has generally higher dimensions (as explained above), which your browser may then be stretching to even higher
|
||||
dimensions, depending on your monitor resolution and browser size.
|
||||
|
||||
The differential between the *buffer* canvas and *screen* canvas is where additional interpolation (fuzziness)
|
||||
creeps in. That is where The Sharpening now occurs.
|
||||
|
||||
All the browsers I've tested so far (Chrome, Firefox, and Safari) support a
|
||||
[Canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API)
|
||||
[Context](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D) property named
|
||||
[imageSmoothingEnabled](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled),
|
||||
which eliminates much of the fuzziness that would occur when copying pixels from the lower-resolution *buffer* canvas
|
||||
to the higher-resolution *screen* canvas.
|
||||
|
||||
So I've added a new [Video](/docs/pcx86/video/) property named *smoothing* that can be set to "true" or "false",
|
||||
and I've set it to "false" for most machines in the project. If *smoothing* is not set, your browser continues to
|
||||
use its default interpolation method.
|
||||
|
||||
{% include screenshot.html src="/blog/images/si1978-fuzzier.png" width="339" height="388" title="Space Invaders (Fuzzier)" link="/devices/pc8080/machine/invaders/?smoothing=true" %}
|
||||
{% include screenshot.html src="/blog/images/si1978-sharper.png" width="339" height="388" title="Space Invaders (Sharper)" link="/devices/pc8080/machine/invaders/?smoothing=false" %}
|
||||
|
||||
For some people, this might be a matter of taste, because less fuzziness necessarily means more pixelation (ie, you
|
||||
can see individual pixels more clearly), which becomes more noticeable when switching a machine **Full Screen**.
|
||||
So I've also added a URL *smoothing* parameter you can use to override a machine's default setting; eg:
|
||||
|
||||
http://www.pcjs.org/devices/pc8080/machine/invaders/?smoothing=true
|
||||
|
||||
See for yourself, by clicking on each of the [Space Invaders](/devices/pc8080/machine/invaders/) images above and
|
||||
then clicking the **Full Screen** button; both images link to the same machine, but left one enables image smoothing,
|
||||
while the right one does not.
|
||||
|
||||
Aspect Ratio
|
||||
---
|
||||
|
||||
The *smoothing* property joins another recent [Video](/docs/pcx86/video/) property, *aspect*, that was added in a
|
||||
[release](https://github.com/jeffpar/pcjs/releases/tag/v1.21.5) last month.
|
||||
|
||||
To recap, aspect ratio is display width divided by display height, but the choice of aspect ratio is complicated by
|
||||
the fact that none of the early IBM video card/monitor combinations (with the exception of the VGA) displayed square
|
||||
pixels, and (with the exception of the MDA) they could display text and graphics at a variety of resolutions.
|
||||
|
||||
So, for those users who either 1) don't like the aspect ratios that PCjs has chosen, or 2) just want to squeeze or
|
||||
stretch a machine's screen a bit more, there is now an *aspect* parameter you can append to the URL of any page
|
||||
containing one or more PCjs machines.
|
||||
|
||||
For example:
|
||||
|
||||
http://www.pcjs.org/disks/pcx86/dos/ibm/1.00/?aspect=2.0
|
||||
|
||||
will modify the height of the machine's screen to conform to the requested aspect ratio of 2.0. The screen should still
|
||||
be responsive to any browser resizing while still retaining that aspect ratio.
|
||||
|
||||
---
|
||||
|
||||
That's all for now. Work continues on the new [PC8080](/modules/pc8080/) emulator and the
|
||||
[Space Invaders](/devices/pc8080/machine/invaders/) test machine. More on that later, when it's finished.
|
||||
|
||||
Until then, May the 4th be with you!
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*May 4, 2016*
|
||||
66
_posts/2016-08-03-the-vt100-terminal.md
Normal file
66
_posts/2016-08-03-the-vt100-terminal.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
layout: post
|
||||
title: The VT100 Terminal
|
||||
date: 2016-08-03 18:00:00
|
||||
permalink: /blog/2016/08/03/
|
||||
machines:
|
||||
- type: pc8080
|
||||
id: vt100
|
||||
config: /devices/pc8080/machine/vt100/machine.xml
|
||||
---
|
||||
|
||||
Summer has been filled with distractions, but I've finally begun making headway on a
|
||||
[DEC VT100 Terminal](/devices/pc8080/machine/vt100/) simulation.
|
||||
|
||||
Unlike other VT100 emulators, this isn't simply an emulation of VT100 protocols. It's a simulation of the VT100's
|
||||
8080 CPU, running the original [VT100 Firmware](/devices/pc8080/rom/vt100/) inside the [PC8080](/modules/pc8080/)
|
||||
CPU emulator, along with other essential components that the CPU interacts with to control the display, keyboard, and
|
||||
serial port.
|
||||
|
||||
Most of the VT100's (non-AVO) functionality should be operational now. Once the VT100 "powers on," it should clear
|
||||
the screen and briefly display a "WAIT" message as it processes its Non-Volatile RAM (NVR). When you see a blinking cursor,
|
||||
it's ready to use. Press the SET-UP key to configure the terminal, just as you would an original VT100 terminal.
|
||||
|
||||
For even more fun, check out the [Dual VT100 Terminals](/devices/pc8080/machine/vt100/dual/) demo.
|
||||
|
||||
{% include machine.html id="vt100" %}
|
||||
|
||||
Function keys are mapped as follows:
|
||||
|
||||
- F1: PF1
|
||||
- F2: PF2
|
||||
- F3: PF3
|
||||
- F4: PF4
|
||||
- F6: BREAK
|
||||
- F7: LINE FEED
|
||||
- F8: NO SCROLL
|
||||
- F9: SET-UP
|
||||
|
||||
From the SET-UP screen, you can press **4** to switch to LOCAL mode and verify local operation of most VT100
|
||||
keys. The following keys have special meaning inside SET-UP Mode:
|
||||
|
||||
- 0: RESET
|
||||
- 2: SET/CLEAR TAB
|
||||
- 3: CLEAR ALL TABS
|
||||
- 4: ONLINE/LOCAL
|
||||
- 5: SET-UP A/B
|
||||
- 6: TOGGLE FEATURE
|
||||
- 7: TRANSMIT SPEED
|
||||
- 8: RECEIVE SPEED
|
||||
- 9: 80/132 COLUMNS
|
||||
- SHIFT-S: Save SET-UP Features
|
||||
- SHIFT-R: Restore SET-UP Features
|
||||
|
||||
The initial goal for the simulation is to provide a virtual terminal that can communicate with other PCjs machines
|
||||
and provide a realistic serial communication experience, all from the comfort of your web browser.
|
||||
|
||||
Eventually, I would also like to recreate a fully commented source-code listing for the [DEC VT100 ROMs](/devices/pc8080/rom/vt100/).
|
||||
DEC's [VT100 Technical Manuals](/pubs/dec/vt100/) are excellent, and they provide an enormous amount of hardware detail,
|
||||
but they are a bit light on certain programming details, and there are no firmware listings like those those that IBM provided
|
||||
in the early IBM PC Technical Reference manuals.
|
||||
|
||||
Check out the [VT100 Debugger Configuration](/devices/pc8080/machine/vt100/debugger/) for additional information about
|
||||
VT100 internals and links to other technical resources.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*Aug 3, 2016*
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
---
|
||||
layout: post
|
||||
title: Connecting an IBM PC to a DEC VT100 Terminal
|
||||
date: 2016-08-19 10:00:00
|
||||
permalink: /blog/2016/08/19/
|
||||
machines:
|
||||
- id: ibm5170
|
||||
type: pcx86
|
||||
connection: com2->vt100.serialPort
|
||||
config: /devices/pcx86/machine/5170/ega/2048kb/rev3/machine.xml
|
||||
- id: vt100
|
||||
type: pc8080
|
||||
connection: serialPort->ibm5170.com2
|
||||
config: /devices/pc8080/machine/vt100/machine.xml
|
||||
---
|
||||
|
||||
Now that you've had a chance to play with a standalone [VT100 Terminal](/devices/pc8080/machine/vt100/), not to mention
|
||||
[Dual VT100 Terminals](/devices/pc8080/machine/vt100/dual/), it's time to take [PCjs Machines](/) to the next level, and
|
||||
begin connecting PCs to terminals.
|
||||
|
||||
Below you'll find an 80286-based [IBM PC AT](/devices/pcx86/machine/5170/ega/2048kb/rev3/) connected to an 8080-based
|
||||
[VT100 Terminal](/devices/pc8080/machine/vt100/) via the PC's **COM2** serial port.
|
||||
|
||||
At this point, the connection is *very* thin. The [PCx86](/modules/pcx86/) [SerialPort](/modules/pcx86/lib/serialport.js)
|
||||
and [PC8080](/modules/pc8080/) [SerialPort](/modules/pc8080/lib/serialport.js) each export exactly two methods:
|
||||
|
||||
- *initConnection()*
|
||||
- *receiveData()*
|
||||
|
||||
The *receiveData()* method always returns *success*, because both SerialPort components buffer all received data.
|
||||
For now, the VT100 SerialPort component avoids overflowing the VT100 firmware's buffers by automatically throttling the flow
|
||||
of data whenever the firmware, in desperation, issues an XOFF. This "Auto XOFF" behavior will eventually be superseded by
|
||||
additional interfaces that provide conventional RS-232 signal-based flow control.
|
||||
|
||||
What can you do with these machines? Click on the PC screen and type:
|
||||
|
||||
DIR > COM2
|
||||
|
||||
or any command redirected to COM2. The output should appear on the VT100's screen.
|
||||
|
||||
A more interesting example:
|
||||
|
||||
CTTY COM2
|
||||
|
||||
redirects all *stdout* (screen) and *stdin* (keyboard) I/O to the VT100. Then click on the VT100 screen to switch focus,
|
||||
and you can now interact with the PC via the terminal. The `CTTY CON` command will restore control to the PC.
|
||||
|
||||
More useful scenarios include machines running PC-based debuggers that communicate via a serial port, such as the
|
||||
OS/2 kernel debugger, Windows debuggers like `WDEB386`, some versions of `SYMDEB`, and so on. PC-to-PC configurations will
|
||||
also be possible, enabling live demonstrations of classic communication software packages such as `CROSSTALK`.
|
||||
|
||||
I've also made it incredibly easy to put machines like this on any PCjs web page. For this blog post, all I had to do
|
||||
was add the following Front Matter to the top of the Markdown file:
|
||||
|
||||
machines:
|
||||
- id: ibm5170
|
||||
type: pcx86
|
||||
connection: com2->vt100.serialPort
|
||||
config: /devices/pcx86/machine/5170/ega/2048kb/rev3/machine.xml
|
||||
- id: vt100
|
||||
type: pc8080
|
||||
connection: serialPort->ibm5170.com2
|
||||
config: /devices/pc8080/machine/vt100/machine.xml
|
||||
|
||||
and then embed the machines in the post, each with a single line:
|
||||
|
||||
{% raw %}
|
||||
{% include machine.html id="ibm5170" %}
|
||||
{% include machine.html id="vt100" %}
|
||||
{% endraw %}
|
||||
|
||||
For people rolling their own web pages, [the basics](/docs/pcx86/) haven't changed, and adding a serial connection merely
|
||||
requires adding a *connection* property (eg, `connection:"com2->vt100.serialPort"`) to the *parms* parameter passed to the
|
||||
*embedPCx86()* interface. A similar property (eg, `connection:"serialPort->ibm5170.com2"`) must also be added to the *parms*
|
||||
passed to *embedPC8080()*.
|
||||
|
||||
For the more adventurous, a [Dual Debugger Configuration](/devices/pcx86/machine/5170/ega/2048kb/rev3/debugger/vt100/)
|
||||
is also available.
|
||||
|
||||
{% include machine.html id="ibm5170" %}
|
||||
|
||||
{% include machine.html id="vt100" %}
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*Aug 19, 2016*
|
||||
53
_posts/2016-10-06-introducing-pdpjs-a-pdp-11-emulator.md
Normal file
53
_posts/2016-10-06-introducing-pdpjs-a-pdp-11-emulator.md
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
---
|
||||
layout: post
|
||||
title: Introducing PDPjs, a PDP-11 Emulator
|
||||
date: 2016-10-06 15:00:00
|
||||
permalink: /blog/2016/10/06/
|
||||
machines:
|
||||
- id: test1170
|
||||
type: pdp11
|
||||
debugger: true
|
||||
config: /devices/pdp11/machine/1170/vt100/debugger/machine.xml
|
||||
connection: dl11->vt100.serialPort
|
||||
- id: vt100
|
||||
type: pc8080
|
||||
config: /devices/pc8080/machine/vt100/machine.xml
|
||||
connection: serialPort->test1170.dl11
|
||||
---
|
||||
|
||||
[PDPjs](/devices/pdp11/machine/) is the newest addition to the PCjs family of emulators, joining PCx86, PC8080, and C1Pjs.
|
||||
|
||||
While PDPjs may eventually support a range of DEC PDP machines, my current focus is on the PDP-11, starting with the
|
||||
PDP-11/70. From there, I'll work backwards to support other PDP-11 models, such as the PDP-11/45, until I reach the
|
||||
beginning of the PDP-11 line: the PDP-11/20.
|
||||
|
||||
I'm starting with the top-of-the-line PDP-11/70 largely because the core of the emulator is being adapted from the
|
||||
JavaScript [PDP-11/70 Emulator (v1.3)](http://skn.noip.me/pdp11/pdp11.html) written by
|
||||
Paul Nankervis, who has generously given permission to use his code in PCjs. Since his emulator is a fully functional
|
||||
11/70, it made sense to start there and work backwards, factoring out features as needed.
|
||||
|
||||
The code has already undergone a lot of refactoring. Opcodes are now decoded by function tables rather than a single
|
||||
switch statement, and every opcode is implemented with a discrete function. Other refactoring includes flag management,
|
||||
interrupt management, and device management.
|
||||
|
||||
Most of the work remaining is in device management. Like other PCjs emulators, PDPjs has a Bus component,
|
||||
[bus.js](/modules/pdp11/lib/bus.js), that allows separate device components to register I/O handlers for specific
|
||||
UNIBUS addresses. During the initial port, I moved all of Paul's original device management code into one "catch-all"
|
||||
component, [device.js](/modules/pdp11/lib/device.js), which has now been converted to the new I/O registration model.
|
||||
|
||||
The first new device component is [serialport.js](/modules/pdp11/lib/serialport.js), which is currently the
|
||||
only means PDPjs has of communicating with the outside world. So you can try
|
||||
[PDPjs connected to a VT100 Terminal](/devices/pdp11/machine/1170/vt100/), by clicking the "Run" button on the test machine.
|
||||
The test machine is running [custom boot code](/apps/pdp11/boot/test/), adapted from boot code written by Paul, but due to the
|
||||
lack of other device support, nothing can be booted yet.
|
||||
|
||||
Obviously PDPjs is very much a work-in-progress. Before I proceed much farther, I really want to put the CPU through
|
||||
some rigorous testing, so I'll be on the lookout for some comprehensive PDP-11 instruction tests. Or I'll write my own,
|
||||
and compare results across 1 or 2 other PDP-11 emulators.
|
||||
|
||||
{% include machine.html id="test1170" %}
|
||||
|
||||
{% include machine.html id="vt100" %}
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*Oct 6, 2016*
|
||||
34
_posts/2016-10-21-booting-pdp-11-basic.md
Normal file
34
_posts/2016-10-21-booting-pdp-11-basic.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
layout: post
|
||||
title: Booting PDP-11 BASIC
|
||||
date: 2016-10-21 23:00:00
|
||||
permalink: /blog/2016/10/21/
|
||||
machines:
|
||||
- id: test1120
|
||||
type: pdp11
|
||||
debugger: true
|
||||
autoMount: ''
|
||||
config: /devices/pdp11/machine/1120/basic/debugger/machine.xml
|
||||
---
|
||||
|
||||
[PDPjs](http://www.pcjs.org/devices/pdp11/machine/) can now simulate a PDP-11/20. It was one of the first PDP-11
|
||||
models, and since it had no MMU, it was limited to a maximum of 56Kb of RAM (or as DEC would say, 28K words), since
|
||||
the top 8Kb (or 4K words) of its 16-bit address space was reserved for UNIBUS devices.
|
||||
|
||||
The first PDPjs test of a PDP-11/20 machine was running [PDP-11 BASIC](/apps/pdp11/tapes/basic/), by loading
|
||||
it directly into memory from the original paper tape image. This required changes to the [RAM](/modules/pdp11/lib/ram.js)
|
||||
component, including a new *loadImage()* interface that understands DEC's paper tape format.
|
||||
|
||||
To provide a more "authentic" experience, there is also a new [PC11 Paper Tape](/devices/pdp11/pc11/) component,
|
||||
and machines can now be configured to include a virtual paper tape reader, with an [assortment of paper tapes](/apps/pdp11/tapes/)
|
||||
ready to be attached.
|
||||
|
||||
In the real world, before you could load *any* paper tape, you had to first enter a
|
||||
[Bootstrap Loader](/apps/pdp11/boot/bootstrap/). PDPjs has simplified that process by including the Bootstrap Loader as
|
||||
just another paper tape image that you can "Load" directly into memory. Once that has been loaded, you can then read any
|
||||
other paper tape image, once you "Attach" it to the paper tape reader.
|
||||
|
||||
{% include machine.html id="test1120" %}
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*Oct 21, 2016*
|
||||
69
_posts/2016-11-08-you-should-have-voted-for-the-pdp-11.md
Normal file
69
_posts/2016-11-08-you-should-have-voted-for-the-pdp-11.md
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
---
|
||||
layout: post
|
||||
title: You Should Have Voted For The PDP-11
|
||||
date: 2016-11-08 11:00:00
|
||||
permalink: /blog/2016/11/08/
|
||||
machines:
|
||||
- id: test1170
|
||||
type: pdp11
|
||||
debugger: true
|
||||
config: /devices/pdp11/machine/1170/panel/debugger/machine.xml
|
||||
---
|
||||
|
||||
Greetings from an alternate reality where DEC's elegant PDP-11 architecture beat out Intel's gross 8086 architecture,
|
||||
and DEC managed to gracefully evolve the 16-bit PDP-11 into powerful 32-bit and 64-bit successors, all while maintaining
|
||||
excellent backward compatibility.
|
||||
|
||||
Unfortunately, you're stuck in your reality, so you have no idea what I'm talking about. Basically, your ancestors voted
|
||||
for the cheapest solution rather than the best solution, and now you have to live with the consequences.
|
||||
|
||||
The good news: [PDPjs](/devices/pdp11/machine/1170/panel/debugger/) makes it possible for you to go back in time, and for a moment at least,
|
||||
and relive the PDP-11 experience. It's still a somewhat primitive experience, but PDPjs is a work-in-progress, so hang in
|
||||
there.
|
||||
|
||||
The latest release, v1.30.3, adds the following features:
|
||||
|
||||
- Functional [Front Panels](/devices/pdp11/panel/1170/#front-panel-basics) (check out the demo below)
|
||||
- ROMs such as DEC's [M9312 ROMs](/devices/pdp11/rom/M9312/) can now be installed
|
||||
- Support for DEC's [RL11 Disk Controller](/devices/pdp11/rl11/) has been implemented
|
||||
|
||||
To test RL11 support below, then select the "XXDP+ Diagnostics" disk from the "Disk Drive Controls",
|
||||
click "Load", and wait for the message:
|
||||
|
||||
Mounted disk "XXDP+ Diagnostics" in drive RL0
|
||||
|
||||
Then start the machine (click "Run") and make sure the following prompt has been displayed:
|
||||
|
||||
PDP-11 MONITOR V1.0
|
||||
|
||||
BOOT>
|
||||
|
||||
At the prompt, type "BOOT RL0". The following text should appear:
|
||||
|
||||
CHMDLD0 XXDP+ DL MONITOR
|
||||
BOOTED VIA UNIT 0
|
||||
28K UNIBUS SYSTEM
|
||||
|
||||
ENTER DATE (DD-MMM-YY):
|
||||
|
||||
RESTART ADDR: 152010
|
||||
THIS IS XXDP+. TYPE "H" OR "H/L" FOR HELP.
|
||||
|
||||
.
|
||||
|
||||
And that's the extent of my testing, so if you try anything else and it doesn't work, feel free to
|
||||
[open an issue](https://github.com/jeffpar/pcjs/issues).
|
||||
|
||||
Better yet, fork the [PCjs Project](https://github.com/jeffpar/pcjs), debug the problem yourself, test a fix,
|
||||
and then send me a pull request. :-)
|
||||
|
||||
Finally, another shout-out to Paul Nankervis, who not only generously gave permission
|
||||
to use code from his JavaScript [PDP-11/70 Emulator (v1.4)](http://skn.noip.me/pdp11/pdp11.html), but has also patiently
|
||||
answered all my questions.
|
||||
|
||||
I'm [@jeffpar](http://twitter.com/jeffpar) and I approve this blog post.
|
||||
|
||||
{% include machine.html id="test1170" %}
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*Nov 8, 2016*
|
||||
92
_posts/2016-11-13-curious-pdp-11-features.md
Normal file
92
_posts/2016-11-13-curious-pdp-11-features.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
---
|
||||
layout: post
|
||||
title: Curious PDP-11 Features
|
||||
date: 2016-11-13 13:00:00
|
||||
permalink: /blog/2016/11/13/
|
||||
---
|
||||
|
||||
Last week, I ran PDPjs through a series of early [PDP-11 Paper Tape Diagnostics](/apps/pdp11/tapes/diags/).
|
||||
These tests were originally released in 1970 and are documented in such DEC publications as the
|
||||
[MAINDEC USER REFERENCE MANUAL](http://archive.pcjs.org/pubs/dec/pdp11/diags/MAINDEC_User_Reference_Manual_Oct73.pdf)
|
||||
(October 1973).
|
||||
|
||||
[Tests 1-12](/apps/pdp11/tapes/diags/#tests-1-12) (MAINDEC-11-D0AA-PB through MAINDEC-11-D0LA-PB)
|
||||
uncovered a couple of uninteresting bugs in the emulator that affected the ASRB and RORB instructions, both involving some
|
||||
incorrect masks. But aside from those hiccups, the tests ran fine. Ditto for [Test 13](/apps/pdp11/tapes/diags/#test-13).
|
||||
|
||||
Things got much more interesting in [Test 14](/apps/pdp11/tapes/diags/#test-14). For starters (and as DEC's documentation
|
||||
points out), the test will immediately fail (HALT) if run on a PDP-11/40 or PDP-11/45, because it tests the RESERVED
|
||||
instruction trap by using the MUL opcode, which was only reserved on early PDP-11's, like the PDP-11/20.
|
||||
|
||||
After switching to a [PDP-11/20 configuration](/devices/pdp11/machine/1120/panel/debugger/), Test 14 uncovered a series of
|
||||
problems, including:
|
||||
|
||||
- The DL11 transmitter must generate an interrupt *immediately* after being enabled
|
||||
- When a RESERVED instruction trap occurs with an invalid stack pointer, the RESERVED instruction trap must be immediately
|
||||
followed by a stack overflow trap
|
||||
- When a hardware interrupt occurs with an invalid stack pointer, the hardware interrupt trap must be immediately followed
|
||||
by a stack overflow trap (ie, before the first instruction of the hardware interrupt handler is executed)
|
||||
- When a BUS error occurs while fetching an opcode, the address of the opcode must be pushed by the trap handler
|
||||
- When a trap handler loads a new PSW that allows a hardware interrupt to be acknowledged, the acknowledgement must be delayed
|
||||
by one instruction
|
||||
|
||||
And finally, the most interesting bug uncovered by Test 14 involved instructions like this:
|
||||
|
||||
MOV R0,(R0)+
|
||||
|
||||
Imagine that R0 contains 1000. PDPjs would write the value 1000 to address 1000 after auto-incrementing R0 to
|
||||
1002.
|
||||
|
||||
Unfortunately, that's wrong -- for the PDP-11/20 anyway. Apparently, unlike later (micro-coded) models, the
|
||||
PDP-11/20 performs both source and destination address calculations *before* reading and writing the source and
|
||||
destination values. So, in the above example, the value 1002 must be written to address 1000.
|
||||
|
||||
Don't confuse this behavior with the order in which the source and destination operands are processed (source operands
|
||||
are always decoded first, destination operands next), or with the fact that the auto-increment mode is actually a *post*-
|
||||
increment mode, whereas auto-decrement is a *pre*-decrement mode. Those things are also true, but they have nothing to do
|
||||
with this behavior.
|
||||
|
||||
PDPjs resolved this by using a special (negative) value to indicate a register source operand, which is then converted
|
||||
to the register's current value after both operands have been decoded. Test 14 now passes.
|
||||
|
||||
Next up: [Test 15](/apps/pdp11/tapes/diags/#test-15), which uncovered a couple more problems:
|
||||
|
||||
- The DLL transmitter must *not* generate an interrupt if it is immediately *disabled* after being *enabled*
|
||||
- The (old) RTI instruction needs to manage the Trace flag like the (new) RTT instruction if the machine is a PDP-11/20
|
||||
|
||||
Test 15 was written for the earliest PDP-11 models, which didn't have the RTT instruction, so when an RTI instruction
|
||||
enabled the Trace flag, action on the flag was deferred until after the next instruction. Newer models moved that deferred
|
||||
behavior to the RTT instruction, and changed RTI to act on the Trace flag immediately.
|
||||
|
||||
This seems like a regrettable decision. It would have been far better for the new instruction to have the new behavior,
|
||||
and to leave the original RTI instruction alone, for maximum backward compatibility. DEC engineers probably regretted not
|
||||
having separate RTI and RTT instructions from the beginning, and they probably concluded that very little system software
|
||||
would be affected by changing RTI.
|
||||
|
||||
Unfortunately, these diagnostics are one of the casualties of that decision, meaning that this diagnostic will *not* run
|
||||
successfully on an 11/70. And [Test 15](/apps/pdp11/tapes/diags/#test-15) is not alone in that regard.
|
||||
[Test 14](/apps/pdp11/tapes/diags/#test-14) also will not run properly on an 11/70; there again, the problem could have been
|
||||
avoided if DEC had decided to designate an opcode as *permanently* RESERVED, and then used that for all future RESERVED
|
||||
instruction tests, instead of using opcodes that would become new instructions later (eg, MUL).
|
||||
|
||||
The most recent paper tape diagnostic I've run is the [11/70 CPU EXERCISER](/apps/pdp11/tapes/diags/#md-11-1170-cpu-exerciser),
|
||||
and after several more bug fixes, PDPjs passes that test now, too. That's something not even
|
||||
[SimH](https://github.com/simh/simh) is currently able to do (as of November 2016).
|
||||
|
||||
---
|
||||
|
||||
It's worth noting that all these diagnostic paper tape images are in the [Absolute Loader](/apps/pdp11/tapes/absloader/) format,
|
||||
but unlike tapes like [PDP-11 BASIC](/apps/pdp11/tapes/basic/), they don't include a start address, so you have to read the
|
||||
documentation for each test to learn the starting procedure, including any switches that should be set first.
|
||||
|
||||
However, PDPjs makes life a bit simpler for you. As noted for other [DEC PDP-11 Tape Images](/apps/pdp11/tapes/), any
|
||||
"Absolute Format" tape can be loaded directly into RAM using the machine's "Load" button instead of "Attach", allowing you
|
||||
to bypass the usual three-step process of loading the [Bootstrap Loader](/apps/pdp11/boot/bootstrap/) in order to load the
|
||||
[Absolute Loader](/apps/pdp11/tapes/absloader/) in order to load the desired tape.
|
||||
|
||||
Moreover, PDPjs' JSON-encoded paper tape images support an *exec* property that allows the start address to be explicitly
|
||||
set, which will override any start address inside the image. For these diagnostics, I have set the start address (usually 200)
|
||||
via the *exec* property.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*Nov 13, 2016*
|
||||
19
apps/c1p/BASIC/OSI/README.md
Normal file
19
apps/c1p/BASIC/OSI/README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
layout: page
|
||||
title: OSI Challenger 1P BASIC Programs
|
||||
permalink: /apps/c1p/BASIC/OSI/
|
||||
---
|
||||
|
||||
OSI Challenger 1P BASIC Programs
|
||||
--------------------------------
|
||||
|
||||
- [BASIC MATH](math/)
|
||||
- [CHECKING](checking/)
|
||||
- [COUNTER](counter/)
|
||||
- [POKER](poker/)
|
||||
- [PRESIDENTS](presidents/)
|
||||
- [STAR WARS](starwars/)
|
||||
- [TRIG TUTOR](trigtutor/)
|
||||
|
||||
The project also includes some of [Jeff's](https://twitter.com/jeffpar) [BASIC Programs](../jeffpar/) written
|
||||
from 1979 to 1980.
|
||||
9
apps/c1p/BASIC/OSI/checking/README.md
Normal file
9
apps/c1p/BASIC/OSI/checking/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Challenger 1P BASIC Programs: CHECKING.BAS"
|
||||
permalink: /apps/c1p/BASIC/OSI/checking/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative CHECKING.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/OSI/counter/README.md
Normal file
9
apps/c1p/BASIC/OSI/counter/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Challenger 1P BASIC Programs: COUNTER.BAS"
|
||||
permalink: /apps/c1p/BASIC/OSI/counter/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative COUNTER.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/OSI/math/README.md
Normal file
9
apps/c1p/BASIC/OSI/math/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Challenger 1P BASIC Programs: MATH.BAS"
|
||||
permalink: /apps/c1p/BASIC/OSI/math/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative MATH.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/OSI/poker/README.md
Normal file
9
apps/c1p/BASIC/OSI/poker/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Challenger 1P BASIC Programs: POKER.BAS"
|
||||
permalink: /apps/c1p/BASIC/OSI/poker/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative POKER.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/OSI/presidents/README.md
Normal file
9
apps/c1p/BASIC/OSI/presidents/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Challenger 1P BASIC Programs: PRESIDENTS.BAS"
|
||||
permalink: /apps/c1p/BASIC/OSI/presidents/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative PRESIDENTS.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/OSI/seawolfe/README.md
Normal file
9
apps/c1p/BASIC/OSI/seawolfe/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Challenger 1P BASIC Programs: SEAWOLFE.BAS"
|
||||
permalink: /apps/c1p/BASIC/OSI/seawolfe/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative SEAWOLFE.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/OSI/starwars/README.md
Normal file
9
apps/c1p/BASIC/OSI/starwars/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Challenger 1P BASIC Programs: STARWARS.BAS"
|
||||
permalink: /apps/c1p/BASIC/OSI/starwars/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative STARWARS.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/OSI/tankfortwo/README.md
Normal file
9
apps/c1p/BASIC/OSI/tankfortwo/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Challenger 1P BASIC Programs: TANKFORTWO.BAS"
|
||||
permalink: /apps/c1p/BASIC/OSI/tankfortwo/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative TANKFORTWO.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/OSI/trigtutor/README.md
Normal file
9
apps/c1p/BASIC/OSI/trigtutor/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Challenger 1P BASIC Programs: TRIGTUTOR.BAS"
|
||||
permalink: /apps/c1p/BASIC/OSI/trigtutor/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative TRIGTUTOR.BAS %}
|
||||
{% endhighlight %}
|
||||
|
|
@ -1,27 +1,13 @@
|
|||
---
|
||||
layout: page
|
||||
title: Challenger 1P BASIC Applications
|
||||
title: Challenger 1P BASIC Programs
|
||||
permalink: /apps/c1p/BASIC/
|
||||
---
|
||||
|
||||
Challenger 1P BASIC Applications
|
||||
---
|
||||
Challenger 1P BASIC Programs
|
||||
----------------------------
|
||||
|
||||
The following BASIC applications were supplied by Ohio Scientific:
|
||||
BASIC programs for the Challenger 1P have been archived from the following authors:
|
||||
|
||||
- [BASIC MATH](OSI/MATH.BAS)
|
||||
- [CHECKING](OSI/CHECKING.bas)
|
||||
- [COUNTER](OSI/COUNTER.BAS)
|
||||
- [POKER](OSI/POKER.BAS)
|
||||
- [PRESIDENTS](OSI/PRESIDENTS.BAS)
|
||||
- [STAR WARS](OSI/STARWARS.BAS)
|
||||
- [TRIG TUTOR](OSI/TRIGTUTOR.BAS)
|
||||
|
||||
The project also includes some eclectic BASIC programs written by [Jeff Parsons](https://twitter.com/jeffpar) from 1979 to 1980:
|
||||
|
||||
- [CHECKERS](jeffpar/CHECKERS.BAS)
|
||||
- [HANG WOMAN](jeffpar/HANGWOMAN.BAS)
|
||||
- [LIFE](jeffpar/LIFE.BAS)
|
||||
- [OTHELLO](jeffpar/OTHELLO.BAS)
|
||||
- [SOFORECAST](jeffpar/SOFORECAST.BAS)
|
||||
- [TUBELIST](jeffpar/TUBELIST.BAS)
|
||||
- [Jeff Parsons](jeffpar/)
|
||||
- [Ohio Scientific](OSI/)
|
||||
|
|
|
|||
19
apps/c1p/BASIC/jeffpar/README.md
Normal file
19
apps/c1p/BASIC/jeffpar/README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Jeff's Challenger 1P BASIC Programs"
|
||||
permalink: /apps/c1p/BASIC/jeffpar/
|
||||
---
|
||||
|
||||
Jeff's Challenger 1P BASIC Programs
|
||||
-----------------------------------
|
||||
|
||||
Below are BASIC programs written by [Jeff Parsons](https://twitter.com/jeffpar) from 1979 to 1980:
|
||||
|
||||
- [CHECKERS](checkers/)
|
||||
- [HANG WOMAN](hangwoman/)
|
||||
- [LIFE](life/)
|
||||
- [OTHELLO](othello/)
|
||||
- [SOFORECAST](soforecast/)
|
||||
- [TUBELIST](tubelist/)
|
||||
|
||||
The project also includes an archive of Ohio Scientific's [BASIC Programs](../OSI/).
|
||||
9
apps/c1p/BASIC/jeffpar/checkers/README.md
Normal file
9
apps/c1p/BASIC/jeffpar/checkers/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Jeff's Challenger 1P BASIC Programs: CHECKERS.BAS"
|
||||
permalink: /apps/c1p/BASIC/jeffpar/checkers/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative CHECKERS.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/jeffpar/hangwoman/README.md
Normal file
9
apps/c1p/BASIC/jeffpar/hangwoman/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Jeff's Challenger 1P BASIC Programs: HANGWOMAN.BAS"
|
||||
permalink: /apps/c1p/BASIC/jeffpar/hangwoman/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative HANGWOMAN.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/jeffpar/life/README.md
Normal file
9
apps/c1p/BASIC/jeffpar/life/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Jeff's Challenger 1P BASIC Programs: LIFE.BAS"
|
||||
permalink: /apps/c1p/BASIC/jeffpar/hangwoman/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative LIFE.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/jeffpar/othello/README.md
Normal file
9
apps/c1p/BASIC/jeffpar/othello/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Jeff's Challenger 1P BASIC Programs: OTHELLO.BAS"
|
||||
permalink: /apps/c1p/BASIC/jeffpar/othello/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative OTHELLO.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/jeffpar/soforecast/README.md
Normal file
9
apps/c1p/BASIC/jeffpar/soforecast/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Jeff's Challenger 1P BASIC Programs: SOFORECAST.BAS"
|
||||
permalink: /apps/c1p/BASIC/jeffpar/soforecast/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative SOFORECAST.BAS %}
|
||||
{% endhighlight %}
|
||||
9
apps/c1p/BASIC/jeffpar/tubelist/README.md
Normal file
9
apps/c1p/BASIC/jeffpar/tubelist/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Jeff's Challenger 1P BASIC Programs: TUBELIST.BAS"
|
||||
permalink: /apps/c1p/BASIC/jeffpar/tubelist/
|
||||
---
|
||||
|
||||
{% highlight basic %}
|
||||
{% include_relative TUBELIST.BAS %}
|
||||
{% endhighlight %}
|
||||
|
|
@ -7,19 +7,19 @@
|
|||
<item ref="/apps/c1p/6502/jeffpar/life/LIFE.json">6502 Game of Life (JP)</item>
|
||||
<item ref="/apps/c1p/6502/tests/bcd/bcd.json">6502 BCD Tests</item>
|
||||
<item ref="/apps/c1p/6502/tests/vflag/vflag.json">6502 VFLAG Tests</item>
|
||||
<item ref="/apps/c1p/BASIC/jeffpar/CHECKERS.BAS">CHECKERS (JP)</item>
|
||||
<item ref="/apps/c1p/BASIC/jeffpar/HANGWOMAN.BAS">HANGWOMAN (JP)</item>
|
||||
<item ref="/apps/c1p/BASIC/jeffpar/LIFE.BAS">LIFE (JP)</item>
|
||||
<item ref="/apps/c1p/BASIC/jeffpar/OTHELLO.BAS">OTHELLO (JP)</item>
|
||||
<item ref="/apps/c1p/BASIC/jeffpar/SOFORECAST.BAS">SOFORECAST (JP)</item>
|
||||
<item ref="/apps/c1p/BASIC/jeffpar/TUBELIST.BAS">TUBELIST (JP)</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/MATH.BAS">BASIC MATH</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/CHECKING.BAS">CHECKING</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/COUNTER.BAS">COUNTER</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/POKER.BAS">POKER</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/PRESIDENTS.BAS">PRESIDENTS</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/STARWARS.BAS">STAR WARS</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/TRIGTUTOR.BAS">TRIG TUTOR</item>
|
||||
<item ref="/apps/c1p/BASIC/jeffpar/checkers/CHECKERS.BAS">CHECKERS (JP)</item>
|
||||
<item ref="/apps/c1p/BASIC/jeffpar/hangwoman/HANGWOMAN.BAS">HANGWOMAN (JP)</item>
|
||||
<item ref="/apps/c1p/BASIC/jeffpar/life/LIFE.BAS">LIFE (JP)</item>
|
||||
<item ref="/apps/c1p/BASIC/jeffpar/othello/OTHELLO.BAS">OTHELLO (JP)</item>
|
||||
<item ref="/apps/c1p/BASIC/jeffpar/soforecast/SOFORECAST.BAS">SOFORECAST (JP)</item>
|
||||
<item ref="/apps/c1p/BASIC/jeffpar/tubelist/TUBELIST.BAS">TUBELIST (JP)</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/math/MATH.BAS">BASIC MATH</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/checking/CHECKING.BAS">CHECKING</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/counter/COUNTER.BAS">COUNTER</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/poker/POKER.BAS">POKER</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/presidents/PRESIDENTS.BAS">PRESIDENTS</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/starwars/STARWARS.BAS">STAR WARS</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/trigtutor/TRIGTUTOR.BAS">TRIG TUTOR</item>
|
||||
<item ref="/sites/www.osiweb.org/programs/basic/OsiBas/spacewar.bas">SPACEWAR</item>
|
||||
</control>
|
||||
<control type="button" binding="loadSerial">Load</control>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<serial id="serialPort" pos="left" padLeft="8px">
|
||||
<control type="list" binding="listSerial">
|
||||
<item ref="/apps/c1p/BASIC/OSI/MATH.BAS">BASIC MATH</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/CHECKING.BAS">CHECKING</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/COUNTER.BAS">COUNTER</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/POKER.BAS">POKER</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/PRESIDENTS.BAS">PRESIDENTS</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/STARWARS.BAS">STAR WARS</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/TRIGTUTOR.BAS">TRIG TUTOR</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/math/MATH.BAS">BASIC MATH</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/checking/CHECKING.BAS">CHECKING</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/counter/COUNTER.BAS">COUNTER</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/poker/POKER.BAS">POKER</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/presidents/PRESIDENTS.BAS">PRESIDENTS</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/starwars/STARWARS.BAS">STAR WARS</item>
|
||||
<item ref="/apps/c1p/BASIC/OSI/trigtutor/TRIGTUTOR.BAS">TRIG TUTOR</item>
|
||||
</control>
|
||||
<control type="button" binding="loadSerial">Load</control>
|
||||
<control type="file" binding="mountSerial" style="padding-left:16px"/>
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 44 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 86 KiB |
|
|
@ -144,17 +144,12 @@ This test is also noteworthy because it uncovered a bug involving instructions l
|
|||
|
||||
MOV R0,(R0)+
|
||||
|
||||
Imagine that R0 contains 1000. PDPjs (as well as several other emulators I tested) would write the value 1000
|
||||
to address 1000 after auto-incrementing R0 to 1002.
|
||||
Imagine that R0 contains 1000. PDPjs would write the value 1000 to address 1000 after auto-incrementing R0 to
|
||||
1002.
|
||||
|
||||
Unfortunately, that’s wrong. Apparently, the PDP-11 performs both source and destination address calculations
|
||||
before reading and writing the source and destination values. So, in the above example, the value 1002 must be
|
||||
written to address 1000.
|
||||
|
||||
I should add that not all emulators get this wrong: [SimH](https://github.com/simh/simh), the gold standard of
|
||||
PDP-11 emulators, handles it correctly. However, it's unclear how much confidence one should place in SimH,
|
||||
because as I discovered later when running the [11/70 CPU EXERCISER](#md-11-1170-cpu-exerciser) diagnostic,
|
||||
SimH is not infallible.
|
||||
Unfortunately, that's wrong -- for the PDP-11/20 anyway. Apparently, unlike later (micro-coded) models, the
|
||||
PDP-11/20 performs both source and destination address calculations *before* reading and writing the source and
|
||||
destination values. So, in the above example, the value 1002 must be written to address 1000.
|
||||
|
||||
MAINDEC-11-D0NA (NEW NUMBER - DAKAA)
|
||||
|
||||
|
|
@ -381,7 +376,7 @@ checkStackLimit() handlers based on the CPU model.
|
|||
---
|
||||
|
||||
Here's the next test that PDPjs failed. Again, I found the same sequence of instructions in the 11/40 and 11/45
|
||||
version of the diagnostic, at PC 023360 rather than 023450, so I have annotated the code below with DEC's comments:
|
||||
version of the diagnostic, at PC 023360 rather than 023450, so I've annotated the code below with DEC's comments:
|
||||
|
||||
023450: 012704 000001 MOV #1,R4 ;SET R4
|
||||
023454: 006767 000060 SXT 023540 ;PRESET DATA=0
|
||||
|
|
@ -400,30 +395,5 @@ version of the diagnostic, at PC 023360 rather than 023450, so I have annotated
|
|||
023532: 001401 BEQ 023536
|
||||
023534: 104000 EMT 000 ;ERROR: XOR TESTS ABOVE FAILED [They use HLT instead of EMT here]
|
||||
|
||||
In my case, the failure was caused by the XOR instruction: it hadn't been updated along with the rest of the
|
||||
PDPjs instructions to defer evaluating register operands until BOTH *src* and *dst* operands have been decoded.
|
||||
So at this point:
|
||||
|
||||
R0=154343 R1=154112 R2=023422 R3=154501 R4=100000 R5=155066
|
||||
SP=000700 PC=023502 PS=000010 IR=000000 SL=000377 T0 N1 Z0 V0 C0
|
||||
023502: 074767 000032 XOR PC,023540 ;XOR PC WITH XOR6A (177777)
|
||||
|
||||
the XOR instruction was using 23504 for the *src* operand instead of 23506.
|
||||
|
||||
Interestingly, this test PASSES in SimH, even though it *also* incorrectly uses 23504 for XOR's *src* operand.
|
||||
Why? Because when SimH gets to this instruction:
|
||||
|
||||
023506: 010767 000030 MOV PC,023542 ;FORM PC AS USED IN XOR ABOVE
|
||||
|
||||
it incorrectly stores 023510 instead of 023512 into memory, and both mistakes end up canceling each other out.
|
||||
|
||||
In fact, I'm less impressed with the accuracy of [SimH's](https://github.com/simh/simh) PDP-11 emulation
|
||||
than I used to be, because in the process of getting to this particular test within the "11/70 CPU EXERCISER"
|
||||
(MAINDEC-11-DEQKC-B1-PB) diagnostic, there were numerous other failures as well (eg, TEST 41 and TEST 45).
|
||||
However, SimH is not my baby, so delving into those failures is an exercise for another day.
|
||||
|
||||
DISCLAIMER: Until I can run this test on real PDP-11 hardware, I have to acknowledge another possible
|
||||
explanation for the above failure: that SimH is *correct*, and that unlike all other registers, the value
|
||||
of the PC register is always used immediately, rather than after both *src* and *dst* have been decoded.
|
||||
But that strikes me as a strange architectural inconsistency, and given SimH's other "11/70 CPU EXERCISER"
|
||||
test failures, I'm going to stick with my original assumption -- for now.
|
||||
In my case, the failure was caused by the XOR instruction. When I fixed the PDP-11/20 issue uncovered by
|
||||
[Test 14](#test-14), I had neglected to update XOR, which has some unique operand decoding logic.
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@
|
|||
</keyboard>
|
||||
<serial id="serialPort" pos="left" padLeft="8px">
|
||||
<control type="list" binding="listSerial">
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/POKER.BAS">POKER</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/SAMPLE1.BAS">BASIC MATH</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/SAMPLE2.BAS">CHECKING</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/SAMPLE3.BAS">TRIG TUTOR</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/SAMPLE4.BAS">STAR WARS</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/SAMPLE5.BAS">COUNTER</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/SAMPLE6.BAS">PRESIDENTS</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/math/MATH.BAS">BASIC MATH</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/checking/CHECKING.BAS">CHECKING</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/counter/COUNTER.BAS">COUNTER</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/poker/POKER.BAS">POKER</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/presidents/PRESIDENTS.BAS">PRESIDENTS</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/starwars/STARWARS.BAS">STAR WARS</item>
|
||||
<item ref="../../../../../../apps/c1p/BASIC/OSI/trigtutor/TRIGTUTOR.BAS">TRIG TUTOR</item>
|
||||
</control>
|
||||
<control type="button" binding="loadSerial">Load File</control>
|
||||
</serial>
|
||||
|
|
|
|||
|
|
@ -1883,11 +1883,7 @@ PDP11.opWAIT = function(opCode)
|
|||
PDP11.opXOR = function(opCode)
|
||||
{
|
||||
var reg = (opCode >> PDP11.SRCMODE.SHIFT) & PDP11.OPREG.MASK;
|
||||
/*
|
||||
* As per the WARNING in readSrcWord(), we must supply a register number rather than a register value,
|
||||
* which will then be evaluated by updateDstWord() after both the SRC and DST operands have been decoded.
|
||||
*/
|
||||
this.updateDstWord(opCode, -reg-1 /* this.regsGen[reg] */, PDP11.fnXOR);
|
||||
this.updateDstWord(opCode, this.regsGen[reg + this.offRegSrc], PDP11.fnXOR);
|
||||
this.nStepCycles -= (this.dstMode? (8 + 1) : (2 + 1) + (this.dstReg == 7? 2 : 0));
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -123,9 +123,21 @@ var Trigger;
|
|||
*/
|
||||
CPUStatePDP11.prototype.initProcessor = function()
|
||||
{
|
||||
/*
|
||||
* offRegSrc is a bias added to the register index calculated in readSrcWord() and readSrcByte(),
|
||||
* and by default has no effect on the register index, UNLESS this is a PDP-11/20, in which case the
|
||||
* bias is changed to 8 and we return one of the negative values you see above. Those negative values
|
||||
* act as signals to writeDstWord() and writeDstByte(), effectively delaying evaluation of the register
|
||||
* until then.
|
||||
*/
|
||||
this.offRegSrc = 0;
|
||||
this.maskRegSrcByte = 0xff;
|
||||
|
||||
if (this.model == PDP11.MODEL_1120) {
|
||||
this.decode = PDP11.op1120.bind(this);
|
||||
this.checkStackLimit = this.checkStackLimit1120;
|
||||
this.offRegSrc = 8;
|
||||
this.maskRegSrcByte = -1;
|
||||
} else {
|
||||
this.decode = PDP11.op1145.bind(this);
|
||||
this.checkStackLimit = this.checkStackLimit1145;
|
||||
|
|
@ -177,10 +189,12 @@ CPUStatePDP11.prototype.initRegs = function()
|
|||
this.flagZ = f; // ~ PSW Z bit (TODO: Why do we clear instead of set Z, like other flags?)
|
||||
this.flagN = 0x8000; // PSW N bit
|
||||
this.regPSW = 0x000f; // PSW other bits (TODO: What's the point of setting the flag bits here, too?)
|
||||
this.regsGen = [ // General R0 - R7
|
||||
0, 0, 0, 0, 0, 0, 0, this.addrReset
|
||||
this.regsGen = [ // General R0-R7
|
||||
0, 0, 0, 0, 0, 0, 0, this.addrReset,
|
||||
-1, -2, -3, -4, -5, -6, -7, -8
|
||||
];
|
||||
this.regsAlt = [ // Alternate R0 - R5
|
||||
|
||||
this.regsAlt = [ // Alternate R0-R5
|
||||
0, 0, 0, 0, 0, 0
|
||||
];
|
||||
this.regsAltStack = [ // Alternate R6 stack pointers (KERNEL, SUPER, UNUSED, USER)
|
||||
|
|
@ -2197,10 +2211,10 @@ CPUStatePDP11.prototype.writeWordToPrevSpace = function(opCode, access, data)
|
|||
/**
|
||||
* readSrcByte(opCode)
|
||||
*
|
||||
* WARNING: If the SRC operand is a register, we return a negative register number rather than the
|
||||
* register value, because the final value of the register must be resolved AFTER the DST operand has
|
||||
* been decoded and any pre-decrement or post-increment operations affecting the SRC register have
|
||||
* been completed. See readSrcWord() for more details.
|
||||
* WARNING: If the SRC operand is a register, offRegSrc ensures we return a negative register number
|
||||
* rather than the register value, because on the PDP-11/20, the final value of the register must be
|
||||
* resolved AFTER the DST operand has been decoded and any pre-decrement or post-increment operations
|
||||
* affecting the SRC register have been completed. See readSrcWord() for more details.
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
|
|
@ -2213,7 +2227,7 @@ CPUStatePDP11.prototype.readSrcByte = function(opCode)
|
|||
var reg = this.srcReg = opCode & PDP11.OPREG.MASK;
|
||||
var mode = this.srcMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;
|
||||
if (!mode) {
|
||||
result = -reg-1;
|
||||
result = this.regsGen[reg + this.offRegSrc] & this.maskRegSrcByte;
|
||||
} else {
|
||||
result = this.readByteFromPhysical(this.getAddr(mode, reg, PDP11.ACCESS.READ_BYTE));
|
||||
}
|
||||
|
|
@ -2223,10 +2237,10 @@ CPUStatePDP11.prototype.readSrcByte = function(opCode)
|
|||
/**
|
||||
* readSrcWord(opCode)
|
||||
*
|
||||
* WARNING: If the SRC operand is a register, we return a negative register number rather than the
|
||||
* register value, because the final value of the register must be resolved AFTER the DST operand has
|
||||
* been decoded and any pre-decrement or post-increment operations affecting the SRC register have
|
||||
* been completed.
|
||||
* WARNING: If the SRC operand is a register, offRegSrc ensures we return a negative register number
|
||||
* rather than the register value, because on the PDP-11/20, the final value of the register must be
|
||||
* resolved AFTER the DST operand has been decoded and any pre-decrement or post-increment operations
|
||||
* affecting the SRC register have been completed.
|
||||
*
|
||||
* Here's an example from DEC's "TRAP TEST" (MAINDEC-11-D0NA-PB):
|
||||
*
|
||||
|
|
@ -2255,7 +2269,7 @@ CPUStatePDP11.prototype.readSrcWord = function(opCode)
|
|||
var reg = this.srcReg = opCode & PDP11.OPREG.MASK;
|
||||
var mode = this.srcMode = (opCode & PDP11.OPMODE.MASK) >> PDP11.OPMODE.SHIFT;
|
||||
if (!mode) {
|
||||
result = -reg-1;
|
||||
result = this.regsGen[reg + this.offRegSrc];
|
||||
} else {
|
||||
result = this.bus.getWord(this.getAddr(mode, reg, PDP11.ACCESS.READ_WORD));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,97 +46,97 @@ function Fa(){return"http://"+(window?window.location.host:"www.pcjs.org")}funct
|
|||
function Ka(a){var b;if(window)try{b=window.localStorage.getItem(a)}catch(c){}return b}function La(a,b){try{return window.localStorage.setItem(a,b),!0}catch(c){}return!1}function Ma(a){if(window){var b=window?window.navigator.userAgent:"";return"iOS"==a&&b.match(/(iPod|iPhone|iPad)/)&&b.match(/AppleWebKit/)||"MSIE"==a&&b.match(/(MSIE|Trident)/)||0<=b.indexOf(a)?!0:!1}return!1}function Oa(a,b,c){function d(){--a;0<=a&&(b()||(a=0));0<a?setTimeout(d,0):c()}d()}
|
||||
function Ua(a,b){function c(){b(100===d)&&(e=setTimeout(c,d),d=100)}var d=0,e=null,f=!1;a.onmousedown=function(){f||e||(d=500,c())};a.ontouchstart=function(){e||(d=500,c())};a.onmouseup=a.onmouseout=function(){e&&(clearTimeout(e),e=null)};a.ontouchend=a.ontouchcancel=function(){e&&(clearTimeout(e),e=null);f=!0}}var Va={init:[],show:[],exit:[]},Wa=!1,Xa=!1,Ya=!0;function Za(a,b){if(window){var c=window[a];window[a]="function"!==typeof c?b:function(){c&&c();b()}}}function $a(a){Va.init.push(a)}
|
||||
function ab(a){if(Ya)try{for(var b=0;b<a.length;b++)a[b]()}catch(c){u(""+("An unexpected exception occurred:\n\n"+c.message+"\n\nPlease send this information to support@pcjs.org. Thanks."))}}function bb(a){!Ya&&a?(Ya=!0,Wa&&cb("init"),Xa&&cb("show")):Ya=a}function cb(a){Va[a]&&ab(Va[a])}Za("onload",function(){Wa=!0;ab(Va.init)});Za("onpageshow",function(){Xa=!0;ab(Va.show)});Za(Ma("Opera")||Ma("iOS")?"onunload":"onbeforeunload",function(){ab(Va.exit)});
|
||||
function w(a,b,c,d){this.type=a;b||(b={id:"",name:""});this.id=b.id||"";this.name=b.name;this.Cc=b.comment;this.nd=b;b=this.id.indexOf(".");0>b?this.bb=this.id:(this.Ua=this.id.substr(0,b),this.bb=this.id.substr(b+1));this[a]=c;this.A={ready:!1,eb:!1,ec:!1,ia:!1,error:!1};this.Xb=null;this.A.error=!1;this.G={};this.j=null;this.la=d||0;y.push(this)}var db=void 0,eb={};
|
||||
function w(a,b,c,d){this.type=a;b||(b={id:"",name:""});this.id=b.id||"";this.name=b.name;this.Dc=b.comment;this.he=b;b=this.id.indexOf(".");0>b?this.bb=this.id:(this.Ua=this.id.substr(0,b),this.bb=this.id.substr(b+1));this[a]=c;this.A={ready:!1,eb:!1,ec:!1,ia:!1,error:!1};this.Xb=null;this.A.error=!1;this.G={};this.j=null;this.la=d||0;y.push(this)}var db=void 0,eb={};
|
||||
if(window){db||(db=window.location.search.substr(1));for(var fb,gb=/\+/g,hb=/([^&=]+)=?([^&]*)/g;fb=hb.exec(db);)eb[decodeURIComponent(fb[1].replace(gb," "))]=decodeURIComponent(fb[2].replace(gb," "))}function ib(a){function b(){}if(window){if(!a)throw new TypeError;if(Object.create)return Object.create(a);var c=typeof a;if("object"!==c&&"function"!==c)throw new TypeError;}b.prototype=a;return new b}
|
||||
function A(a,b){b||(b=w);a.prototype=ib(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}if(window){window.PCjs||(window.PCjs={});var jb=window.PCjs.Machines||(window.PCjs.Machines={}),y=window.PCjs.Components||(window.PCjs.Components=[])}else jb={},y=[];function kb(a,b,c){jb[a]&&b&&(jb[a][b]=c)}function sb(a){var b,c=[];a&&(a=0<(b=a.indexOf("."))?a.substr(0,b+1):"");for(b=0;b<y.length;b++){var d=y[b];a&&d.id.indexOf(a)||c.push(d)}return c}
|
||||
function tb(a){if(void 0!==a){var b;for(b=0;b<y.length;b++)if(y[b].id===a)return y[b]}return null}function ub(a,b){var c;if(void 0!==a){var d;b&&(b=0<(d=b.indexOf("."))?b.substr(0,d+1):"");for(d=0;d<y.length;d++)if(c)c==y[d]&&(c=null);else if(!(a!=y[d].type||b&&y[d].id.indexOf(b)))return y[d]}return null}function C(a){var b=null;if(a=a.getAttribute("data-value"))try{b=eval("("+a+")")}catch(c){u(c.message+" ("+a+")")}return b}
|
||||
function D(a,b){b=E(b.parentNode,"pdp11-control");for(var c=0;c<b.length;c++)for(var d=b[c].childNodes,e=0;e<d.length;e++){var f=d[e];if(1===f.nodeType){var g=f.getAttribute("class");if(g)for(var h=g.split(" "),l=0;l<h.length;l++)switch(g=h[l],g){case "pdp11-binding":(g=C(f))&&g.binding&&a.wa(g.type,g.binding,f,g.value),l=h.length}}}}
|
||||
function E(a,b,c){c&&(b+="-"+c+"-object");if(a.getElementsByClassName)return a.getElementsByClassName(b);var d;c=[];a=a.getElementsByTagName("*");var e=new RegExp("(^| )"+b+"( |$)");b=0;for(d=a.length;b<d;b++)e.test(a[b].className)&&c.push(a[b]);return c}
|
||||
w.prototype={constructor:w,parent:null,toString:function(){return this.name?this.name:this.id||this.type},wa:function(a,b,c){switch(b){case "clear":return this.G[b]||(this.G[b]=c,c.onclick=function(a){return function(){a.G.print&&(a.G.print.value="")}}(this)),!0;case "print":return this.G[b]||(this.Wa=this.G[b]=c,c.value="",this.i=function(a){return function(b,c){8192<a.value.length&&(a.value=a.value.substr(a.value.length-4096));a.value+=(void 0!==c?c+": ":"")+(b||"")+"\n";a.scrollTop=a.scrollHeight}}(c),
|
||||
this.R=function(a){this.i(a,this.bb)}),!0;default:return!1}},log:function(){},i:function(){},status:function(a){this.i(this.bb+": "+a)},R:function(a,b,c){c=c||this.type;b||u((c?c+": ":"")+a)},Ka:function(){return this.A.ia=!0},Ja:function(a,b){b&&(this.A.ia=!1);return!0}};function F(a,b,c,d){a.j&&(!0===c||H(a,c|0))&&a.j.message(b,d)}function H(a,b){if(a.j){a===a.j?b|=0:b=b||a.la;var c=a.j.la&b;return!!b&&c===b||!!(c&a.j.Uc)}return!1}
|
||||
this.R=function(a){this.i(a,this.bb)}),!0;default:return!1}},log:function(){},i:function(){},status:function(a){this.i(this.bb+": "+a)},R:function(a,b,c){c=c||this.type;b||u((c?c+": ":"")+a)},Ka:function(){return this.A.ia=!0},Ja:function(a,b){b&&(this.A.ia=!1);return!0}};function F(a,b,c,d){a.j&&(!0===c||H(a,c|0))&&a.j.message(b,d)}function H(a,b){if(a.j){a===a.j?b|=0:b=b||a.la;var c=a.j.la&b;return!!b&&c===b||!!(c&a.j.Wc)}return!1}
|
||||
function vb(a,b){if(a.A.ec)return a.A.eb=!1,a.A.ec=!1;if(a.A.error)return a.i(a.toString()+" error"),!1;a.A.eb=b;return a.A.eb}function wb(a,b){a.A.eb&&(b?a.A.ec=!0:void 0===b&&a.i(a.toString()+" busy"));return a.A.eb}function I(a,b){a.A.error||(a.A.ready=!1!==b,a.A.ready&&(b=a.Xb,a.Xb=null,b&&b()))}function xb(a,b){b&&(a.A.ready?b():a.Xb=b);return a.A.ready}function yb(a){return a.A.error?(a.i(a.toString()+" error"),!0):!1}function zb(a,b){a.A.error=!0;a.R(b)}
|
||||
Array.prototype.indexOf||(Array.prototype.indexOf=function(a,b){b=b||0;for(var c=this.length;b<c;b++)if(this[b]===a)return b;return-1});Array.isArray||(Array.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)});
|
||||
Function.prototype.bind||(Function.prototype.bind=function(a){function b(){return e.apply(this instanceof c&&a?this:a,d.concat(Array.prototype.slice.call(arguments)))}function c(){}if("function"!=typeof this)throw new TypeError("Function.prototype.bind: non-callable object");var d=Array.prototype.slice.call(arguments,1),e=this;c.prototype=this.prototype;b.prototype=new c;return b});
|
||||
var Ab="undefined"!==typeof ArrayBuffer,Bb="UNKNOWN ABORT ILLEGAL RED YELLOW FAULT TRACE HALT OPCODE INTERRUPT".split(" "),Cb={cpu:1,trap:16,fault:32,bus:64,memory:128,mmu:256,rom:512,device:1024,panel:2048,keyboard:65536,key:131072,paper:1048576,disk:4194304,rl11:8388608,serial:16777216,speaker:33554432,computer:67108864,log:268435456,warn:536870912,buffer:1073741824,halt:-2147483648};
|
||||
function Db(a){w.call(this,"Panel",a,Db,2048);this.ua=this.w=this.Za=this.sb=this.B=this.D=0;this.I=this.K=this.H=!1;this.L=Eb;this.g={};this.f={START:[1,1,!0,!1,this.kd],STEP:[1,1,!1,!1,this.ld],ENABLE:[1,1,!1,!1,this.fd],CONT:[1,1,!0,!1,this.dd],DEP:[0,0,!0,!1,this.ed],EXAM:[1,1,!0,!1,this.gd],LOAD:[1,1,!0,!1,this.jd],TEST:[0,0,!0,!1,this.hd]};for(a=0;22>a;a++)this.f["S"+a]=[0,0,!1,!1,this.md,a]}A(Db);var Eb=7;function Fb(a,b){return a.f[b]&&a.f[b][1]}k=Db.prototype;k.reset=function(){this.stop()};
|
||||
function Db(a){w.call(this,"Panel",a,Db,2048);this.ua=this.w=this.Za=this.tb=this.B=this.D=0;this.I=this.K=this.H=!1;this.L=Eb;this.g={};this.f={START:[1,1,!0,!1,this.ld],STEP:[1,1,!1,!1,this.md],ENABLE:[1,1,!1,!1,this.gd],CONT:[1,1,!0,!1,this.ed],DEP:[0,0,!0,!1,this.fd],EXAM:[1,1,!0,!1,this.hd],LOAD:[1,1,!0,!1,this.kd],TEST:[0,0,!0,!1,this.jd]};for(a=0;22>a;a++)this.f["S"+a]=[0,0,!1,!1,this.nd,a]}A(Db);var Eb=7;function Fb(a,b){return a.f[b]&&a.f[b][1]}k=Db.prototype;k.reset=function(){this.stop()};
|
||||
k.wa=function(a,b,c,d){if(this.C&&this.C.wa(a,b,c,d)||this.b&&this.b.wa(a,b,c,d)||this.j&&this.j.wa(a,b,c,d))return!0;switch(b){case "R0":case "R1":case "R2":case "R3":case "R4":case "R5":case "R6":case "R7":case "NF":case "ZF":case "VF":case "CF":case "PS":return this.G[b]=c,this.D++,!0;default:return"led"==a||"rled"==a?(this.G[b]=c,this.g[b]=d?1:0,this.D++,!0):"switch"==a?(void 0===this.f[b]&&(this.f[b]=[d?1:0,d?1:0]),this.G[b]=c,a=c.parentElement||c,a=a.parentElement||a,a.onmousedown=function(a,
|
||||
b){return function(){Gb(a,b)}}(this,b),a.onmouseup=a.onmouseout=function(a,b){return function(){Hb(a,b)}}(this,b),a.ontouchstart=function(a,b){return function(c){Gb(a,b);c.preventDefault()}}(this,b),a.ontouchend=function(a,b){return function(){Hb(a,b)}}(this,b),!0):this.parent.wa.call(this,a,b,c,d)}};k.Ia=function(a,b,c,d){this.C=a;this.v=b;this.b=c;this.j=d;Ib(b,this,Jb);Kb(b,this.reset.bind(this));Lb(this);Mb(this)};k.Ka=function(a,b){b||(Nb(),this.reset());return!0};k.Ja=function(){return!0};
|
||||
function Ob(a,b,c){if(a=a.G[b])a.style.backgroundColor=c?"#ff0000":"#000000"}function Lb(a,b){for(var c in a.g)Ob(a,c,null!=b?b:a.g[c])}function Pb(a,b,c){if(a=a.G[b])a.style.marginTop=c?"0px":"20px",a.style.backgroundColor=c?"#00ff00":"#228B22"}function Mb(a){for(var b in a.f)Pb(a,b,a.f[b][1])}function Qb(a,b,c,d){a.G[b]&&(void 0===c&&(zb(a,"Value for "+b+" is invalid"),a.b.da()),c=8==(a.j&&a.j.ca||8)?na(c,d):p(c,d),a.G[b].textContent!=c&&(a.G[b].textContent=c))}
|
||||
function Gb(a,b){var c=a.f[b];Pb(a,b,c[1]=1-c[1]);c[3]=!0;c[4]&&c[4].call(a,c[1],c[5]);"STEP"!=b&&(a.I="DEP"==b,a.K="EXAM"==b)}function Hb(a,b){var c=a.f[b];c[2]&&c[3]&&(Pb(a,b,c[1]=c[0]),c[4]&&c[4].call(a,c[1],c[5]));c[3]=!1}k.kd=function(a){a||this.b.A.W||(a=this.b,a.v.reset(),Rb(a),Fb(this,"ENABLE")&&this.b.jb())};k.ld=function(){};k.fd=function(a){a||this.b.da()};
|
||||
k.dd=function(a){if(!a&&!this.b.A.W)if(Fb(this,"ENABLE"))this.b.jb();else{if((a=this.j)&&!wb(a,!0))vb(a,!0),a.kb(0,null),vb(a,!1);else try{var b=this.b.kb(1);0<b&&(Sb(this.b,b),Tb(this.b,b,!0),Ub(this.b,b))}catch(c){"number"!=typeof c&&zb(this.b,c.stack||c.message)}this.stop();this.C&&this.C.ra()}};k.ed=function(a){a&&!this.b.A.W&&(this.I&&Vb(this),a=ic(this,this.Za),this.L==Eb?this.v.wb(this.ua,a):this.b.wb(this.ua,a))};
|
||||
k.gd=function(a){a||this.b.A.W||(this.K&&Vb(this),a=this.L==Eb?this.v.Ya(this.ua):this.b.Ya(this.ua),ic(this,a))};k.jd=function(a){a||this.b.A.W||jc(this,this.Za)};k.hd=function(a){a?(this.H=!0,Lb(this,!0)):(this.H=!1,Lb(this),kc(this,0))};k.md=function(a,b){this.Za=a?this.Za|1<<b:this.Za&~(1<<b)};function Vb(a){var b=1145>a.b.fb?8:16,c=65472<=a.ua&&a.ua<65472+b,b=c?1:2,c=c?15:a.v.Qa;Fb(a,"STEP")||(b=-b);jc(a,a.ua&~c|a.ua+b&c)}
|
||||
function jc(a,b){a.ua=b&a.v.Qa;b=a.ua;for(var c=0;22>c;c++)lc(a,"A"+c,b&1<<c)}function ic(a,b){a.w=b&65535;b=a.w;for(var c=0;16>c;c++)lc(a,"D"+c,b&1<<c);return a.w}function lc(a,b,c){a.g[b]=c;a.H||Ob(a,b,c)}function mc(a){return void 0!==a.G.S0}function kc(a,b){if(mc(a)){a.Za=b;for(var c=0;22>c;c++)a.f["S"+c][1]=b&1<<c?1:0;Mb(a)}}k.stop=function(){jc(this,this.b.u[7])};k.oc=function(a){this.ua=a};k.setData=function(a,b){b?this.sb=a:this.w=a};k.pd=function(a,b){return(b?this.sb:this.Za)&65535};
|
||||
k.ke=function(a){this.sb=a};var nc={},Jb=(nc[65400]=[null,null,Db.prototype.pd,Db.prototype.ke,"CNSW"],nc);function Nb(){for(var a=!1,b=E(document,"pdp11","panel"),c=0;c<b.length;c++){var d=b[c],e=C(d),f=tb(e.id);f||(a=!0,f=new Db(e));D(f,d);a&&I(f)}}$a(Nb);
|
||||
function oc(a,b,c){w.call(this,"Bus",a,oc,64);this.b=b;this.j=c;this.K=a.busWidth||16;this.C=0;this.w=[];this.g=null;this.H=1<<this.K;this.Qa=this.H-1;this.Da=pc;this.ka=Math.log2(this.Da);this.I=this.Da>>2;this.v=this.Da-1;this.D=this.H/this.Da|0;this.cb=[];this.ma=0;this.f=!1;this.gc=0;this.B=[];this.Rc=[qc,rc,sc,tc];a=new J(this);uc(a,this.j);this.Y=Array(this.D);for(b=0;b<this.D;b++)this.Y[b]=a;I(this)}A(oc);var pc=8192,vc=pc-1;
|
||||
function Gb(a,b){var c=a.f[b];Pb(a,b,c[1]=1-c[1]);c[3]=!0;c[4]&&c[4].call(a,c[1],c[5]);"STEP"!=b&&(a.I="DEP"==b,a.K="EXAM"==b)}function Hb(a,b){var c=a.f[b];c[2]&&c[3]&&(Pb(a,b,c[1]=c[0]),c[4]&&c[4].call(a,c[1],c[5]));c[3]=!1}k.ld=function(a){a||this.b.A.W||(a=this.b,a.v.reset(),Rb(a),Fb(this,"ENABLE")&&this.b.jb())};k.md=function(){};k.gd=function(a){a||this.b.da()};
|
||||
k.ed=function(a){if(!a&&!this.b.A.W)if(Fb(this,"ENABLE"))this.b.jb();else{if((a=this.j)&&!wb(a,!0))vb(a,!0),a.kb(0,null),vb(a,!1);else try{var b=this.b.kb(1);0<b&&(Sb(this.b,b),Tb(this.b,b,!0),Ub(this.b,b))}catch(c){"number"!=typeof c&&zb(this.b,c.stack||c.message)}this.stop();this.C&&this.C.ra()}};k.fd=function(a){a&&!this.b.A.W&&(this.I&&Vb(this),a=ic(this,this.Za),this.L==Eb?this.v.xb(this.ua,a):this.b.xb(this.ua,a))};
|
||||
k.hd=function(a){a||this.b.A.W||(this.K&&Vb(this),a=this.L==Eb?this.v.Ya(this.ua):this.b.Ya(this.ua),ic(this,a))};k.kd=function(a){a||this.b.A.W||jc(this,this.Za)};k.jd=function(a){a?(this.H=!0,Lb(this,!0)):(this.H=!1,Lb(this),kc(this,0))};k.nd=function(a,b){this.Za=a?this.Za|1<<b:this.Za&~(1<<b)};function Vb(a){var b=1145>a.b.fb?8:16,c=65472<=a.ua&&a.ua<65472+b,b=c?1:2,c=c?15:a.v.Qa;Fb(a,"STEP")||(b=-b);jc(a,a.ua&~c|a.ua+b&c)}
|
||||
function jc(a,b){a.ua=b&a.v.Qa;b=a.ua;for(var c=0;22>c;c++)lc(a,"A"+c,b&1<<c)}function ic(a,b){a.w=b&65535;b=a.w;for(var c=0;16>c;c++)lc(a,"D"+c,b&1<<c);return a.w}function lc(a,b,c){a.g[b]=c;a.H||Ob(a,b,c)}function mc(a){return void 0!==a.G.S0}function kc(a,b){if(mc(a)){a.Za=b;for(var c=0;22>c;c++)a.f["S"+c][1]=b&1<<c?1:0;Mb(a)}}k.stop=function(){jc(this,this.b.u[7])};k.pc=function(a){this.ua=a};k.setData=function(a,b){b?this.tb=a:this.w=a};k.pd=function(a,b){return(b?this.tb:this.Za)&65535};
|
||||
k.me=function(a){this.tb=a};var nc={},Jb=(nc[65400]=[null,null,Db.prototype.pd,Db.prototype.me,"CNSW"],nc);function Nb(){for(var a=!1,b=E(document,"pdp11","panel"),c=0;c<b.length;c++){var d=b[c],e=C(d),f=tb(e.id);f||(a=!0,f=new Db(e));D(f,d);a&&I(f)}}$a(Nb);
|
||||
function oc(a,b,c){w.call(this,"Bus",a,oc,64);this.b=b;this.j=c;this.K=a.busWidth||16;this.C=0;this.w=[];this.g=null;this.H=1<<this.K;this.Qa=this.H-1;this.Da=pc;this.ka=Math.log2(this.Da);this.I=this.Da>>2;this.v=this.Da-1;this.D=this.H/this.Da|0;this.cb=[];this.ma=0;this.f=!1;this.gc=0;this.B=[];this.Tc=[qc,rc,sc,tc];a=new J(this);uc(a,this.j);this.Y=Array(this.D);for(b=0;b<this.D;b++)this.Y[b]=a;I(this)}A(oc);var pc=8192,vc=pc-1;
|
||||
function qc(a,b){var c=-1,d=this.controller,e=d.cb[a],f=b&65535;e?e[0]?c=e[0](f):e[2]&&(c=f&1?e[2](f&-2)>>8:e[2](f)&255):f&1&&(e=d.cb[a&-2])&&(e[2]?c=e[2](f&-2)>>8:e[0]&&(c=e[0](f)));if(0<=c)return this.j&&H(this.j,e[5])&&F(this.j,e[4]+".readByte("+K(this.j,b)+"): "+K(this.j,c),!0,!d.ma),c;d.Ha(b,16,3);c=255;this.j&&H(this.j,64)&&F(this.j,"warning: unconverted read access to byte @"+K(this.j,b)+": "+K(this.j,c),!0,!d.ma);return c}
|
||||
function rc(a,b,c){var d=!1,e=this.controller,f=e.cb[a],g=c&65535;if(f)if(f[1])f[1](b,g),d=!0;else{if(f[3]){a=f[2]?f[2](g,!0):0;if(g&1)f[3](a&255|b<<8,g&-2);else f[3](a&-256|b,g);d=!0}}else g&1&&(f=e.cb[a&-2])&&(f[3]?(g&=-2,a=f[2]?f[2](g,!0):0,f[3](a&255|b<<8,g),d=!0):f[1]&&(f[1](b,g),d=!0));d?this.j&&H(this.j,f[5])&&F(this.j,f[4]+".writeByte("+K(this.j,c)+","+K(this.j,b)+")",!0,!e.ma):(e.Ha(c,16,5),this.j&&H(this.j,64)&&F(this.j,"warning: unconverted write access to byte @"+K(this.j,c)+": "+K(this.j,
|
||||
b),!0,!e.ma))}function sc(a,b){var c=-1,d=this.controller;a=d.cb[a];var e=b&65535;a&&(a[2]?c=a[2](e):a[0]&&(c=a[0](e)|a[0](e+1)<<8));if(0<=c)return this.j&&H(this.j,a[5])&&F(this.j,a[4]+".readWord("+K(this.j,b)+"): "+K(this.j,c),!0,!d.ma),c;d.Ha(b,16,2);c=65535;this.j&&H(this.j,64)&&F(this.j,"warning: unconverted read access to word @"+K(this.j,b)+": "+K(this.j,c),!0,!d.ma);return c}
|
||||
function tc(a,b,c){var d=!1,e=this.controller;a=e.cb[a];var f=c&65535;a&&(a[3]?(a[3](b,f),d=!0):a[1]&&(a[1](b&255,f),a[1](b>>8,f+1),d=!0));d?this.j&&H(this.j,a[5])&&F(this.j,a[4]+".writeWord("+K(this.j,c)+","+K(this.j,b)+")",!0,!e.ma):(e.Ha(c,16,4),this.j&&H(this.j,64)&&F(this.j,"warning: unconverted write access to word @"+K(this.j,c)+": "+K(this.j,b),!0,!e.ma))}
|
||||
function wc(a,b){if(b!=a.C){var c;a.C&&(c=(1<<a.C)-pc,xc(a,c,pc,a.w),a.C=0);b&&(a.C=b,c=1<<b,a.Qa=c-1,c-=pc,a.w=yc(a,c,pc),a.g?xc(a,c,pc,a.g):(zc(a,c,pc,Ac,a),a.g=yc(a,c,pc)))}}k=oc.prototype;k.reset=function(){for(var a=0;a<this.B.length;a++)this.B[a]();wc(this,16)};k.Ka=function(a,b){b||this.reset();return!0};
|
||||
function zc(a,b,c,d,e){for(var f=b,g=c,h=f>>>a.ka;0<g&&h<a.Y.length;){var l=a.Y[h],m=h*a.Da,n=a.Da-(f-m);n>g&&(n=g);if(!e&&l&&l.size){if(l.type==d){if(f+g<=l.F)return l.Tb+=l.F-f,l.F=f,!0;if(f>=l.F+l.Tb){n=l.size-(f-m);n>g&&(n=g);l.Tb=f-l.F+n;f=m+a.Da;g-=n;h++;continue}}return Bc(1,f,g)}f=new J(a,f,n,a.Da,d,e);uc(f,a.j,l);a.Y[h++]=f;f=m+a.Da;g-=n}return 0>=g?(d==Cc&&(a.gc+=c),a.status((c>>10)+"Kb "+Dc[d]+" at "+na(b)),!0):Bc(2,b,c)}
|
||||
function yc(a,b,c){var d=[];for(b>>>=a.ka;0<c&&b<a.Y.length;)d.push(a.Y[b++]),c-=a.Da;return d}function xc(a,b,c,d){var e=0;for(b>>>=a.ka;0<c&&b<a.Y.length;){var f=d[e++];if(!f)break;a.Y[b++]=f;c-=a.Da}}k.Yb=function(a){3932160<=a&&(a=Ec(this.b,a));return this.Y[(a&this.Qa)>>>this.ka].$b(a&this.v,a)};k.Zb=function(a){3932160<=a&&(a=Ec(this.b,a));this.f=!1;this.ma++;a=this.Y[(a&this.Qa)>>>this.ka].mc(a&this.v,a);this.ma--;return a};
|
||||
k.oa=function(a){3932160<=a&&(a=Ec(this.b,a));return this.Y[(a&this.Qa)>>>this.ka].ta(a&this.v,a)};k.Ya=function(a){3932160<=a&&(a=Ec(this.b,a));var b=a&this.v,c=(a&this.Qa)>>>this.ka;this.f=!1;this.ma++;a=this.Y[c].nc(b,a);this.ma--;return a};k.Fb=function(a,b){3932160<=a&&(a=Ec(this.b,a));this.Y[(a&this.Qa)>>>this.ka].cc(a&this.v,b&255,a)};k.tb=function(a,b){3932160<=a&&(a=Ec(this.b,a));this.f=!1;this.ma++;this.Y[(a&this.Qa)>>>this.ka].dc(a&this.v,b&255,a);this.ma--};
|
||||
k.vb=function(a,b){3932160<=a&&(a=Ec(this.b,a));this.Y[(a&this.Qa)>>>this.ka].Ub(a&this.v,b&65535,a)};k.wb=function(a,b){3932160<=a&&(a=Ec(this.b,a));var c=a&this.v,d=(a&this.Qa)>>>this.ka;this.f=!1;this.ma++;this.Y[d].qc(c,b&65535,a);this.ma--};
|
||||
function Fc(a){for(var b=0,c=[],d=0;d<a.D;d++){var e=a.Y[d];if(e.Xa||e.Yc){c[b++]=d;var f=b++;if(e=e.save()){for(var g=0,h=0,l=[];g<e.length;){for(var m=e[g],n=g+1;n<e.length&&e[n]===m;)n++;l[h++]=n-g;l[h++]=m;g=n}l.length<e.length&&(e=l)}c[f]=e}}return c}function Gc(a,b,c,d,e,f,g,h,l){for(;b<=c;b+=2){var m=b&vc;if(void 0!==a.cb[m])return u("I/O address already registered: "+p(b,8,!0)),!1;a.cb[m]=[d,e,f,g,l||"unknown",h,!1]}return!0}
|
||||
function yc(a,b,c){var d=[];for(b>>>=a.ka;0<c&&b<a.Y.length;)d.push(a.Y[b++]),c-=a.Da;return d}function xc(a,b,c,d){var e=0;for(b>>>=a.ka;0<c&&b<a.Y.length;){var f=d[e++];if(!f)break;a.Y[b++]=f;c-=a.Da}}k.Yb=function(a){3932160<=a&&(a=Ec(this.b,a));return this.Y[(a&this.Qa)>>>this.ka].$b(a&this.v,a)};k.Zb=function(a){3932160<=a&&(a=Ec(this.b,a));this.f=!1;this.ma++;a=this.Y[(a&this.Qa)>>>this.ka].nc(a&this.v,a);this.ma--;return a};
|
||||
k.oa=function(a){3932160<=a&&(a=Ec(this.b,a));return this.Y[(a&this.Qa)>>>this.ka].ta(a&this.v,a)};k.Ya=function(a){3932160<=a&&(a=Ec(this.b,a));var b=a&this.v,c=(a&this.Qa)>>>this.ka;this.f=!1;this.ma++;a=this.Y[c].oc(b,a);this.ma--;return a};k.Fb=function(a,b){3932160<=a&&(a=Ec(this.b,a));this.Y[(a&this.Qa)>>>this.ka].cc(a&this.v,b&255,a)};k.ub=function(a,b){3932160<=a&&(a=Ec(this.b,a));this.f=!1;this.ma++;this.Y[(a&this.Qa)>>>this.ka].dc(a&this.v,b&255,a);this.ma--};
|
||||
k.wb=function(a,b){3932160<=a&&(a=Ec(this.b,a));this.Y[(a&this.Qa)>>>this.ka].Ub(a&this.v,b&65535,a)};k.xb=function(a,b){3932160<=a&&(a=Ec(this.b,a));var c=a&this.v,d=(a&this.Qa)>>>this.ka;this.f=!1;this.ma++;this.Y[d].rc(c,b&65535,a);this.ma--};
|
||||
function Fc(a){for(var b=0,c=[],d=0;d<a.D;d++){var e=a.Y[d];if(e.Xa||e.$c){c[b++]=d;var f=b++;if(e=e.save()){for(var g=0,h=0,l=[];g<e.length;){for(var m=e[g],n=g+1;n<e.length&&e[n]===m;)n++;l[h++]=n-g;l[h++]=m;g=n}l.length<e.length&&(e=l)}c[f]=e}}return c}function Gc(a,b,c,d,e,f,g,h,l){for(;b<=c;b+=2){var m=b&vc;if(void 0!==a.cb[m])return u("I/O address already registered: "+p(b,8,!0)),!1;a.cb[m]=[d,e,f,g,l||"unknown",h,!1]}return!0}
|
||||
function Ib(a,b,c){for(var d in c){var e=+d,f=c[d];if(!(f[6]&&f[6]>a.b.fb)){var g=f[0]?f[0].bind(b):null,h=f[1]?f[1].bind(b):null,l=f[2]?f[2].bind(b):null,m=f[3]?f[3].bind(b):null;65472<=e&&65487>=e&&(!g&&l&&(g=function(a){return function(b){return a(b)&255}.bind(b)}(l)),!h&&m&&(h=function(a){return function(b,c){return a(b,c)}.bind(b)}(m)));for(var n=f[4],r=f[5]||1,t=0;t<r;t++,e+=2)if(n&&1<r&&(n=f[4]+t),!Gc(a,e,e,g,h,l,m,f[7]||b.la||64,n||b.bb))return!1}}return!0}function Kb(a,b){a.B.push(b)}
|
||||
k.Ha=function(a,b,c){this.f=!0;this.ma||(this.j&&H(this.j,32)&&F(this.j,"memory fault ("+c+") on "+K(this.j,a),!0,!0),b&&(this.b.va|=b),this.b.qa(4,0,a))};function Hc(a){var b=a.f;a.f=!1;return b}function Bc(a,b,c){u("Memory block error ("+a+": "+p(b)+","+p(c)+")");return!1}function L(a){w.call(this,"Device",a,L,1024);this.f={fa:0,pc:-1}}A(L);k=L.prototype;
|
||||
k.Ia=function(a,b,c,d){this.v=b;this.C=a;this.b=c;this.j=d;var e=this;this.f.pc=Ic(c,function(){e.f.Nb|=128;e.f.Nb&64&&Jc(e.b,e.f.ie);e.C&&e.C.ra(1);Kc(e.b,e.f.pc,1E3/60)});this.f.ie=Lc(64,6);Ib(b,this,Uc);Kb(b,this.reset.bind(this));d&&Vc(d,256,function(a){var b=e.b;M(e,"KIPDR",b.P[0],0,a[0]);M(e,"KDPDR",b.P[0],8,a[0]);M(e,"KIPAR",b.ha[0],0,a[0]);M(e,"KDPAR",b.ha[0],8,a[0],!0);M(e,"SIPDR",b.P[1],0,a[0]);M(e,"SDPDR",b.P[1],8,a[0]);M(e,"SIPAR",b.ha[1],0,a[0]);M(e,"SDPAR",b.ha[1],8,a[0],!0);M(e,"UIPDR",
|
||||
b.P[3],0,a[0]);M(e,"UDPDR",b.P[3],8,a[0]);M(e,"UIPAR",b.ha[3],0,a[0]);M(e,"UDPAR",b.ha[3],8,a[0],!0)});I(this)};function M(a,b,c,d,e,f){a=a.j;if(!(e&&0>b.indexOf(e.toUpperCase()))){b+=":";for(e=0;8>e;e++)b+=" "+K(a,c[d+e]);a.i(b+(f?"\n":""))}}k.reset=function(){this.f.Nb=128;Kc(this.b,this.f.pc,1E3/60,!0)};k.xd=function(){return this.f.Nb};k.se=function(a){this.f.Nb=a&192};k.zd=function(){return Wc(this.b)};k.ue=function(a){Xc(this.b,a&-129|this.b.za&128)};k.Ad=function(){return Yc(this.b)};
|
||||
k.Bd=function(){return Zc(this.b)};k.Cd=function(){return this.b.Ta};k.ve=function(a){$c(this.b,a)};k.ce=function(a){a=a>>1&63;var b=this.b.Sb[a>>1];return a&1?b>>16:b&65535};k.We=function(a,b){b=b>>1&63;var c=b>>1;this.b.Sb[c]=b&1?this.b.Sb[c]&65535|(a&63)<<16:this.b.Sb[c]&-65536|a&65534};k.Wd=function(a){return this.b.P[1][a>>1&7]};k.Pe=function(a,b){this.b.P[1][b>>1&7]=a&65295};k.Ud=function(a){return this.b.P[1][(a>>1&7)+8]};k.Ne=function(a,b){this.b.P[1][(b>>1&7)+8]=a&65295};
|
||||
k.Vd=function(a){return this.b.ha[1][a>>1&7]};k.Oe=function(a,b){b=b>>1&7;this.b.ha[1][b]=a;this.b.P[1][b]&=65295};k.Td=function(a){return this.b.ha[1][(a>>1&7)+8]};k.Me=function(a,b){b=(b>>1&7)+8;this.b.ha[1][b]=a;this.b.P[1][b]&=65295};k.wd=function(a){return this.b.P[0][a>>1&7]};k.re=function(a,b){b=b>>1&7;this.b.P[0][b]=a&=65295;H(this,256)&&F(this,"writeKIPDR["+b+"]: "+na(a),!0)};k.ud=function(a){return this.b.P[0][(a>>1&7)+8]};k.pe=function(a,b){this.b.P[0][(b>>1&7)+8]=a&65295};
|
||||
k.vd=function(a){return this.b.ha[0][a>>1&7]};k.qe=function(a,b){b=b>>1&7;this.b.ha[0][b]=a;this.b.P[0][b]&=65295};k.td=function(a){return this.b.ha[0][(a>>1&7)+8]};k.oe=function(a,b){b=(b>>1&7)+8;this.b.ha[0][b]=a;this.b.P[0][b]&=65295};k.be=function(a){return this.b.P[3][a>>1&7]};k.Ve=function(a,b){this.b.P[3][b>>1&7]=a&65295};k.$d=function(a){return this.b.P[3][(a>>1&7)+8]};k.Te=function(a,b){this.b.P[3][(b>>1&7)+8]=a&65295};k.ae=function(a){return this.b.ha[3][a>>1&7]};
|
||||
k.Ue=function(a,b){b=b>>1&7;this.b.ha[3][b]=a;this.b.P[3][b]&=65295};k.Zd=function(a){return this.b.ha[3][(a>>1&7)+8]};k.Se=function(a,b){b=(b>>1&7)+8;this.b.ha[3][b]=a;this.b.P[3][b]&=65295};k.Db=function(a){a&=7;return this.b.N&2048?this.b.$a[a]:this.b.u[a]};k.Gb=function(a,b){b&=7;this.b.N&2048?this.b.$a[b]=a:this.b.u[b]=a};k.Hd=function(){return this.b.N&49152?this.b.La[0]:this.b.u[6]};k.Ae=function(a){this.b.N&49152?this.b.La[0]=a:this.b.u[6]=a};k.Kd=function(){return this.b.u[7]};
|
||||
k.De=function(a){this.b.u[7]=a};k.Eb=function(a){a&=7;return this.b.N&2048?this.b.u[a]:this.b.$a[a]};k.Hb=function(a,b){b&=7;this.b.N&2048?this.b.u[b]=a:this.b.$a[b]=a};k.Id=function(){return 1==(this.b.N&49152)>>14?this.b.u[6]:this.b.La[1]};k.Be=function(a){1==(this.b.N&49152)>>14?this.b.u[6]=a:this.b.La[1]=a};k.Jd=function(){return 3==(this.b.N&49152)>>14?this.b.u[6]:this.b.La[3]};k.Ce=function(a){3==(this.b.N&49152)>>14?this.b.u[6]=a:this.b.La[3]=a};k.rd=function(a){return this.b.Kc[a-65504>>1]};
|
||||
k.me=function(a,b){this.b.Kc[b-65504>>1]=a};k.Hc=function(a){if(65520==a){a=0;switch(Cc){case Cc:a=this.v.gc}a=(a>>6)-1}else a=0;return a};k.Oc=function(){};k.Yd=function(){return 1};k.Re=function(){};k.qd=function(){return this.b.va};k.le=function(){this.b.va=0};k.yd=function(){return this.b.Jc};k.te=function(a,b){b&1||(a&=255);this.b.Jc=a};k.Dd=function(a,b){return b?0:this.b.Rb};k.we=function(a){ad(this.b,a)};k.Xd=function(a,b){return b?0:this.b.hb&65280};k.Qe=function(a){this.b.hb=a|255};
|
||||
k.Gd=function(){return bd(this.b)};k.ze=function(a){cd(this.b,a&-1793|bd(this.b)&1792);this.b.J|=128};k.Nc=function(a,b){H(this)&&F(this,"writeIgnored("+na(b)+"): "+na(a),!0,!0)};
|
||||
var N={},Uc=(N[61568]=[null,null,L.prototype.ce,L.prototype.We,"UNIMAP",64,1170],N[62592]=[null,null,L.prototype.Wd,L.prototype.Pe,"SIPDR",8,1145,256],N[62608]=[null,null,L.prototype.Ud,L.prototype.Ne,"SDPDR",8,1145,256],N[62624]=[null,null,L.prototype.Vd,L.prototype.Oe,"SIPAR",8,1145,256],N[62640]=[null,null,L.prototype.Td,L.prototype.Me,"SDPAR",8,1145,256],N[62656]=[null,null,L.prototype.wd,L.prototype.re,"KIPDR",8,1145,256],N[62672]=[null,null,L.prototype.ud,L.prototype.pe,"KDPDR",8,1145,256],
|
||||
N[62688]=[null,null,L.prototype.vd,L.prototype.qe,"KIPAR",8,1145,256],N[62704]=[null,null,L.prototype.td,L.prototype.oe,"KDPAR",8,1145,256],N[62798]=[null,null,L.prototype.Cd,L.prototype.ve,"MMR3",1,1145,256],N[65382]=[null,null,L.prototype.xd,L.prototype.se,"LKS"],N[65402]=[null,null,L.prototype.zd,L.prototype.ue,"MMR0",1,1145,256],N[65404]=[null,null,L.prototype.Ad,L.prototype.Nc,"MMR1",1,1145,256],N[65406]=[null,null,L.prototype.Bd,L.prototype.Nc,"MMR2",1,1145,256],N[65408]=[null,null,L.prototype.be,
|
||||
L.prototype.Ve,"UIPDR",8,1145,256],N[65424]=[null,null,L.prototype.$d,L.prototype.Te,"UDPDR",8,1145,256],N[65440]=[null,null,L.prototype.ae,L.prototype.Ue,"UIPAR",8,1145,256],N[65456]=[null,null,L.prototype.Zd,L.prototype.Se,"UDPAR",8,1145,256],N[65472]=[null,null,L.prototype.Db,L.prototype.Gb,"R0SET0"],N[65473]=[null,null,L.prototype.Db,L.prototype.Gb,"R1SET0"],N[65474]=[null,null,L.prototype.Db,L.prototype.Gb,"R2SET0"],N[65475]=[null,null,L.prototype.Db,L.prototype.Gb,"R3SET0"],N[65476]=[null,null,
|
||||
L.prototype.Db,L.prototype.Gb,"R4SET0"],N[65477]=[null,null,L.prototype.Db,L.prototype.Gb,"R5SET0"],N[65478]=[null,null,L.prototype.Hd,L.prototype.Ae,"R6KERNEL"],N[65479]=[null,null,L.prototype.Kd,L.prototype.De,"R7KERNEL"],N[65480]=[null,null,L.prototype.Eb,L.prototype.Hb,"R0SET1",1,1145],N[65481]=[null,null,L.prototype.Eb,L.prototype.Hb,"R1SET1",1,1145],N[65482]=[null,null,L.prototype.Eb,L.prototype.Hb,"R2SET1",1,1145],N[65483]=[null,null,L.prototype.Eb,L.prototype.Hb,"R3SET1",1,1145],N[65484]=
|
||||
[null,null,L.prototype.Eb,L.prototype.Hb,"R4SET1",1,1145],N[65485]=[null,null,L.prototype.Eb,L.prototype.Hb,"R5SET1",1,1145],N[65486]=[null,null,L.prototype.Id,L.prototype.Be,"R6SUPER",1,1145],N[65487]=[null,null,L.prototype.Jd,L.prototype.Ce,"R6USER",1,1145],N[65504]=[null,null,L.prototype.rd,L.prototype.me,"CTRL",8,1170],N[65520]=[null,null,L.prototype.Hc,L.prototype.Oc,"LSIZE",1,1170],N[65522]=[null,null,L.prototype.Hc,L.prototype.Oc,"HSIZE",1,1170],N[65524]=[null,null,L.prototype.Yd,L.prototype.Re,
|
||||
"SYSID",1,1170],N[65526]=[null,null,L.prototype.qd,L.prototype.le,"CPUERR",1,1170],N[65528]=[null,null,L.prototype.yd,L.prototype.te,"MB",1,1170],N[65530]=[null,null,L.prototype.Dd,L.prototype.we,"PIR"],N[65532]=[null,null,L.prototype.Xd,L.prototype.Qe,"SL"],N[65534]=[null,null,L.prototype.Gd,L.prototype.ze,"PSW"],N);
|
||||
k.Ha=function(a,b,c){this.f=!0;this.ma||(this.j&&H(this.j,32)&&F(this.j,"memory fault ("+c+") on "+K(this.j,a),!0,!0),b&&(this.b.va|=b),this.b.qa(4,0,a))};function Hc(a){var b=a.f;a.f=!1;return b}function Bc(a,b,c){u("Memory block error ("+a+": "+p(b)+","+p(c)+")");return!1}function L(a){w.call(this,"Device",a,L,1024);this.f={fa:0,qc:-1}}A(L);k=L.prototype;
|
||||
k.Ia=function(a,b,c,d){this.v=b;this.C=a;this.b=c;this.j=d;var e=this;this.f.qc=Ic(c,function(){e.f.Nb|=128;e.f.Nb&64&&Jc(e.b,e.f.je);e.C&&e.C.ra(1);Kc(e.b,e.f.qc,1E3/60)});this.f.je=Lc(64,6);Ib(b,this,Uc);Kb(b,this.reset.bind(this));d&&Vc(d,256,function(a){var b=e.b;M(e,"KIPDR",b.P[0],0,a[0]);M(e,"KDPDR",b.P[0],8,a[0]);M(e,"KIPAR",b.ha[0],0,a[0]);M(e,"KDPAR",b.ha[0],8,a[0],!0);M(e,"SIPDR",b.P[1],0,a[0]);M(e,"SDPDR",b.P[1],8,a[0]);M(e,"SIPAR",b.ha[1],0,a[0]);M(e,"SDPAR",b.ha[1],8,a[0],!0);M(e,"UIPDR",
|
||||
b.P[3],0,a[0]);M(e,"UDPDR",b.P[3],8,a[0]);M(e,"UIPAR",b.ha[3],0,a[0]);M(e,"UDPAR",b.ha[3],8,a[0],!0)});I(this)};function M(a,b,c,d,e,f){a=a.j;if(!(e&&0>b.indexOf(e.toUpperCase()))){b+=":";for(e=0;8>e;e++)b+=" "+K(a,c[d+e]);a.i(b+(f?"\n":""))}}k.reset=function(){this.f.Nb=128;Kc(this.b,this.f.qc,1E3/60,!0)};k.xd=function(){return this.f.Nb};k.ue=function(a){this.f.Nb=a&192};k.zd=function(){return Wc(this.b)};k.we=function(a){Xc(this.b,a&-129|this.b.za&128)};k.Ad=function(){return Yc(this.b)};
|
||||
k.Bd=function(){return Zc(this.b)};k.Cd=function(){return this.b.Ta};k.xe=function(a){$c(this.b,a)};k.ce=function(a){a=a>>1&63;var b=this.b.Sb[a>>1];return a&1?b>>16:b&65535};k.Ye=function(a,b){b=b>>1&63;var c=b>>1;this.b.Sb[c]=b&1?this.b.Sb[c]&65535|(a&63)<<16:this.b.Sb[c]&-65536|a&65534};k.Wd=function(a){return this.b.P[1][a>>1&7]};k.Re=function(a,b){this.b.P[1][b>>1&7]=a&65295};k.Ud=function(a){return this.b.P[1][(a>>1&7)+8]};k.Pe=function(a,b){this.b.P[1][(b>>1&7)+8]=a&65295};
|
||||
k.Vd=function(a){return this.b.ha[1][a>>1&7]};k.Qe=function(a,b){b=b>>1&7;this.b.ha[1][b]=a;this.b.P[1][b]&=65295};k.Td=function(a){return this.b.ha[1][(a>>1&7)+8]};k.Oe=function(a,b){b=(b>>1&7)+8;this.b.ha[1][b]=a;this.b.P[1][b]&=65295};k.wd=function(a){return this.b.P[0][a>>1&7]};k.te=function(a,b){b=b>>1&7;this.b.P[0][b]=a&=65295;H(this,256)&&F(this,"writeKIPDR["+b+"]: "+na(a),!0)};k.ud=function(a){return this.b.P[0][(a>>1&7)+8]};k.re=function(a,b){this.b.P[0][(b>>1&7)+8]=a&65295};
|
||||
k.vd=function(a){return this.b.ha[0][a>>1&7]};k.se=function(a,b){b=b>>1&7;this.b.ha[0][b]=a;this.b.P[0][b]&=65295};k.td=function(a){return this.b.ha[0][(a>>1&7)+8]};k.qe=function(a,b){b=(b>>1&7)+8;this.b.ha[0][b]=a;this.b.P[0][b]&=65295};k.be=function(a){return this.b.P[3][a>>1&7]};k.Xe=function(a,b){this.b.P[3][b>>1&7]=a&65295};k.$d=function(a){return this.b.P[3][(a>>1&7)+8]};k.Ve=function(a,b){this.b.P[3][(b>>1&7)+8]=a&65295};k.ae=function(a){return this.b.ha[3][a>>1&7]};
|
||||
k.We=function(a,b){b=b>>1&7;this.b.ha[3][b]=a;this.b.P[3][b]&=65295};k.Zd=function(a){return this.b.ha[3][(a>>1&7)+8]};k.Ue=function(a,b){b=(b>>1&7)+8;this.b.ha[3][b]=a;this.b.P[3][b]&=65295};k.Db=function(a){a&=7;return this.b.N&2048?this.b.$a[a]:this.b.u[a]};k.Gb=function(a,b){b&=7;this.b.N&2048?this.b.$a[b]=a:this.b.u[b]=a};k.Hd=function(){return this.b.N&49152?this.b.La[0]:this.b.u[6]};k.Ce=function(a){this.b.N&49152?this.b.La[0]=a:this.b.u[6]=a};k.Kd=function(){return this.b.u[7]};
|
||||
k.Fe=function(a){this.b.u[7]=a};k.Eb=function(a){a&=7;return this.b.N&2048?this.b.u[a]:this.b.$a[a]};k.Hb=function(a,b){b&=7;this.b.N&2048?this.b.u[b]=a:this.b.$a[b]=a};k.Id=function(){return 1==(this.b.N&49152)>>14?this.b.u[6]:this.b.La[1]};k.De=function(a){1==(this.b.N&49152)>>14?this.b.u[6]=a:this.b.La[1]=a};k.Jd=function(){return 3==(this.b.N&49152)>>14?this.b.u[6]:this.b.La[3]};k.Ee=function(a){3==(this.b.N&49152)>>14?this.b.u[6]=a:this.b.La[3]=a};k.rd=function(a){return this.b.Mc[a-65504>>1]};
|
||||
k.oe=function(a,b){this.b.Mc[b-65504>>1]=a};k.Jc=function(a){if(65520==a){a=0;switch(Cc){case Cc:a=this.v.gc}a=(a>>6)-1}else a=0;return a};k.Qc=function(){};k.Yd=function(){return 1};k.Te=function(){};k.qd=function(){return this.b.va};k.ne=function(){this.b.va=0};k.yd=function(){return this.b.Lc};k.ve=function(a,b){b&1||(a&=255);this.b.Lc=a};k.Dd=function(a,b){return b?0:this.b.Rb};k.ye=function(a){ad(this.b,a)};k.Xd=function(a,b){return b?0:this.b.hb&65280};k.Se=function(a){this.b.hb=a|255};
|
||||
k.Gd=function(){return bd(this.b)};k.Be=function(a){cd(this.b,a&-1793|bd(this.b)&1792);this.b.J|=128};k.Pc=function(a,b){H(this)&&F(this,"writeIgnored("+na(b)+"): "+na(a),!0,!0)};
|
||||
var N={},Uc=(N[61568]=[null,null,L.prototype.ce,L.prototype.Ye,"UNIMAP",64,1170],N[62592]=[null,null,L.prototype.Wd,L.prototype.Re,"SIPDR",8,1145,256],N[62608]=[null,null,L.prototype.Ud,L.prototype.Pe,"SDPDR",8,1145,256],N[62624]=[null,null,L.prototype.Vd,L.prototype.Qe,"SIPAR",8,1145,256],N[62640]=[null,null,L.prototype.Td,L.prototype.Oe,"SDPAR",8,1145,256],N[62656]=[null,null,L.prototype.wd,L.prototype.te,"KIPDR",8,1145,256],N[62672]=[null,null,L.prototype.ud,L.prototype.re,"KDPDR",8,1145,256],
|
||||
N[62688]=[null,null,L.prototype.vd,L.prototype.se,"KIPAR",8,1145,256],N[62704]=[null,null,L.prototype.td,L.prototype.qe,"KDPAR",8,1145,256],N[62798]=[null,null,L.prototype.Cd,L.prototype.xe,"MMR3",1,1145,256],N[65382]=[null,null,L.prototype.xd,L.prototype.ue,"LKS"],N[65402]=[null,null,L.prototype.zd,L.prototype.we,"MMR0",1,1145,256],N[65404]=[null,null,L.prototype.Ad,L.prototype.Pc,"MMR1",1,1145,256],N[65406]=[null,null,L.prototype.Bd,L.prototype.Pc,"MMR2",1,1145,256],N[65408]=[null,null,L.prototype.be,
|
||||
L.prototype.Xe,"UIPDR",8,1145,256],N[65424]=[null,null,L.prototype.$d,L.prototype.Ve,"UDPDR",8,1145,256],N[65440]=[null,null,L.prototype.ae,L.prototype.We,"UIPAR",8,1145,256],N[65456]=[null,null,L.prototype.Zd,L.prototype.Ue,"UDPAR",8,1145,256],N[65472]=[null,null,L.prototype.Db,L.prototype.Gb,"R0SET0"],N[65473]=[null,null,L.prototype.Db,L.prototype.Gb,"R1SET0"],N[65474]=[null,null,L.prototype.Db,L.prototype.Gb,"R2SET0"],N[65475]=[null,null,L.prototype.Db,L.prototype.Gb,"R3SET0"],N[65476]=[null,null,
|
||||
L.prototype.Db,L.prototype.Gb,"R4SET0"],N[65477]=[null,null,L.prototype.Db,L.prototype.Gb,"R5SET0"],N[65478]=[null,null,L.prototype.Hd,L.prototype.Ce,"R6KERNEL"],N[65479]=[null,null,L.prototype.Kd,L.prototype.Fe,"R7KERNEL"],N[65480]=[null,null,L.prototype.Eb,L.prototype.Hb,"R0SET1",1,1145],N[65481]=[null,null,L.prototype.Eb,L.prototype.Hb,"R1SET1",1,1145],N[65482]=[null,null,L.prototype.Eb,L.prototype.Hb,"R2SET1",1,1145],N[65483]=[null,null,L.prototype.Eb,L.prototype.Hb,"R3SET1",1,1145],N[65484]=
|
||||
[null,null,L.prototype.Eb,L.prototype.Hb,"R4SET1",1,1145],N[65485]=[null,null,L.prototype.Eb,L.prototype.Hb,"R5SET1",1,1145],N[65486]=[null,null,L.prototype.Id,L.prototype.De,"R6SUPER",1,1145],N[65487]=[null,null,L.prototype.Jd,L.prototype.Ee,"R6USER",1,1145],N[65504]=[null,null,L.prototype.rd,L.prototype.oe,"CTRL",8,1170],N[65520]=[null,null,L.prototype.Jc,L.prototype.Qc,"LSIZE",1,1170],N[65522]=[null,null,L.prototype.Jc,L.prototype.Qc,"HSIZE",1,1170],N[65524]=[null,null,L.prototype.Yd,L.prototype.Te,
|
||||
"SYSID",1,1170],N[65526]=[null,null,L.prototype.qd,L.prototype.ne,"CPUERR",1,1170],N[65528]=[null,null,L.prototype.yd,L.prototype.ve,"MB",1,1170],N[65530]=[null,null,L.prototype.Dd,L.prototype.ye,"PIR"],N[65532]=[null,null,L.prototype.Xd,L.prototype.Se,"SL"],N[65534]=[null,null,L.prototype.Gd,L.prototype.Be,"PSW"],N);
|
||||
$a(function(){for(var a=E(document,"pdp11","device"),b=0;b<a.length;b++){var c,d=a[b];c=C(d);switch(c.type){case "default":c=new L(c);D(c,d);break;case "pc11":c=new dd(c);D(c,d);break;case "rl11":c=new O(c),D(c,d)}}});var ed;if(Ab){var fd=new ArrayBuffer(2);(new DataView(fd)).setUint16(0,256,!0);ed=256===(new Uint16Array(fd))[0]}else ed=!1;var gd=ed;
|
||||
function J(a,b,c,d,e,f){this.v=a;this.id=hd+=2;this.b=null;this.F=b;this.Tb=c;this.size=d||0;this.type=e||id;this.f=e==jd;this.controller=null;uc(this);this.Xa=this.Yc=!1;if(this.size)if(f)this.controller=f,a=[null,0],this.b=a[0],kd(this,f.Rc);else if(Ab)this.B=new ArrayBuffer(this.size),this.D=new DataView(this.B,0,this.size),this.G=new Uint8Array(this.B,0,this.size),this.I=new Uint16Array(this.B,0,this.size>>1),this.b=new Int32Array(this.B,0,this.size>>2),kd(this,gd?ld:md);else{a=this.b=Array(this.size>>
|
||||
function J(a,b,c,d,e,f){this.v=a;this.id=hd+=2;this.b=null;this.F=b;this.Tb=c;this.size=d||0;this.type=e||id;this.f=e==jd;this.controller=null;uc(this);this.Xa=this.$c=!1;if(this.size)if(f)this.controller=f,a=[null,0],this.b=a[0],kd(this,f.Tc);else if(Ab)this.B=new ArrayBuffer(this.size),this.D=new DataView(this.B,0,this.size),this.G=new Uint8Array(this.B,0,this.size),this.I=new Uint16Array(this.B,0,this.size>>1),this.b=new Int32Array(this.B,0,this.size>>2),kd(this,gd?ld:md);else{a=this.b=Array(this.size>>
|
||||
2);for(f=0;f<a.length;f++)a[f]=0;kd(this,nd)}else kd(this)}var id=0,Cc=1,jd=2,Ac=4,Dc=["NONE","RAM","ROM","VID","H/W"],hd=0;
|
||||
J.prototype={constructor:J,parent:null,save:function(){var a,b;if(this.controller)a=null;else if(Ab)for(a=Array(this.size>>2),b=0;b<a.length;b++)a[b]=this.D.getInt32(b<<2,!0);else a=this.b;return a},restore:function(a){if(this.controller)return!a;if(a&&this.size==a.length<<2){var b;if(Ab)for(b=0;b<a.length;b++)this.D.setInt32(b<<2,a[b],!0);else this.b=a;return this.Xa=!0}return!1},ob:function(a,b){b?this.C++||od(this,pd,!1):this.g++||qd(this,pd,!1)},K:function(a,b){this.j&&H(this.j,128)&&F(this.j,
|
||||
"attempt to read invalid address "+K(this.j,b),!0);this.v.Ha(b,32,2);return 255},w:function(a,b,c){this.j&&H(this.j,128)&&F(this.j,"attempt to write "+K(this.j,b)+" to invalid addresses "+K(this.j,c),!0);this.v.Ha(c,32,4)},L:function(a,b){return this.$b(a++,b++)|this.$b(a,b)<<8},H:function(a,b,c){this.cc(a++,b&255,c++);this.cc(a,b>>8,c)},T:function(a){return this.b[a>>2]>>>((a&3)<<3)&255},ca:function(a,b){a&1&&this.v.Ha(b,64,2);b=a>>2;a=(a&3)<<3;var c=this.b[b]>>a;return 24>a?c&65535:c&255|(this.b[b+
|
||||
1]&255)<<8},xa:function(a,b){var c=a>>2;a=(a&3)<<3;this.b[c]=this.b[c]&~(255<<a)|b<<a;this.Xa=!0},Ma:function(a,b,c){a&1&&this.v.Ha(c,64,4);c=a>>2;a=(a&3)<<3;24>a?this.b[c]=this.b[c]&~(65535<<a)|b<<a:(this.b[c]=this.b[c]&16777215|b<<24,c++,this.b[c]=this.b[c]&-256|b>>8);this.Xa=!0},O:function(a,b){if(this.j&&null!=this.F){var c=this.j;rd(c,this.F+a,1,c.M)&&c.da(!0)}return this.mc(a,b)},Ua:function(a,b){if(this.j&&null!=this.F){var c=this.j;rd(c,this.F+a,2,c.M)&&c.da(!0)}return this.nc(a,b)},na:function(a,
|
||||
b,c){if(this.j&&null!=this.F){var d=this.j;rd(d,this.F+a,1,d.D)&&d.da(!0)}this.f?this.w(a,b,c):this.dc(a,b,c)},Ba:function(a,b,c){if(this.j&&null!=this.F){var d=this.j;rd(d,this.F+a,2,d.D)&&d.da(!0)}this.f?this.w(a,b,c):this.qc(a,b,c)},M:function(a){return this.G[a]},S:function(a,b){a=this.G[a];this.j&&H(this.j,128)&&F(this.j,"Memory.readByte("+K(this.j,b)+"): "+K(this.j,a),!0);return a},X:function(a,b){a&1&&this.v.Ha(b,64,2);return this.D.getUint16(a,!0)},ba:function(a,b){a&1&&this.v.Ha(b,64,2);
|
||||
1]&255)<<8},xa:function(a,b){var c=a>>2;a=(a&3)<<3;this.b[c]=this.b[c]&~(255<<a)|b<<a;this.Xa=!0},Ma:function(a,b,c){a&1&&this.v.Ha(c,64,4);c=a>>2;a=(a&3)<<3;24>a?this.b[c]=this.b[c]&~(65535<<a)|b<<a:(this.b[c]=this.b[c]&16777215|b<<24,c++,this.b[c]=this.b[c]&-256|b>>8);this.Xa=!0},O:function(a,b){if(this.j&&null!=this.F){var c=this.j;rd(c,this.F+a,1,c.M)&&c.da(!0)}return this.nc(a,b)},Ua:function(a,b){if(this.j&&null!=this.F){var c=this.j;rd(c,this.F+a,2,c.M)&&c.da(!0)}return this.oc(a,b)},na:function(a,
|
||||
b,c){if(this.j&&null!=this.F){var d=this.j;rd(d,this.F+a,1,d.D)&&d.da(!0)}this.f?this.w(a,b,c):this.dc(a,b,c)},Ba:function(a,b,c){if(this.j&&null!=this.F){var d=this.j;rd(d,this.F+a,2,d.D)&&d.da(!0)}this.f?this.w(a,b,c):this.rc(a,b,c)},M:function(a){return this.G[a]},S:function(a,b){a=this.G[a];this.j&&H(this.j,128)&&F(this.j,"Memory.readByte("+K(this.j,b)+"): "+K(this.j,a),!0);return a},X:function(a,b){a&1&&this.v.Ha(b,64,2);return this.D.getUint16(a,!0)},ba:function(a,b){a&1&&this.v.Ha(b,64,2);
|
||||
a=this.I[a>>1];this.j&&H(this.j,128)&&F(this.j,"Memory.readWord("+K(this.j,b)+"): "+K(this.j,a),!0);return a},ja:function(a,b){this.G[a]=b;this.Xa=!0},bb:function(a,b,c){this.G[a]=b;this.Xa=!0;this.j&&H(this.j,128)&&F(this.j,"Memory.writeByte("+K(this.j,c)+","+K(this.j,b)+")",!0)},Aa:function(a,b,c){a&1&&this.v.Ha(c,64,4);this.D.setUint16(a,b,!0);this.Xa=!0},Ca:function(a,b,c){a&1&&this.v.Ha(c,64,4);this.I[a>>1]=b;this.Xa=!0;this.j&&H(this.j,128)&&F(this.j,"Memory.writeWord("+K(this.j,c)+","+K(this.j,
|
||||
b)+")",!0)}};function uc(a,b,c){a.j=b;a.g=a.C=0;c&&((a.g=c.g)&&qd(a,pd,!1),(a.C=c.C)&&od(a,pd,!1))}function sd(a,b){b?--a.C||(a.cc=a.f?a.w:a.dc,a.Ub=a.f?a.H:a.qc):--a.g||(a.$b=a.mc,a.ta=a.nc)}function od(a,b,c){c&&a.C||(a.cc=!a.f&&b[1]||a.w,a.Ub=!a.f&&b[3]||a.H);if(c||void 0===c)a.dc=b[1]||a.w,a.qc=b[3]||a.H}function qd(a,b,c){c&&a.g||(a.$b=b[0]||a.K,a.ta=b[2]||a.L);if(c||void 0===c)a.mc=b[0]||a.K,a.nc=b[2]||a.L}function kd(a,b){b||(b=td);qd(a,b,void 0);od(a,b,void 0)}
|
||||
b)+")",!0)}};function uc(a,b,c){a.j=b;a.g=a.C=0;c&&((a.g=c.g)&&qd(a,pd,!1),(a.C=c.C)&&od(a,pd,!1))}function sd(a,b){b?--a.C||(a.cc=a.f?a.w:a.dc,a.Ub=a.f?a.H:a.rc):--a.g||(a.$b=a.nc,a.ta=a.oc)}function od(a,b,c){c&&a.C||(a.cc=!a.f&&b[1]||a.w,a.Ub=!a.f&&b[3]||a.H);if(c||void 0===c)a.dc=b[1]||a.w,a.rc=b[3]||a.H}function qd(a,b,c){c&&a.g||(a.$b=b[0]||a.K,a.ta=b[2]||a.L);if(c||void 0===c)a.nc=b[0]||a.K,a.oc=b[2]||a.L}function kd(a,b){b||(b=td);qd(a,b,void 0);od(a,b,void 0)}
|
||||
var td=[],nd=[J.prototype.T,J.prototype.xa,J.prototype.ca,J.prototype.Ma],pd=[J.prototype.O,J.prototype.na,J.prototype.Ua,J.prototype.Ba];if(Ab)var md=[J.prototype.M,J.prototype.ja,J.prototype.X,J.prototype.Aa],ld=[J.prototype.S,J.prototype.bb,J.prototype.ba,J.prototype.Ca];
|
||||
function ud(a,b){w.call(this,"CPU",a,ud,1);b=a.cycles||b;var c=a.multiplier||1;this.zb=0;this.pb=b;this.gb=c;this.Jb=Math.round(this.pb/1E4)/100;this.rb=this.Jb*this.gb;this.A.W=!1;this.A.bc=!1;this.A.xb=a.autoStart;this.A.yb=!1;this.Ob=this.Aa=0;this.Pb=a.csStart;this.Ab=a.csInterval;this.Bb=a.csStop;this.L=[];this.Gc=this.ge.bind(this);I(this)}A(ud);var vd=["power","reset"];k=ud.prototype;
|
||||
k.Ia=function(a,b,c,d){this.C=a;this.v=b;this.j=d;this.w=a.w;for(b=0;b<vd.length;b++)(c=this.G[vd[b]])&&this.C.wa(null,vd[b],c);a=wd(a,"autoStart");null!=a&&(this.A.xb="true"==a?!0:"false"==a?!1:!!a);I(this)};k.reset=function(){};k.save=function(){return null};k.restore=function(){return!1};
|
||||
k.Ka=function(a,b){if(!b){if(a&&this.restore){xd(this);if(!this.restore(a))return!1;yd(this)}else this.reset();this.j?(a=this.j,b=this.A.xb,a.lb=!0,a.i("Type ? for help with PDPjs Debugger commands"),zd(a),b||a.ub(),a.Va&&(b=a.Va,a.Va=null,Ad(a,b))):this.i("No debugger detected")}return!0};k.Ja=function(a){return a?this.save():!0};k.xb=function(){return this.A.xb||!this.j&&void 0===this.G.run?(this.jb(),!0):!1};k.wc=function(){return 0};
|
||||
function yd(a){void 0===a.Pb&&(a.Pb=0);void 0===a.Ab&&(a.Ab=-1);void 0===a.Bb&&(a.Bb=-1);a.A.yb=0<=a.Pb&&0<a.Ab;a.A.yb&&(a.Ob=0,a.Aa=a.Pb-a.ja)}function Ub(a,b){if(a.A.yb){var c=!1;a.Ob=a.Ob+a.wc()|0;a.Aa-=b;0>=a.Aa&&(a.Aa+=a.Ab,c=!0);0<=a.Bb&&a.Bb<=Bd(a)&&(a.Ab=a.Bb=-1,yd(a),a.da(),c=!0);c&&a.i(Bd(a)+" cycles: checksum="+p(a.Ob))}}
|
||||
function ud(a,b){w.call(this,"CPU",a,ud,1);b=a.cycles||b;var c=a.multiplier||1;this.Ib=0;this.pb=b;this.gb=c;this.Kb=Math.round(this.pb/1E4)/100;this.sb=this.Kb*this.gb;this.A.W=!1;this.A.bc=!1;this.A.yb=a.autoStart;this.A.zb=!1;this.Ob=this.Aa=0;this.Pb=a.csStart;this.Ab=a.csInterval;this.Bb=a.csStop;this.L=[];this.Ic=this.ge.bind(this);I(this)}A(ud);var vd=["power","reset"];k=ud.prototype;
|
||||
k.Ia=function(a,b,c,d){this.C=a;this.v=b;this.j=d;this.w=a.w;for(b=0;b<vd.length;b++)(c=this.G[vd[b]])&&this.C.wa(null,vd[b],c);a=wd(a,"autoStart");null!=a&&(this.A.yb="true"==a?!0:"false"==a?!1:!!a);I(this)};k.reset=function(){};k.save=function(){return null};k.restore=function(){return!1};
|
||||
k.Ka=function(a,b){if(!b){if(a&&this.restore){xd(this);if(!this.restore(a))return!1;yd(this)}else this.reset();this.j?(a=this.j,b=this.A.yb,a.lb=!0,a.i("Type ? for help with PDPjs Debugger commands"),zd(a),b||a.vb(),a.Va&&(b=a.Va,a.Va=null,Ad(a,b))):this.i("No debugger detected")}return!0};k.Ja=function(a){return a?this.save():!0};k.yb=function(){return this.A.yb||!this.j&&void 0===this.G.run?(this.jb(),!0):!1};k.xc=function(){return 0};
|
||||
function yd(a){void 0===a.Pb&&(a.Pb=0);void 0===a.Ab&&(a.Ab=-1);void 0===a.Bb&&(a.Bb=-1);a.A.zb=0<=a.Pb&&0<a.Ab;a.A.zb&&(a.Ob=0,a.Aa=a.Pb-a.ja)}function Ub(a,b){if(a.A.zb){var c=!1;a.Ob=a.Ob+a.xc()|0;a.Aa-=b;0>=a.Aa&&(a.Aa+=a.Ab,c=!0);0<=a.Bb&&a.Bb<=Bd(a)&&(a.Ab=a.Bb=-1,yd(a),a.da(),c=!0);c&&a.i(Bd(a)+" cycles: checksum="+p(a.Ob))}}
|
||||
k.wa=function(a,b,c){var d=this;switch(b){case "power":case "reset":return this.G[b]=c,!0;case "run":return this.G[b]=c,c.onclick=function(){var a;if(a=d.C)if(a=d.C,a.A.ia)a=!0;else{var b=null,c,h=sb(a.id);for(c=0;c<h.length&&(b=h[c],b===a||b.A.ready);c++);if(c==h.length)for(c=0;c<h.length&&(b=h[c],b===a||b.A.ia);c++);c==h.length&&(b=a);u("The "+b.type+" component ("+b.id+") is not "+(b.A.ready?"powered yet":"ready yet"+(b.Xb?" (waiting for notification)":""))+".");a=!1}a&&(d.A.W?d.da():d.jb())},
|
||||
!0;case "speed":return this.G[b]=c,!0;case "setSpeed":return this.G[b]=c,c.onclick=function(){Cd(d,d.gb<<1,!0)},c.textContent=this.rb.toFixed(2)+"Mhz",!0}return!1};k.ra=function(a){this.C&&this.C.ra(a)};function Tb(a,b,c){a.ja+=b;c&&(a.ca=a.b=a.I=0)}function Dd(a,b){var c=1;b&&1<a.gb&&a.xa&&(c=a.xa/a.Jb);a.Dc=Math.round(1E3/30);a.qb=Math.floor(a.pb/30*c);b||(a.Ba=a.qb);a.Kb=0}function Bd(a){return a.ja+a.X+a.ca-a.b}function xd(a){a.xa=0;a.Fc=0;a.ja=a.X=a.ca=a.b=a.I=0;yd(a);Cd(a,1)}
|
||||
function Cd(a,b,c){var d=!1;if(void 0!==b){.8>a.xa/a.rb?b=1:d=!0;a.gb=b;b=a.Jb*a.gb;if(a.rb!=b){a.rb=b;b=a.rb.toFixed(2)+"Mhz";var e=a.G.setSpeed;e&&(e.textContent=b);a.i("target speed: "+b)}c&&a.C&&a.C.ub()}Tb(a,a.X);a.X=0;a.T=Ba();a.ba=0;Dd(a);return d}function Ic(a,b){var c=a.L.length;a.L.push([-1,b]);return c}function Kc(a,b,c,d){0<=b&&b<a.L.length&&(d||0>a.L[b][0])&&(c=a.pb*a.gb/1E3*c|0,a.A.W&&(c+=Ed(a)),a.L[b][0]=c)}
|
||||
!0;case "speed":return this.G[b]=c,!0;case "setSpeed":return this.G[b]=c,c.onclick=function(){Cd(d,d.gb<<1,!0)},c.textContent=this.sb.toFixed(2)+"Mhz",!0}return!1};k.ra=function(a){this.C&&this.C.ra(a)};function Tb(a,b,c){a.ja+=b;c&&(a.ca=a.b=a.I=0)}function Dd(a,b){var c=1;b&&1<a.gb&&a.xa&&(c=a.xa/a.Kb);a.Gc=Math.round(1E3/30);a.qb=Math.floor(a.pb/30*c);b||(a.Ba=a.qb);a.Lb=0}function Bd(a){return a.ja+a.X+a.ca-a.b}function xd(a){a.xa=0;a.Hc=0;a.ja=a.X=a.ca=a.b=a.I=0;yd(a);Cd(a,1)}
|
||||
function Cd(a,b,c){var d=!1;if(void 0!==b){.8>a.xa/a.sb?b=1:d=!0;a.gb=b;b=a.Kb*a.gb;if(a.sb!=b){a.sb=b;b=a.sb.toFixed(2)+"Mhz";var e=a.G.setSpeed;e&&(e.textContent=b);a.i("target speed: "+b)}c&&a.C&&a.C.vb()}Tb(a,a.X);a.X=0;a.T=Ba();a.ba=0;Dd(a);return d}function Ic(a,b){var c=a.L.length;a.L.push([-1,b]);return c}function Kc(a,b,c,d){0<=b&&b<a.L.length&&(d||0>a.L[b][0])&&(c=a.pb*a.gb/1E3*c|0,a.A.W&&(c+=Ed(a)),a.L[b][0]=c)}
|
||||
function Fd(a,b){for(var c=a.L.length-1;0<=c;c--){var d=a.L[c];0>d[0]||b>d[0]&&(b=d[0])}return b}function Sb(a,b){for(var c=a.L.length-1;0<=c;c--){var d=a.L[c];0>d[0]||(d[0]-=b,0>=d[0]&&(d[0]=-1,d[1]()))}}function Ed(a,b){var c=a.ca-=a.b;a.b=a.I=0;b&&(a.ca=0);return c}
|
||||
k.ge=function(){if(this.A.W){this.Kb>=this.pb&&Dd(this,!0);this.Va=0;this.nb=Ba();if(this.ba){var a=this.nb-this.ba;a>this.Dc&&(this.T+=a,this.T>this.nb&&(this.T=this.nb))}try{do{var b=Fd(this,this.A.yb?1:this.qb);try{this.kb(b)}catch(e){if("number"!=typeof e)throw e;}b=Ed(this,!0);this.Va+=b;this.X+=b;Ub(this,b);Sb(this,b);this.Ba-=b;if(0>=this.Ba){this.Ba+=this.qb;15<=++this.Fc&&(this.ra(),this.Fc=0);break}}while(this.A.W)}catch(e){this.da();this.C&&this.C.stop(Ba(),Bd(this));zb(this,e.stack||e.message);
|
||||
return}if(this.A.W){a=setTimeout;b=this.Gc;this.ba=Ba();var c=this.Dc;this.Va&&(c=Math.round(c*this.Va/this.qb));var c=c-(this.ba-this.nb),d=this.ba-this.T;d&&(this.xa=Math.round(this.X/(10*d))/100,864E5<=d&&(this.ja=0,Cd(this)));if(0>c||this.xa<this.rb)-1E3>c&&(this.T-=c),c=0;this.Kb+=this.Va;this.ba+=c;a(b,c)}}};
|
||||
k.jb=function(a){if(yb(this))return!1;if(this.A.W)return this.i(this.toString()+" busy"),!1;Cd(this);this.A.W=!0;this.A.bc=!0;var b=this.G.run;b&&(b.textContent="Halt");this.C&&(a&&this.C.ub(!0),this.C.start(this.T,Bd(this)));setTimeout(this.Gc,0);return!0};k.kb=function(){return 0};k.da=function(a){var b=!1;if(this.A.W){Ed(this);Tb(this,this.X);this.X=0;this.A.W=!1;if(b=this.G.run)b.textContent="Run";this.C&&this.C.stop(Ba(),Bd(this));b=!0}this.A.complete=a;return b};
|
||||
function Gd(a){this.fb=+a.model||1170;this.Bc=a.addrReset||0;ud.call(this,a,6666667);1120==this.fb?(this.decode=Hd.bind(this),this.na=this.Vc):(this.decode=Id.bind(this),this.na=this.Wc);Jd(this);this.K=0;this.O=null;this.A.complete=!1}A(Gd,ud);k=Gd.prototype;k.reset=function(){this.status("model "+this.fb);this.A.W&&this.da();Jd(this);xd(this);this.A.error=!1;this.parent.reset.call(this)};
|
||||
function Jd(a){a.U=65536;a.V=32768;a.$=65535;a.Z=32768;a.N=15;a.u=[0,0,0,0,0,0,0,a.Bc];a.$a=[0,0,0,0,0,0];a.La=[0,0,0,0];a.B=0;a.lb=0;a.cd=[4,2,0,1];a.P=[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];a.ha=[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];a.Sb=
|
||||
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];a.Kc=[0,0,0,0,0,0,0,0];a.Jc=0;a.J=0;a.D=a.H=0;a.g=a.f=a.Ib=0;a.Ca=-1;Rb(a)}function Rb(a){a.za=0;a.Lb=0;a.lc=0;a.Ta=0;a.va=0;a.Rb=0;a.hb=255;a.M=0;a.mb=0;a.Ma=262143;a.Mb=0;a.pa=0;a.O=null;a.v&&Kd(a)}function Kd(a){a.M?(a.S=65536,a.Ac=a.Ta&16?4186112:253952,a.aa=a.ad,a.ta=a.de,a.Ub=a.Xe,wc(a.v,a.Ta&16?22:18)):(a.S=0,a.Ac=57344,a.aa=a.$c,a.ta=a.Ic,a.Ub=a.Pc,wc(a.v,16))}
|
||||
function Wc(a){var b=a.za;b&57344||(b=b&-3199|a.mb<<5|a.lb<<1);return b}function Xc(a,b){b&=-3073;if(a.za!=b){b&57344&&!(a.za&57344)&&(a.Lb=a.pa>>16&65535,a.lc=a.pa&65535);a.za=b;a.mb=b>>5&3;a.lb=b>>1&15;var c=0;b&257&&(c=4,b&1&&(c|=2));a.M!=c&&(a.M=c,Kd(a))}}function Yc(a){a.za&57344||(a.Lb=a.pa>>16&65535);a=a.Lb;a&65280&&(a=(a<<8|a>>8)&65535);return a}function Zc(a){a.za&57344||(a.lc=a.pa&65535);return a.lc}function $c(a,b){1170>a.fb&&(b&=-49);a.Ta!=b&&(a.Ta=b,a.Ma=b&16?4194303:262143,Kd(a))}
|
||||
k.wc=function(){return 0};k.save=function(){var a=new Q(this);a.set(0,[]);a.set(1,[this.ja,this.gb]);a.set(2,Fc(this.v));return a.data()};k.restore=function(a){var b=a[1];this.ja=b[1];Cd(this,b[3]);a:{b=this.v;a=a[2];var c;for(c=0;c<a.length-1;c+=2){var d=a[c],e=a[c+1];if(e&&e.length<b.I){for(var f=0,g=Array(b.I),h=0;h<e.length-1;)for(var l=e[h++],m=e[h++];l--;)g[f++]=m;e=g}f=b.Y[d];if(!f||!f.restore(e)){u("Unable to restore memory block "+d);b=!1;break a}}b=!0}return b};
|
||||
function Ld(a){return a.U&65536?1:0}function Md(a){return a.V&32768?2:0}function Nd(a){return a.$&65535?0:4}function Od(a){return a.Z&32768?8:0}function Pd(a){var b=a.u[7];a.pa=b;var c=a.ta(b);a.u[7]=b+2&65535;return c}function Qd(a,b){var c=a.u[7];a.u[7]=c+b&65535;return c}function R(a,b){a.u[7]=b&65535}function Lc(a,b){return{je:a,Cb:b,next:null}}function Rd(a,b){var c=a.O;if(c==b)a.O=b.next;else for(;c;){a=c.next;if(a==b){c.next=a.next;break}c=a}}
|
||||
k.ge=function(){if(this.A.W){this.Lb>=this.pb&&Dd(this,!0);this.Va=0;this.nb=Ba();if(this.ba){var a=this.nb-this.ba;a>this.Gc&&(this.T+=a,this.T>this.nb&&(this.T=this.nb))}try{do{var b=Fd(this,this.A.zb?1:this.qb);try{this.kb(b)}catch(e){if("number"!=typeof e)throw e;}b=Ed(this,!0);this.Va+=b;this.X+=b;Ub(this,b);Sb(this,b);this.Ba-=b;if(0>=this.Ba){this.Ba+=this.qb;15<=++this.Hc&&(this.ra(),this.Hc=0);break}}while(this.A.W)}catch(e){this.da();this.C&&this.C.stop(Ba(),Bd(this));zb(this,e.stack||e.message);
|
||||
return}if(this.A.W){a=setTimeout;b=this.Ic;this.ba=Ba();var c=this.Gc;this.Va&&(c=Math.round(c*this.Va/this.qb));var c=c-(this.ba-this.nb),d=this.ba-this.T;d&&(this.xa=Math.round(this.X/(10*d))/100,864E5<=d&&(this.ja=0,Cd(this)));if(0>c||this.xa<this.sb)-1E3>c&&(this.T-=c),c=0;this.Lb+=this.Va;this.ba+=c;a(b,c)}}};
|
||||
k.jb=function(a){if(yb(this))return!1;if(this.A.W)return this.i(this.toString()+" busy"),!1;Cd(this);this.A.W=!0;this.A.bc=!0;var b=this.G.run;b&&(b.textContent="Halt");this.C&&(a&&this.C.vb(!0),this.C.start(this.T,Bd(this)));setTimeout(this.Ic,0);return!0};k.kb=function(){return 0};k.da=function(a){var b=!1;if(this.A.W){Ed(this);Tb(this,this.X);this.X=0;this.A.W=!1;if(b=this.G.run)b.textContent="Run";this.C&&this.C.stop(Ba(),Bd(this));b=!0}this.A.complete=a;return b};
|
||||
function Gd(a){this.fb=+a.model||1170;this.Cc=a.addrReset||0;ud.call(this,a,6666667);this.rb=0;this.Fc=255;1120==this.fb?(this.decode=Hd.bind(this),this.na=this.Xc,this.rb=8,this.Fc=-1):(this.decode=Id.bind(this),this.na=this.Yc);Jd(this);this.K=0;this.O=null;this.A.complete=!1}A(Gd,ud);k=Gd.prototype;k.reset=function(){this.status("model "+this.fb);this.A.W&&this.da();Jd(this);xd(this);this.A.error=!1;this.parent.reset.call(this)};
|
||||
function Jd(a){a.U=65536;a.V=32768;a.$=65535;a.Z=32768;a.N=15;a.u=[0,0,0,0,0,0,0,a.Cc,-1,-2,-3,-4,-5,-6,-7,-8];a.$a=[0,0,0,0,0,0];a.La=[0,0,0,0];a.B=0;a.lb=0;a.od=[4,2,0,1];a.P=[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];a.ha=[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0]];a.Sb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];a.Mc=[0,0,0,0,0,0,0,0];a.Lc=0;a.J=0;a.D=a.H=0;a.g=a.f=a.Jb=0;a.Ca=-1;Rb(a)}function Rb(a){a.za=0;a.lc=0;a.mc=0;a.Ta=0;a.va=0;a.Rb=0;a.hb=255;a.M=0;a.mb=0;a.Ma=262143;a.Mb=0;a.pa=0;a.O=null;a.v&&Kd(a)}function Kd(a){a.M?(a.S=65536,a.Bc=a.Ta&16?4186112:253952,a.aa=a.cd,a.ta=a.de,a.Ub=a.Ze,wc(a.v,a.Ta&16?22:18)):(a.S=0,a.Bc=57344,a.aa=a.bd,a.ta=a.Kc,a.Ub=a.Rc,wc(a.v,16))}
|
||||
function Wc(a){var b=a.za;b&57344||(b=b&-3199|a.mb<<5|a.lb<<1);return b}function Xc(a,b){b&=-3073;if(a.za!=b){b&57344&&!(a.za&57344)&&(a.lc=a.pa>>16&65535,a.mc=a.pa&65535);a.za=b;a.mb=b>>5&3;a.lb=b>>1&15;var c=0;b&257&&(c=4,b&1&&(c|=2));a.M!=c&&(a.M=c,Kd(a))}}function Yc(a){a.za&57344||(a.lc=a.pa>>16&65535);a=a.lc;a&65280&&(a=(a<<8|a>>8)&65535);return a}function Zc(a){a.za&57344||(a.mc=a.pa&65535);return a.mc}function $c(a,b){1170>a.fb&&(b&=-49);a.Ta!=b&&(a.Ta=b,a.Ma=b&16?4194303:262143,Kd(a))}
|
||||
k.xc=function(){return 0};k.save=function(){var a=new Q(this);a.set(0,[]);a.set(1,[this.ja,this.gb]);a.set(2,Fc(this.v));return a.data()};k.restore=function(a){var b=a[1];this.ja=b[1];Cd(this,b[3]);a:{b=this.v;a=a[2];var c;for(c=0;c<a.length-1;c+=2){var d=a[c],e=a[c+1];if(e&&e.length<b.I){for(var f=0,g=Array(b.I),h=0;h<e.length-1;)for(var l=e[h++],m=e[h++];l--;)g[f++]=m;e=g}f=b.Y[d];if(!f||!f.restore(e)){u("Unable to restore memory block "+d);b=!1;break a}}b=!0}return b};
|
||||
function Ld(a){return a.U&65536?1:0}function Md(a){return a.V&32768?2:0}function Nd(a){return a.$&65535?0:4}function Od(a){return a.Z&32768?8:0}function Pd(a){var b=a.u[7];a.pa=b;var c=a.ta(b);a.u[7]=b+2&65535;return c}function Qd(a,b){var c=a.u[7];a.u[7]=c+b&65535;return c}function R(a,b){a.u[7]=b&65535}function Lc(a,b){return{le:a,Cb:b,next:null}}function Rd(a,b){var c=a.O;if(c==b)a.O=b.next;else for(;c;){a=c.next;if(a==b){c.next=a.next;break}c=a}}
|
||||
function Jc(a,b){if(b!=a.O){var c=a.O;if(!c||c.Cb<=b.Cb)b.next=c,a.O=b;else{do{var d=c.next;if(!d||d.Cb<=b.Cb){b.next=d;c.next=b;break}c=d}while(c)}}a.J|=1}function me(a){return a.J&64?(a.qa(168,64,-5),!0):a.J&32?(a.qa(4,32,-4),!0):a.J&16?(a.qa(12,16,-6),!0):!1}function bd(a){return a.N=a.N&63728|Od(a)|Nd(a)|Md(a)|Ld(a)}
|
||||
function cd(a,b){a.Z=b<<12;a.$=~b&4;a.V=b<<14;a.U=b<<16;if((b^a.N)&2048)for(var c=a.$a.length;0<=--c;){var d=a.u[c];a.u[c]=a.$a[c];a.$a[c]=d}a.B=b>>14&3;c=a.N>>14&3;a.B!=c&&(a.La[c]=a.u[6],a.u[6]=a.La[a.B]);a.N=b;a.J|=2}function ad(a,b){if(b&=65024){var c=b>>9;do b+=34;while(c>>=1)}a.Rb=b;a.J|=2}function S(a,b){a.J&128||(a.Z=a.$=b,a.V=0)}function ne(a,b,c){a.J&128||(a.Z=a.$=a.U=b,a.V=c||0)}function oe(a,b,c,d){a.J&128||(a.Z=a.$=a.U=b,a.V=(c^b)&(d^b))}
|
||||
function pe(a,b){a.J&128||(a.Z=a.$=a.U=b,a.V=a.Z^a.U>>1)}function qe(a,b,c,d){a.J&128||(a.Z=a.$=a.U=b,a.V=(c^d)&(d^b))}k.qa=function(a,b,c){if(!this.K){0>this.Ca?this.Ca=bd(this):this.B||(c=-3);var d=!1;-3==c&&(a=4,this.va|=4,this.u[6]=4,d=!0);this.pa=a|4143316992;this.B=0;var e=this.ta(a|this.S),f=this.ta(a+2&65535|this.S);cd(this,f&-12289|this.Ca>>2&12288);re(this,this.Ca,d);re(this,this.u[7],d);R(this,e);this.J&=~(b|18);this.J|=9;this.Ca=-1;this.he=a;this.od=c;if(-3<=c)throw a;}};
|
||||
function pe(a,b){a.J&128||(a.Z=a.$=a.U=b,a.V=a.Z^a.U>>1)}function qe(a,b,c,d){a.J&128||(a.Z=a.$=a.U=b,a.V=(c^d)&(d^b))}k.qa=function(a,b,c){if(!this.K){0>this.Ca?this.Ca=bd(this):this.B||(c=-3);var d=!1;-3==c&&(a=4,this.va|=4,this.u[6]=4,d=!0);this.pa=a|4143316992;this.B=0;var e=this.ta(a|this.S),f=this.ta(a+2&65535|this.S);cd(this,f&-12289|this.Ca>>2&12288);re(this,this.Ca,d);re(this,this.u[7],d);R(this,e);this.J&=~(b|18);this.J|=9;this.Ca=-1;this.ke=a;this.ie=c;if(-3<=c)throw a;}};
|
||||
function se(a){var b=te(a),c=te(a)&-1793;a.N&49152&&(c=c&-225|a.N&63712);R(a,b);cd(a,c);a.J&=-17}function Ec(a,b){var c=b>>13&31;31>c&&(b=a.Ta&32?a.Sb[c]+(b&8190)&4194302:b&-3932161);return b}
|
||||
function ue(a,b,c){var d,e,f;if(!(c&a.M))return f=b&65535,57344<=f&&(f|=a.Ac),f;d=b>>13;a.Ta&a.cd[a.B]||(d&=7);e=a.P[a.B][d];f=(a.ha[a.B][d]<<6)+(b&8191)&a.Ma;if(a.K)return f;f&1&&!(c&1)&&(a.va|=64,a.qa(4,0,f));var g=0;switch(e&7){case 1:g=4096;case 2:e|=128;c&4&&(g=8192);break;case 4:g=4096;case 5:c&4&&(g=4096);case 6:e|=c&4?192:128;break;default:g=32768}32512!=(e&32520)&&(e&8?e&32512&&(b&8128)<(e>>2&8128)&&(g|=16384):(b&8128)>(e>>2&8128)&&(g|=16384));a.P[a.B][d]=e;if(f!=(4194170&a.Ma)||a.B)a.mb=
|
||||
function ue(a,b,c){var d,e,f;if(!(c&a.M))return f=b&65535,57344<=f&&(f|=a.Bc),f;d=b>>13;a.Ta&a.od[a.B]||(d&=7);e=a.P[a.B][d];f=(a.ha[a.B][d]<<6)+(b&8191)&a.Ma;if(a.K)return f;f&1&&!(c&1)&&(a.va|=64,a.qa(4,0,f));var g=0;switch(e&7){case 1:g=4096;case 2:e|=128;c&4&&(g=8192);break;case 4:g=4096;case 5:c&4&&(g=4096);case 6:e|=c&4?192:128;break;default:g=32768}32512!=(e&32520)&&(e&8?e&32512&&(b&8128)<(e>>2&8128)&&(g|=16384):(b&8128)>(e>>2&8128)&&(g|=16384));a.P[a.B][d]=e;if(f!=(4194170&a.Ma)||a.B)a.mb=
|
||||
a.B,a.lb=d;g&&(g&57344&&(0<=a.Ca&&(g|=128),a.za&57344||(g|=a.za&4096|a.mb<<5|a.lb<<1,Xc(a,a.za&-61695|g&61694)),a.qa(168,64,-1)),a.za&61440||!(f<(4191360&a.Ma)||f>(4194239&a.Ma))||(a.za|=4096,a.za&512&&(a.J|=64)));return f}function ve(a,b){return a.v.Yb(b)}function te(a){var b=a.ta(a.u[6]|a.S);a.u[6]=a.u[6]+2&65535;return b}function re(a,b,c){var d=a.u[6]-2&65535;a.u[6]=d;a.pa=a.pa&65535|(a.pa&-65536)<<8|16121856;c||a.na(4,-2,d);a.Ub(d,b)}
|
||||
function we(a,b,c,d){var e,f,g=d&8?0:a.S;switch(b){case 0:return a.qa(4,0,-2),0;case 1:return 6==c&&a.na(d,0,a.u[6]),a.b-=3,7==c?a.u[c]:a.u[c]|g;case 2:f=2;e=a.u[c];6==c&&a.na(d,f,e);7!=c&&(e|=g,6>c&&d&1&&(f=1));a.b-=3;break;case 3:f=2;e=a.u[c];7!=c&&(e|=g);e=a.ta(e);e|=g;a.b-=7;break;case 4:f=-2;6>c&&d&1&&(f=-1);e=a.u[c]+f&65535;6==c&&a.na(d,f,e);7!=c&&(e|=g);a.b-=4;break;case 5:f=-2;e=a.u[c]-2&65535;7!=c&&(e|=g);e=a.ta(e)|g;a.b-=8;break;case 6:return e=a.ta(Qd(a,2)),e=e+a.u[c]&65535,6==c&&a.na(d,
|
||||
0,e),a.b-=6,e|g;case 7:return e=a.ta(Qd(a,2)),e=e+a.u[c]&65535,e=a.ta(e|a.S),a.b-=10,e|g}a.u[c]=a.u[c]+f&65535;a.pa=a.pa&65535|(a.pa&-65536)<<8|(f<<3&248|c)<<16;return e}k.Vc=function(a,b,c){!this.B&&0>=b&&c<=this.hb&&(this.J|=32)};k.Wc=function(a,b,c){!this.B&&a&4&&c<=this.hb&&(c<=this.hb-32?this.qa(4,0,-3):(this.va|=8,this.J|=32))};k.Zb=function(a){if(!this.M)return this.v.Zb(a);this.K++;a=ve(this,ue(this,a,3));this.K--;return a};
|
||||
k.Ya=function(a){if(!this.M)return this.v.Ya(a);this.K++;a=this.Ic(ue(this,a,2));this.K--;return a};k.tb=function(a,b){this.M?(this.K++,a=ue(this,a,5),a&1&&this.b--,this.v.Fb(a,b),this.K--):this.v.tb(a,b)};k.wb=function(a,b){this.M?(this.K++,this.Pc(ue(this,a,4),b),this.K--):this.v.wb(a,b)};k.$c=function(a,b,c){return we(this,a,b,c)};k.ad=function(a,b,c){return ue(this,we(this,a,b,c),c)};k.Ic=function(a){return this.v.oa(this.Mb=a)};k.de=function(a){return this.v.oa(this.Mb=ue(this,a,2))};
|
||||
k.Pc=function(a,b){this.v.vb(this.Mb=a,b&65535)};k.Xe=function(a,b){this.v.vb(this.Mb=ue(this,a,4),b)};function xe(a,b,c){var d=a.f=b&7;(b=a.g=(b&56)>>3)?(d=we(a,b,d,2),c&65536||61440!==(a.N&61440)&&(d&=65535),a.B=a.N>>12&3,c=a.ta(d|c&a.S),a.B=a.N>>14&3):c=6!=d||(a.N>>2&12288)===(a.N&12288)?a.u[d]:a.La[a.N>>12&3];return c}
|
||||
function ye(a,b,c,d){a.pa=a.pa&65535|1441792;var e=a.f=b&7;(b=a.g=(b&56)>>3)?(e=we(a,b,e,4),c&65536||(e&=65535),a.B=a.N>>12&3,e=ue(a,e|c&65536,4),a.B=a.N>>14&3,a.v.vb(e,d)):6!=e||(a.N>>2&12288)===(a.N&12288)?a.u[e]=d:a.La[a.N>>12&3]=d}function ze(a,b){b>>=6;var c=a.H=b&7;return(b=a.D=(b&56)>>3)?ve(a,a.aa(b,c,3)):-c-1}function Ae(a,b){var c;b>>=6;var d=a.H=b&7;(b=a.D=(b&56)>>3)?c=a.v.oa(a.aa(b,d,2)):c=-d-1;return c}function Be(a,b){var c=a.f=b&7;b=a.g=(b&56)>>3;return we(a,b,c,8)}
|
||||
function Ce(a,b){var c=a.f=b&7;return(b=a.g=(b&56)>>3)?ve(a,a.aa(b,c,3)):a.u[c]&255}function De(a,b){var c=a.f=b&7;return(b=a.g=(b&56)>>3)?a.v.oa(a.aa(b,c,2)):a.u[c]}function T(a,b,c,d){var e=a.f=b&7;(b=a.g=(b&56)>>3)?(e=a.Ib=a.aa(b,e,7),c=0>c?a.u[-c-1]&255:c,c=d.call(a,c,ve(a,e)),e&1&&a.b--,a.v.Fb(e,c)):(b=a.u[e],c=0>c?a.u[-c-1]&255:c,a.u[e]=b&65280|d.call(a,c,b&255))}
|
||||
function U(a,b,c,d){var e=a.f=b&7;(b=a.g=(b&56)>>3)?(e=a.aa(b,e,6),a.v.vb(e,d.call(a,0>c?a.u[-c-1]:c,a.v.oa(e)))):a.u[e]=d.call(a,0>c?a.u[-c-1]:c,a.u[e])}function Ee(a,b,c,d){var e=a.f=b&7;(b=a.g=(b&56)>>3)?(d=a.aa(b,e,5),e=c=0>c?a.u[-c-1]&255:c,d&1&&a.b--,a.v.Fb(d,e)):c?(c=0>c?a.u[-c-1]&255:c,a.u[e]=a.u[e]&~d|c<<24>>24&d):a.u[e]&=~d;return c}function Fe(a,b,c){var d=a.f=b&7;(b=a.g=(b&56)>>3)?(d=a.aa(b,d,4),a.v.vb(d,c=0>c?a.u[-c-1]:c)):a.u[d]=c=0>c?a.u[-c-1]:c;return c}
|
||||
0,e),a.b-=6,e|g;case 7:return e=a.ta(Qd(a,2)),e=e+a.u[c]&65535,e=a.ta(e|a.S),a.b-=10,e|g}a.u[c]=a.u[c]+f&65535;a.pa=a.pa&65535|(a.pa&-65536)<<8|(f<<3&248|c)<<16;return e}k.Xc=function(a,b,c){!this.B&&0>=b&&c<=this.hb&&(this.J|=32)};k.Yc=function(a,b,c){!this.B&&a&4&&c<=this.hb&&(c<=this.hb-32?this.qa(4,0,-3):(this.va|=8,this.J|=32))};k.Zb=function(a){if(!this.M)return this.v.Zb(a);this.K++;a=ve(this,ue(this,a,3));this.K--;return a};
|
||||
k.Ya=function(a){if(!this.M)return this.v.Ya(a);this.K++;a=this.Kc(ue(this,a,2));this.K--;return a};k.ub=function(a,b){this.M?(this.K++,a=ue(this,a,5),a&1&&this.b--,this.v.Fb(a,b),this.K--):this.v.ub(a,b)};k.xb=function(a,b){this.M?(this.K++,this.Rc(ue(this,a,4),b),this.K--):this.v.xb(a,b)};k.bd=function(a,b,c){return we(this,a,b,c)};k.cd=function(a,b,c){return ue(this,we(this,a,b,c),c)};k.Kc=function(a){return this.v.oa(this.Mb=a)};k.de=function(a){return this.v.oa(this.Mb=ue(this,a,2))};
|
||||
k.Rc=function(a,b){this.v.wb(this.Mb=a,b&65535)};k.Ze=function(a,b){this.v.wb(this.Mb=ue(this,a,4),b)};function xe(a,b,c){var d=a.f=b&7;(b=a.g=(b&56)>>3)?(d=we(a,b,d,2),c&65536||61440!==(a.N&61440)&&(d&=65535),a.B=a.N>>12&3,c=a.ta(d|c&a.S),a.B=a.N>>14&3):c=6!=d||(a.N>>2&12288)===(a.N&12288)?a.u[d]:a.La[a.N>>12&3];return c}
|
||||
function ye(a,b,c,d){a.pa=a.pa&65535|1441792;var e=a.f=b&7;(b=a.g=(b&56)>>3)?(e=we(a,b,e,4),c&65536||(e&=65535),a.B=a.N>>12&3,e=ue(a,e|c&65536,4),a.B=a.N>>14&3,a.v.wb(e,d)):6!=e||(a.N>>2&12288)===(a.N&12288)?a.u[e]=d:a.La[a.N>>12&3]=d}function ze(a,b){b>>=6;var c=a.H=b&7;return(b=a.D=(b&56)>>3)?ve(a,a.aa(b,c,3)):a.u[c+a.rb]&a.Fc}function Ae(a,b){b>>=6;var c=a.H=b&7;return(b=a.D=(b&56)>>3)?a.v.oa(a.aa(b,c,2)):a.u[c+a.rb]}function Be(a,b){var c=a.f=b&7;b=a.g=(b&56)>>3;return we(a,b,c,8)}
|
||||
function Ce(a,b){var c=a.f=b&7;return(b=a.g=(b&56)>>3)?ve(a,a.aa(b,c,3)):a.u[c]&255}function De(a,b){var c=a.f=b&7;return(b=a.g=(b&56)>>3)?a.v.oa(a.aa(b,c,2)):a.u[c]}function T(a,b,c,d){var e=a.f=b&7;(b=a.g=(b&56)>>3)?(e=a.Jb=a.aa(b,e,7),c=0>c?a.u[-c-1]&255:c,c=d.call(a,c,ve(a,e)),e&1&&a.b--,a.v.Fb(e,c)):(b=a.u[e],c=0>c?a.u[-c-1]&255:c,a.u[e]=b&65280|d.call(a,c,b&255))}
|
||||
function U(a,b,c,d){var e=a.f=b&7;(b=a.g=(b&56)>>3)?(e=a.aa(b,e,6),a.v.wb(e,d.call(a,0>c?a.u[-c-1]:c,a.v.oa(e)))):a.u[e]=d.call(a,0>c?a.u[-c-1]:c,a.u[e])}function Ee(a,b,c,d){var e=a.f=b&7;(b=a.g=(b&56)>>3)?(d=a.aa(b,e,5),e=c=0>c?a.u[-c-1]&255:c,d&1&&a.b--,a.v.Fb(d,e)):c?(c=0>c?a.u[-c-1]&255:c,a.u[e]=a.u[e]&~d|c<<24>>24&d):a.u[e]&=~d;return c}function Fe(a,b,c){var d=a.f=b&7;(b=a.g=(b&56)>>3)?(d=a.aa(b,d,4),a.v.wb(d,c=0>c?a.u[-c-1]:c)):a.u[d]=c=0>c?a.u[-c-1]:c;return c}
|
||||
function V(a,b,c){c&&(R(a,a.u[7]+(b<<24>>23)),a.b-=2);a.b-=3}
|
||||
k.kb=function(a){this.A.complete=!0;var b=this.j?Ge(this.j)?1:this.A.bc?-1:0:0,c=a?this.A.bc?0:1:-1;this.A.bc=!1;this.ca=this.b=a;do{if(b){if(He(this.j,this.u[7],c)){this.da();break}c||c++;b++}if(this.J){if(a=this.J&7)if(a=!1,this.J&2){this.J&=-3;var d=160,e=(this.Rb&224)>>5,f=this.O&&this.O.Cb>e?this.O:null;f&&(d=f.je,e=f.Cb);e>(this.N&224)>>5?(this.J&4&&(Qd(this,2),this.J&=-5),this.qa(d,0,-9),e=!0):e=!1;e&&(f&&Rd(this,f),a=!0)}else this.J&1&&this.J++;if(a){if(b&&He(this.j,this.u[7],c)){this.da();
|
||||
k.kb=function(a){this.A.complete=!0;var b=this.j?Ge(this.j)?1:this.A.bc?-1:0:0,c=a?this.A.bc?0:1:-1;this.A.bc=!1;this.ca=this.b=a;do{if(b){if(He(this.j,this.u[7],c)){this.da();break}c||c++;b++}if(this.J){if(a=this.J&7)if(a=!1,this.J&2){this.J&=-3;var d=160,e=(this.Rb&224)>>5,f=this.O&&this.O.Cb>e?this.O:null;f&&(d=f.le,e=f.Cb);e>(this.N&224)>>5?(this.J&4&&(Qd(this,2),this.J&=-5),this.qa(d,0,-9),e=!0):e=!1;e&&(f&&Rd(this,f),a=!0)}else this.J&1&&this.J++;if(a){if(b&&He(this.j,this.u[7],c)){this.da();
|
||||
break}if(0>c)break}if(this.J&112&&me(this)){if(b&&He(this.j,this.u[7],c)){this.da();break}if(0>c)break}}this.J=this.J&7|this.N&16;this.decode(Pd(this))}while(0<this.b);return this.A.complete?this.ca-this.b:void 0===this.A.complete?0:-1};$a(function(){for(var a=E(document,"pdp11","cpu"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new Gd(d);D(d,c)}});function Ie(a,b){var c=b+a;oe(this,c,a,b);return c&65535}function Je(a,b){var c=b+a;oe(this,c<<8,a<<8,b<<8);return c&255}
|
||||
function Ke(a,b){a=b<<1;pe(this,a);return a&65535}function Le(a,b){a=b<<1;pe(this,a<<8);return a&255}function Me(a,b){a=b&32768|b>>1|b<<16;pe(this,a);return a&65535}function Ne(a,b){a=b&128|b>>1|b<<8;pe(this,a<<8);return a&255}function Oe(a,b){a=b&~a;S(this,a);return a}function Pe(a,b){a=b&~a;S(this,a<<8);return a}function Qe(a,b){a|=b;S(this,a);return a}function Re(a,b){a|=b;S(this,a<<8);return a}function Se(a,b){a=~b|65536;ne(this,a);return a&65535}
|
||||
function Te(a,b){a=~b|256;ne(this,a<<8);return a&255}function Ue(a,b){a=b-a;this.J&128||(this.Z=this.$=a,this.V=b&(b^a));return a&65535}function Ve(a,b){a=b-a;var c=a<<8;b<<=8;this.J&128||(this.Z=this.$=c,this.V=b&(b^c));return a&255}function We(a,b){a=b+a;this.J&128||(this.Z=this.$=a,this.V=a&(b^a));return a&65535}function Xe(a,b){a=b+a;var c=a<<8;this.J&128||(this.Z=this.$=c,this.V=c&(b<<8^c));return a&255}function Ye(a,b){a=-b;ne(this,a,a&b&32768);return a&65535}
|
||||
|
|
@ -153,34 +153,34 @@ function Mf(){this.N&49152?(this.va|=128,this.qa(4,0,-7)):(this.w&&1120==this.fb
|
|||
var Tf=[3,9,9,13,10,14,12,16,4,9,9,13,10,14,13,17];function Uf(a){var b=Ae(this,a);this.I=this.b;S(this,Fe(this,a,b));this.b=this.I-Tf[(this.D?8:0)+this.g]+(7!=this.f||this.g?0:2)}function Vf(a){var b=ze(this,a);S(this,Ee(this,a,b,65535)<<8);this.b-=this.g?9+(this.H&&6<=this.f?1:0):(this.D?5:3)+(7==this.f?2:0)}var Wf=[7,13,13,17,14,18,17,21];
|
||||
function Xf(a){var b=De(this,a);a=a>>6&7;b&32768&&(b|=-65536);var c=this.u[a];c&32768&&(c|=-65536);b=~~(b*c);this.u[a]=b>>16&65535;this.u[a|1]=b&65535;this.J&128||(this.Z=b>>16,this.$=this.Z|b,this.V=0,this.U=-32768>b||32767<b?65536:0);this.b-=23}function Yf(){this.b-=5}function Zf(){this.N&49152||(this.v.reset(),Rb(this),this.w&&this.w.setData(this.u[0],!0));this.b-=667}function $f(a){if(a&8)W.call(this,a);else{var b=te(this);a&=7;7==a?R(this,b):(R(this,this.u[a]),this.u[a]=b);this.b-=9}}
|
||||
function ag(){se(this);this.b-=13}function bg(a){a&1&&(this.U=65536);a&2&&(this.V=32768);a&4&&(this.$=0);a&8&&(this.Z=32768);this.b-=5}function cg(a){var b=(a&448)>>6;if(this.u[b]=this.u[b]-1&65535)R(this,this.u[7]-((a&63)<<1)),this.b+=1;this.b-=6}function dg(a){U(this,a,Ae(this,a),df);this.b-=this.g?9+(this.H&&6<=this.f?1:0):(this.D?5:3)+(7==this.f?2:0)}function eg(a){U(this,a,0,ff);this.b-=this.g?9:3+(7==this.f?2:0)}function fg(){this.qa(28,0,-8);this.b-=5}
|
||||
function gg(){this.w&&(this.w.oc(this.u[7],!0),this.w.setData(this.u[0],!0));this.J|=4;Qd(this,-2);this.b-=3}function hg(a){U(this,a,-(a>>6&7)-1,gf);this.b-=this.g?9:3+(7==this.f?2:0)}function W(a){var b;if(b=this.j)b=this.j,H(b,1)?(F(b,"undefined opcode "+K(b,a),!0,!0),b=Nf(b)):b=!1;b||this.qa(8,0,-8)}function Hd(a){ig[a>>12].call(this,a)}function jg(a){kg[a>>6&3].call(this,a)}function lg(a){mg[a>>6&3].call(this,a)}function ng(a){og[a>>6&3].call(this,a)}function pg(a){qg[a&15].call(this,a)}
|
||||
function rg(a){sg[a&15].call(this,a)}function tg(a){ug[a>>6&3].call(this,a)}function vg(a){wg[a>>6&3].call(this,a)}function xg(a){yg[a>>6&3].call(this,a)}
|
||||
function gg(){this.w&&(this.w.pc(this.u[7],!0),this.w.setData(this.u[0],!0));this.J|=4;Qd(this,-2);this.b-=3}function hg(a){U(this,a,this.u[(a>>6&7)+this.rb],gf);this.b-=this.g?9:3+(7==this.f?2:0)}function W(a){var b;if(b=this.j)b=this.j,H(b,1)?(F(b,"undefined opcode "+K(b,a),!0,!0),b=Nf(b)):b=!1;b||this.qa(8,0,-8)}function Hd(a){ig[a>>12].call(this,a)}function jg(a){kg[a>>6&3].call(this,a)}function lg(a){mg[a>>6&3].call(this,a)}function ng(a){og[a>>6&3].call(this,a)}
|
||||
function pg(a){qg[a&15].call(this,a)}function rg(a){sg[a&15].call(this,a)}function tg(a){ug[a>>6&3].call(this,a)}function vg(a){wg[a>>6&3].call(this,a)}function xg(a){yg[a>>6&3].call(this,a)}
|
||||
var ig=[function(a){zg[a>>8&15].call(this,a)},Uf,If,rf,nf,pf,hf,W,function(a){Ag[a>>8&15].call(this,a)},Vf,Jf,sf,of,qf,dg,W],zg=[function(a){Bg[a>>4&15].call(this,a)},Ef,Bf,tf,uf,zf,vf,xf,Sf,Sf,jg,lg,ng,W,W,W],kg=[function(a){ne(this,Fe(this,a,0));this.b-=this.g?9:3+(7==this.f?2:0)},function(a){U(this,a,0,Se);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){U(this,a,1,We);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){U(this,a,1,Ue);this.b-=this.g?9:3+(7==this.f?2:0)}],mg=[function(a){U(this,a,0,
|
||||
Ye);this.b-=this.g?11:6},function(a){U(this,a,Ld(this)?1:0,Ie);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){U(this,a,Ld(this)?1:0,df);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){a=De(this,a);ne(this,a);this.b-=this.g?4:3+(7==this.f?2:0)}],og=[function(a){U(this,a,0,bf);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){U(this,a,0,$e);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){U(this,a,0,Me);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){U(this,a,0,Ke);this.b-=this.g?9:3+(7==this.f?2:0)}],
|
||||
Bg=[function(a){Cg[a&15].call(this,a)},W,W,W,Qf,Qf,Qf,Qf,$f,W,pg,rg,eg,eg,eg,eg],Cg=[Mf,gg,ag,Df,Of,Zf,W,W,W,W,W,W,W,W,W,W],qg=[Yf,function(){this.U=0;this.b-=5},function(){this.V=0;this.b-=5},Hf,function(){this.$=1;this.b-=5},Hf,Hf,Hf,function(){this.Z=0;this.b-=5},Hf,Hf,Hf,Hf,Hf,Hf,Hf],sg=[Yf,function(){this.U=65536;this.b-=5},function(){this.V=32768;this.b-=5},bg,function(){this.$=0;this.b-=5},bg,bg,bg,function(){this.Z=32768;this.b-=5},bg,bg,bg,bg,bg,bg,bg],Ag=[Cf,Af,wf,yf,Ff,Gf,lf,mf,Lf,fg,tg,
|
||||
vg,xg,W,W,W],ug=[function(a){ne(this,Ee(this,a,0,255));this.b-=this.g?9:3+(7==this.f?2:0)},function(a){T(this,a,0,Te);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){T(this,a,1,Xe);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){T(this,a,1,Ve);this.b-=this.g?9:3+(7==this.f?2:0)}],wg=[function(a){T(this,a,0,Ze);this.b-=this.g?11:6},function(a){T(this,a,Ld(this)?1:0,Je);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){T(this,a,Ld(this)?1:0,ef);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){a=Ce(this,
|
||||
a);ne(this,a<<8);this.b-=this.g?4:3+(7==this.f?2:0)}],yg=[function(a){T(this,a,0,cf);this.b-=this.g?9+(this.Ib&1):3+(7==this.f?2:0)},function(a){T(this,a,0,af);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){T(this,a,0,Ne);this.b-=this.g?9+(this.Ib&1):3+(7==this.f?2:0)},function(a){T(this,a,0,Le);this.b-=this.g?9:3+(7==this.f?2:0)}];function Id(a){Dg[a>>12].call(this,a)}
|
||||
a);ne(this,a<<8);this.b-=this.g?4:3+(7==this.f?2:0)}],yg=[function(a){T(this,a,0,cf);this.b-=this.g?9+(this.Jb&1):3+(7==this.f?2:0)},function(a){T(this,a,0,af);this.b-=this.g?9:3+(7==this.f?2:0)},function(a){T(this,a,0,Ne);this.b-=this.g?9+(this.Jb&1):3+(7==this.f?2:0)},function(a){T(this,a,0,Le);this.b-=this.g?9:3+(7==this.f?2:0)}];function Id(a){Dg[a>>12].call(this,a)}
|
||||
var Dg=[function(a){Eg[a>>8&15].call(this,a)},Uf,If,rf,nf,pf,hf,function(a){Fg[a>>8&15].call(this,a)},function(a){Gg[a>>8&15].call(this,a)},Vf,Jf,sf,of,qf,dg,W],Eg=[function(a){Hg[a>>4&15].call(this,a)},Ef,Bf,tf,uf,zf,vf,xf,Sf,Sf,jg,lg,ng,function(a){Ig[a>>6&3].call(this,a)},W,W],Ig=[function(a){a=this.u[7]+((a&63)<<1)&65535;var b=this.ta(a|this.S);R(this,this.u[5]);this.u[6]=a+2&65535;this.u[5]=b;this.b-=8},function(a){a=xe(this,a,0);re(this,a);S(this,a);this.b-=11},function(a){var b=te(this);this.I=
|
||||
this.b;ye(this,a,0,b);S(this,b);this.b=this.I-Wf[this.g]},function(a){S(this,Fe(this,a,Od(this)?65535:0));this.b-=this.g?9:3+(7==this.f?2:0)}],Hg=[function(a){Jg[a&15].call(this,a)},W,W,W,Qf,Qf,Qf,Qf,$f,function(a){a&8?(this.N&49152||(this.N=this.N&-2017|(a&7)<<5,this.J|=1),this.b-=5):W.call(this,a)},pg,rg,eg,eg,eg,eg],Jg=[Mf,gg,function(){se(this);this.J|=this.N&16;this.b-=13},Df,Of,Zf,ag,function(){this.qa(8,0,-8)},W,W,W,W,W,W,W,W],Fg=[Xf,Xf,Kf,Kf,jf,jf,kf,kf,hg,hg,W,W,W,W,cg,cg],Gg=[Cf,Af,wf,yf,
|
||||
Ff,Gf,lf,mf,Lf,fg,tg,vg,xg,function(a){Kg[a>>6&3].call(this,a)},W,W],Kg=[W,function(a){a=xe(this,a,65536);re(this,a);S(this,a);this.b-=11},function(a){var b=te(this);this.I=this.b;ye(this,a,65536,b);S(this,b);this.b=this.I-Wf[this.g]},W];
|
||||
function Lg(a){w.call(this,"ROM",a,Lg,512);this.ga=this.g=null;this.B=a.addr;this.f=a.size;this.D=!1;this.w=a.alias;this.C=a.file;this.H=oa(this.C);if(this.C){a=this.C;var b=ta(this.H);"json"!=b&&"hex"!=b&&(a=Fa()+"/api/v1/dump?file="+this.C+"&format=bytes&decimal=true");var c=this;Da(a,null,!0,function(a,b,f){f?(c.R("Unable to load ROM resource (error "+f+": "+a+")"),c.C=null):(kb(c.Ua,a,b),(a=Ea(a,b))?(c.g=a.ea,c.ga=a.ga):c.C=null);eh(c)})}}A(Lg);k=Lg.prototype;
|
||||
k.Ia=function(a,b,c,d){this.v=b;this.b=c;this.j=d;eh(this)};k.Ka=function(){this.ga&&(this.j&&fh(this.j,this.id,this.B,this.f,this.ga),delete this.ga);return!0};k.Ja=function(){return!0};
|
||||
function eh(a){if(!xb(a)){if(a.C){if(!a.g||!a.v)return;a.f||(a.f=a.g.length);if(a.g.length!=a.f)zb(a,"ROM size ("+p(a.g.length,8,!0)+") does not match specified size ("+p(a.f,8,!0)+")");else{var b;a:{b=a.B;a.status(a.f+"-byte ROM at "+na(b));if(57344<=b&&b<57344+pc){var c={};b=(c[b]=[Lg.prototype.Sd,Lg.prototype.Le,null,null,null,a.f>>1],c);if(Ib(a.v,a,b)){b=a.D=!0;break a}}else if(zc(a.v,b,a.f,jd)){for(c=0;c<a.g.length;c++)a.v.tb(b+c,a.g[c]);b=!0;break a}b=!1}if(b){b=[];"number"==typeof a.w?b.push(a.w):
|
||||
null!=a.w&&a.w.length&&(b=a.w);for(c=0;c<b.length;c++){var d=a,e=b[c],f=yc(d.v,d.B,d.f);xc(d.v,e,d.f,f)}a.D||delete a.g}}}I(a)}}k.Sd=function(a){return this.g[a-this.B]};k.Le=function(){};$a(function(){for(var a=E(document,"pdp11","rom"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new Lg(d);D(d,c)}});
|
||||
function eh(a){if(!xb(a)){if(a.C){if(!a.g||!a.v)return;a.f||(a.f=a.g.length);if(a.g.length!=a.f)zb(a,"ROM size ("+p(a.g.length,8,!0)+") does not match specified size ("+p(a.f,8,!0)+")");else{var b;a:{b=a.B;a.status(a.f+"-byte ROM at "+na(b));if(57344<=b&&b<57344+pc){var c={};b=(c[b]=[Lg.prototype.Sd,Lg.prototype.Ne,null,null,null,a.f>>1],c);if(Ib(a.v,a,b)){b=a.D=!0;break a}}else if(zc(a.v,b,a.f,jd)){for(c=0;c<a.g.length;c++)a.v.ub(b+c,a.g[c]);b=!0;break a}b=!1}if(b){b=[];"number"==typeof a.w?b.push(a.w):
|
||||
null!=a.w&&a.w.length&&(b=a.w);for(c=0;c<b.length;c++){var d=a,e=b[c],f=yc(d.v,d.B,d.f);xc(d.v,e,d.f,f)}a.D||delete a.g}}}I(a)}}k.Sd=function(a){return this.g[a-this.B]};k.Ne=function(){};$a(function(){for(var a=E(document,"pdp11","rom"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new Lg(d);D(d,c)}});
|
||||
function gh(a){w.call(this,"RAM",a,gh);this.ga=this.g=null;this.C=a.addr;this.B=a.size;this.Oa=a.load;this.Na=a.exec;this.w=!1;this.f=a.file;this.D=oa(this.f);if(this.f){a=this.f;var b=ta(this.D);"json"!=b&&"hex"!=b&&(a=Fa()+"/api/v1/dump?file="+this.f+"&format=bytes&decimal=true");var c=this;Da(a,null,!0,function(a,b,f){f?(c.R("Unable to load RAM resource (error "+f+": "+a+")"),c.f=null):(kb(c.Ua,a,b),(a=Ea(a,b))?(c.g=a.ea,c.ga=a.ga,null==c.Oa&&(c.Oa=a.Oa),null==c.Na&&(c.Na=a.Na)):c.f=null);hh(c)})}}
|
||||
A(gh);gh.prototype.Ia=function(a,b,c,d){this.v=b;this.b=c;this.j=d;hh(this)};gh.prototype.Ka=function(){this.ga&&(this.j&&fh(this.j,this.id,this.C,this.B,this.ga),delete this.ga);return!0};gh.prototype.Ja=function(){return!0};function hh(a){if(a.v&&(!a.w&&a.B&&zc(a.v,a.C,a.B,Cc)&&(a.w=!0),!xb(a))){if(!a.w)u("No RAM allocated");else if(a.f){if(!a.g||!a.v)return;ih(a,a.g,a.Oa,a.Na,a.C)}I(a)}}
|
||||
gh.prototype.reset=function(){if(this.w){for(var a=this.v,b=this.C,c=this.B,d=b&a.v,b=b>>>a.ka;0<c&&b<a.Y.length;){var e=a.Y[b];if(e.controller&&a.g&&a.g.length==a.w.length){var f=a.g.indexOf(e);0<=f&&(e=a.w[f])}if(e){var f=c,g=0,h,d=d||0,g=g&255;void 0===f&&(f=e.size);if(Ab&&e.G)for(h=d;f--&&h<e.G.length;h++)e.G[h]=g;else for(h=d;f--&&h<e.size;h++)e.dc(d,g,e.F+d)}c-=a.Da;b++;d=0}this.g&&ih(this,this.g,this.Oa,this.Na,this.C,!0)}};
|
||||
function ih(a,b,c,d,e,f){var g=!1;if(null==c)for(var h=0;h<b.length-1;){var l=b[h]&255|(b[h+1]&255)<<8;if(l)if(l&255){var m=h;if(1!=l){F(a,"invalid signature ("+q(l)+") at offset "+q(m),1048576);break}if(h+6>=b.length){F(a,"invalid block at offset "+q(m),1048576);break}for(var h=h+2,n=b[h++]&255|(b[h++]&255)<<8,r=b[h++]&255|(b[h++]&255)<<8,l=l+((n&255)+(n>>8)+(r&255)+(r>>8)),t=h,v=n-=6;0<n&&h<b.length;)l+=b[h++]&255,n--;if(n||h>=b.length){F(a,"insufficient data for block at offset "+q(m),1048576);
|
||||
break}l+=b[h++]&255;if(l&255){F(a,"invalid checksum ("+p(l,2,!0)+") for block at offset "+q(m),1048576);break}if(v)for(F(a,"loading "+q(v)+" bytes at "+q(r)+"-"+q(r+v-1),1048576);v--;)a.b.tb(r++,b[t++]&255);else r&1?a.b.da():null==d&&(d=r),null!=d&&F(a,"starting address: "+q(d),1048576);g=!0}else h++;else h+=2}if(!g&&(null==c&&(c=e),null!=c)){for(g=0;g<b.length;g++)a.b.tb(c+g,b[g]);g=!0}g&&null!=d&&(a=a.b,a.Bc=d,a.v.reset(),Rb(a),R(a,d),cd(a,0),!f&&a.j&&(a.da()||zd(a.j)));return g}
|
||||
break}l+=b[h++]&255;if(l&255){F(a,"invalid checksum ("+p(l,2,!0)+") for block at offset "+q(m),1048576);break}if(v)for(F(a,"loading "+q(v)+" bytes at "+q(r)+"-"+q(r+v-1),1048576);v--;)a.b.ub(r++,b[t++]&255);else r&1?a.b.da():null==d&&(d=r),null!=d&&F(a,"starting address: "+q(d),1048576);g=!0}else h++;else h+=2}if(!g&&(null==c&&(c=e),null!=c)){for(g=0;g<b.length;g++)a.b.ub(c+g,b[g]);g=!0}g&&null!=d&&(a=a.b,a.Cc=d,a.v.reset(),Rb(a),R(a,d),cd(a,0),!f&&a.j&&(a.da()||zd(a.j)));return g}
|
||||
$a(function(){for(var a=E(document,"pdp11","ram"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new gh(d);D(d,c)}});function jh(a){w.call(this,"Keyboard",a,jh,65536);I(this)}A(jh);jh.prototype.wa=function(){return!1};jh.prototype.Ia=function(a,b,c,d){this.C=a;this.b=c;this.j=d};$a(function(){for(var a=E(document,"pdp11","keyboard"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new jh(d);D(d,c)}});
|
||||
function X(a){this.O=a.baudReceive||9600;this.ca=a.baudTransmit||9600;this.ba=a.upperCase;this.w=this.D=null;this.T=a.tabSize;this.S=a.charBOL;this.H=0;w.call(this,"SerialPort",a,X,16777216);var b=a.binding;if("console"==b)this.D="";else{var c;a=kh;b&&(void 0===c&&(c="Panel"),(c=ub(c,this.id))&&(b=c.G[b])&&this.wa(null,a,b))}this.I=this.L=null;this.exports={connect:this.zc,receiveData:this.ac}}A(X);var kh="buffer";k=X.prototype;
|
||||
function X(a){this.O=a.baudReceive||9600;this.ca=a.baudTransmit||9600;this.ba=a.upperCase;this.w=this.D=null;this.T=a.tabSize;this.S=a.charBOL;this.H=0;w.call(this,"SerialPort",a,X,16777216);var b=a.binding;if("console"==b)this.D="";else{var c;a=kh;b&&(void 0===c&&(c="Panel"),(c=ub(c,this.id))&&(b=c.G[b])&&this.wa(null,a,b))}this.I=this.L=null;this.exports={connect:this.Ac,receiveData:this.ac}}A(X);var kh="buffer";k=X.prototype;
|
||||
k.wa=function(a,b,c){var d=this;switch(b){case kh:return this.G[b]=this.w=c,c.onkeydown=function(a){a=a||window.event;var b=a.keyCode;if(8===b||a.ctrlKey&&65<=b&&90>=b)a.preventDefault&&a.preventDefault(),64<b&&(b-=64),d.ac(b);return!0},c.onkeypress=function(a){a=a||window.event;d.ac(a.which||a.keyCode);a.preventDefault&&a.preventDefault();return!0},c.onpaste=function(a){a.stopPropagation&&a.stopPropagation();a.preventDefault&&a.preventDefault();(a=a.clipboardData||window.clipboardData)&&d.ac(a.getData("Text"))},
|
||||
c.removeAttribute("readonly"),!0}return!1};k.Ia=function(a,b,c,d){this.C=a;this.v=b;this.b=c;this.j=d;var e=this;this.na=Lc(48,4);this.X=Ic(this.b,function(){e.f&128||!e.B.length||(e.K=e.B.shift()&255,e.ba&&97<=e.K&&122>e.K&&(e.K-=32),e.f|=128,e.f&64&&Jc(e.b,e.na))});this.M=Lc(52,4);this.ja=Ic(this.b,function(){e.g|=128;e.g&64&&Jc(e.b,e.M)});Ib(b,this,lh);Kb(b,this.reset.bind(this));I(this)};
|
||||
k.zc=function(){if(!this.I){var a=wd(this.C,"connection");if(a){var b=a.split("->");if(2==b.length){var c=ya(b[0]);if(c!=this.bb)return;b=ya(b[1]);if(this.I=tb(b)){var d=this.I.exports;if(d){var e=d.connect;e&&e.call(this.I);if(this.L=d.receiveData){this.status(this.Ua+"."+c+" connected to "+b);return}}}}this.status("Unable to establish connection: "+a)}}};k.Ka=function(a,b){if(!b)if(this.zc(),!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};
|
||||
k.Ac=function(){if(!this.I){var a=wd(this.C,"connection");if(a){var b=a.split("->");if(2==b.length){var c=ya(b[0]);if(c!=this.bb)return;b=ya(b[1]);if(this.I=tb(b)){var d=this.I.exports;if(d){var e=d.connect;e&&e.call(this.I);if(this.L=d.receiveData){this.status(this.Ua+"."+c+" connected to "+b);return}}}}this.status("Unable to establish connection: "+a)}}};k.Ka=function(a,b){if(!b)if(this.Ac(),!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};
|
||||
k.Ja=function(a){return a?this.save():!0};k.reset=function(){mh(this)};k.save=function(){var a=new Q(this);a.set(0,[]);return a.data()};k.restore=function(){return mh(this)};function mh(a){a.K=0;a.f=0;a.g=128;a.B=[];return!0}k.ac=function(a){if("number"==typeof a)this.B.push(a);else if("string"==typeof a)for(var b=0,c,d=0;d<a.length;d++){c=b;b=a.charCodeAt(d);if(10==b){if(13==c)continue;b=13}this.B.push(b)}else this.B=this.B.concat(a);Kc(this.b,this.X,1E3/Math.round(this.O/10));return!0};
|
||||
k.Md=function(){return this.f&65534};k.Fe=function(a){this.f=this.f&-112|a&111};k.Ld=function(){this.f&=-129;0<this.B.length&&Kc(this.b,this.X,1E3/Math.round(this.O/10));return this.K};k.Ee=function(){};k.fe=function(){return this.g};k.Ze=function(a){this.g&128&&(a&64?Jc(this.b,this.M):Rd(this.b,this.M));this.g=this.g&-70|a&69};k.ee=function(){return 0};
|
||||
k.Ye=function(a){if(a&=255){F(this,"transmitByte("+p(a,2,!0)+")");this.L&&this.L.call(this.I,a);a&=127;if(this.w)if(13==a)this.H=0;else if(8==a)this.w.value=this.w.value.slice(0,-1),0<this.H&&this.H--;else{var b;b=(b=za[a])?"<"+b+">":String.fromCharCode(a);var c=b.length;32>a&&1==c&&(c=0);9==a&&(a=this.T||8,c=a-this.H%a,this.T&&(b=xa("",c)));this.S&&!this.H&&c&&(b=String.fromCharCode(this.S)+b);this.w.value+=b;this.w.scrollTop=this.w.scrollHeight;this.H+=c}else if(null!=this.D){if(10==a||1024<=this.D.length)this.i(this.D),
|
||||
this.D="";10!=a&&(this.D+=String.fromCharCode(a))}this.g&=-129;Kc(this.b,this.ja,1E3/Math.round(this.ca/10))}};var nh={},lh=(nh[65392]=[null,null,X.prototype.Md,X.prototype.Fe,"RCSR"],nh[65394]=[null,null,X.prototype.Ld,X.prototype.Ee,"RBUF"],nh[65396]=[null,null,X.prototype.fe,X.prototype.Ze,"XCSR"],nh[65398]=[null,null,X.prototype.ee,X.prototype.Ye,"XBUF"],nh);$a(function(){for(var a=E(document,"pdp11","serial"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new X(d);D(d,c)}});
|
||||
k.Md=function(){return this.f&65534};k.He=function(a){this.f=this.f&-112|a&111};k.Ld=function(){this.f&=-129;0<this.B.length&&Kc(this.b,this.X,1E3/Math.round(this.O/10));return this.K};k.Ge=function(){};k.fe=function(){return this.g};k.af=function(a){this.g&128&&(a&64?Jc(this.b,this.M):Rd(this.b,this.M));this.g=this.g&-70|a&69};k.ee=function(){return 0};
|
||||
k.$e=function(a){if(a&=255){F(this,"transmitByte("+p(a,2,!0)+")");this.L&&this.L.call(this.I,a);a&=127;if(this.w)if(13==a)this.H=0;else if(8==a)this.w.value=this.w.value.slice(0,-1),0<this.H&&this.H--;else{var b;b=(b=za[a])?"<"+b+">":String.fromCharCode(a);var c=b.length;32>a&&1==c&&(c=0);9==a&&(a=this.T||8,c=a-this.H%a,this.T&&(b=xa("",c)));this.S&&!this.H&&c&&(b=String.fromCharCode(this.S)+b);this.w.value+=b;this.w.scrollTop=this.w.scrollHeight;this.H+=c}else if(null!=this.D){if(10==a||1024<=this.D.length)this.i(this.D),
|
||||
this.D="";10!=a&&(this.D+=String.fromCharCode(a))}this.g&=-129;Kc(this.b,this.ja,1E3/Math.round(this.ca/10))}};var nh={},lh=(nh[65392]=[null,null,X.prototype.Md,X.prototype.He,"RCSR"],nh[65394]=[null,null,X.prototype.Ld,X.prototype.Ge,"RBUF"],nh[65396]=[null,null,X.prototype.fe,X.prototype.af,"XCSR"],nh[65398]=[null,null,X.prototype.ee,X.prototype.$e,"XBUF"],nh);$a(function(){for(var a=E(document,"pdp11","serial"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new X(d);D(d,c)}});
|
||||
function dd(a){w.call(this,"PC11",a,dd);this.g=a.autoMount||null;this.D=0;this.ba=a.baudReceive||3600;this.K=this.L=this.f=0;this.I=[];this.H=oh;this.w=ph;this.M=this.B="";this.ea=this.Oa=this.Na=null;this.S=-1;this.O=!Ma("Mobi")&&window&&"FileReader"in window}A(dd);var oh="",ph=0;k=dd.prototype;
|
||||
k.wa=function(a,b,c){var d=this,e=ph;switch(b){case "listTapes":return this.G[b]=c,c.onchange=function(){var a=d.G.descTape,b=c.options[c.selectedIndex];if(a&&b){var e={};if(b=b.getAttribute("data-value"))try{e=eval("("+b+")")}catch(l){u("PC11 option error: "+l.message)}b=e.desc;void 0===b&&(b="");e=e.href;void 0!==e&&(b='<a href="'+e+'" target="_blank">'+b+"</a>");a.innerHTML=b}},!0;case "descTape":return this.G[b]=c,!0;case "loadTape":e=2;case "attachTape":return e||(e=1),this.G[b]=c,c.onclick=
|
||||
function(){var a=d.G.listTapes;a&&qh(d,a.options[a.selectedIndex].text,a.value,e)},!0;case "mountTape":if(!this.O){c.parentNode.removeChild(c);break}this.G[b]=c;c.addEventListener("change",function(){var a=c.children[0];a.children[1].disabled=!a.children[0].files.length});c.onsubmit=function(a){if(a=a.currentTarget[1].files[0]){var b=a.name;qh(d,oa(b,!0),b,1,a)}return!1};return!0;case "readProgress":return this.G[b]=c,!0}return!1};
|
||||
|
|
@ -192,16 +192,16 @@ function zh(a,b,c,d,e){var f=c;if(e){var g=new FileReader;g.onload=function(){va
|
|||
e.Na));a.A.eb=!1;a.D&&(a.D--,a.D||I(a));xh(a)})}function uh(a,b,c,d){if((a=a.G.listTapes)&&a.options){for(var e=0;e<a.options.length;e++)if(a.options[e].value==c)return;e=document.createElement("option");e.text=b;e.value=c;d&&a.childNodes[0]?a.insertBefore(e,a.childNodes[0]):a.appendChild(e)}}
|
||||
function xh(a){var b=a.G.listTapes;if(b&&b.options){a=a.H||a.B;for(var c=0;c<b.options.length;c++)if(b.options[c].value==a){b.selectedIndex!=c&&(b.selectedIndex=c);break}c==b.options.length&&(b.selectedIndex=0)}}function sh(a,b){b|=0;if(b!==a.S){var c=a.G.readProgress;c&&(c=(c=E(c,"pcjs-progress-bar"))&&c[0])&&c.style&&(c.style.width=b+"%");a.S=b}}
|
||||
function Ah(a,b,c,d,e,f,g){a.M=b;a.B=c;a.w=d;a.ea=e;a.Oa=f;a.Na=g;2==d?a.T&&ih(a.T,e,f,g)?a.status("tape loaded: "+b):(a.M="",a.B="",a.H=oh,a.w=ph,a.R("No load address available for tape: "+b)):(a.K=0,a.I=e,a.status("tape attached: "+b),sh(a,0))}function yh(a,b){if(a.B||!1===b)a.M="",a.B="",b||(a.w&&a.status(1==a.w?"tape detached":"tape unloaded"),a.H=oh,a.w=ph,xh(a))}k.save=function(){return(new Q(this)).data()};k.restore=function(){return!0};k.Fd=function(){return this.f&65534};
|
||||
k.ye=function(a){a&1&&(this.f&32768?(a&=-2,this.f&64&&Jc(this.b,this.X)):(this.f&=-129,this.f|=2048,this.L=0,Kc(this.b,this.ca,1E3/Math.round(this.ba/10))));this.f=this.f&-66|a&65};k.Ed=function(){this.f&=-129;this.f|=2048;return this.L};k.xe=function(){};var Bh={},th=(Bh[65384]=[null,null,dd.prototype.Fd,dd.prototype.ye,"PRS"],Bh[65386]=[null,null,dd.prototype.Ed,dd.prototype.xe,"PRB"],Bh);
|
||||
k.Ae=function(a){a&1&&(this.f&32768?(a&=-2,this.f&64&&Jc(this.b,this.X)):(this.f&=-129,this.f|=2048,this.L=0,Kc(this.b,this.ca,1E3/Math.round(this.ba/10))));this.f=this.f&-66|a&65};k.Ed=function(){this.f&=-129;this.f|=2048;return this.L};k.ze=function(){};var Bh={},th=(Bh[65384]=[null,null,dd.prototype.Fd,dd.prototype.Ae,"PRS"],Bh[65386]=[null,null,dd.prototype.Ed,dd.prototype.ze,"PRB"],Bh);
|
||||
function Ch(a,b,c){w.call(this,"Disk",{id:a.Ua+".disk"+p(++Dh,4)},Ch,4194304);this.controller=a;this.C=a.C;this.j=a.j;this.w=b;this.ab=b.name;this.jc=b.jc;Eh(this,c,b.ya,b.Ea,b.sa,b.Pa);I(this)}var Dh=0;A(Ch);k=Ch.prototype;k.Ia=function(a,b,c,d){this.j=d};
|
||||
function Eh(a,b,c,d,e,f){a.mode=b;a.ya=c;a.Ea=d;a.sa=e;a.Pa=f;a.b=[];if("preload"!=a.mode){b=Array(a.ya);for(c=0;c<b.length;c++){d=Array(a.Ea);for(e=0;e<d.length;e++){f=Array(a.sa);for(var g=1;g<=f.length;g++)f[g-1]=Fh(null,c,e,g,a.Pa,0);d[e]=f}b[c]=d}a.b=b}a.f=null}
|
||||
function Gh(a,b,c,d,e){var f=c;if(a.v)return!0;a.ab=b;a.ib=c;a.Mc=oa(c);a.v=e;a.B=a.controller;if(d){var g=new FileReader;g.onload=function(){var b=g.result,c,d=b?b.byteLength:0,e=ka[d];if(e){a.ya=e[0];a.Ea=e[1];a.sa=e[2];a.Pa=e[3]||512;c=a.Pa>>2;var f=e=0,b=new DataView(b,0,d);a.b=Array(a.ya);for(d=0;d<a.b.length;d++)for(var t=a.b[d]=Array(a.Ea),v=0;v<t.length;v++)for(var z=t[v]=Array(a.sa),x=0;x<z.length;x++){for(var B=Fh(null,d,v,x+1,a.Pa,0),ma=B.data,Na=0;Na<c;Na++,f+=4)var P=ma[Na]=b.getInt32(f,
|
||||
function Gh(a,b,c,d,e){var f=c;if(a.v)return!0;a.ab=b;a.ib=c;a.Oc=oa(c);a.v=e;a.B=a.controller;if(d){var g=new FileReader;g.onload=function(){var b=g.result,c,d=b?b.byteLength:0,e=ka[d];if(e){a.ya=e[0];a.Ea=e[1];a.sa=e[2];a.Pa=e[3]||512;c=a.Pa>>2;var f=e=0,b=new DataView(b,0,d);a.b=Array(a.ya);for(d=0;d<a.b.length;d++)for(var t=a.b[d]=Array(a.Ea),v=0;v<t.length;v++)for(var z=t[v]=Array(a.sa),x=0;x<z.length;x++){for(var B=Fh(null,d,v,x+1,a.Pa,0),ma=B.data,Na=0;Na<c;Na++,f+=4)var P=ma[Na]=b.getInt32(f,
|
||||
!0),e=e+P&-1;B.Fa=c;z[x]=B}a.f=e;c=a}else a.R("Unrecognized disk format ("+d+" bytes)");a.v&&(a.v.call(a.controller,a.w,c,a.ab,a.ib),a.v=null)};g.readAsArrayBuffer(d);return!0}0>c.indexOf("/api/v1/dump")&&(b=ta(c),"json"==b||"gz"==b?f=encodeURI(c):(d="path",e="&mbhd=10",!c.indexOf("http:")||!c.indexOf("ftp:")||0<="dsk ima img 360 720 12 144".split(" ").indexOf(b)?(d="disk",e="&mbhd=0"):ua(c,"/")&&(d="dir"),f=Fa()+"/api/v1/dump?"+d+"="+encodeURIComponent(c)+(a.jc?"":e)+"&format=json"));return!!Da(f,
|
||||
null,!0,function(b,c,d){Hh(a,b,c,d)})}
|
||||
function Hh(a,b,c,d){var e=null;a.g=!1;var f=0>d&&a.C&&!a.C.A.ia;if(d)a.controller.R('Unable to load disk "'+a.ab+'" (error '+d+": "+b+")",f);else{kb(a.controller.Ua,b,c);try{if(0<oa(a.Mc,!0).toLowerCase().indexOf("-readonly"))a.g=!0;else{var g=c.indexOf("\n");0<g&&1024>g&&0<c.substring(0,g).indexOf("write-protected")&&(a.g=!0)}var h;"<"==c.substr(0,1)?h=["Missing disk image: "+a.ab]:h=0>c.indexOf("0x")&&'["'!=c.substr(0,2)?JSON.parse(c.replace(/([a-z]+):/gm,'"$1":').replace(/\/\/[^\n]*/gm,"")):eval("("+
|
||||
function Hh(a,b,c,d){var e=null;a.g=!1;var f=0>d&&a.C&&!a.C.A.ia;if(d)a.controller.R('Unable to load disk "'+a.ab+'" (error '+d+": "+b+")",f);else{kb(a.controller.Ua,b,c);try{if(0<oa(a.Oc,!0).toLowerCase().indexOf("-readonly"))a.g=!0;else{var g=c.indexOf("\n");0<g&&1024>g&&0<c.substring(0,g).indexOf("write-protected")&&(a.g=!0)}var h;"<"==c.substr(0,1)?h=["Missing disk image: "+a.ab]:h=0>c.indexOf("0x")&&'["'!=c.substr(0,2)?JSON.parse(c.replace(/([a-z]+):/gm,'"$1":').replace(/\/\/[^\n]*/gm,"")):eval("("+
|
||||
c+")");if(h.length)if(1==h.length)u(h[0]);else{a.ya=h.length;a.Ea=h[0].length;a.sa=h[0][0].length;var l=h[0][0][0];a.Pa=l&&l.length||512;for(d=c=0;d<a.ya;d++)for(f=0;f<a.Ea;f++)for(g=0;g<a.sa;g++)if(l=h[d][f][g]){var m=l.length;void 0===m&&(m=l.length=512);var m=m>>2,n=l.pattern;void 0===n&&(n=l.pattern=0);var r=l.data;if(void 0===r){var t=l.bytes;if(void 0!==t&&t.length){for(var v=m<<2,z=t.length;z<v;z++)t[z]=n;Ih(l,t)}else r=[],n=l.pattern=n|n<<8|n<<16|n<<24,l.data=r;delete l.bytes}Fh(l,d,f);for(v=
|
||||
0;v<r.length;v++)c=c+r[v]&-1}a.b=h;a.f=c;e=a}else u("Empty disk image: "+a.ab)}catch(x){u("Disk image error ("+b+"): "+x.message)}}a.v&&(a.v.call(a.B,a.w,e,a.ab,a.ib),a.v=null)}function Fh(a,b,c,d,e,f){a||(a={sector:d,length:e,data:[],pattern:f});a.bf=b;a.cf=c;a.Sa=a.Fa=0;a.Xa=!1;return a}
|
||||
k.seek=function(a,b,c,d,e){d=null;var f=this.w,g=this.b[a];if(g){var h=g[b];if(!h&&f.Sc&&b<f.Ea)for(h=g[b]=Array(f.Tc),g=0;g<h.length;g++)h[g]=Fh(null,a,b,g+1,f.Ec,0);if(h){for(g=0;g<h.length;g++)if(h[g]&&h[g].sector==c){d=h[g];break}!d&&f.Sc&&9==f.sc&&(d=h[g]=Fh(null,a,b,f.sc,f.Ec,0))}}e&&e(d,!1);return d};function Ih(a,b){for(var c=0,d=a.length>>2,e=Array(d),f=0;f<d;f++)e[f]=b[c]|b[c+1]<<8|b[c+2]<<16|b[c+3]<<24,c+=4;a.data=e}
|
||||
0;v<r.length;v++)c=c+r[v]&-1}a.b=h;a.f=c;e=a}else u("Empty disk image: "+a.ab)}catch(x){u("Disk image error ("+b+"): "+x.message)}}a.v&&(a.v.call(a.B,a.w,e,a.ab,a.ib),a.v=null)}function Fh(a,b,c,d,e,f){a||(a={sector:d,length:e,data:[],pattern:f});a.df=b;a.ef=c;a.Sa=a.Fa=0;a.Xa=!1;return a}
|
||||
k.seek=function(a,b,c,d,e){d=null;var f=this.w,g=this.b[a];if(g){var h=g[b];if(!h&&f.Uc&&b<f.Ea)for(h=g[b]=Array(f.Vc),g=0;g<h.length;g++)h[g]=Fh(null,a,b,g+1,f.Ec,0);if(h){for(g=0;g<h.length;g++)if(h[g]&&h[g].sector==c){d=h[g];break}!d&&f.Uc&&9==f.tc&&(d=h[g]=Fh(null,a,b,f.tc,f.Ec,0))}}e&&e(d,!1);return d};function Ih(a,b){for(var c=0,d=a.length>>2,e=Array(d),f=0;f<d;f++)e[f]=b[c]|b[c+1]<<8|b[c+2]<<16|b[c+3]<<24,c+=4;a.data=e}
|
||||
k.read=function(a,b){var c=-1;if(a&&b<a.length)var c=a.data,d=b>>2,c=(d<c.length?c[d]:a.pattern)>>((b&3)<<3)&255;return c};k.write=function(a,b,c){if(this.g)return!1;if(b<a.length){if(c!=this.read(a,b,!0)){var d=a.data,e=a.pattern,f=b>>2;b=(b&3)<<3;for(var g=d.length;g<=f;g++)d[g]=e;a.Fa?f<a.Sa?(a.Fa+=a.Sa-f,a.Sa=f):f>=a.Sa+a.Fa&&(a.Fa+=f-(a.Sa+a.Fa)+1):(a.Sa=f,a.Fa=1);d[f]=d[f]&~(255<<b)|c<<b}return!0}return null};
|
||||
function Jh(a,b){var c=a.Ea*a.sa,d=b/c|0;return d<a.ya?(b%=c,a.seek(d,b/a.sa|0,b%a.sa+1)):null}function Kh(a,b,c){for(var d=1,e=0,f=0;d--;){var g=a.read(b,c++);if(0>g)break;e|=g<<f;f+=8}return e}
|
||||
k.save=function(){var a=0,b=[];b[a++]=[this.ib,this.f,this.ya,this.Ea,this.sa,this.Pa];if(!this.g)for(var c=this.b,d=0;d<c.length;d++)for(var e=0;e<c[d].length;e++)for(var f=0;f<c[d][e].length;f++){var g=c[d][e][f];if(g&&g.Fa){for(var h=[],l=0,m=g.Sa,n=g.Sa+g.Fa;m<n;)h[l++]=g.data[m++];b[a++]=[d,e,f,g.Sa,h]}}return b};
|
||||
|
|
@ -210,31 +210,31 @@ b+" changes applied)";b=-1;break}if(this.g){c="unable to modify write-protected
|
|||
k.toJSON=function(){var a;a=0;for(var b;b=Jh(this,a++);)Lh(b);a=JSON.stringify(this.b,function(a,b){if("file"!=a)return b});a=a.replace(/,"length":512/gm,"").replace(/,"pattern":0/gm,"");a=a.replace(/"(sector|length|data|pattern)":/gm,"$1:");a=a.replace(/,"[^"]*":([0-9]+|true|false)/gm,"");a=a.replace(/(sector|length|data|pattern):/gm,'"$1":');return a=a.replace(/([\]}]),/gm,"$1,\n")};
|
||||
function Lh(a){var b=a.data,c=b.length;if(c<<2==a.length){for(var d=c-1,e=b[d],f=0;d--&&b[d]===e;)f++;f++&&(b.length=c-f,a.pattern=e)}}function O(a){w.call(this,"RL11",a,O,8388608);this.w=a.autoMount||null;this.H=0;this.f=Array(4);this.L=!Ma("Mobi")&&window&&"FileReader"in window}A(O);k=O.prototype;
|
||||
k.wa=function(a,b,c){var d=this;switch(b){case "listDisks":return this.G[b]=c,c.onchange=function(){var a=d.G.descDisk,b=c.options[c.selectedIndex];if(a&&b){var g={};if(b=b.getAttribute("data-value"))try{g=eval("("+b+")")}catch(h){u("RL11 option error: "+h.message)}b=g.desc;void 0===b&&(b="");g=g.href;void 0!==g&&(b='<a href="'+g+'" target="_blank">'+b+"</a>");a.innerHTML=b}},!0;case "descDisk":case "listDrives":return this.G[b]=c,c.onchange=function(){var a=la(c.value,10);null!=a&&Mh(d,a)},!0;case "loadDrive":return this.G[b]=
|
||||
c,c.onclick=function(){var a=d.G.listDisks;a&&Nh(d,a.options[a.selectedIndex].text,a.value)},!0;case "saveDrive":if(!this.L){c.parentNode.removeChild(c);break}this.G[b]=c;c.onclick=function(){var a=d.G.listDrives;if(a&&a.options&&d.f)if(a=d.f[la(a.value,10)||0])if(a=a.Ga){var b;b="";for(var c=0,h;h=Jh(a,c++);)for(var l=0,m=h.length;l<m;l++)b+=String.fromCharCode(Kh(a,h,l));b=btoa(b);a=a.Mc.replace(".json",".img");c=null;b="data:application/octet-stream;base64,"+b;a&&(c=document.createElement("a"),
|
||||
c,c.onclick=function(){var a=d.G.listDisks;a&&Nh(d,a.options[a.selectedIndex].text,a.value)},!0;case "saveDrive":if(!this.L){c.parentNode.removeChild(c);break}this.G[b]=c;c.onclick=function(){var a=d.G.listDrives;if(a&&a.options&&d.f)if(a=d.f[la(a.value,10)||0])if(a=a.Ga){var b;b="";for(var c=0,h;h=Jh(a,c++);)for(var l=0,m=h.length;l<m;l++)b+=String.fromCharCode(Kh(a,h,l));b=btoa(b);a=a.Oc.replace(".json",".img");c=null;b="data:application/octet-stream;base64,"+b;a&&(c=document.createElement("a"),
|
||||
"string"!=typeof c.download&&(c=null));c?(c.href=b,c.download=a,document.body.appendChild(c),c.click(),document.body.removeChild(c),a="Check your Downloads folder for "+a+"."):(window.open(b),a="Check your browser for a new window/tab containing the requested data"+(a?" ("+a+")":"")+".");u(a)}else d.R("No disk loaded in drive.");else d.R("No disk drive selected.")};return!0;case "mountDrive":if(this.L)return this.G[b]=c,c.addEventListener("change",function(){var a=c.children[0];a.children[1].disabled=
|
||||
!a.children[0].files.length}),c.onsubmit=function(a){if(a=a.currentTarget[1].files[0]){var b=a.name;Nh(d,oa(b,!0),b,a)}return!1},!0;c.parentNode.removeChild(c)}return!1};
|
||||
k.Ia=function(a,b,c,d){this.C=a;this.v=b;this.b=c;this.j=d;if((this.w=wd(this.C,"autoMount")||this.w)&&"string"==typeof this.w)try{this.w=eval("("+this.w+")")}catch(e){u("RL11 auto-mount error: "+e.message+" ("+this.w+")"),this.w=null}Oh(this);this.O=Lc(112,5);Ib(b,this,Ph);Kb(b,this.reset.bind(this));Qh(this,"None","",!0);this.L&&Qh(this,"Local Disk","?");Qh(this,"Remote Disk","??");Rh(this)||I(this)};
|
||||
k.Ka=function(a,b){if(!b){if(!a||!this.restore){if(this.reset(),this.C.vc){for(a=0;a<this.f.length;a++)Sh(this,a,!0);Rh(this,!0)}}else if(!this.restore(a))return!1;if(a=this.G.listDrives){for(;a.firstChild;)a.removeChild(a.firstChild);a.value="";for(b=0;4>b;b++){var c=document.createElement("option");c.value=b;c.text="RL"+b;a.appendChild(c)}a.value="0";Mh(this,0)}}return!0};k.Ja=function(a){return a?this.save():!0};k.reset=function(){Oh(this)};k.save=function(){return(new Q(this)).data()};
|
||||
k.Ka=function(a,b){if(!b){if(!a||!this.restore){if(this.reset(),this.C.wc){for(a=0;a<this.f.length;a++)Sh(this,a,!0);Rh(this,!0)}}else if(!this.restore(a))return!1;if(a=this.G.listDrives){for(;a.firstChild;)a.removeChild(a.firstChild);a.value="";for(b=0;4>b;b++){var c=document.createElement("option");c.value=b;c.text="RL"+b;a.appendChild(c)}a.value="0";Mh(this,0)}}return!0};k.Ja=function(a){return a?this.save():!0};k.reset=function(){Oh(this)};k.save=function(){return(new Q(this)).data()};
|
||||
k.restore=function(a){return Oh(this,a[0])};function Rh(a,b){b||(a.H=0);if(a.w)for(var c in a.w){var d=a.w[c],e=d.path||"",f;if(!(f=d.name))a:{if((f=a.G.listDisks)&&f.options)for(var g=0;g<f.options.length;g++){var h=f.options[g];if(h.value==e){f=h.text;break a}}f=oa(e,!0)}if(e&&f&&(g=-1,c&&(g=c.charCodeAt(c.length-1)-48,0>g||9<g)&&(g=-1),0<=g&&g<a.f.length)){!Th(a,g,f,e,!0)&&b&&I(a,!1);continue}a.R("Incorrect auto-mount settings for drive "+c+" ("+JSON.stringify(d)+")")}return!!a.H}
|
||||
function Nh(a,b,c,d){var e=a.G.listDrives,e=e&&la(e.value,10);if(void 0===e||0>e||e>=a.f.length)a.R("Unable to load the selected drive");else if(c)if("?"==c)a.R('Use "Choose File" and "Mount" to select and load a local disk.');else{if("??"==c){c=window.prompt("Enter the URL of a remote disk image.","")||"";if(!c)return;b=oa(c);a.status("Attempting to load "+c+' as "'+b+'"')}Th(a,e,b,c,!1,d)}else Sh(a,e)}
|
||||
function Th(a,b,c,d,e,f){var g=-1,h=a.f[b];h.ib.toLowerCase()!=d.toLowerCase()&&(g++,Sh(a,b,!0),h.ic?a.R("RL11 busy"):(h.ic=!0,e&&(h.hc=!0,a.H++,H(a)&&F(a,"auto-loading disk: "+c)),h.Vb=!!f,Gh(new Ch(a,h,"preload"),c,d,f,a.Zc)&&g++));return g}
|
||||
k.Zc=function(a,b,c,d,e){var f;a.ic=!1;b&&(f=b.b.length?[b.b.length,b.b[0].length,b.b[0][0].length,b.b[0][0][0].length]:[0,0,0,0],b&&f[0]>a.ya||f[1]>a.Ea)&&(this.R('Disk "'+c+'" too large for drive '+("RL"+a.kc)),b=null);b?(a.Ga=b,a.ab=c,a.ib=d,this.R('Mounted disk "'+c+'" in drive '+("RL"+a.kc),a.hc||e),this.C&&this.C.ub()):a.Vb=!1;a.hc&&(a.hc=!1,--this.H||I(this));Mh(this,a.kc)};
|
||||
function Th(a,b,c,d,e,f){var g=-1,h=a.f[b];h.ib.toLowerCase()!=d.toLowerCase()&&(g++,Sh(a,b,!0),h.ic?a.R("RL11 busy"):(h.ic=!0,e&&(h.hc=!0,a.H++,H(a)&&F(a,"auto-loading disk: "+c)),h.Vb=!!f,Gh(new Ch(a,h,"preload"),c,d,f,a.ad)&&g++));return g}
|
||||
k.ad=function(a,b,c,d,e){var f;a.ic=!1;b&&(f=b.b.length?[b.b.length,b.b[0].length,b.b[0][0].length,b.b[0][0][0].length]:[0,0,0,0],b&&f[0]>a.ya||f[1]>a.Ea)&&(this.R('Disk "'+c+'" too large for drive '+("RL"+a.kc)),b=null);b?(a.Ga=b,a.ab=c,a.ib=d,this.R('Mounted disk "'+c+'" in drive '+("RL"+a.kc),a.hc||e),this.C&&this.C.vb()):a.Vb=!1;a.hc&&(a.hc=!1,--this.H||I(this));Mh(this,a.kc)};
|
||||
function Qh(a,b,c,d){if((a=a.G.listDisks)&&a.options){for(var e=0;e<a.options.length;e++)if(a.options[e].value==c)return;e=document.createElement("option");e.text=b;e.value=c;d&&a.childNodes[0]?a.insertBefore(e,a.childNodes[0]):a.appendChild(e)}}
|
||||
function Mh(a,b){if(0<=b&&b<a.f.length){var c=a.f[b],d=a.G.listDisks;a=a.G.listDrives;if(d&&a&&d.options&&a.options&&(a=la(a.value,10),c=c.Vb?"?":c.ib,!isNaN(a)&&a==b)){for(b=0;b<d.options.length;b++)if(d.options[b].value==c){d.selectedIndex!=b&&(d.selectedIndex=b);break}b==d.options.length&&(d.selectedIndex=0)}}}function Sh(a,b,c){var d=a.f[b];if(d.Ga||!1===c)d.ab="",d.ib="",d.Ga=null,d.Vb=!1,c||(a.R("Drive RL"+b+" unloaded",c),Mh(a,b))}
|
||||
function Oh(a,b){var c=0;b||(b=[]);a.fa=b[c++]||0;a.I=b[c++]||0;a.g=b[c++]||0;a.B=b[c++]||0;a.D=b[c++]||0;a.K=b[c]||0;for(b=0;b<a.f.length;b++){var d=a.f[b];void 0===d&&(d=a.f[b]={});c=a;d.kc=b;d.ic=d.Vb=!1;d.name=c.bb;d.ya=512;d.Ea=2;d.sa=40;d.Pa=256;d.jc=!0;d.af=0;d.$e=0;d.sc=1;d.Tc=d.sa;d.Ec=d.Pa;d.df=0;d.ff=null;d.Ga||(d.ib="");d.status=29|(512==d.ya?128:0)}return!0}
|
||||
k.Xc=function(a,b,c,d,e,f){this.I=f&65535;this.fa=this.fa&-49|f>>12&48;this.K=f>>16&63;this.B=this.g=b<<7|(c?64:0)|d&63;this.D=65536-e&65535;a&&(this.fa=this.fa|a|32768);return!0};
|
||||
k.sd=function(a,b,c,d,e,f,g){var h=0,l=a.Ga,m=null,n;l||(h=5120,e=0);for(;e--;){if(!m){m=a.Ga.seek(b,c,d+1);if(!m){h=5120;break}n=0}var r,t;if(0>(r=a.Ga.read(m,n++))||0>(t=a.Ga.read(m,n++))){h=5120;break}this.v.wb(f,r|t<<8);if(Hc(this.v)){h=8192;break}f+=2;if(n>=l.Pa&&(m=null,++d>=l.sa&&(d=0,++c>=l.Ea&&(c=0,++b>=l.ya)))){h=5120;break}}return g(h,b,c,d,e,f)};
|
||||
k.ne=function(a,b,c,d,e,f,g){var h=0,l=a.Ga,m=null,n;l||(h=5120,e=0);for(;e--;){var r=this.v.Ya(f);if(Hc(this.v)){h=8192;break}f+=2;if(!m){m=a.Ga.seek(b,c,d+1,!0);if(!m){h=5120;break}n=0}if(!a.Ga.write(m,n++,r&255)||!a.Ga.write(m,n++,r>>8)){h=5120;break}if(n>=l.Pa&&(m=null,++d>=l.sa&&(d=0,++c>=l.Ea&&(c=0,++b>=l.ya)))){h=5120;break}}return g(h,b,c,d,e,f)};k.Pd=function(){return this.fa&65535};
|
||||
k.Ie=function(a){this.fa=this.fa&-1023|a&1022;this.M=this.M&-4|(a&48)>>4;if(!(this.fa&128)){var b;a=!0;var c=this.f[(this.fa&768)>>8],d,e,f,g;this.fa&=-2;switch(this.fa&14){case 4:this.g&8&&(this.fa&=63);this.D=c.status|this.B&64;break;case 6:1==(this.g&3)&&(b=this.g&65408,c=(this.g&16)<<2,this.B=this.g&4?this.B+b:this.B-b,this.g=this.B=this.B&65408|c);break;case 8:this.D=this.B;break;case 12:b=this.sd;case 10:b||(b=this.ne),d=this.g>>7,e=this.g&64?1:0,f=this.g&63,d>=c.ya||f>=c.sa?this.fa|=37888:
|
||||
(g=(this.K&63)<<16|this.I,a=65536-this.D&65535,a=b.call(this,c,d,e,f,a,g,this.Xc.bind(this)))}a&&(this.fa|=129,this.fa&64&&Jc(this.b,this.O))}};k.Nd=function(){return this.I};k.Ge=function(a){this.I=a&65534};k.Qd=function(){return this.g};k.Je=function(a){this.g=a};k.Rd=function(){return this.D};k.Ke=function(a){this.D=a};k.Od=function(){return this.K};k.He=function(a){this.K=a&63};
|
||||
var Uh={},Ph=(Uh[63744]=[null,null,O.prototype.Pd,O.prototype.Ie,"RLCS"],Uh[63746]=[null,null,O.prototype.Nd,O.prototype.Ge,"RLBA"],Uh[63748]=[null,null,O.prototype.Qd,O.prototype.Je,"RLDA"],Uh[63750]=[null,null,O.prototype.Rd,O.prototype.Ke,"RLMP"],Uh[63752]=[null,null,O.prototype.Od,O.prototype.He,"RLBE"],Uh);function Vh(a){w.call(this,"Debugger",a,Vh);this.ca=a.base||16;this.Ca=!1;this.K=0;this.T=!1;this.B=-1;this.g=[];this.X={}}A(Vh);
|
||||
var Wh={"||":0,"&&":1,"|":2,"^":3,"&":4,"!=":5,"==":5,">=":6,">":6,"<=":6,"<":6,">>>":7,">>":7,"<<":7,"-":8,"+":8,"%":9,"/":9,"*":9};Vh.prototype.xc=function(){return-1};Vh.prototype.yc=function(){};
|
||||
function Oh(a,b){var c=0;b||(b=[]);a.fa=b[c++]||0;a.I=b[c++]||0;a.g=b[c++]||0;a.B=b[c++]||0;a.D=b[c++]||0;a.K=b[c]||0;for(b=0;b<a.f.length;b++){var d=a.f[b];void 0===d&&(d=a.f[b]={});c=a;d.kc=b;d.ic=d.Vb=!1;d.name=c.bb;d.ya=512;d.Ea=2;d.sa=40;d.Pa=256;d.jc=!0;d.cf=0;d.bf=0;d.tc=1;d.Vc=d.sa;d.Ec=d.Pa;d.ff=0;d.hf=null;d.Ga||(d.ib="");d.status=29|(512==d.ya?128:0)}return!0}
|
||||
k.Zc=function(a,b,c,d,e,f){this.I=f&65535;this.fa=this.fa&-49|f>>12&48;this.K=f>>16&63;this.B=this.g=b<<7|(c?64:0)|d&63;this.D=65536-e&65535;a&&(this.fa=this.fa|a|32768);return!0};
|
||||
k.sd=function(a,b,c,d,e,f,g){var h=0,l=a.Ga,m=null,n;l||(h=5120,e=0);for(;e--;){if(!m){m=a.Ga.seek(b,c,d+1);if(!m){h=5120;break}n=0}var r,t;if(0>(r=a.Ga.read(m,n++))||0>(t=a.Ga.read(m,n++))){h=5120;break}this.v.xb(f,r|t<<8);if(Hc(this.v)){h=8192;break}f+=2;if(n>=l.Pa&&(m=null,++d>=l.sa&&(d=0,++c>=l.Ea&&(c=0,++b>=l.ya)))){h=5120;break}}return g(h,b,c,d,e,f)};
|
||||
k.pe=function(a,b,c,d,e,f,g){var h=0,l=a.Ga,m=null,n;l||(h=5120,e=0);for(;e--;){var r=this.v.Ya(f);if(Hc(this.v)){h=8192;break}f+=2;if(!m){m=a.Ga.seek(b,c,d+1,!0);if(!m){h=5120;break}n=0}if(!a.Ga.write(m,n++,r&255)||!a.Ga.write(m,n++,r>>8)){h=5120;break}if(n>=l.Pa&&(m=null,++d>=l.sa&&(d=0,++c>=l.Ea&&(c=0,++b>=l.ya)))){h=5120;break}}return g(h,b,c,d,e,f)};k.Pd=function(){return this.fa&65535};
|
||||
k.Ke=function(a){this.fa=this.fa&-1023|a&1022;this.M=this.M&-4|(a&48)>>4;if(!(this.fa&128)){var b;a=!0;var c=this.f[(this.fa&768)>>8],d,e,f,g;this.fa&=-2;switch(this.fa&14){case 4:this.g&8&&(this.fa&=63);this.D=c.status|this.B&64;break;case 6:1==(this.g&3)&&(b=this.g&65408,c=(this.g&16)<<2,this.B=this.g&4?this.B+b:this.B-b,this.g=this.B=this.B&65408|c);break;case 8:this.D=this.B;break;case 12:b=this.sd;case 10:b||(b=this.pe),d=this.g>>7,e=this.g&64?1:0,f=this.g&63,d>=c.ya||f>=c.sa?this.fa|=37888:
|
||||
(g=(this.K&63)<<16|this.I,a=65536-this.D&65535,a=b.call(this,c,d,e,f,a,g,this.Zc.bind(this)))}a&&(this.fa|=129,this.fa&64&&Jc(this.b,this.O))}};k.Nd=function(){return this.I};k.Ie=function(a){this.I=a&65534};k.Qd=function(){return this.g};k.Le=function(a){this.g=a};k.Rd=function(){return this.D};k.Me=function(a){this.D=a};k.Od=function(){return this.K};k.Je=function(a){this.K=a&63};
|
||||
var Uh={},Ph=(Uh[63744]=[null,null,O.prototype.Pd,O.prototype.Ke,"RLCS"],Uh[63746]=[null,null,O.prototype.Nd,O.prototype.Ie,"RLBA"],Uh[63748]=[null,null,O.prototype.Qd,O.prototype.Le,"RLDA"],Uh[63750]=[null,null,O.prototype.Rd,O.prototype.Me,"RLMP"],Uh[63752]=[null,null,O.prototype.Od,O.prototype.Je,"RLBE"],Uh);function Vh(a){w.call(this,"Debugger",a,Vh);this.ca=a.base||16;this.Ca=!1;this.K=0;this.T=!1;this.B=-1;this.g=[];this.X={}}A(Vh);
|
||||
var Wh={"||":0,"&&":1,"|":2,"^":3,"&":4,"!=":5,"==":5,">=":6,">":6,"<=":6,"<":6,">>>":7,">>":7,"<<":7,"-":8,"+":8,"%":9,"/":9,"*":9};Vh.prototype.yc=function(){return-1};Vh.prototype.zc=function(){};
|
||||
function Xh(a,b,c,d){if(c)if(b){0>a.B&&a.g.length&&(a.B=0);if(0>a.B||b!=a.g[a.B])a.g.splice(0,0,b),a.B=0;a.B--}else a.T?b="end":b=a.g[a.B+1];a=[];if(b){b=b.replace(/""/g,"'");c=0;var e=null;d=d||";";for(var f=0;f<=b.length;f++){var g=b.charAt(f);if('"'==g||"'"==g)e?g==e&&(e=null):e=g;else if(g==d&&!e||!g)a.push(ya(b.substring(c,f))),c=f+1}}return a}
|
||||
function Yh(a,b,c){for(c=c||-1;c--&&b.length;){var d=b.pop();if(2>a.length)return!1;var e=a.pop(),f=a.pop();switch(d){case "*":d=f*e;break;case "/":if(!e)return!1;d=f/e;break;case "%":if(!e)return!1;d=f%e;break;case "+":d=f+e;break;case "-":d=f-e;break;case "<<":d=f<<e;break;case ">>":d=f>>e;break;case ">>>":d=f>>>e;break;case "<":d=f<e?1:0;break;case "<=":d=f<=e?1:0;break;case ">":d=f>e?1:0;break;case ">=":d=f>=e?1:0;break;case "==":d=f==e?1:0;break;case "!=":d=f!=e?1:0;break;case "&":d=f&e;break;
|
||||
case "^":d=f^e;break;case "|":d=f|e;break;case "&&":d=f&&e?1:0;break;case "||":d=f||e?1:0;break;default:return!1}a.push(d|0)}return!0}
|
||||
function Zh(a,b,c){var d;if(b){b=$h(a,b);for(var e=0,f=!1,g=b,h=[],l=[],m=b.split(/(\|\||&&|\||^|&|!=|==|>=|>>>|>>|>|<=|<<|<|-|\+|%|\/|\*)/);e<m.length;){var n=m[e++],r=n.length,n=ya(n);if(!n){f=!0;break}n=ai(a,n,null,!1===c);if(void 0===n){f=!0;c=!1;break}h.push(n);if(e==m.length)break;var n=m[e++],t=n.length;l.length&&Wh[n]<Wh[l[l.length-1]]&&Yh(h,l,1);l.push(n);b=b.substr(r+t)}Yh(h,l)&&1==h.length||(f=!0);f?c&&a.i("error parsing '"+g+"' at character "+(g.length-b.length)):(d=h.pop(),c&&bi(a,null,
|
||||
d))}return d}function $h(a,b){for(var c,d=a.Ca?"(":"{",e=a.Ca?")":"}",f=new RegExp(a.Ca?"\\((.*?)\\)":"\\{(.*?)\\}");(c=b.match(f))&&!(0<=c[1].indexOf(d));){var g=Zh(a,c[1]);b=b.replace(d+c[1]+e,null!=g?K(a,g):"undefined")}for(;(c=b.match(/\[(.*?)]/))&&!(0<=c[1].indexOf("["));)b=b.replace("["+c[1]+"]","unimplemented");for(a=b;b=a.match(/\$([a-z]+)/i);){c=null;switch(b[1].toLowerCase()){case "ops":c=0}if(null==c)break;a=a.replace(b[0],c.toString())}return a}
|
||||
function ai(a,b,c,d){var e;null!=b?(e=a.xc(b),0<=e?e=a.yc(e):(e=a.X[b],null==e&&(e=la(b,a.ca))),null!=e||d||a.i("invalid "+(c?c:"value")+": "+b)):d||a.i("missing "+(c||"value"));return e}
|
||||
function ai(a,b,c,d){var e;null!=b?(e=a.yc(b),0<=e?e=a.zc(e):(e=a.X[b],null==e&&(e=la(b,a.ca))),null!=e||d||a.i("invalid "+(c?c:"value")+": "+b)):d||a.i("missing "+(c||"value"));return e}
|
||||
function bi(a,b,c){var d,e=!1;if(void 0!==c){e=!0;d=c;var f=0,g="";if(!f||4<f)f=4;for(var h=0;h<f;h++){g&&(g=","+g);var l=d&255,m=8,n="";m?32<m&&(m=32):m=32;if(null==l||isNaN(l))for(;0<m--;)n="?"+n;else for(;0<m--;)n=(l&1?"1":"0")+n,l>>=1;g=n+g;d>>=8}d=p(c,0,!0)+" "+c+". "+na(c,0,!0)+" "+("0b"+g);32<=c&&127>c&&(d+=" '"+String.fromCharCode(c)+"'")}a.i((null!=b?b+": ":"")+d);return e}function ci(a,b){if(b)return bi(a,b,a.X[b]);var c=0;for(b in a.X)bi(a,b,a.X[b]),c++;return 0<c}
|
||||
function K(a,b,c,d){switch(a.ca){case 8:a=na(b,3*c-(2<c?1:0));break;case 10:a=b.toString();break;default:a=p(b,2*c)}d?d=a.replace(/^0+([0-9A-F]+)$/i,"$1"):d=a;return d}
|
||||
function di(a){Vh.call(this,a);this.lb=!1;this.Ca=!0;this.L=Y(0);this.mb=Y(0);this.S=Y(0);this.I=[];this.f=this.M=this.D=[];ei(this);this.xa=0;fi(this);this.Ma={};gi(this,a.messages);this.Va=a.commands;var b=this;window?void 0===window.pdp11&&(window.pdp11=function(a){return Ad(b,a)}):void 0===global.pdp11&&(global.pdp11=function(a){return Ad(b,a)})}A(di,Vh);
|
||||
|
|
@ -246,36 +246,36 @@ ji={SP:6,PC:7,PS:20,IR:21,ER:22,SL:23,MMR0:24,MMR1:25,MMR2:26,MMR3:27,AR:28,DR:2
|
|||
k.Ia=function(a,b,c,d){this.v=b;this.C=a;this.b=c;this.w=a.w;(a=wd(a,"messages"))&&gi(this,a);this.qb=ki;this.Ib=1145>this.b.fb?mi:[];Vc(this,64,function(a){a:{var b=d.v.Y,c=a[0],e=a=0,l=b.length;if(c){a=d.aa(ni(d,c));if(-1===a){d.i("invalid address: "+c);break a}e=a>>>d.v.ka;l=1}d.i("blockid physical blockaddr used size type");d.i("-------- --------- ---------- ------ ------ ----");for(var c=-1,m=0;l--;){var n=b[e];n.type==c?m++||d.i("..."):(c=n.type,m=Dc[c],n&&d.i(p(n.id,8)+" %"+
|
||||
p(e<<d.v.ka,8)+" %%"+p(n.F,8)+" "+q(n.Tb)+" "+q(n.size)+" "+m),c!=id&&(c=-1),m=0);a+=d.v.Da;e++}}});I(this)};
|
||||
k.wa=function(a,b,c){var d=this;switch(b){case "debugInput":return this.na=this.G[b]=c,c.onkeydown=function(a){var b;if(13==a.keyCode)b=c.value,c.value="",Ad(d,b,!0);else if(27==a.keyCode)c.value=b="";else if(38==a.keyCode?(b=null,d.B<d.g.length-1&&(b=d.g[++d.B])):40==a.keyCode&&(0<d.B?b=d.g[--d.B]:(b="",d.B=-1)),null!=b){var e=b.length;c.value=b;c.setSelectionRange(e,e)}null!=b&&a.preventDefault&&a.preventDefault()},!0;case "debugEnter":return this.G[b]=c,Ua(c,function(){if(d.na){var a=d.na.value;
|
||||
d.na.value="";Ad(d,a,!0);return!0}return!1}),!0;case "step":return this.G[b]=c,Ua(c,function(a){var b=!1;wb(d,!0)||(vb(d,!0),b=d.kb(a?1:0,null),vb(d,!1));return b}),!0}return!1};k.ub=function(a){if(this.na){var b=0,c=0;!a&&window&&(b=window.scrollX,c=window.scrollY);this.na.focus();!a&&window&&window.scrollTo(b,c)}};k.aa=function(a){a=a&&a.F;null==a&&(a=-1);return a};k.Yb=function(a,b){var c=255,d=this.aa(a,!1,1);-1!==d&&(c=a.Wb?this.v.Zb(d):this.b.Zb(d),b&&oi(a,b));return c};
|
||||
k.oa=function(a,b){var c=65535,d=this.aa(a,!1,2);-1!==d&&(c=a.Wb?this.v.Ya(d):this.b.Ya(d),b&&oi(a,b));return c};k.Fb=function(a,b,c){var d=this.aa(a,!0,1);-1!==d&&(a.Wb?this.v.tb(d,b):this.b.tb(d,b),c&&oi(a,c),this.C.ra(-1))};k.vb=function(a,b,c){var d=this.aa(a,!0,2);-1!==d&&(a.Wb?this.v.wb(d,b):this.b.wb(d,b),c&&oi(a,c),this.C.ra(-1))};function Y(a,b){return{F:a,Wb:b,Ra:!1}}k.oc=function(a,b){a.F=b;a.Ra=!1;return a};function pi(a){return[a.F,a.Ra]}function qi(a){return{F:a[0],Ra:a[1]}}
|
||||
function ni(a,b,c){var d,e=(c?a.L:a.mb).F;c=!1;if(void 0!==b){b=$h(a,b);"%"==b.charAt(0)&&(c=!0,b=b.substr(1));d=b;var f;if(d.match(/^[a-z_][a-z0-9_]*$/i))for(d=d.toUpperCase(),e=0;e<a.I.length;e++){var g=a.I[e].ga[d];if(void 0!==g){d=g.o;void 0!==d&&(f=Y(d));break}}if(d=f)return d;e=Zh(a,b,void 0)}null!=e&&(d=Y(e,c));return d}function ri(a,b,c){c&&(c=c.match(/(['"])(.*?)\1/))&&(b.Qc=Xh(a,b.Lc=c[2]))}function oi(a,b){null!=a.F&&(a.F+=b||1)}
|
||||
function gi(a,b){a.j=a;a.la=a.Uc=536870912;a.ja=null;a.Aa=[];b=Xh(a,b.replace("keys","key").replace("kbd","keyboard"),!1,"|");if(b.length)for(var c in Cb){var d;a:if(d=void 0,Array.prototype.indexOf)d=b.indexOf(c,d);else{d=d||0;0>d&&(d+=b.length);0>d&&(d=0);for(var e=b.length;d<e;d++)if(d in b&&b[d]===c)break a;d=-1}0<=d&&(a.la|=Cb[c],a.i(c+" messages enabled"))}}function Vc(a,b,c){for(var d in Cb)if(b==Cb[d]){a.Ma[d]=c;break}}
|
||||
k.xc=function(a){a=a.toUpperCase();var b=ji[a];null==b&&(b=-1,"R"==a.charAt(0)&&(b=+a.charAt(1),0>b||7<b))&&(b=-1);return b};function si(a){return 6>a?"R"+a:6==a?"SP":"PC"}
|
||||
k.yc=function(a){var b;if(0<=a)if(8>a)b=this.b.u[a];else if(16>a)b=this.b.$a[a-8];else if(20>a)b=this.b.La[a-16];else{var c=this.b,d=this.w;switch(a){case 20:b=bd(this.b);break;case 21:b=c.Rb;break;case 22:b=c.va;break;case 23:b=c.hb;break;case 24:b=Wc(c);break;case 25:b=Yc(c);break;case 26:b=Zc(c);break;case 27:b=c.Ta;break;case 28:d&&(b=d.ua);break;case 29:d&&(b=d.sb);break;case 30:d&&mc(d)&&(b=d.Za)}}return b};
|
||||
d.na.value="";Ad(d,a,!0);return!0}return!1}),!0;case "step":return this.G[b]=c,Ua(c,function(a){var b=!1;wb(d,!0)||(vb(d,!0),b=d.kb(a?1:0,null),vb(d,!1));return b}),!0}return!1};k.vb=function(a){if(this.na){var b=0,c=0;!a&&window&&(b=window.scrollX,c=window.scrollY);this.na.focus();!a&&window&&window.scrollTo(b,c)}};k.aa=function(a){a=a&&a.F;null==a&&(a=-1);return a};k.Yb=function(a,b){var c=255,d=this.aa(a,!1,1);-1!==d&&(c=a.Wb?this.v.Zb(d):this.b.Zb(d),b&&oi(a,b));return c};
|
||||
k.oa=function(a,b){var c=65535,d=this.aa(a,!1,2);-1!==d&&(c=a.Wb?this.v.Ya(d):this.b.Ya(d),b&&oi(a,b));return c};k.Fb=function(a,b,c){var d=this.aa(a,!0,1);-1!==d&&(a.Wb?this.v.ub(d,b):this.b.ub(d,b),c&&oi(a,c),this.C.ra(-1))};k.wb=function(a,b,c){var d=this.aa(a,!0,2);-1!==d&&(a.Wb?this.v.xb(d,b):this.b.xb(d,b),c&&oi(a,c),this.C.ra(-1))};function Y(a,b){return{F:a,Wb:b,Ra:!1}}k.pc=function(a,b){a.F=b;a.Ra=!1;return a};function pi(a){return[a.F,a.Ra]}function qi(a){return{F:a[0],Ra:a[1]}}
|
||||
function ni(a,b,c){var d,e=(c?a.L:a.mb).F;c=!1;if(void 0!==b){b=$h(a,b);"%"==b.charAt(0)&&(c=!0,b=b.substr(1));d=b;var f;if(d.match(/^[a-z_][a-z0-9_]*$/i))for(d=d.toUpperCase(),e=0;e<a.I.length;e++){var g=a.I[e].ga[d];if(void 0!==g){d=g.o;void 0!==d&&(f=Y(d));break}}if(d=f)return d;e=Zh(a,b,void 0)}null!=e&&(d=Y(e,c));return d}function ri(a,b,c){c&&(c=c.match(/(['"])(.*?)\1/))&&(b.Sc=Xh(a,b.Nc=c[2]))}function oi(a,b){null!=a.F&&(a.F+=b||1)}
|
||||
function gi(a,b){a.j=a;a.la=a.Wc=536870912;a.ja=null;a.Aa=[];b=Xh(a,b.replace("keys","key").replace("kbd","keyboard"),!1,"|");if(b.length)for(var c in Cb){var d;a:if(d=void 0,Array.prototype.indexOf)d=b.indexOf(c,d);else{d=d||0;0>d&&(d+=b.length);0>d&&(d=0);for(var e=b.length;d<e;d++)if(d in b&&b[d]===c)break a;d=-1}0<=d&&(a.la|=Cb[c],a.i(c+" messages enabled"))}}function Vc(a,b,c){for(var d in Cb)if(b==Cb[d]){a.Ma[d]=c;break}}
|
||||
k.yc=function(a){a=a.toUpperCase();var b=ji[a];null==b&&(b=-1,"R"==a.charAt(0)&&(b=+a.charAt(1),0>b||7<b))&&(b=-1);return b};function si(a){return 6>a?"R"+a:6==a?"SP":"PC"}
|
||||
k.zc=function(a){var b;if(0<=a)if(8>a)b=this.b.u[a];else if(16>a)b=this.b.$a[a-8];else if(20>a)b=this.b.La[a-16];else{var c=this.b,d=this.w;switch(a){case 20:b=bd(this.b);break;case 21:b=c.Rb;break;case 22:b=c.va;break;case 23:b=c.hb;break;case 24:b=Wc(c);break;case 25:b=Yc(c);break;case 26:b=Zc(c);break;case 27:b=c.Ta;break;case 28:d&&(b=d.ua);break;case 29:d&&(b=d.tb);break;case 30:d&&mc(d)&&(b=d.Za)}}return b};
|
||||
k.message=function(a,b){b&&(a+=" @"+K(this,Y(this.b.pa&65535).F));if(this.la&1073741824)this.Aa.push(a);else if(!this.ja||a!=this.ja){this.ja=a;b=!1;if(this.la&-2147483648&&this.b&&(b=this.b.A.W)||wb(this,!0))this.da(),b&&(a+=" (cpu halted)");this.i(a);this.b&&(a=this.b,Ed(a),a.Ba=0,a.ra())}};
|
||||
function fi(a){var b;if(!Ge(a))a.H&&a.H.length&&a.i("instruction history buffer freed"),a.ba=0,a.H=[];else if(!a.H||!a.H.length){a.H=Array(1E3);for(b=0;b<a.H.length;b++)a.H[b]=Y();a.ba=0;a.i("instruction history buffer allocated")}}k.jb=function(a,b){if(!ti(this,b))return!1;this.b.jb(a);return!0};
|
||||
k.kb=function(a,b,c){if(!ti(this))return!1;null===b&&(b=!this.zb||"tr"==this.zb);this.K=0;a||Ge(this)&&He(this,this.b.u[7],0);try{a=Fd(this.b,a);var d=this.b.kb(a);0<d&&(Sb(this.b,d),this.K+=d,Tb(this.b,d,!0),Ub(this.b,d),this.Ba++)}catch(e){"number"!=typeof e&&(this.K=0,zb(this.b,e.stack||e.message))}!1!==c&&(this.w&&this.w.stop&&this.w.stop(),this.C.ra(-1));zd(this,b||!1);return 0<this.K};k.da=function(a){this.b&&this.b.da(a)};
|
||||
function zd(a,b){if(a.lb){void 0===b&&(b=!0);var c;c=a.b;if(c=c.J&8?c.he|c.od<<8:0){var d=c>>8;a.i("trapped to "+K(a,c&255,1)+" ("+(0>d?Bb[-d]:K(a,d))+")")}a.L=Y(a.b.u[7]);b&&1!=a.O?ui(a):vi(a)}}function ti(a,b){var c;(c=!a.b||!xb(a.b))||(c=a.b,c.A.ia?c=!0:(c.i(c.toString()+" not powered"),c=!1),c=!c);return c||a.b.A.W?(b||a.i("cpu busy or unavailable, command ignored"),!1):!yb(a.b)}k.Ka=function(a,b){return!b&&(this.reset(!0),a&&this.restore&&!this.restore(a))?!1:!0};
|
||||
k.kb=function(a,b,c){if(!ti(this))return!1;null===b&&(b=!this.rb||"tr"==this.rb);this.K=0;a||Ge(this)&&He(this,this.b.u[7],0);try{a=Fd(this.b,a);var d=this.b.kb(a);0<d&&(Sb(this.b,d),this.K+=d,Tb(this.b,d,!0),Ub(this.b,d),this.Ba++)}catch(e){"number"!=typeof e&&(this.K=0,zb(this.b,e.stack||e.message))}!1!==c&&(this.w&&this.w.stop&&this.w.stop(),this.C.ra(-1));zd(this,b||!1);return 0<this.K};k.da=function(a){this.b&&this.b.da(a)};
|
||||
function zd(a,b){if(a.lb){void 0===b&&(b=!0);var c;c=a.b;if(c=c.J&8?c.ke|c.ie<<8:0){var d=c>>8;a.i("trapped to "+K(a,c&255,1)+" ("+(0>d?Bb[-d]:K(a,d))+")")}a.L=Y(a.b.u[7]);b&&1!=a.O?ui(a):vi(a)}}function ti(a,b){var c;(c=!a.b||!xb(a.b))||(c=a.b,c.A.ia?c=!0:(c.i(c.toString()+" not powered"),c=!1),c=!c);return c||a.b.A.W?(b||a.i("cpu busy or unavailable, command ignored"),!1):!yb(a.b)}k.Ka=function(a,b){return!b&&(this.reset(!0),a&&this.restore&&!this.restore(a))?!1:!0};
|
||||
k.Ja=function(a,b){b&&this.i(a?"suspending":"shutting down");return a?this.save():!0};k.reset=function(a){fi(this);this.Ba=0;this.ja=null;this.K=0;this.L=Y(this.b.u[7]);this.A.W=!1;wi(this);a||zd(this)};k.save=function(){var a=new Q(this);a.set(0,pi(this.L));a.set(1,pi(this.S));a.set(2,[this.g,this.T,this.la]);a.set(3,this.I);return a.data()};
|
||||
k.restore=function(a){var b=0;void 0!==a[2]&&(this.L=qi(a[b++]),this.S=qi(a[b++]),this.g=a[b][0],"string"==typeof this.g&&(this.g=[this.g]),this.T=a[b][1],this.la|=a[b][2]);a[3]&&(this.I=a[3]);return!0};k.start=function(a,b){this.O||this.i("running");this.A.W=!0;this.Jb=a;this.Kb=b};
|
||||
k.stop=function(a,b){if(this.A.W){this.A.W=!1;this.K=b-this.Kb;if(!this.O){b="stopped";if(this.K){a-=this.Jb;var c=0<a?Math.round(1E3*this.K/a):0;b+=" (";Ge(this)&&(b+=this.Ba+" instructions, ",this.Ba=0);b+=this.K+" cycles, "+a+" ms, "+c+" hz)"}else H(this,-2147483648)&&(b+=" (use the 't' command to execute blocked faults)");this.i(b)}zd(this,!0);this.ub();wi(this,this.b.u[7]);this.ja=null}};function Ge(a){return 1<a.f.length||!!a.xa}
|
||||
function He(a,b,c){var d=-1;c||(d=a.b.Ya(b),0==d&&(b=Qd(a.b,2)));if(0<c&&(a.xa&&!--a.xa||rd(a,b,1,a.f)))return!0;0<=c&&a.H.length&&(a.Ba++,0>d&&(d=a.b.Ya(b)),65535!=(d&65535)&&(a.oc(a.H[a.ba],b),++a.ba==a.H.length&&(a.ba=0)));return!1}function Nf(a){var b=a.b;if(b.A.W)throw R(b,a.b.pa&65535),a.da(),-1;return!1}
|
||||
k.stop=function(a,b){if(this.A.W){this.A.W=!1;this.K=b-this.Kb;if(!this.O){b="stopped";if(this.K){a-=this.Jb;var c=0<a?Math.round(1E3*this.K/a):0;b+=" (";Ge(this)&&(b+=this.Ba+" instructions, ",this.Ba=0);b+=this.K+" cycles, "+a+" ms, "+c+" hz)"}else H(this,-2147483648)&&(b+=" (use the 't' command to execute blocked faults)");this.i(b)}zd(this,!0);this.vb();wi(this,this.b.u[7]);this.ja=null}};function Ge(a){return 1<a.f.length||!!a.xa}
|
||||
function He(a,b,c){var d=-1;c||(d=a.b.Ya(b),0==d&&(b=Qd(a.b,2)));if(0<c&&(a.xa&&!--a.xa||rd(a,b,1,a.f)))return!0;0<=c&&a.H.length&&(a.Ba++,0>d&&(d=a.b.Ya(b)),65535!=(d&65535)&&(a.pc(a.H[a.ba],b),++a.ba==a.H.length&&(a.ba=0)));return!1}function Nf(a){var b=a.b;if(b.A.W)throw R(b,a.b.pa&65535),a.da(),-1;return!1}
|
||||
function ei(a){var b,c;a.f=["bp"];if(a.M)for(b=1;b<a.M.length;b++){c=a.M[b];var d=a.v;c=a.aa(c);sd(d.Y[c>>>d.ka],!1)}a.M=["br"];if(a.D)for(b=1;b<a.D.length;b++)c=a.D[b],d=a.v,c=a.aa(c),sd(d.Y[c>>>d.ka],!0);a.D=["bw"];a.nb=0}k.ob=function(a,b,c){var d=!0;c||xi(this,a,b,!1,!0);if(a!=this.f){var e=this.aa(b);if(-1===e)this.i("invalid address: "+K(this,b.F)),d=!1;else{var f=this.v;f.Y[e>>>f.ka].ob(e&f.v,a==this.D)}}d&&(a.push(b),c?b.Ra=!0:(yi(this,a,a.length-1,"set"),fi(this)));return d};
|
||||
function xi(a,b,c,d,e){var f=!1;c=a.aa(c);for(var g=1;g<b.length;g++){var h=b[g];if(c==a.aa(h)&&(!d||h.Ra)){f=!0;h.Ra||e||yi(a,b,g,"cleared");b.splice(g,1);b!=a.f&&(d=a.v,sd(d.Y[c>>>d.ka],b==a.D));h.Ra||fi(a);break}}return f}function zi(a,b){for(var c=1;c<b.length;c++)yi(a,b,c);return b.length-1}function yi(a,b,c,d){c=b[c];a.i(b[0]+" "+K(a,c.F)+(d?" "+d:c.Lc?' "'+c.Lc+'"':""))}
|
||||
function xi(a,b,c,d,e){var f=!1;c=a.aa(c);for(var g=1;g<b.length;g++){var h=b[g];if(c==a.aa(h)&&(!d||h.Ra)){f=!0;h.Ra||e||yi(a,b,g,"cleared");b.splice(g,1);b!=a.f&&(d=a.v,sd(d.Y[c>>>d.ka],b==a.D));h.Ra||fi(a);break}}return f}function zi(a,b){for(var c=1;c<b.length;c++)yi(a,b,c);return b.length-1}function yi(a,b,c,d){c=b[c];a.i(b[0]+" "+K(a,c.F)+(d?" "+d:c.Nc?' "'+c.Nc+'"':""))}
|
||||
function wi(a,b){if(void 0!==b)rd(a,b,1,a.f,!0),a.O=0;else for(b=1;b<a.f.length;b++){var c=a.f[b];if(c.Ra){if(!xi(a,a.f,c,!0))break;b=0}}}
|
||||
function rd(a,b,c,d,e){var f=!1;if(!a.nb++)for(var g=1;!f&&g<d.length;g++){var h=d[g];if(!e||h.Ra)for(var l=a.aa(h)&65535,m=0;m<c;m++)if(b+m==l){var n,f=!0;h.Ra&&(xi(a,d,h,!0),e=!0);if(n=h.Qc){for(var f=!1,r=0;r<n.length;r++)if(!Ai(a,n[r],!0)){if(n[r].indexOf("if")){f=!0;break}for(var t=r+1;t<n.length&&n[t].indexOf("else");t++)r++;if(t==n.length){f=!0;break}}a.b.A.W||(f=!0)}if(f){e||yi(a,d,g,"hit");break}}}a.nb--;return f}
|
||||
function rd(a,b,c,d,e){var f=!1;if(!a.nb++)for(var g=1;!f&&g<d.length;g++){var h=d[g];if(!e||h.Ra)for(var l=a.aa(h)&65535,m=0;m<c;m++)if(b+m==l){var n,f=!0;h.Ra&&(xi(a,d,h,!0),e=!0);if(n=h.Sc){for(var f=!1,r=0;r<n.length;r++)if(!Ai(a,n[r],!0)){if(n[r].indexOf("if")){f=!0;break}for(var t=r+1;t<n.length&&n[t].indexOf("else");t++)r++;if(t==n.length){f=!0;break}}a.b.A.W||(f=!0)}if(f){e||yi(a,d,g,"hit");break}}}a.nb--;return f}
|
||||
function Bi(a,b,c,d){var e=Y(b.F),f=a.oa(b,2),g,h;for(h in a.qb)if(g=a.qb[h][f&h])break;g||(g=li);var l=g[0];0<=a.Ib.indexOf(l)&&(g=li,l=g[0]);var m=h="",n=ii[l],r=g.length-1;l||r||(h=K(a,f));for(l=1;l<=r;l++){var t=g[l];if(void 0!==t){var v;v=a;var z=t,t=b,x="",B=z&61440;if(4096==B)t=t.F+((f&255)<<24>>23)&65535,x=K(v,t);else if(8192==B)t=t.F-((f&63)<<1)&65535,x=K(v,t);else if(12288==B)x=K(v,f&7,1);else if(24576==B)x=K(v,f&63,1);else if(32768==B)x=K(v,f&255,1);else if(B=f&z,z&4032&&(B>>=6,z>>=6),
|
||||
z&63)switch(z=B&7,B&56){case 0:x=si(z);break;case 8:x="@"+si(z);break;case 16:7>z?x="("+si(z)+")+":(B=v.oa(t,2),x="#"+K(v,B,0,!0));break;case 24:7>z?x="@("+si(z)+")+":(B=v.oa(t,2),x="@#"+K(v,B,0,!0));break;case 32:x="-("+si(z)+")";break;case 40:x="@-("+si(z)+")";break;case 48:B=v.oa(t,2);x=K(v,B,0,!0)+"("+si(z)+")";7==z&&(x=K(v,B+t.F&65535));break;case 56:B=v.oa(t,2),x="@"+K(v,B)+"("+si(z)+")",7==z&&(x="@"+K(v,B+t.F&65535))}v=x;if(!v||!v.length){h="INVALID";break}"string"!=typeof v&&(m=v[1],v=v[0]);
|
||||
0<h.length&&(h+=",");h+=v||"???"}}f="";g=K(a,e.F)+":";if(-1!==e.F&&-1!==b.F){do if(f+=" "+K(a,a.oa(e,2)),null==e.F)break;while(e.F!=b.F)}g+=xa(f,24);g+=xa(n,5);h&&(g+=" "+h);if(c||m)g=xa(g,60)+";"+(c||""),g=a.b.A.yb?g+("cycles="+Bd(a.b).toString()+" cs="+p(a.b.Ob)):g+(null!=d?"="+d.toString():""),m&&(g+=" @"+m);return g}function Ci(a,b){switch(b){case "N":a=Od(a.b);break;case "Z":a=Nd(a.b);break;case "V":a=Md(a.b);break;case "C":a=Ld(a.b);break;default:a=0}return b.charAt(0)+(a?"1":"0")+" "}
|
||||
0<h.length&&(h+=",");h+=v||"???"}}f="";g=K(a,e.F)+":";if(-1!==e.F&&-1!==b.F){do if(f+=" "+K(a,a.oa(e,2)),null==e.F)break;while(e.F!=b.F)}g+=xa(f,24);g+=xa(n,5);h&&(g+=" "+h);if(c||m)g=xa(g,60)+";"+(c||""),g=a.b.A.zb?g+("cycles="+Bd(a.b).toString()+" cs="+p(a.b.Ob)):g+(null!=d?"="+d.toString():""),m&&(g+=" @"+m);return g}function Ci(a,b){switch(b){case "N":a=Od(a.b);break;case "Z":a=Nd(a.b);break;case "V":a=Md(a.b);break;case "C":a=Ld(a.b);break;default:a=0}return b.charAt(0)+(a?"1":"0")+" "}
|
||||
function Z(a,b){var c="",d=a.b;if(8>b)c=si(b),c+="="+K(a,d.u[b]);else if(13>b)c="A"+(b-8)+"="+K(a,d.$a[b-8]);else if(16<=b&&20>b)c="S"+(b-16)+"="+K(a,d.La[b-16]);else switch(b){case 20:c="PS="+K(a,bd(d));break;case 21:c="IR="+K(a,d.Rb);break;case 22:c="ER="+K(a,d.va);break;case 23:c="SL="+K(a,d.hb);break;case 24:c="MMR0="+K(a,Wc(d));break;case 25:c="MMR1="+K(a,Yc(d));break;case 26:c="MMR2="+K(a,Zc(d));break;case 27:c="MMR3="+K(a,d.Ta);break;case 28:a.w&&(c="AR="+K(a,a.w.ua,3));break;case 29:a.w&&
|
||||
(c="DR="+K(a,a.w.sb));break;case 30:a.w&&mc(a.w)&&(c="SR="+K(a,a.w.Za,3))}c&&(c+=" ");return c}function Di(a,b){var c,d="";for(c=0;6>c;c++)d+=Z(a,c);d=d+"\n"+(Z(a,6)+Z(a,7));d+=Z(a,20)+Z(a,21)+Z(a,23);d+=Ci(a,"T")+Ci(a,"N")+Ci(a,"Z")+Ci(a,"V")+Ci(a,"C");b&&(b=d,c=""+(Z(a,24)+Z(a,25)),c+=Z(a,26)+Z(a,27)+Z(a,22),c=c+"\n"+(Z(a,30)+Z(a,28)+Z(a,29)),d=b+("\n"+c));return d}k.tc=function(a,b){return a[0]>b[0]?1:a[0]<b[0]?-1:0};
|
||||
function fh(a,b,c,d,e){var f=[],g;for(g in e){var h=e[g];"number"==typeof h&&(e[g]=h={o:h});var l=h.o,m=h.a;if(void 0!==l){var n=f,l=[l>>>0,g],r=Aa(n,l,a.tc);0>r&&n.splice(-(r+1),0,l)}m&&(h.a=m.replace(/''/g,'"'))}a.I.push({ef:b,F:c,bd:d,ga:e,rc:f})}function Ei(a,b,c){var d=[],e=a.aa(b)>>>0;for(b=0;b<a.I.length;b++){var f=a.I[b],g=f.F>>>0,h=f.bd;if(e>=g&&e<g+h){e=Aa(f.rc,[e-g],a.tc);0<=e?Fi(a,b,e,d):c&&(e=~e,Fi(a,b,e-1,d),Fi(a,b,e,d));break}}return d}
|
||||
function Fi(a,b,c,d){var e={},f=a.I[b].rc,g=0,h=null;0<=c&&c<f.length&&(g=f[c][0],h=f[c][1]);h&&(e=a.I[b].ga[h],h="."==h.charAt(0)?null:e.l||h);d.push(h);d.push(g);d.push(e.a);d.push(e.c)}function Gi(a,b){var c=b.match(/^\s*([A-Z_]?[A-Z0-9_]*)\s*(=?)\s*(.*)$/i);if(c){if(!c[1])return ci(a)||a.i("no variables"),!0;if(!c[2])return ci(a,c[1]);if(!c[3])return delete a.X[c[1]],!0;b=Zh(a,c[3]);return void 0!==b?(a.X[c[1]]=b,!0):!1}a.i("invalid assignment:"+b);return!1}
|
||||
(c="DR="+K(a,a.w.tb));break;case 30:a.w&&mc(a.w)&&(c="SR="+K(a,a.w.Za,3))}c&&(c+=" ");return c}function Di(a,b){var c,d="";for(c=0;6>c;c++)d+=Z(a,c);d=d+"\n"+(Z(a,6)+Z(a,7));d+=Z(a,20)+Z(a,21)+Z(a,23);d+=Ci(a,"T")+Ci(a,"N")+Ci(a,"Z")+Ci(a,"V")+Ci(a,"C");b&&(b=d,c=""+(Z(a,24)+Z(a,25)),c+=Z(a,26)+Z(a,27)+Z(a,22),c=c+"\n"+(Z(a,30)+Z(a,28)+Z(a,29)),d=b+("\n"+c));return d}k.uc=function(a,b){return a[0]>b[0]?1:a[0]<b[0]?-1:0};
|
||||
function fh(a,b,c,d,e){var f=[],g;for(g in e){var h=e[g];"number"==typeof h&&(e[g]=h={o:h});var l=h.o,m=h.a;if(void 0!==l){var n=f,l=[l>>>0,g],r=Aa(n,l,a.uc);0>r&&n.splice(-(r+1),0,l)}m&&(h.a=m.replace(/''/g,'"'))}a.I.push({gf:b,F:c,dd:d,ga:e,sc:f})}function Ei(a,b,c){var d=[],e=a.aa(b)>>>0;for(b=0;b<a.I.length;b++){var f=a.I[b],g=f.F>>>0,h=f.dd;if(e>=g&&e<g+h){e=Aa(f.sc,[e-g],a.uc);0<=e?Fi(a,b,e,d):c&&(e=~e,Fi(a,b,e-1,d),Fi(a,b,e,d));break}}return d}
|
||||
function Fi(a,b,c,d){var e={},f=a.I[b].sc,g=0,h=null;0<=c&&c<f.length&&(g=f[c][0],h=f[c][1]);h&&(e=a.I[b].ga[h],h="."==h.charAt(0)?null:e.l||h);d.push(h);d.push(g);d.push(e.a);d.push(e.c)}function Gi(a,b){var c=b.match(/^\s*([A-Z_]?[A-Z0-9_]*)\s*(=?)\s*(.*)$/i);if(c){if(!c[1])return ci(a)||a.i("no variables"),!0;if(!c[2])return ci(a,c[1]);if(!c[3])return delete a.X[c[1]],!0;b=Zh(a,c[3]);return void 0!==b?(a.X[c[1]]=b,!0):!1}a.i("invalid assignment:"+b);return!1}
|
||||
function Hi(a,b,c){var d=null;if(b=ni(a,b,!0)){a.aa(b);var e=Ei(a,b,!0);if(e.length){var f,g;e[0]&&(g="",(f=b.F-e[1])&&(g=" + "+q(f)),f=e[0]+" ("+K(a,e[1])+")"+g,c&&a.i(f),d=f);4<e.length&&e[4]&&(g="",(f=e[5]-b.F)&&(g=" - "+q(f)),f=e[4]+" ("+K(a,e[5])+")"+g,c&&a.i(f),d||(d=f))}else c&&a.i("no symbols")}return d}
|
||||
function ui(a,b){var c;if(b&&"?"==b[1])a.i("register commands:"),a.i("\tr\tdump registers"),a.i("\trm\tdump misc registers"),a.i("\trx [#]\tset flag or register x to [#]");else{var d=!1,e=a.b;null==c&&(c=!0);if(b&&1<b.length){var f=b[1];if("m"==f)d=!0;else{var g=f.indexOf("=");if(0<g)b=f.substr(g+1),f=f.substr(0,g);else if(2<b.length)b=b[2];else{a.i("missing value for "+b[1]);return}g=Zh(a,b);if(void 0===g)return;b=f.toUpperCase();switch(b){case "SP":case "R6":e.u[6]=g&65535;break;case "PC":case "R7":R(e,
|
||||
g);a.L=Y(e.u[7]);break;case "N":e.Z=g?32768:0;break;case "Z":e.$=g?0:1;break;case "V":e.V=g?32768:0;break;case "C":e.U=g?65536:0;break;case "PS":cd(e,g);break;case "IR":ad(e,g);break;case "ER":e.va=g;d=!0;break;case "SL":e.hb=g|255;break;case "MMR0":Xc(e,g);d=!0;break;case "MMR3":$c(e,g);d=!0;break;case "AR":a.w&&(d=a.w,jc(d,d.ua=g));d=!0;break;case "DR":a.w&&(d=a.w,ic(d,d.sb=g));d=!0;break;case "SR":if(a.w&&mc(a.w)){kc(a.w,g);d=!0;break}default:if("R"==b.charAt(0)&&(b=+b.charAt(1),0<=b&&6>b)){e.u[b]=
|
||||
g);a.L=Y(e.u[7]);break;case "N":e.Z=g?32768:0;break;case "Z":e.$=g?0:1;break;case "V":e.V=g?32768:0;break;case "C":e.U=g?65536:0;break;case "PS":cd(e,g);break;case "IR":ad(e,g);break;case "ER":e.va=g;d=!0;break;case "SL":e.hb=g|255;break;case "MMR0":Xc(e,g);d=!0;break;case "MMR3":$c(e,g);d=!0;break;case "AR":a.w&&(d=a.w,jc(d,d.ua=g));d=!0;break;case "DR":a.w&&(d=a.w,ic(d,d.tb=g));d=!0;break;case "SR":if(a.w&&mc(a.w)){kc(a.w,g);d=!0;break}default:if("R"==b.charAt(0)&&(b=+b.charAt(1),0<=b&&6>b)){e.u[b]=
|
||||
g&65535;break}a.i("unknown register: "+f);return}a.C.ra();a.i("updated registers:")}}a.i(Di(a,d));c&&(a.L=Y(e.u[7]),vi(a,K(a,a.L.F)))}}function Ii(a,b){b=ya(b);var c=b.match(/^(['"])(.*?)\1$/);c?1<c[2].length?a.i(c[2]):bi(a,null,c[2].charCodeAt(0)):Zh(a,b,!0)}
|
||||
function Ji(a,b,c){if("?"==c)a.i("trace commands:"),a.i("\tt [#]\ttrace # instructions"),a.i("\ttr [#]\ttrace # instructions with register updates"),a.i("\ttc [#]\ttrace # cycles"),a.i("note: bn [#] breaks after # instructions without updates");else{var d="t"!=b;c=ai(a,c,null,!0)||1;var e=1==c?0:1;"tc"==b&&(e=c,c=1);a.zb=b;Oa(c,function(){return vb(a,!0)&&a.kb(e,d,!1)},function(){a.w&&a.w.stop&&a.w.stop();a.C.ra(-1);vb(a,!1)})}}
|
||||
function Ji(a,b,c){if("?"==c)a.i("trace commands:"),a.i("\tt [#]\ttrace # instructions"),a.i("\ttr [#]\ttrace # instructions with register updates"),a.i("\ttc [#]\ttrace # cycles"),a.i("note: bn [#] breaks after # instructions without updates");else{var d="t"!=b;c=ai(a,c,null,!0)||1;var e=1==c?0:1;"tc"==b&&(e=c,c=1);a.rb=b;Oa(c,function(){return vb(a,!0)&&a.kb(e,d,!1)},function(){a.w&&a.w.stop&&a.w.stop();a.C.ra(-1);vb(a,!1)})}}
|
||||
function vi(a,b,c,d){if(b=ni(a,b,!0)){void 0===d&&(d=1);var e=256;if(void 0!==c)if("l"==c.charAt(0))c=ai(a,c.substr(1)),null!=c&&(d=c);else{d=ni(a,c,!0);if(!d||d.F<b.F)return;e=d.F-b.F;if(256<e){a.i("range too large");return}d=-1}c=0;for(var f;0<e&&d--;){f=wb(a,!1)||a.O?a.K:null;var g=null!=f?"cycles":null,h=Ei(a,b),l=b.F;if(h[0]&&d&&(!c&&d||0>h[0].indexOf("+"))){var m=h[0]+":";h[2]&&(m+=" "+h[2]);a.i(m)}h[3]&&(g=h[3],f=null);f=Bi(a,b,g,f);a.i(f);a.L=b;e-=b.F-l;c++}}}
|
||||
function Ai(a,b,c){var d=!0;try{b.length&&"end"!=b?c||a.i(">> "+b):(a.T&&(a.i("ended assemble at "+K(a,a.S.F)),a.L=a.S,a.T=!1),b="");var e=b.charAt(0);if('"'==e||"'"==e)return!0;a.ja=null;if(xb(a)&&0<b.length){a.T&&(b="a "+K(a,a.S.F)+" "+b);var f=!1,g=b.replace(/ +/g," ").split(" ");g[0]=g[0].toLowerCase();if(g&&g.length)for(var h=g[0],l=h.charAt(0),m=1;m<h.length;m++){var n=h.charAt(m);if("?"==l||"r"==l||"a">n||"z"<n){g[0]=h.substr(m);g.unshift(h.substr(0,m));break}}switch(g[0].charAt(0)){case "a":var r=
|
||||
ni(a,g[1],!0);if(r)if(a.S=r,void 0===g[2])a.i("begin assemble at "+K(a,r.F)),a.T=!0,a.C.ra();else{var t;a.i("not supported yet");t=[];if(t.length){for(var v=0;v<t.length;v++)a.Fb(r,t[v],1);a.i(Bi(a,a.S))}}break;case "b":a:{var z=g[0],x=g[1],B=b;if("?"==x)a.i("breakpoint commands:"),a.i("\tbp [#]\tset exec breakpoint at addr #"),a.i("\tbr [#]\tset read breakpoint at addr #"),a.i("\tbw [#]\tset write breakpoint at addr #"),a.i("\tbc [#]\tclear breakpoint at addr #"),a.i("\tbl\tlist all breakpoints"),
|
||||
|
|
@ -284,14 +284,14 @@ P):"r"==ma?a.ob(a.M,P):"w"==ma?a.ob(a.D,P):a.i("unknown breakpoint command: "+ma
|
|||
mb.length&&a.i("dump extension commands:\n\t"+mb)}else if("state"==pa){var Mg=Ki(a.C,!0);"console"==Qa?console.log(Mg):(a.Wa&&(a.Wa.value=""),a.i(Mg))}else if("symbols"==pa)for(var Sd=0;Sd<a.I.length;Sd++){var Td=a.I[Sd],nb;for(nb in Td.ga)if("."!=nb.charAt(0)){var Ng=Td.ga[nb].o;if(void 0!==Ng){var Og=Td.ga[nb].l;Og&&(nb=Og);a.i(K(a,Ng)+" "+nb)}}}else{if("d"==Pa){for(lb in Cb)if(g[1]==lb){var Pg=a.Ma[lb];Pg?(g.shift(),g.shift(),Pg(g)):a.i("no dump registered for "+pa);break a}pa||(Pa=a.Lb||"dw")}else a.Lb=
|
||||
Pa;if("dh"==Pa){var Qg=pa,Rg=Qa,Sg="",Tg=0,ia=a.ba,qa=a.H;if(qa.length){var ca=+Qg||a.pb,Wb=+Rg||10;isNaN(ca)?ca=Wb:Sg="more ";ca>qa.length&&(a.i("note: only "+qa.length+" available"),ca=qa.length);ia-=ca;0>ia&&(null==qa[qa.length-1].F?(ca=ia+ca,ia=0):ia+=qa.length);var Ud=[];"call"==Rg&&(Wb=1E5,Ud=["CALL"]);for(void 0!==Qg&&a.i(ca+" instructions earlier:");0<Wb&&ia!=a.ba;){var Ug=qa[ia++];if(null==Ug.F)break;var Xb=Y(Ug.F),cj=ca--,Vg=Bi(a,Xb,"history",cj);(!Ud.length||0<=Vg.indexOf(Ud[0]))&&a.i(Vg);
|
||||
Xb.fc&&(ia+=Xb.fc,Wb-=Xb.fc,ca-=Xb.fc);ia>=qa.length&&(ia=0);a.pb=ca;Tg++;Wb--}}Tg||(a.i("no "+Sg+"history available"),a.pb=void 0)}else{var ob=ni(a,pa);if(ob){var Yb=0,Vd=!1,Wd="ds"==Pa;Qa&&(Vd=!0,"l"==Qa.charAt(0)&&(Vd=!1,Qa=Qa.substr(1)||bj),Yb=ai(a,Qa)>>>0,65536<Yb&&(Yb=65536));for(var pb="dd"==Pa?4:"db"==Pa?1:2,Mc=(Vd?Yb-ob.F:pb*Yb)||128,Xd=Wd?16:a.ca,dj=(Mc+Xd-1)/Xd|0||1,Ra="";dj--&&0<Mc;){for(var Sa="",Yd="",pa=K(a,ob.F),Nc=Xd,Zb=0,$b=0;0<Nc&&0<Mc;){var qb=1,Oc=1==pb?a.Yb(ob,qb):a.oa(ob,qb=
|
||||
2),Zb=Zb|Oc<<($b<<3),$b=$b+qb;$b==pb&&(Wd?(Sa&&(Sa+=","),Sa+="0x"+p(Zb,2*pb)):(Sa+=K(a,Zb,pb),Sa+=1==pb?9==Nc?"-":" ":" "),Zb=$b=0);Nc-=qb;for(Mc-=qb;qb--;)var Zd=Oc&255,Yd=Yd+(32<=Zd&&128>Zd?String.fromCharCode(Zd):"."),Oc=Oc>>8}Ra&&(Ra+="\n");Ra=Wd?Ra+(Sa+","):Ra+(pa+" "+Sa+(0==Nc?" "+Yd:""))}Ra&&a.i(Ra);a.mb=ob}}}}break;case "e":if("else"==g[0])break;var rb,$d,ae,be,ce=g[0],de=g[1];"eb"==ce?(rb=1,$d=255,ae=a.Yb,be=a.Fb):"e"==ce||"ew"==ce?(rb=2,$d=65535,ae=a.oa,be=a.vb):de=null;if(null==de)a.i("edit memory commands:"),
|
||||
2),Zb=Zb|Oc<<($b<<3),$b=$b+qb;$b==pb&&(Wd?(Sa&&(Sa+=","),Sa+="0x"+p(Zb,2*pb)):(Sa+=K(a,Zb,pb),Sa+=1==pb?9==Nc?"-":" ":" "),Zb=$b=0);Nc-=qb;for(Mc-=qb;qb--;)var Zd=Oc&255,Yd=Yd+(32<=Zd&&128>Zd?String.fromCharCode(Zd):"."),Oc=Oc>>8}Ra&&(Ra+="\n");Ra=Wd?Ra+(Sa+","):Ra+(pa+" "+Sa+(0==Nc?" "+Yd:""))}Ra&&a.i(Ra);a.mb=ob}}}}break;case "e":if("else"==g[0])break;var rb,$d,ae,be,ce=g[0],de=g[1];"eb"==ce?(rb=1,$d=255,ae=a.Yb,be=a.Fb):"e"==ce||"ew"==ce?(rb=2,$d=65535,ae=a.oa,be=a.wb):de=null;if(null==de)a.i("edit memory commands:"),
|
||||
a.i("\teb [a] [...] edit bytes at address a"),a.i("\tew [a] [...] edit words at address a");else{var Pc=ni(a,de);if(Pc)for(var Qc=2;Qc<g.length;Qc++){var ac=Zh(a,g[Qc]);if(void 0===ac){a.i("unrecognized value: "+g[Qc]);break}ac&~$d&&a.i("warning: "+p(ac)+" exceeds "+rb+"-byte value");a.i("changing "+K(a,Pc.F)+(H(a,64)?"":" from "+K(a,ae.call(a,Pc),rb))+" to "+K(a,ac,rb));be.call(a,Pc,ac,rb)}}break;case "g":a:{var Wg=g[1],ej=b;if(void 0!==Wg){var ee=ni(a,Wg,!0);if(!ee)break a;ri(a,ee,ej);a.ob(a.f,
|
||||
ee,!0)}a.jb(!0,c)}break;case "h":a.A.W?(c||a.i("halting"),a.da()):wb(a,!0)||c||a.i("already halted");break;case "i":if("if"==g[0]){var fe;var bc=b.substr(2),bc=ya(bc);Zh(a,bc)?(c||a.i("true: "+bc),fe=!0):(c||a.i("false: "+bc),fe=!1);fe||(d=!1);break}f=!0;break;case "k":var fj=g[0];if("?"==g[1])a.i("stack trace commands:"),a.i("\tk\tshow frame addresses"),a.i("\tks\tshow symbol information");else{var ge=0,he=Y(),cc=Y(a.b.u[6]);for(a.i("stack trace for "+K(a,cc.F));10>ge;){for(var Ta=null,gj=256;65536>
|
||||
cc.F>>>0;){he.F=a.oa(cc,2);if(null==cc.F||!gj--)break;if(!(he.F&1)){for(var hj=a,Rc=he,Xg=null,dc=Rc.F,Yg=dc,ie=1;6>=ie&&dc;ie++){if(2<ie){Rc.F=dc;var Sc=Bi(hj,Rc);if(0<=Sc.indexOf("JSR")){var Zg=Sc.indexOf(" ");if(dc+(Sc.indexOf(" ",Zg+1)-Zg-1)/2==Yg){Xg=Sc;break}}}dc-=2}Rc.F=Yg;if(Ta=Xg)break}}if(!Ta||null==Ta)break;var $g=null;if("ks"==fj){var ah=Ta.match(/[0-9A-F]+$/);ah&&($g=Hi(a,ah[0]))}Ta=xa(Ta,50)+" ;"+($g||"stack="+K(a,cc.F));a.i(Ta);ge++}ge||a.i("no return addresses found")}break;case "l":if("ln"==
|
||||
g[0]){Hi(a,g[1],!0);break}f=!0;break;case "m":a:{var ra,sa=null,G=g[1];"?"==G&&(G=void 0);if(void 0!==G){var Ga=0;if("all"==G)Ga=1878917119,G=null;else if("on"==G)sa=!0,G=null;else if("off"==G)sa=!1,G=null;else{"keys"==G&&(G="key");"kbd"==G&&(G="keyboard");for(ra in Cb)if(G==ra){Ga=Cb[ra];sa=!!(a.la&Ga);break}if(!Ga){a.i("unknown message category: "+G);break a}}if(Ga)if("on"==g[2])a.la|=Ga,sa=!0;else if("off"==g[2]&&(a.la&=~Ga,sa=!1,1073741824==Ga)){for(var je=0;je<a.Aa.length;je++)a.i(a.Aa[je]);
|
||||
a.Aa=[]}}var ij=0,ec="";for(ra in Cb)if(!G||G==ra){var jj=!!(a.la&Cb[ra]);if(null===sa||sa==jj)ec&&(ec+=","),++ij%10||(ec+="\n\t"),"key"==ra&&(ra="keys"),ec+=ra}void 0===G&&a.i("message commands:\n\tm [category] [on|off]\tturn categories on/off");a.i((null!==sa?sa?"messages on: ":"messages off: ":"message categories:\n\t")+(ec||"none"));fi(a)}break;case "p":if("print"==g[0]){Ii(a,b.substr(5));break}var kj=g[0];if("?"==g[1])a.i("step commands:"),a.i("\tp\tstep over instruction"),a.i("\tpr\tstep over instruction with register update");
|
||||
else{var bh="pr"==kj?1:0,ch=1+bh;if(a.O)a.i("step in progress");else{var Tc=Y(a.b.u[7]),fc=a.oa(Tc);3==fc||4==fc||34816==(fc&65280)||35072==(fc&65280)?(a.O=ch,oi(Tc,2)):2048==(fc&65024)&&(Bi(a,Tc),a.O=ch);a.O?(a.ob(a.f,Tc,!0),a.jb()||(a.C&&a.C.ub(),a.O=0)):Ji(a,bh?"tr":"t")}}break;case "r":if("reset"==b){a.C&&a.C.reset();break}ui(a,g);break;case "s":a:switch(g[1]){case "base":if(g[2]){var gc=+g[2];if(8==gc||10==gc||16==gc)a.ca=gc;else{a.i("invalid base: "+gc);break}}a.i("default base: "+a.ca);break;
|
||||
case "cs":var hc;void 0!==g[3]&&(hc=+g[3]);switch(g[2]){case "int":a.b.Ab=hc;break;case "start":a.b.Pb=hc;break;case "stop":a.b.Bb=hc;break;default:a.i("unknown cs option");break a}void 0!==hc&&yd(a.b);a.i("checksums "+(a.b.A.yb?"enabled":"disabled"));break;case "sp":void 0!==g[2]&&(Cd(a.b,+g[2])||a.i("warning: using 1x multiplier, previous target not reached"));a.i("target speed: "+(a.b.rb.toFixed(2)+"Mhz")+" ("+a.b.gb+"x)");break;default:if(g[1]){a.i("unknown option: "+g[1]);break}case "?":a.i("debugger options:"),
|
||||
else{var bh="pr"==kj?1:0,ch=1+bh;if(a.O)a.i("step in progress");else{var Tc=Y(a.b.u[7]),fc=a.oa(Tc);3==fc||4==fc||34816==(fc&65280)||35072==(fc&65280)?(a.O=ch,oi(Tc,2)):2048==(fc&65024)&&(Bi(a,Tc),a.O=ch);a.O?(a.ob(a.f,Tc,!0),a.jb()||(a.C&&a.C.vb(),a.O=0)):Ji(a,bh?"tr":"t")}}break;case "r":if("reset"==b){a.C&&a.C.reset();break}ui(a,g);break;case "s":a:switch(g[1]){case "base":if(g[2]){var gc=+g[2];if(8==gc||10==gc||16==gc)a.ca=gc;else{a.i("invalid base: "+gc);break}}a.i("default base: "+a.ca);break;
|
||||
case "cs":var hc;void 0!==g[3]&&(hc=+g[3]);switch(g[2]){case "int":a.b.Ab=hc;break;case "start":a.b.Pb=hc;break;case "stop":a.b.Bb=hc;break;default:a.i("unknown cs option");break a}void 0!==hc&&yd(a.b);a.i("checksums "+(a.b.A.zb?"enabled":"disabled"));break;case "sp":void 0!==g[2]&&(Cd(a.b,+g[2])||a.i("warning: using 1x multiplier, previous target not reached"));a.i("target speed: "+(a.b.sb.toFixed(2)+"Mhz")+" ("+a.b.gb+"x)");break;default:if(g[1]){a.i("unknown option: "+g[1]);break}case "?":a.i("debugger options:"),
|
||||
a.i("\tbase #\t\tset default base to #"),a.i("\tcs int #\tset checksum cycle interval to #"),a.i("\tcs start #\tset checksum cycle start count to #"),a.i("\tcs stop #\tset checksum cycle stop count to #"),a.i("\tsp #\t\tset speed multiplier to #")}break;case "t":Ji(a,g[0],g[1]);break;case "u":vi(a,g[1],g[2],8);break;case "v":if("var"==g[0]){Gi(a,b.substr(3))||(d=!1);break}if("ver"==g[0]){a.i("PDPjs version 1.30.3 ("+a.b.fb+",RELEASE"+(Ab?",TYPEDARRAYS":",LONGARRAYS")+")");a.i(window?window.navigator.userAgent:
|
||||
"");break}f=!0;break;case "?":if(g[1]){Ii(a,b.substr(1));break}var ke="commands:",le;for(le in hi)ke+="\n"+xa(le,9)+hi[le];Ge(a)||(ke+="\nnote: history disabled if no exec breakpoints");a.i(ke);break;default:f=!0}f&&(a.i("unknown command: "+b),d=!1)}}catch(dh){a.i("debugger error: "+(dh.stack||dh.message)),d=!1}return d}function Ad(a,b,c){b=Xh(a,b,c);for(var d in b)if(!Ai(a,b[+d]))return!1;return!0}
|
||||
$a(function(){for(var a=E(document,"pdp11","debugger"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new di(d);D(d,c)}});
|
||||
|
|
@ -301,23 +301,23 @@ new Q(this,"1.30.3"),Pi(this.K)?b=null:delete this.K);!b&&this.f&&(b=Qi(this))&&
|
|||
function Mi(a,b){if(!b){var c;if("object"==typeof resources&&(c=resources.parms))try{b=eval("("+c+")")}catch(d){u(d.message+" ("+c+")")}}a.T=b}function wd(a,b,c){var d=b.toLowerCase(),d=eb[b]||eb[d];void 0===d&&a.T&&(d=a.T[b]);void 0===d&&c&&(d=c[b]);void 0===d&&"object"==typeof resources&&resources[b]&&(d=b);return d}function Ri(a,b,c){for(var d=sb(a.id),e=0;e<=d.length;e++){var f=e<d.length?d[e]:a;if(!xb(f)){xb(f,function(){Ri(a,b,c)});return}}b.call(a,c)}
|
||||
function Si(a,b){var c=new Q(a,"1.30.3","validate");if(Pi(c)&&Ti(c)){var d=c.get("timestamp"),e=b?b.get("timestamp"):"unknown";d!=e&&(a.R("Machine state may be out-of-date\n("+d+" vs. "+e+")\nCheck your browser's local storage limits"),b||c.clear())}}k=Li.prototype;
|
||||
k.Qb=function(a){void 0===a&&(a=this.f||(this.I?1:Ni));if(!this.C){this.C++;var b=!1,c=!1;this.O=!1;var d=this.K||new Q(this,"1.30.3");if(-1==a)b=!0;else if(a>Ni){if(Pi(d,this.I)){this.B=new Q(this,"1.30.3","failsafe");Pi(this.B)&&(Ui(this,d),a=2,Vi(this.B));this.B.set("timestamp",Ca());Wi(this.B);var e=this.f&&!this.D;if(1==a||Ha("Click OK to restore the previous PDPjs machine state, or CANCEL to reset the machine.")){if(c=Ti(d)){var f=d.get("code"),g=d.get("data");f&&("ok"==f?Pi(d,g):("error"==
|
||||
f&&"no machine state"!=g?(this.R("Error: "+g),"unable to verify user"==g&&(La("user",""),this.g=null)):this.i(f+": "+g),Vi(d),Pi(d)?(c=Ti(d),e=!0):c=!1))}e&&Si(this,c?d:null)}else 2==a&&d.clear()}else Si(this);delete this.I;delete this.K}e=sb(this.id);for(f=0;f<e.length;f++)g=e[f],g!==this&&g!=this.b&&(c=Xi(this,g,d,b,c));b=[d,a,c];-1!=a?Ri(this,this.uc,b):this.uc(b)}};
|
||||
function Xi(a,b,c,d,e){if(!b.A.ia){b.A.ia=!0;if(b.Ka){var f=null;e&&((f=c.get(b.id))||(f=c.get(b.id.replace(/[a-z0-9]\./i,"."))));"string"===typeof f&&(f=null);!b.Ka(f,d)&&f&&(u("Unable to restore state for "+b.type),a.M&&!a.S?(c.clear(),a.f=Ni,window&&window.location.reload()):a.O=!0,b.Ka(null),e=!1)}if(!d&&b.Cc)for(a=b.Cc.split("|"),c=0;c<a.length;c++)b.status(a[c])}return e}
|
||||
k.uc=function(a){var b=a[0],c=0>a[1];a=a[2];this.ca=!0;this.A.ia=!0;var d=this.G.power;d&&(d.textContent="Shutdown");this.b&&(Xi(this,this.b,b,c,a),this.ra(),this.b.xb());this.O&&(Ui(this,b),b.clear());!c&&this.B&&(this.B.clear(),delete this.B);this.C=0};
|
||||
f&&"no machine state"!=g?(this.R("Error: "+g),"unable to verify user"==g&&(La("user",""),this.g=null)):this.i(f+": "+g),Vi(d),Pi(d)?(c=Ti(d),e=!0):c=!1))}e&&Si(this,c?d:null)}else 2==a&&d.clear()}else Si(this);delete this.I;delete this.K}e=sb(this.id);for(f=0;f<e.length;f++)g=e[f],g!==this&&g!=this.b&&(c=Xi(this,g,d,b,c));b=[d,a,c];-1!=a?Ri(this,this.vc,b):this.vc(b)}};
|
||||
function Xi(a,b,c,d,e){if(!b.A.ia){b.A.ia=!0;if(b.Ka){var f=null;e&&((f=c.get(b.id))||(f=c.get(b.id.replace(/[a-z0-9]\./i,"."))));"string"===typeof f&&(f=null);!b.Ka(f,d)&&f&&(u("Unable to restore state for "+b.type),a.M&&!a.S?(c.clear(),a.f=Ni,window&&window.location.reload()):a.O=!0,b.Ka(null),e=!1)}if(!d&&b.Dc)for(a=b.Dc.split("|"),c=0;c<a.length;c++)b.status(a[c])}return e}
|
||||
k.vc=function(a){var b=a[0],c=0>a[1];a=a[2];this.ca=!0;this.A.ia=!0;var d=this.G.power;d&&(d.textContent="Shutdown");this.b&&(Xi(this,this.b,b,c,a),this.ra(),this.b.yb());this.O&&(Ui(this,b),b.clear());!c&&this.B&&(this.B.clear(),delete this.B);this.C=0};
|
||||
function Ui(a,b){if(Ha("There may be a problem with your PDPjs machine.\n\nTo help us diagnose it, click OK to send this PDPjs machine state to http://www.pcjs.org.")){var c=a.g||"";b=b.toString();var d={app:"PDPjs",ver:"1.30.3"};d.url=a.ba;d.user=c;d.type="bug";d.data=b;Da("http://www.pcjs.org/api/v1/report",d,!0)}}
|
||||
function Ki(a,b,c){var d,e="none";if(a.C)return null;a.C--;var f=new Q(a,"1.30.3"),g=new Q(a,"1.30.3","validate"),h=Ca();g.set("timestamp",h);f.set("timestamp",h);f.set("version","1.30.3");f.set("url",window?window.location.href:null);f.set("browser",window?window.navigator.userAgent:"");a.b&&a.b.Ja&&(c&&a.b.da(),d=a.b.Ja(b,c),"object"===typeof d&&f.set(a.b.id,d),c&&(a.b.A.ia=!1,!1===d&&(e=null)));for(var h=sb(a.id),l=0;l<h.length;l++){var m=h[l];m.A.ia&&(m.Ja&&(d=m.Ja(b,c),"object"===typeof d&&f.set(m.id,
|
||||
d)),c&&(m.A.ia=!1,!1===d&&(e=null)))}e&&(c?(h=d=!1,b?(a.g&&Yi(a,a.g,f.toString()),Wi(g)&&Wi(f)||(e=null,d=h=!0)):a.f&&(d=!0,h=3==a.f),d&&f.clear(h)):e=f.toString());c&&(a.A.ia=!1,b=a.G.power)&&(b.textContent="Power");a.C=0;return e}
|
||||
k.reset=function(){this.v&&this.v.reset&&(F(this,"Resetting "+this.v.type),this.v.reset());this.b&&this.b.reset&&(F(this,"Resetting "+this.b.type),this.b.reset());for(var a=sb(this.id),b=0;b<a.length;b++){var c=a[b];c!==this&&c!==this.v&&c!==this.b&&c.reset&&(F(this,"Resetting "+c.type),c.reset())}this.ra(-1)};k.start=function(a,b){for(var c=sb(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.start&&e.start(a,b)}this.ra(-1)};
|
||||
k.stop=function(a,b){for(var c=sb(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.stop&&e.stop(a,b)}this.ra(-1)};
|
||||
k.ra=function(a){if(this.b){var b=this.b,c=a||0,d=b.G.speed;d&&(0>=c||30<=(b.zb+=c))&&(d.textContent=b.A.W?b.xa.toFixed(2)+"Mhz":"Stopped",b.zb=0)}if(this.w&&(b=this.w,a=a||0,b.D)){c=b.b.A.W;d=!!(b.b.J&4);if(0>=a||60<=(b.B+=a)){for(var e=0;e<b.b.u.length;e++)Qb(b,"R"+e,b.b.u[e]);e=bd(b.b);Qb(b,"PS",e);Qb(b,"NF",e&8?1:0,1);Qb(b,"ZF",e&4?1:0,1);Qb(b,"VF",e&2?1:0,1);Qb(b,"CF",e&1?1:0,1);b.B=0}jc(b,0<a&&c&&!d?b.b.Mb:b.ua);ic(b,b.sb);a=b.b;a=a.M?a.Ta&16?1:2:4;lc(b,"B22",a&1);lc(b,"B18",a&2);lc(b,"B16",
|
||||
k.ra=function(a){if(this.b){var b=this.b,c=a||0,d=b.G.speed;d&&(0>=c||30<=(b.Ib+=c))&&(d.textContent=b.A.W?b.xa.toFixed(2)+"Mhz":"Stopped",b.Ib=0)}if(this.w&&(b=this.w,a=a||0,b.D)){c=b.b.A.W;d=!!(b.b.J&4);if(0>=a||60<=(b.B+=a)){for(var e=0;e<b.b.u.length;e++)Qb(b,"R"+e,b.b.u[e]);e=bd(b.b);Qb(b,"PS",e);Qb(b,"NF",e&8?1:0,1);Qb(b,"ZF",e&4?1:0,1);Qb(b,"VF",e&2?1:0,1);Qb(b,"CF",e&1?1:0,1);b.B=0}jc(b,0<a&&c&&!d?b.b.Mb:b.ua);ic(b,b.tb);a=b.b;a=a.M?a.Ta&16?1:2:4;lc(b,"B22",a&1);lc(b,"B18",a&2);lc(b,"B16",
|
||||
a&4)}};
|
||||
k.wa=function(a,b,c){var d=this;switch(b){case "power":return this.G[b]=c,c.onclick=function(){d.C||(d.A.ia?Ki(d,!1,!0):Ri(d,d.Qb))},!0;case "reset":return this.G[b]=c,c.onclick=function(){if(d.A.ia&&!d.C)if(d.f&&!d.H){var a=Ha("Click OK to save changes to this PDPjs machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded.");Ki(d,a,!0);!a&&d.M?window&&window.location.reload():(a||(d.vc=!0),d.Qb(Ni),d.vc=!1)}else d.reset(),d.b&&d.b.xb()},!0;case "save":if(ua(Fa(),"pcjs.org"))c.parentNode.removeChild(c);else return this.G[b]=
|
||||
k.wa=function(a,b,c){var d=this;switch(b){case "power":return this.G[b]=c,c.onclick=function(){d.C||(d.A.ia?Ki(d,!1,!0):Ri(d,d.Qb))},!0;case "reset":return this.G[b]=c,c.onclick=function(){if(d.A.ia&&!d.C)if(d.f&&!d.H){var a=Ha("Click OK to save changes to this PDPjs machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded.");Ki(d,a,!0);!a&&d.M?window&&window.location.reload():(a||(d.wc=!0),d.Qb(Ni),d.wc=!1)}else d.reset(),d.b&&d.b.yb()},!0;case "save":if(ua(Fa(),"pcjs.org"))c.parentNode.removeChild(c);else return this.G[b]=
|
||||
c,c.onclick=function(){var a=Oi(d,!0);if(a){var b=!!(d.f&&!d.H||d.M),c=Ki(d,b);b?Yi(d,a,c):d.R("Resume disabled, machine state not saved")}},!0}return!1};
|
||||
function Oi(a,b){var c=a.g;c||((c=Ka("user"),void 0!==c)?!c&&b&&(b=null,window&&(b=window.prompt("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below.","")),c=b)&&((c=Zi(a,c))||a.R("The user ID is invalid.")):b&&a.R("Browser local storage is not available"));return c}
|
||||
function Zi(a,b){a.g=null;b=Da(Fa()+"/api/v1/user?req=verify&user="+b);var c=b[1];if(!b[0]&&c)try{b=eval("("+c+")"),b.code&&"ok"==b.code&&(La("user",b.data),a.g=b.data)}catch(d){u(d.message+" ("+c+")")}return a.g}function Qi(a){var b=null;a.g&&(b=Fa()+"/api/v1/user?req=load&user="+a.g+"&state="+$i(a,"1.30.3"));return b}
|
||||
function Yi(a,b,c){if(c){var d={req:"store"};d.user=b;d.state=$i(a,"1.30.3");d.data=c;b=Da(Fa()+"/api/v1/user",d);d=b[0];if(b[1]){if(d){var e=d.indexOf("\n");0<e&&(d=d.substr(0,e));d.indexOf("Error: ")||(d=d.substr(7))}d='{"code":'+b[1]+',"data":"'+d+'"}'}b=JSON.parse(d);b&&"ok"==b.code?a.R("Machine state saved to server"):c&&(c=b&&b.data||"unable to save machine state",c="error"==b.code?"Error: "+c:"Error "+b.code+": "+c,a.R(c),La("user",""),a.g=null)}}
|
||||
function rh(a){var b;a=sb(a.id);for(var c=0;c<a.length;c++){var d=a[c];if(b)b==d&&(b=null);else if("RAM"==d.type)return d}return null}k.ub=function(a){if(this.Wa){var b=0,c=0;!a&&window&&(b=window.scrollX,c=window.scrollY);this.Wa.focus();!a&&window&&window.scrollTo(b,c)}};$a(function(){for(var a=E(document,"pdp11-machine"),b=0;b<a.length;b++)for(var c=a[b],d=C(c),c=E(c,"pdp11","computer"),e=0;e<c.length;e++){var f=c[e],g=C(f),g=new Li(g,d,!0);D(g,f);g.L&&Ri(g,g.Qb)}});
|
||||
Va.show.push(function(){for(var a=E(document,"pdp11","computer"),b=0;b<a.length;b++){var c=C(a[b]);(c=ub("Computer",c.id))&&c.ca&&!c.A.ia&&c.Qb(-1)}});Va.exit.push(function(){for(var a=E(document,"pdp11","computer"),b=0;b<a.length;b++){var c=C(a[b]);(c=ub("Computer",c.id))&&c.A.ia&&Ki(c,!(!c.f||c.H),!0)}});function Q(a,b,c){this.id=a.id;this.key=$i(a,b,c);this.j=a.j;Vi(this,a.nd)}function $i(a,b,c){a=a.id;if(b){var d=b.indexOf(".");0<d&&(a+=".v"+b.substr(0,d))}c&&(a+="."+c);return a}
|
||||
function rh(a){var b;a=sb(a.id);for(var c=0;c<a.length;c++){var d=a[c];if(b)b==d&&(b=null);else if("RAM"==d.type)return d}return null}k.vb=function(a){if(this.Wa){var b=0,c=0;!a&&window&&(b=window.scrollX,c=window.scrollY);this.Wa.focus();!a&&window&&window.scrollTo(b,c)}};$a(function(){for(var a=E(document,"pdp11-machine"),b=0;b<a.length;b++)for(var c=a[b],d=C(c),c=E(c,"pdp11","computer"),e=0;e<c.length;e++){var f=c[e],g=C(f),g=new Li(g,d,!0);D(g,f);g.L&&Ri(g,g.Qb)}});
|
||||
Va.show.push(function(){for(var a=E(document,"pdp11","computer"),b=0;b<a.length;b++){var c=C(a[b]);(c=ub("Computer",c.id))&&c.ca&&!c.A.ia&&c.Qb(-1)}});Va.exit.push(function(){for(var a=E(document,"pdp11","computer"),b=0;b<a.length;b++){var c=C(a[b]);(c=ub("Computer",c.id))&&c.A.ia&&Ki(c,!(!c.f||c.H),!0)}});function Q(a,b,c){this.id=a.id;this.key=$i(a,b,c);this.j=a.j;Vi(this,a.he)}function $i(a,b,c){a=a.id;if(b){var d=b.indexOf(".");0<d&&(a+=".v"+b.substr(0,d))}c&&(a+="."+c);return a}
|
||||
Q.prototype={constructor:Q,set:function(a,b){try{this[this.id][a]=b}catch(c){}},get:function(a){return this[this.id][a]||null},value:function(){return this[this.id]},data:function(){return this[this.id]},toString:function(){var a=this[this.id];return"string"==typeof a?a:JSON.stringify(a)},clear:function(a){Vi(this);var b=[];try{for(var c=0,d=window.localStorage.length;c<d;c++)b.push(window.localStorage.key(c))}catch(e){}for(c=0;c<b.length;c++)if((d=b[c])&&(a||d.substr(0,this.key.length)==this.key)){try{window.localStorage.removeItem(d)}catch(e){}b.splice(c,
|
||||
1);c=0}}};function Vi(a,b){a[a.id]={};b&&a.set("parms",b);a.b=!1}function Wi(a){var b=!0;if(Ja()){var c=JSON.stringify(a[a.id]);La(a.key,c)||(u("Unable to store "+c.length+" bytes in browser local storage"),b=!1)}return b}function Ti(a){var b=!0;try{a[a.id]=JSON.parse(a[a.id])}catch(c){u(c.message||c),b=!1}return b}function Pi(a,b){return b?(a[a.id]=b,a.b=!0):a.b?!0:Ja()&&(b=Ka(a.key))?(a[a.id]=b,a.b=!0):!1}var aj=0;
|
||||
function lj(a,b,c,d,e,f){e("Loading "+a+"...");Da(a,null,!0,function(g,h,l){l?(h||(h="unable to load "+a+" ("+l+")"),f(h,null)):mj(h,a,b,c,d,e,f)})}
|
||||
|
|
|
|||
|
|
@ -45,194 +45,194 @@ d.K[f++]=e[c]>>8&255,d.K[f++]=e[c]>>16&255,d.K[f++]=e[c]>>24&255;else d.K=g;d.X=
|
|||
function v(){return"http://"+(window?window.location.host:"www.pcjs.org")}function t(a){window&&window.alert(a)}function ua(a){var b=!1;window&&(b=window.confirm(a));return b}var xa=null;function ya(){if(null==xa){var a=!1;if(window)try{window.localStorage.setItem("PCjs.localStorage","PCjs.localStorage"),a="PCjs.localStorage"==window.localStorage.getItem("PCjs.localStorage"),window.localStorage.removeItem("PCjs.localStorage")}catch(b){a=!1}xa=a}return xa}
|
||||
function za(a){var b;if(window)try{b=window.localStorage.getItem(a)}catch(c){}return b}function Aa(a,b){try{return window.localStorage.setItem(a,b),!0}catch(c){}return!1}function Ba(a){if(window){var b=window?window.navigator.userAgent:"";return"iOS"==a&&b.match(/(iPod|iPhone|iPad)/)&&b.match(/AppleWebKit/)||"MSIE"==a&&b.match(/(MSIE|Trident)/)||0<=b.indexOf(a)?!0:!1}return!1}var x={init:[],show:[],exit:[]},Ca=!1,Da=!1,Ea=!0;
|
||||
function Fa(a,b){if(window){var c=window[a];window[a]="function"!==typeof c?b:function(){c&&c();b()}}}function Ga(a){x.init.push(a)}function Ha(a){if(Ea)try{for(var b=0;b<a.length;b++)a[b]()}catch(c){t(""+("An unexpected exception occurred:\n\n"+c.message+"\n\nPlease send this information to support@pcjs.org. Thanks."))}}function Ia(a){!Ea&&a?(Ea=!0,Ca&&Ja("init"),Da&&Ja("show")):Ea=a}function Ja(a){x[a]&&Ha(x[a])}Fa("onload",function(){Ca=!0;Ha(x.init)});Fa("onpageshow",function(){Da=!0;Ha(x.show)});
|
||||
Fa(Ba("Opera")||Ba("iOS")?"onunload":"onbeforeunload",function(){Ha(x.exit)});function y(a,b,c,d){this.type=a;b||(b={id:"",name:""});this.id=b.id||"";this.name=b.name;this.Ub=b.comment;this.xd=b;b=this.id.indexOf(".");0>b?this.Fa=this.id:(this.ra=this.id.substr(0,b),this.Fa=this.id.substr(b+1));this[a]=c;this.j={ready:!1,Da:!1,ub:!1,N:!1,error:!1};this.nb=null;this.j.error=!1;this.o={};this.F=null;this.ud=d||0;z.push(this)}var Ka=void 0,La={};
|
||||
Fa(Ba("Opera")||Ba("iOS")?"onunload":"onbeforeunload",function(){Ha(x.exit)});function y(a,b,c,d){this.type=a;b||(b={id:"",name:""});this.id=b.id||"";this.name=b.name;this.Vb=b.comment;this.oe=b;b=this.id.indexOf(".");0>b?this.Fa=this.id:(this.ra=this.id.substr(0,b),this.Fa=this.id.substr(b+1));this[a]=c;this.j={ready:!1,Da:!1,vb:!1,N:!1,error:!1};this.nb=null;this.j.error=!1;this.o={};this.F=null;this.xd=d||0;z.push(this)}var Ka=void 0,La={};
|
||||
if(window){Ka||(Ka=window.location.search.substr(1));for(var Ma,Na=/\+/g,Oa=/([^&=]+)=?([^&]*)/g;Ma=Oa.exec(Ka);)La[decodeURIComponent(Ma[1].replace(Na," "))]=decodeURIComponent(Ma[2].replace(Na," "))}function Pa(a){function b(){}if(window){if(!a)throw new TypeError;if(Object.create)return Object.create(a);var c=typeof a;if("object"!==c&&"function"!==c)throw new TypeError;}b.prototype=a;return new b}
|
||||
function A(a,b){b||(b=y);a.prototype=Pa(b.prototype);a.prototype.constructor=a;a.prototype.parent=b.prototype}if(window){window.PCjs||(window.PCjs={});var Qa=window.PCjs.Machines||(window.PCjs.Machines={}),z=window.PCjs.Components||(window.PCjs.Components=[])}else Qa={},z=[];function Ra(a,b,c){Qa[a]&&b&&(Qa[a][b]=c)}function B(a){var b,c=[];a&&(a=0<(b=a.indexOf("."))?a.substr(0,b+1):"");for(b=0;b<z.length;b++){var d=z[b];a&&d.id.indexOf(a)||c.push(d)}return c}
|
||||
function Sa(a){if(void 0!==a){var b;for(b=0;b<z.length;b++)if(z[b].id===a)return z[b]}return null}function Ta(a,b){var c;if(void 0!==a){var d;b&&(b=0<(d=b.indexOf("."))?b.substr(0,d+1):"");for(d=0;d<z.length;d++)if(c)c==z[d]&&(c=null);else if(!(a!=z[d].type||b&&z[d].id.indexOf(b)))return z[d]}return null}function C(a){var b=null;if(a=a.getAttribute("data-value"))try{b=eval("("+a+")")}catch(c){t(c.message+" ("+a+")")}return b}
|
||||
function D(a,b){b=E(b.parentNode,"pdp11-control");for(var c=0;c<b.length;c++)for(var d=b[c].childNodes,e=0;e<d.length;e++){var f=d[e];if(1===f.nodeType){var g=f.getAttribute("class");if(g)for(var k=g.split(" "),l=0;l<k.length;l++)switch(g=k[l],g){case "pdp11-binding":(g=C(f))&&g.binding&&a.$(g.type,g.binding,f,g.value),l=k.length}}}}
|
||||
function E(a,b,c){c&&(b+="-"+c+"-object");if(a.getElementsByClassName)return a.getElementsByClassName(b);var d;c=[];a=a.getElementsByTagName("*");var e=new RegExp("(^| )"+b+"( |$)");b=0;for(d=a.length;b<d;b++)e.test(a[b].className)&&c.push(a[b]);return c}
|
||||
y.prototype={constructor:y,parent:null,toString:function(){return this.name?this.name:this.id||this.type},$:function(a,b,c){switch(b){case "clear":return this.o[b]||(this.o[b]=c,c.onclick=function(a){return function(){a.o.print&&(a.o.print.value="")}}(this)),!0;case "print":return this.o[b]||(this.Xa=this.o[b]=c,c.value="",this.T=function(a){return function(b,c){8192<a.value.length&&(a.value=a.value.substr(a.value.length-4096));a.value+=(void 0!==c?c+": ":"")+(b||"")+"\n";a.scrollTop=a.scrollHeight}}(c),
|
||||
this.G=function(a){this.T(a,this.Fa)}),!0;default:return!1}},log:function(){},T:function(){},status:function(a){this.T(this.Fa+": "+a)},G:function(a,b,c){c=c||this.type;b||t((c?c+": ":"")+a)},la:function(){return this.j.N=!0},ka:function(a,b){b&&(this.j.N=!1);return!0}};function Ua(a,b){a.j.ub?(a.j.Da=!1,a.j.ub=!1):a.j.error?a.T(a.toString()+" error"):a.j.Da=b}function F(a,b){a.j.error||(a.j.ready=!1!==b,a.j.ready&&(b=a.nb,a.nb=null,b&&b()))}
|
||||
this.G=function(a){this.T(a,this.Fa)}),!0;default:return!1}},log:function(){},T:function(){},status:function(a){this.T(this.Fa+": "+a)},G:function(a,b,c){c=c||this.type;b||t((c?c+": ":"")+a)},la:function(){return this.j.N=!0},ka:function(a,b){b&&(this.j.N=!1);return!0}};function Ua(a,b){a.j.vb?(a.j.Da=!1,a.j.vb=!1):a.j.error?a.T(a.toString()+" error"):a.j.Da=b}function F(a,b){a.j.error||(a.j.ready=!1!==b,a.j.ready&&(b=a.nb,a.nb=null,b&&b()))}
|
||||
function Va(a,b){b&&(a.j.ready?b():a.nb=b);return a.j.ready}function Wa(a,b){a.j.error=!0;a.G(b)}Array.prototype.indexOf||(Array.prototype.indexOf=function(a,b){b=b||0;for(var c=this.length;b<c;b++)if(this[b]===a)return b;return-1});Array.isArray||(Array.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)});
|
||||
Function.prototype.bind||(Function.prototype.bind=function(a){function b(){return e.apply(this instanceof c&&a?this:a,d.concat(Array.prototype.slice.call(arguments)))}function c(){}if("function"!=typeof this)throw new TypeError("Function.prototype.bind: non-callable object");var d=Array.prototype.slice.call(arguments,1),e=this;c.prototype=this.prototype;b.prototype=new c;return b});var Xa="undefined"!==typeof ArrayBuffer;
|
||||
function Ya(a){y.call(this,"Panel",a,Ya,2048);this.ea=this.i=this.c=this.m=this.s=this.v=0;this.A=this.B=this.w=!1;this.D=Za;this.f={};this.b={START:[1,1,!0,!1,this.xc],STEP:[1,1,!1,!1,this.yc],ENABLE:[1,1,!1,!1,this.tc],CONT:[1,1,!0,!1,this.rc],DEP:[0,0,!0,!1,this.sc],EXAM:[1,1,!0,!1,this.uc],LOAD:[1,1,!0,!1,this.wc],TEST:[0,0,!0,!1,this.vc]};for(a=0;22>a;a++)this.b["S"+a]=[0,0,!1,!1,this.zc,a]}A(Ya);var Za=7;function $a(a,b){return a.b[b]&&a.b[b][1]}h=Ya.prototype;h.reset=function(){this.stop()};
|
||||
h.$=function(a,b,c,d){if(this.l&&this.l.$(a,b,c,d)||this.a&&this.a.$(a,b,c,d))return!0;switch(b){case "R0":case "R1":case "R2":case "R3":case "R4":case "R5":case "R6":case "R7":case "NF":case "ZF":case "VF":case "CF":case "PS":return this.o[b]=c,this.v++,!0;default:return"led"==a||"rled"==a?(this.o[b]=c,this.f[b]=d?1:0,this.v++,!0):"switch"==a?(void 0===this.b[b]&&(this.b[b]=[d?1:0,d?1:0]),this.o[b]=c,a=c.parentElement||c,a=a.parentElement||a,a.onmousedown=function(a,b){return function(){ab(a,b)}}(this,
|
||||
function Ya(a){y.call(this,"Panel",a,Ya,2048);this.ea=this.i=this.c=this.m=this.s=this.v=0;this.A=this.B=this.w=!1;this.D=Za;this.g={};this.b={START:[1,1,!0,!1,this.zc],STEP:[1,1,!1,!1,this.Ac],ENABLE:[1,1,!1,!1,this.vc],CONT:[1,1,!0,!1,this.tc],DEP:[0,0,!0,!1,this.uc],EXAM:[1,1,!0,!1,this.wc],LOAD:[1,1,!0,!1,this.yc],TEST:[0,0,!0,!1,this.xc]};for(a=0;22>a;a++)this.b["S"+a]=[0,0,!1,!1,this.Bc,a]}A(Ya);var Za=7;function $a(a,b){return a.b[b]&&a.b[b][1]}h=Ya.prototype;h.reset=function(){this.stop()};
|
||||
h.$=function(a,b,c,d){if(this.l&&this.l.$(a,b,c,d)||this.a&&this.a.$(a,b,c,d))return!0;switch(b){case "R0":case "R1":case "R2":case "R3":case "R4":case "R5":case "R6":case "R7":case "NF":case "ZF":case "VF":case "CF":case "PS":return this.o[b]=c,this.v++,!0;default:return"led"==a||"rled"==a?(this.o[b]=c,this.g[b]=d?1:0,this.v++,!0):"switch"==a?(void 0===this.b[b]&&(this.b[b]=[d?1:0,d?1:0]),this.o[b]=c,a=c.parentElement||c,a=a.parentElement||a,a.onmousedown=function(a,b){return function(){ab(a,b)}}(this,
|
||||
b),a.onmouseup=a.onmouseout=function(a,b){return function(){bb(a,b)}}(this,b),a.ontouchstart=function(a,b){return function(c){ab(a,b);c.preventDefault()}}(this,b),a.ontouchend=function(a,b){return function(){bb(a,b)}}(this,b),!0):this.parent.$.call(this,a,b,c,d)}};h.ja=function(a,b,c,d){this.l=a;this.h=b;this.a=c;this.F=d;cb(b,this,db);eb(b,this.reset.bind(this));fb(this);gb(this)};h.la=function(a,b){b||(hb(),this.reset());return!0};h.ka=function(){return!0};
|
||||
function ib(a,b,c){if(a=a.o[b])a.style.backgroundColor=c?"#ff0000":"#000000"}function fb(a,b){for(var c in a.f)ib(a,c,null!=b?b:a.f[c])}function jb(a,b,c){if(a=a.o[b])a.style.marginTop=c?"0px":"20px",a.style.backgroundColor=c?"#00ff00":"#228B22"}function gb(a){for(var b in a.b)jb(a,b,a.b[b][1])}function kb(a,b,c,d){a.o[b]&&(void 0===c&&(Wa(a,"Value for "+b+" is invalid"),G(a.a)),c=8==(a.F&&a.F.h||8)?ka(c,d):m(c,d),a.o[b].textContent!=c&&(a.o[b].textContent=c))}
|
||||
function ab(a,b){var c=a.b[b];jb(a,b,c[1]=1-c[1]);c[3]=!0;c[4]&&c[4].call(a,c[1],c[5]);"STEP"!=b&&(a.A="DEP"==b,a.B="EXAM"==b)}function bb(a,b){var c=a.b[b];c[2]&&c[3]&&(jb(a,b,c[1]=c[0]),c[4]&&c[4].call(a,c[1],c[5]));c[3]=!1}h.xc=function(a){a||this.a.j.P||(a=this.a,a.h.reset(),lb(a),$a(this,"ENABLE")&&mb(this.a))};h.yc=function(){};h.tc=function(a){a||G(this.a)};
|
||||
h.rc=function(a){if(!a&&!this.a.j.P)if($a(this,"ENABLE"))mb(this.a);else{a=this.F;var b;if(b=a)a.j.Da&&(a.j.ub=!0),b=!a.j.Da;if(b)Ua(a,!0),a.rb(0,null),Ua(a,!1);else try{var c=this.a.rb(1);0<c&&(nb(this.a,c),ob(this.a,c,!0),pb(this.a,c))}catch(d){"number"!=typeof d&&Wa(this.a,d.stack||d.message)}this.stop();this.l&&this.l.ya()}};h.sc=function(a){a&&!this.a.j.P&&(this.A&&qb(this),a=rb(this,this.c),this.D==Za?this.h.eb(this.ea,a):this.a.eb(this.ea,a))};
|
||||
h.uc=function(a){a||this.a.j.P||(this.B&&qb(this),a=this.D==Za?this.h.Ya(this.ea):this.a.Ya(this.ea),rb(this,a))};h.wc=function(a){a||this.a.j.P||sb(this,this.c)};h.vc=function(a){if(a)this.w=!0,fb(this,!0);else if(this.w=!1,fb(this),void 0!==this.o.S0){for(a=this.c=0;22>a;a++)this.b["S"+a][1]=0&1<<a?1:0;gb(this)}};h.zc=function(a,b){this.c=a?this.c|1<<b:this.c&~(1<<b)};
|
||||
function qb(a){var b=1145>a.a.La?8:16,c=65472<=a.ea&&a.ea<65472+b,b=c?1:2,c=c?15:a.h.pa;$a(a,"STEP")||(b=-b);sb(a,a.ea&~c|a.ea+b&c)}function sb(a,b){a.ea=b&a.h.pa;b=a.ea;for(var c=0;22>c;c++)tb(a,"A"+c,b&1<<c)}function rb(a,b){a.i=b&65535;b=a.i;for(var c=0;16>c;c++)tb(a,"D"+c,b&1<<c);return a.i}function tb(a,b,c){a.f[b]=c;a.w||ib(a,b,c)}h.stop=function(){sb(this,this.a.g[7])};h.setData=function(a,b){b?this.m=a:this.i=a};h.Ac=function(a,b){return(b?this.m:this.c)&65535};h.yd=function(a){this.m=a};
|
||||
var ub={},db=(ub[65400]=[null,null,Ya.prototype.Ac,Ya.prototype.yd,"CNSW"],ub);function hb(){for(var a=!1,b=E(document,"pdp11","panel"),c=0;c<b.length;c++){var d=b[c],e=C(d),f=Sa(e.id);f||(a=!0,f=new Ya(e));D(f,d);a&&F(f)}}Ga(hb);
|
||||
function vb(a,b,c){y.call(this,"Bus",a,vb,64);this.a=b;this.F=c;this.I=a.busWidth||16;this.s=0;this.v=[];this.i=null;this.B=1<<this.I;this.pa=this.B-1;this.b=H;this.c=Math.log2(this.b);this.D=this.b>>2;this.l=this.b-1;this.A=this.B/this.b|0;this.Aa=[];this.f=0;this.m=!1;this.vb=0;this.w=[];this.hc=[wb,xb,yb,zb];a=new I(this);Ab(a,this.F);this.h=Array(this.A);for(b=0;b<this.A;b++)this.h[b]=a;F(this)}A(vb);var H=8192,Bb=H-1;
|
||||
function ib(a,b,c){if(a=a.o[b])a.style.backgroundColor=c?"#ff0000":"#000000"}function fb(a,b){for(var c in a.g)ib(a,c,null!=b?b:a.g[c])}function jb(a,b,c){if(a=a.o[b])a.style.marginTop=c?"0px":"20px",a.style.backgroundColor=c?"#00ff00":"#228B22"}function gb(a){for(var b in a.b)jb(a,b,a.b[b][1])}function kb(a,b,c,d){a.o[b]&&(void 0===c&&(Wa(a,"Value for "+b+" is invalid"),G(a.a)),c=8==(a.F&&a.F.h||8)?ka(c,d):m(c,d),a.o[b].textContent!=c&&(a.o[b].textContent=c))}
|
||||
function ab(a,b){var c=a.b[b];jb(a,b,c[1]=1-c[1]);c[3]=!0;c[4]&&c[4].call(a,c[1],c[5]);"STEP"!=b&&(a.A="DEP"==b,a.B="EXAM"==b)}function bb(a,b){var c=a.b[b];c[2]&&c[3]&&(jb(a,b,c[1]=c[0]),c[4]&&c[4].call(a,c[1],c[5]));c[3]=!1}h.zc=function(a){a||this.a.j.P||(a=this.a,a.h.reset(),lb(a),$a(this,"ENABLE")&&mb(this.a))};h.Ac=function(){};h.vc=function(a){a||G(this.a)};
|
||||
h.tc=function(a){if(!a&&!this.a.j.P)if($a(this,"ENABLE"))mb(this.a);else{a=this.F;var b;if(b=a)a.j.Da&&(a.j.vb=!0),b=!a.j.Da;if(b)Ua(a,!0),a.sb(0,null),Ua(a,!1);else try{var c=this.a.sb(1);0<c&&(nb(this.a,c),ob(this.a,c,!0),pb(this.a,c))}catch(d){"number"!=typeof d&&Wa(this.a,d.stack||d.message)}this.stop();this.l&&this.l.ya()}};h.uc=function(a){a&&!this.a.j.P&&(this.A&&qb(this),a=rb(this,this.c),this.D==Za?this.h.eb(this.ea,a):this.a.eb(this.ea,a))};
|
||||
h.wc=function(a){a||this.a.j.P||(this.B&&qb(this),a=this.D==Za?this.h.Ya(this.ea):this.a.Ya(this.ea),rb(this,a))};h.yc=function(a){a||this.a.j.P||sb(this,this.c)};h.xc=function(a){if(a)this.w=!0,fb(this,!0);else if(this.w=!1,fb(this),void 0!==this.o.S0){for(a=this.c=0;22>a;a++)this.b["S"+a][1]=0&1<<a?1:0;gb(this)}};h.Bc=function(a,b){this.c=a?this.c|1<<b:this.c&~(1<<b)};
|
||||
function qb(a){var b=1145>a.a.La?8:16,c=65472<=a.ea&&a.ea<65472+b,b=c?1:2,c=c?15:a.h.pa;$a(a,"STEP")||(b=-b);sb(a,a.ea&~c|a.ea+b&c)}function sb(a,b){a.ea=b&a.h.pa;b=a.ea;for(var c=0;22>c;c++)tb(a,"A"+c,b&1<<c)}function rb(a,b){a.i=b&65535;b=a.i;for(var c=0;16>c;c++)tb(a,"D"+c,b&1<<c);return a.i}function tb(a,b,c){a.g[b]=c;a.w||ib(a,b,c)}h.stop=function(){sb(this,this.a.f[7])};h.setData=function(a,b){b?this.m=a:this.i=a};h.Cc=function(a,b){return(b?this.m:this.c)&65535};h.yd=function(a){this.m=a};
|
||||
var ub={},db=(ub[65400]=[null,null,Ya.prototype.Cc,Ya.prototype.yd,"CNSW"],ub);function hb(){for(var a=!1,b=E(document,"pdp11","panel"),c=0;c<b.length;c++){var d=b[c],e=C(d),f=Sa(e.id);f||(a=!0,f=new Ya(e));D(f,d);a&&F(f)}}Ga(hb);
|
||||
function vb(a,b,c){y.call(this,"Bus",a,vb,64);this.a=b;this.F=c;this.I=a.busWidth||16;this.s=0;this.v=[];this.i=null;this.B=1<<this.I;this.pa=this.B-1;this.b=H;this.c=Math.log2(this.b);this.D=this.b>>2;this.l=this.b-1;this.A=this.B/this.b|0;this.Aa=[];this.g=0;this.m=!1;this.wb=0;this.w=[];this.jc=[wb,xb,yb,zb];a=new I(this);Ab(a,this.F);this.h=Array(this.A);for(b=0;b<this.A;b++)this.h[b]=a;F(this)}A(vb);var H=8192,Bb=H-1;
|
||||
function wb(a,b){var c=-1,d=this.controller,e=d.Aa[a],f=b&65535;e?e[0]?c=e[0](f):e[2]&&(c=f&1?e[2](f&-2)>>8:e[2](f)&255):f&1&&(e=d.Aa[a&-2])&&(e[2]?c=e[2](f&-2)>>8:e[0]&&(c=e[0](f)));if(0<=c)return c;J(d,b,16);return 255}
|
||||
function xb(a,b,c){var d=!1,e=this.controller,f=e.Aa[a],g=c&65535;if(f)if(f[1])f[1](b,g),d=!0;else{if(f[3]){a=f[2]?f[2](g,!0):0;if(g&1)f[3](a&255|b<<8,g&-2);else f[3](a&-256|b,g);d=!0}}else g&1&&(f=e.Aa[a&-2])&&(f[3]?(g&=-2,a=f[2]?f[2](g,!0):0,f[3](a&255|b<<8,g),d=!0):f[1]&&(f[1](b,g),d=!0));d||J(e,c,16)}function yb(a,b){var c=-1,d=this.controller;a=d.Aa[a];var e=b&65535;a&&(a[2]?c=a[2](e):a[0]&&(c=a[0](e)|a[0](e+1)<<8));if(0<=c)return c;J(d,b,16);return 65535}
|
||||
function zb(a,b,c){var d=!1,e=this.controller;a=e.Aa[a];var f=c&65535;a&&(a[3]?(a[3](b,f),d=!0):a[1]&&(a[1](b&255,f),a[1](b>>8,f+1),d=!0));d||J(e,c,16)}function Cb(a,b){if(b!=a.s){var c;a.s&&(c=(1<<a.s)-H,Db(a,c,H,a.v),a.s=0);b&&(a.s=b,c=1<<b,a.pa=c-1,c-=H,a.v=Eb(a,c,H),a.i?Db(a,c,H,a.i):(Fb(a,c,H,Gb,a),a.i=Eb(a,c,H)))}}h=vb.prototype;h.reset=function(){for(var a=0;a<this.w.length;a++)this.w[a]();Cb(this,16)};h.la=function(a,b){b||this.reset();return!0};
|
||||
function Fb(a,b,c,d,e){for(var f=b,g=c,k=f>>>a.c;0<g&&k<a.h.length;){var l=a.h[k],n=k*a.b,p=a.b-(f-n);p>g&&(p=g);if(!e&&l&&l.size){if(l.type==d){if(f+g<=l.Ka)return l.sb+=l.Ka-f,l.Ka=f,!0;if(f>=l.Ka+l.sb){p=l.size-(f-n);p>g&&(p=g);l.sb=f-l.Ka+p;f=n+a.b;g-=p;k++;continue}}return Hb(1,f,g)}f=new I(a,f,p,a.b,d,e);Ab(f,a.F,l);a.h[k++]=f;f=n+a.b;g-=p}return 0>=g?(d==Ib&&(a.vb+=c),a.status((c>>10)+"Kb "+Jb[d]+" at "+ka(b)),!0):Hb(2,b,c)}
|
||||
function Eb(a,b,c){var d=[];for(b>>>=a.c;0<c&&b<a.h.length;)d.push(a.h[b++]),c-=a.b;return d}function Db(a,b,c,d){var e=0;for(b>>>=a.c;0<c&&b<a.h.length;){var f=d[e++];if(!f)break;a.h[b++]=f;c-=a.b}}function Kb(a,b){3932160<=b&&(b=Lb(a.a,b));return a.h[(b&a.pa)>>>a.c].Gb(b&a.l,b)}function Mb(a,b){3932160<=b&&(b=Lb(a.a,b));return a.h[(b&a.pa)>>>a.c].V(b&a.l,b)}h.Ya=function(a){3932160<=a&&(a=Lb(this.a,a));var b=a&this.l,c=(a&this.pa)>>>this.c;this.m=!1;this.f++;a=this.h[c].Xb(b,a);this.f--;return a};
|
||||
function Nb(a,b,c){3932160<=b&&(b=Lb(a.a,b));a.h[(b&a.pa)>>>a.c].Kb(b&a.l,c&255,b)}h.cb=function(a,b){3932160<=a&&(a=Lb(this.a,a));this.m=!1;this.f++;this.h[(a&this.pa)>>>this.c].Lb(a&this.l,b&255,a);this.f--};function Ob(a,b,c){3932160<=b&&(b=Lb(a.a,b));a.h[(b&a.pa)>>>a.c].tb(b&a.l,c&65535,b)}h.eb=function(a,b){3932160<=a&&(a=Lb(this.a,a));var c=a&this.l,d=(a&this.pa)>>>this.c;this.m=!1;this.f++;this.h[d].fc(c,b&65535,a);this.f--};
|
||||
function Pb(a){for(var b=0,c=[],d=0;d<a.A;d++){var e=a.h[d];if(e.wa||e.nc){c[b++]=d;var f=b++;if(e=e.save()){for(var g=0,k=0,l=[];g<e.length;){for(var n=e[g],p=g+1;p<e.length&&e[p]===n;)p++;l[k++]=p-g;l[k++]=n;g=p}l.length<e.length&&(e=l)}c[f]=e}}return c}function Qb(a,b,c,d,e,f,g,k,l){for(;b<=c;b+=2){var n=b&Bb;if(void 0!==a.Aa[n])return t("I/O address already registered: "+m(b,8,!0)),!1;a.Aa[n]=[d,e,f,g,l||"unknown",k,!1]}return!0}
|
||||
function cb(a,b,c){for(var d in c){var e=+d,f=c[d];if(!(f[6]&&f[6]>a.a.La)){var g=f[0]?f[0].bind(b):null,k=f[1]?f[1].bind(b):null,l=f[2]?f[2].bind(b):null,n=f[3]?f[3].bind(b):null;65472<=e&&65487>=e&&(!g&&l&&(g=function(a){return function(b){return a(b)&255}.bind(b)}(l)),!k&&n&&(k=function(a){return function(b,c){return a(b,c)}.bind(b)}(n)));for(var p=f[4],u=f[5]||1,w=0;w<u;w++,e+=2)if(p&&1<u&&(p=f[4]+w),!Qb(a,e,e,g,k,l,n,f[7]||b.ud||64,p||b.Fa))return!1}}return!0}function eb(a,b){a.w.push(b)}
|
||||
function J(a,b,c){a.m=!0;a.f||(c&&(a.a.fa|=c),K(a.a,4,0,b))}function Rb(a){var b=a.m;a.m=!1;return b}function Hb(a,b,c){t("Memory block error ("+a+": "+m(b)+","+m(c)+")");return!1}function L(a){y.call(this,"Device",a,L,1024);this.b={L:0,Jb:-1}}A(L);h=L.prototype;h.ja=function(a,b,c,d){this.h=b;this.l=a;this.a=c;this.F=d;var e=this;this.b.Jb=Sb(c,function(){e.b.$a|=128;e.b.$a&64&&Tb(e.a,e.b.td);e.l&&e.l.ya(1);Ub(e.a,e.b.Jb,1E3/60)});this.b.td=Vb(64,6);cb(b,this,Wb);eb(b,this.reset.bind(this));F(this)};
|
||||
h.reset=function(){this.b.$a=128;Ub(this.a,this.b.Jb,1E3/60,!0)};h.Ic=function(){return this.b.$a};h.Gd=function(a){this.b.$a=a&192};h.Kc=function(){var a=this.a,b=a.W;b&57344||(b=b&-3199|a.gb<<5|a.hb<<1);return b};h.Id=function(a){Xb(this.a,a&-129|this.a.W&128)};h.Lc=function(){var a=this.a;a.W&57344||(a.Eb=a.A>>16&65535);a=a.Eb;a&65280&&(a=(a<<8|a>>8)&65535);return a};h.Mc=function(){var a=this.a;a.W&57344||(a.Fb=a.A&65535);return a.Fb};h.Nc=function(){return this.a.Ba};
|
||||
h.Jd=function(a){var b=this.a;1170>b.La&&(a&=-49);b.Ba!=a&&(b.Ba=a,b.Sa=a&16?4194303:262143,Yb(b))};h.od=function(a){a=a>>1&63;var b=this.a.fb[a>>1];return a&1?b>>16:b&65535};h.je=function(a,b){b=b>>1&63;var c=b>>1;this.a.fb[c]=b&1?this.a.fb[c]&65535|(a&63)<<16:this.a.fb[c]&-65536|a&65534};h.gd=function(a){return this.a.H[1][a>>1&7]};h.ce=function(a,b){this.a.H[1][b>>1&7]=a&65295};h.ed=function(a){return this.a.H[1][(a>>1&7)+8]};h.ae=function(a,b){this.a.H[1][(b>>1&7)+8]=a&65295};
|
||||
h.fd=function(a){return this.a.Y[1][a>>1&7]};h.be=function(a,b){b=b>>1&7;this.a.Y[1][b]=a;this.a.H[1][b]&=65295};h.dd=function(a){return this.a.Y[1][(a>>1&7)+8]};h.$d=function(a,b){b=(b>>1&7)+8;this.a.Y[1][b]=a;this.a.H[1][b]&=65295};h.Hc=function(a){return this.a.H[0][a>>1&7]};h.Fd=function(a,b){this.a.H[0][b>>1&7]=a&65295};h.Fc=function(a){return this.a.H[0][(a>>1&7)+8]};h.Dd=function(a,b){this.a.H[0][(b>>1&7)+8]=a&65295};h.Gc=function(a){return this.a.Y[0][a>>1&7]};
|
||||
h.Ed=function(a,b){b=b>>1&7;this.a.Y[0][b]=a;this.a.H[0][b]&=65295};h.Ec=function(a){return this.a.Y[0][(a>>1&7)+8]};h.Cd=function(a,b){b=(b>>1&7)+8;this.a.Y[0][b]=a;this.a.H[0][b]&=65295};h.nd=function(a){return this.a.H[3][a>>1&7]};h.ie=function(a,b){this.a.H[3][b>>1&7]=a&65295};h.ld=function(a){return this.a.H[3][(a>>1&7)+8]};h.ge=function(a,b){this.a.H[3][(b>>1&7)+8]=a&65295};h.md=function(a){return this.a.Y[3][a>>1&7]};h.he=function(a,b){b=b>>1&7;this.a.Y[3][b]=a;this.a.H[3][b]&=65295};
|
||||
h.kd=function(a){return this.a.Y[3][(a>>1&7)+8]};h.fe=function(a,b){b=(b>>1&7)+8;this.a.Y[3][b]=a;this.a.H[3][b]&=65295};h.Na=function(a){a&=7;return this.a.C&2048?this.a.Ea[a]:this.a.g[a]};h.Pa=function(a,b){b&=7;this.a.C&2048?this.a.Ea[b]=a:this.a.g[b]=a};h.Sc=function(){return this.a.C&49152?this.a.qa[0]:this.a.g[6]};h.Od=function(a){this.a.C&49152?this.a.qa[0]=a:this.a.g[6]=a};h.Vc=function(){return this.a.g[7]};h.Rd=function(a){this.a.g[7]=a};
|
||||
h.Oa=function(a){a&=7;return this.a.C&2048?this.a.g[a]:this.a.Ea[a]};h.Qa=function(a,b){b&=7;this.a.C&2048?this.a.g[b]=a:this.a.Ea[b]=a};h.Tc=function(){return 1==(this.a.C&49152)>>14?this.a.g[6]:this.a.qa[1]};h.Pd=function(a){1==(this.a.C&49152)>>14?this.a.g[6]=a:this.a.qa[1]=a};h.Uc=function(){return 3==(this.a.C&49152)>>14?this.a.g[6]:this.a.qa[3]};h.Qd=function(a){3==(this.a.C&49152)>>14?this.a.g[6]=a:this.a.qa[3]=a};h.Cc=function(a){return this.a.$b[a-65504>>1]};
|
||||
h.Ad=function(a,b){this.a.$b[b-65504>>1]=a};h.Wb=function(a){if(65520==a){a=0;switch(Ib){case Ib:a=this.h.vb}a=(a>>6)-1}else a=0;return a};h.ec=function(){};h.jd=function(){return 1};h.ee=function(){};h.Bc=function(){return this.a.fa};h.zd=function(){this.a.fa=0};h.Jc=function(){return this.a.Zb};h.Hd=function(a,b){b&1||(a&=255);this.a.Zb=a};h.Oc=function(a,b){return b?0:this.a.Hb};h.Kd=function(a){var b=this.a;if(a&=65024){var c=a>>9;do a+=34;while(c>>=1)}b.Hb=a;b.u|=2};
|
||||
h.hd=function(a,b){return b?0:this.a.bb&65280};h.de=function(a){this.a.bb=a|255};h.Rc=function(){return Zb(this.a)};h.Nd=function(a){$b(this.a,a&-1793|Zb(this.a)&1792);this.a.u|=128};h.dc=function(){};
|
||||
var M={},Wb=(M[61568]=[null,null,L.prototype.od,L.prototype.je,"UNIMAP",64,1170],M[62592]=[null,null,L.prototype.gd,L.prototype.ce,"SIPDR",8,1145,256],M[62608]=[null,null,L.prototype.ed,L.prototype.ae,"SDPDR",8,1145,256],M[62624]=[null,null,L.prototype.fd,L.prototype.be,"SIPAR",8,1145,256],M[62640]=[null,null,L.prototype.dd,L.prototype.$d,"SDPAR",8,1145,256],M[62656]=[null,null,L.prototype.Hc,L.prototype.Fd,"KIPDR",8,1145,256],M[62672]=[null,null,L.prototype.Fc,L.prototype.Dd,"KDPDR",8,1145,256],
|
||||
M[62688]=[null,null,L.prototype.Gc,L.prototype.Ed,"KIPAR",8,1145,256],M[62704]=[null,null,L.prototype.Ec,L.prototype.Cd,"KDPAR",8,1145,256],M[62798]=[null,null,L.prototype.Nc,L.prototype.Jd,"MMR3",1,1145,256],M[65382]=[null,null,L.prototype.Ic,L.prototype.Gd,"LKS"],M[65402]=[null,null,L.prototype.Kc,L.prototype.Id,"MMR0",1,1145,256],M[65404]=[null,null,L.prototype.Lc,L.prototype.dc,"MMR1",1,1145,256],M[65406]=[null,null,L.prototype.Mc,L.prototype.dc,"MMR2",1,1145,256],M[65408]=[null,null,L.prototype.nd,
|
||||
L.prototype.ie,"UIPDR",8,1145,256],M[65424]=[null,null,L.prototype.ld,L.prototype.ge,"UDPDR",8,1145,256],M[65440]=[null,null,L.prototype.md,L.prototype.he,"UIPAR",8,1145,256],M[65456]=[null,null,L.prototype.kd,L.prototype.fe,"UDPAR",8,1145,256],M[65472]=[null,null,L.prototype.Na,L.prototype.Pa,"R0SET0"],M[65473]=[null,null,L.prototype.Na,L.prototype.Pa,"R1SET0"],M[65474]=[null,null,L.prototype.Na,L.prototype.Pa,"R2SET0"],M[65475]=[null,null,L.prototype.Na,L.prototype.Pa,"R3SET0"],M[65476]=[null,null,
|
||||
L.prototype.Na,L.prototype.Pa,"R4SET0"],M[65477]=[null,null,L.prototype.Na,L.prototype.Pa,"R5SET0"],M[65478]=[null,null,L.prototype.Sc,L.prototype.Od,"R6KERNEL"],M[65479]=[null,null,L.prototype.Vc,L.prototype.Rd,"R7KERNEL"],M[65480]=[null,null,L.prototype.Oa,L.prototype.Qa,"R0SET1",1,1145],M[65481]=[null,null,L.prototype.Oa,L.prototype.Qa,"R1SET1",1,1145],M[65482]=[null,null,L.prototype.Oa,L.prototype.Qa,"R2SET1",1,1145],M[65483]=[null,null,L.prototype.Oa,L.prototype.Qa,"R3SET1",1,1145],M[65484]=
|
||||
[null,null,L.prototype.Oa,L.prototype.Qa,"R4SET1",1,1145],M[65485]=[null,null,L.prototype.Oa,L.prototype.Qa,"R5SET1",1,1145],M[65486]=[null,null,L.prototype.Tc,L.prototype.Pd,"R6SUPER",1,1145],M[65487]=[null,null,L.prototype.Uc,L.prototype.Qd,"R6USER",1,1145],M[65504]=[null,null,L.prototype.Cc,L.prototype.Ad,"CTRL",8,1170],M[65520]=[null,null,L.prototype.Wb,L.prototype.ec,"LSIZE",1,1170],M[65522]=[null,null,L.prototype.Wb,L.prototype.ec,"HSIZE",1,1170],M[65524]=[null,null,L.prototype.jd,L.prototype.ee,
|
||||
"SYSID",1,1170],M[65526]=[null,null,L.prototype.Bc,L.prototype.zd,"CPUERR",1,1170],M[65528]=[null,null,L.prototype.Jc,L.prototype.Hd,"MB",1,1170],M[65530]=[null,null,L.prototype.Oc,L.prototype.Kd,"PIR"],M[65532]=[null,null,L.prototype.hd,L.prototype.de,"SL"],M[65534]=[null,null,L.prototype.Rc,L.prototype.Nd,"PSW"],M);
|
||||
function Fb(a,b,c,d,e){for(var f=b,g=c,k=f>>>a.c;0<g&&k<a.h.length;){var l=a.h[k],n=k*a.b,p=a.b-(f-n);p>g&&(p=g);if(!e&&l&&l.size){if(l.type==d){if(f+g<=l.Ka)return l.tb+=l.Ka-f,l.Ka=f,!0;if(f>=l.Ka+l.tb){p=l.size-(f-n);p>g&&(p=g);l.tb=f-l.Ka+p;f=n+a.b;g-=p;k++;continue}}return Hb(1,f,g)}f=new I(a,f,p,a.b,d,e);Ab(f,a.F,l);a.h[k++]=f;f=n+a.b;g-=p}return 0>=g?(d==Ib&&(a.wb+=c),a.status((c>>10)+"Kb "+Jb[d]+" at "+ka(b)),!0):Hb(2,b,c)}
|
||||
function Eb(a,b,c){var d=[];for(b>>>=a.c;0<c&&b<a.h.length;)d.push(a.h[b++]),c-=a.b;return d}function Db(a,b,c,d){var e=0;for(b>>>=a.c;0<c&&b<a.h.length;){var f=d[e++];if(!f)break;a.h[b++]=f;c-=a.b}}function Kb(a,b){3932160<=b&&(b=Lb(a.a,b));return a.h[(b&a.pa)>>>a.c].Hb(b&a.l,b)}function Mb(a,b){3932160<=b&&(b=Lb(a.a,b));return a.h[(b&a.pa)>>>a.c].V(b&a.l,b)}h.Ya=function(a){3932160<=a&&(a=Lb(this.a,a));var b=a&this.l,c=(a&this.pa)>>>this.c;this.m=!1;this.g++;a=this.h[c].Xb(b,a);this.g--;return a};
|
||||
function Nb(a,b,c){3932160<=b&&(b=Lb(a.a,b));a.h[(b&a.pa)>>>a.c].Lb(b&a.l,c&255,b)}h.cb=function(a,b){3932160<=a&&(a=Lb(this.a,a));this.m=!1;this.g++;this.h[(a&this.pa)>>>this.c].Mb(a&this.l,b&255,a);this.g--};function Ob(a,b,c){3932160<=b&&(b=Lb(a.a,b));a.h[(b&a.pa)>>>a.c].ub(b&a.l,c&65535,b)}h.eb=function(a,b){3932160<=a&&(a=Lb(this.a,a));var c=a&this.l,d=(a&this.pa)>>>this.c;this.m=!1;this.g++;this.h[d].hc(c,b&65535,a);this.g--};
|
||||
function Pb(a){for(var b=0,c=[],d=0;d<a.A;d++){var e=a.h[d];if(e.wa||e.pc){c[b++]=d;var f=b++;if(e=e.save()){for(var g=0,k=0,l=[];g<e.length;){for(var n=e[g],p=g+1;p<e.length&&e[p]===n;)p++;l[k++]=p-g;l[k++]=n;g=p}l.length<e.length&&(e=l)}c[f]=e}}return c}function Qb(a,b,c,d,e,f,g,k,l){for(;b<=c;b+=2){var n=b&Bb;if(void 0!==a.Aa[n])return t("I/O address already registered: "+m(b,8,!0)),!1;a.Aa[n]=[d,e,f,g,l||"unknown",k,!1]}return!0}
|
||||
function cb(a,b,c){for(var d in c){var e=+d,f=c[d];if(!(f[6]&&f[6]>a.a.La)){var g=f[0]?f[0].bind(b):null,k=f[1]?f[1].bind(b):null,l=f[2]?f[2].bind(b):null,n=f[3]?f[3].bind(b):null;65472<=e&&65487>=e&&(!g&&l&&(g=function(a){return function(b){return a(b)&255}.bind(b)}(l)),!k&&n&&(k=function(a){return function(b,c){return a(b,c)}.bind(b)}(n)));for(var p=f[4],u=f[5]||1,w=0;w<u;w++,e+=2)if(p&&1<u&&(p=f[4]+w),!Qb(a,e,e,g,k,l,n,f[7]||b.xd||64,p||b.Fa))return!1}}return!0}function eb(a,b){a.w.push(b)}
|
||||
function J(a,b,c){a.m=!0;a.g||(c&&(a.a.fa|=c),K(a.a,4,0,b))}function Rb(a){var b=a.m;a.m=!1;return b}function Hb(a,b,c){t("Memory block error ("+a+": "+m(b)+","+m(c)+")");return!1}function L(a){y.call(this,"Device",a,L,1024);this.b={L:0,Kb:-1}}A(L);h=L.prototype;h.ja=function(a,b,c,d){this.h=b;this.l=a;this.a=c;this.F=d;var e=this;this.b.Kb=Sb(c,function(){e.b.$a|=128;e.b.$a&64&&Tb(e.a,e.b.vd);e.l&&e.l.ya(1);Ub(e.a,e.b.Kb,1E3/60)});this.b.vd=Vb(64,6);cb(b,this,Wb);eb(b,this.reset.bind(this));F(this)};
|
||||
h.reset=function(){this.b.$a=128;Ub(this.a,this.b.Kb,1E3/60,!0)};h.Kc=function(){return this.b.$a};h.Gd=function(a){this.b.$a=a&192};h.Mc=function(){var a=this.a,b=a.W;b&57344||(b=b&-3199|a.gb<<5|a.hb<<1);return b};h.Id=function(a){Xb(this.a,a&-129|this.a.W&128)};h.Nc=function(){var a=this.a;a.W&57344||(a.Fb=a.A>>16&65535);a=a.Fb;a&65280&&(a=(a<<8|a>>8)&65535);return a};h.Oc=function(){var a=this.a;a.W&57344||(a.Gb=a.A&65535);return a.Gb};h.Pc=function(){return this.a.Ba};
|
||||
h.Jd=function(a){var b=this.a;1170>b.La&&(a&=-49);b.Ba!=a&&(b.Ba=a,b.Sa=a&16?4194303:262143,Yb(b))};h.qd=function(a){a=a>>1&63;var b=this.a.fb[a>>1];return a&1?b>>16:b&65535};h.je=function(a,b){b=b>>1&63;var c=b>>1;this.a.fb[c]=b&1?this.a.fb[c]&65535|(a&63)<<16:this.a.fb[c]&-65536|a&65534};h.jd=function(a){return this.a.H[1][a>>1&7]};h.ce=function(a,b){this.a.H[1][b>>1&7]=a&65295};h.gd=function(a){return this.a.H[1][(a>>1&7)+8]};h.ae=function(a,b){this.a.H[1][(b>>1&7)+8]=a&65295};
|
||||
h.hd=function(a){return this.a.Y[1][a>>1&7]};h.be=function(a,b){b=b>>1&7;this.a.Y[1][b]=a;this.a.H[1][b]&=65295};h.fd=function(a){return this.a.Y[1][(a>>1&7)+8]};h.$d=function(a,b){b=(b>>1&7)+8;this.a.Y[1][b]=a;this.a.H[1][b]&=65295};h.Jc=function(a){return this.a.H[0][a>>1&7]};h.Fd=function(a,b){this.a.H[0][b>>1&7]=a&65295};h.Hc=function(a){return this.a.H[0][(a>>1&7)+8]};h.Dd=function(a,b){this.a.H[0][(b>>1&7)+8]=a&65295};h.Ic=function(a){return this.a.Y[0][a>>1&7]};
|
||||
h.Ed=function(a,b){b=b>>1&7;this.a.Y[0][b]=a;this.a.H[0][b]&=65295};h.Gc=function(a){return this.a.Y[0][(a>>1&7)+8]};h.Cd=function(a,b){b=(b>>1&7)+8;this.a.Y[0][b]=a;this.a.H[0][b]&=65295};h.pd=function(a){return this.a.H[3][a>>1&7]};h.ie=function(a,b){this.a.H[3][b>>1&7]=a&65295};h.nd=function(a){return this.a.H[3][(a>>1&7)+8]};h.ge=function(a,b){this.a.H[3][(b>>1&7)+8]=a&65295};h.od=function(a){return this.a.Y[3][a>>1&7]};h.he=function(a,b){b=b>>1&7;this.a.Y[3][b]=a;this.a.H[3][b]&=65295};
|
||||
h.md=function(a){return this.a.Y[3][(a>>1&7)+8]};h.fe=function(a,b){b=(b>>1&7)+8;this.a.Y[3][b]=a;this.a.H[3][b]&=65295};h.Na=function(a){a&=7;return this.a.C&2048?this.a.Ea[a]:this.a.f[a]};h.Pa=function(a,b){b&=7;this.a.C&2048?this.a.Ea[b]=a:this.a.f[b]=a};h.Uc=function(){return this.a.C&49152?this.a.qa[0]:this.a.f[6]};h.Od=function(a){this.a.C&49152?this.a.qa[0]=a:this.a.f[6]=a};h.Xc=function(){return this.a.f[7]};h.Rd=function(a){this.a.f[7]=a};
|
||||
h.Oa=function(a){a&=7;return this.a.C&2048?this.a.f[a]:this.a.Ea[a]};h.Qa=function(a,b){b&=7;this.a.C&2048?this.a.f[b]=a:this.a.Ea[b]=a};h.Vc=function(){return 1==(this.a.C&49152)>>14?this.a.f[6]:this.a.qa[1]};h.Pd=function(a){1==(this.a.C&49152)>>14?this.a.f[6]=a:this.a.qa[1]=a};h.Wc=function(){return 3==(this.a.C&49152)>>14?this.a.f[6]:this.a.qa[3]};h.Qd=function(a){3==(this.a.C&49152)>>14?this.a.f[6]=a:this.a.qa[3]=a};h.Ec=function(a){return this.a.$b[a-65504>>1]};
|
||||
h.Ad=function(a,b){this.a.$b[b-65504>>1]=a};h.Wb=function(a){if(65520==a){a=0;switch(Ib){case Ib:a=this.h.wb}a=(a>>6)-1}else a=0;return a};h.gc=function(){};h.ld=function(){return 1};h.ee=function(){};h.Dc=function(){return this.a.fa};h.zd=function(){this.a.fa=0};h.Lc=function(){return this.a.Zb};h.Hd=function(a,b){b&1||(a&=255);this.a.Zb=a};h.Qc=function(a,b){return b?0:this.a.Ib};h.Kd=function(a){var b=this.a;if(a&=65024){var c=a>>9;do a+=34;while(c>>=1)}b.Ib=a;b.u|=2};
|
||||
h.kd=function(a,b){return b?0:this.a.bb&65280};h.de=function(a){this.a.bb=a|255};h.Tc=function(){return Zb(this.a)};h.Nd=function(a){$b(this.a,a&-1793|Zb(this.a)&1792);this.a.u|=128};h.fc=function(){};
|
||||
var M={},Wb=(M[61568]=[null,null,L.prototype.qd,L.prototype.je,"UNIMAP",64,1170],M[62592]=[null,null,L.prototype.jd,L.prototype.ce,"SIPDR",8,1145,256],M[62608]=[null,null,L.prototype.gd,L.prototype.ae,"SDPDR",8,1145,256],M[62624]=[null,null,L.prototype.hd,L.prototype.be,"SIPAR",8,1145,256],M[62640]=[null,null,L.prototype.fd,L.prototype.$d,"SDPAR",8,1145,256],M[62656]=[null,null,L.prototype.Jc,L.prototype.Fd,"KIPDR",8,1145,256],M[62672]=[null,null,L.prototype.Hc,L.prototype.Dd,"KDPDR",8,1145,256],
|
||||
M[62688]=[null,null,L.prototype.Ic,L.prototype.Ed,"KIPAR",8,1145,256],M[62704]=[null,null,L.prototype.Gc,L.prototype.Cd,"KDPAR",8,1145,256],M[62798]=[null,null,L.prototype.Pc,L.prototype.Jd,"MMR3",1,1145,256],M[65382]=[null,null,L.prototype.Kc,L.prototype.Gd,"LKS"],M[65402]=[null,null,L.prototype.Mc,L.prototype.Id,"MMR0",1,1145,256],M[65404]=[null,null,L.prototype.Nc,L.prototype.fc,"MMR1",1,1145,256],M[65406]=[null,null,L.prototype.Oc,L.prototype.fc,"MMR2",1,1145,256],M[65408]=[null,null,L.prototype.pd,
|
||||
L.prototype.ie,"UIPDR",8,1145,256],M[65424]=[null,null,L.prototype.nd,L.prototype.ge,"UDPDR",8,1145,256],M[65440]=[null,null,L.prototype.od,L.prototype.he,"UIPAR",8,1145,256],M[65456]=[null,null,L.prototype.md,L.prototype.fe,"UDPAR",8,1145,256],M[65472]=[null,null,L.prototype.Na,L.prototype.Pa,"R0SET0"],M[65473]=[null,null,L.prototype.Na,L.prototype.Pa,"R1SET0"],M[65474]=[null,null,L.prototype.Na,L.prototype.Pa,"R2SET0"],M[65475]=[null,null,L.prototype.Na,L.prototype.Pa,"R3SET0"],M[65476]=[null,null,
|
||||
L.prototype.Na,L.prototype.Pa,"R4SET0"],M[65477]=[null,null,L.prototype.Na,L.prototype.Pa,"R5SET0"],M[65478]=[null,null,L.prototype.Uc,L.prototype.Od,"R6KERNEL"],M[65479]=[null,null,L.prototype.Xc,L.prototype.Rd,"R7KERNEL"],M[65480]=[null,null,L.prototype.Oa,L.prototype.Qa,"R0SET1",1,1145],M[65481]=[null,null,L.prototype.Oa,L.prototype.Qa,"R1SET1",1,1145],M[65482]=[null,null,L.prototype.Oa,L.prototype.Qa,"R2SET1",1,1145],M[65483]=[null,null,L.prototype.Oa,L.prototype.Qa,"R3SET1",1,1145],M[65484]=
|
||||
[null,null,L.prototype.Oa,L.prototype.Qa,"R4SET1",1,1145],M[65485]=[null,null,L.prototype.Oa,L.prototype.Qa,"R5SET1",1,1145],M[65486]=[null,null,L.prototype.Vc,L.prototype.Pd,"R6SUPER",1,1145],M[65487]=[null,null,L.prototype.Wc,L.prototype.Qd,"R6USER",1,1145],M[65504]=[null,null,L.prototype.Ec,L.prototype.Ad,"CTRL",8,1170],M[65520]=[null,null,L.prototype.Wb,L.prototype.gc,"LSIZE",1,1170],M[65522]=[null,null,L.prototype.Wb,L.prototype.gc,"HSIZE",1,1170],M[65524]=[null,null,L.prototype.ld,L.prototype.ee,
|
||||
"SYSID",1,1170],M[65526]=[null,null,L.prototype.Dc,L.prototype.zd,"CPUERR",1,1170],M[65528]=[null,null,L.prototype.Lc,L.prototype.Hd,"MB",1,1170],M[65530]=[null,null,L.prototype.Qc,L.prototype.Kd,"PIR"],M[65532]=[null,null,L.prototype.kd,L.prototype.de,"SL"],M[65534]=[null,null,L.prototype.Tc,L.prototype.Nd,"PSW"],M);
|
||||
Ga(function(){for(var a=E(document,"pdp11","device"),b=0;b<a.length;b++){var c,d=a[b];c=C(d);switch(c.type){case "default":c=new L(c);D(c,d);break;case "pc11":c=new ac(c);D(c,d);break;case "rl11":c=new N(c),D(c,d)}}});var bc;if(Xa){var cc=new ArrayBuffer(2);(new DataView(cc)).setUint16(0,256,!0);bc=256===(new Uint16Array(cc))[0]}else bc=!1;var dc=bc;
|
||||
function I(a,b,c,d,e,f){this.h=a;this.id=ec+=2;this.a=null;this.Ka=b;this.sb=c;this.size=d||0;this.type=e||fc;this.l=e==gc;this.controller=null;Ab(this);this.wa=this.nc=!1;if(this.size)if(f)this.controller=f,a=[null,0],this.a=a[0],hc(this,f.hc);else if(Xa)this.b=new ArrayBuffer(this.size),this.c=new DataView(this.b,0,this.size),this.o=new Uint8Array(this.b,0,this.size),this.s=new Uint16Array(this.b,0,this.size>>1),this.a=new Int32Array(this.b,0,this.size>>2),hc(this,dc?ic:jc);else{a=this.a=Array(this.size>>
|
||||
function I(a,b,c,d,e,f){this.h=a;this.id=ec+=2;this.a=null;this.Ka=b;this.tb=c;this.size=d||0;this.type=e||fc;this.l=e==gc;this.controller=null;Ab(this);this.wa=this.pc=!1;if(this.size)if(f)this.controller=f,a=[null,0],this.a=a[0],hc(this,f.jc);else if(Xa)this.b=new ArrayBuffer(this.size),this.c=new DataView(this.b,0,this.size),this.o=new Uint8Array(this.b,0,this.size),this.s=new Uint16Array(this.b,0,this.size>>1),this.a=new Int32Array(this.b,0,this.size>>2),hc(this,dc?ic:jc);else{a=this.a=Array(this.size>>
|
||||
2);for(f=0;f<a.length;f++)a[f]=0;hc(this,mc)}else hc(this)}var fc=0,Ib=1,gc=2,Gb=4,Jb=["NONE","RAM","ROM","VID","H/W"],ec=0;
|
||||
I.prototype={constructor:I,parent:null,save:function(){var a,b;if(this.controller)a=null;else if(Xa)for(a=Array(this.size>>2),b=0;b<a.length;b++)a[b]=this.c.getInt32(b<<2,!0);else a=this.a;return a},restore:function(a){if(this.controller)return!a;if(a&&this.size==a.length<<2){var b;if(Xa)for(b=0;b<a.length;b++)this.c.setInt32(b<<2,a[b],!0);else this.a=a;return this.wa=!0}return!1},v:function(a,b){J(this.h,b,32);return 255},f:function(a,b,c){J(this.h,c,32)},w:function(a,b){return this.Gb(a++,b++)|
|
||||
this.Gb(a,b)<<8},A:function(a,b,c){this.Kb(a++,b&255,c++);this.Kb(a,b>>8,c)},M:function(a){return this.a[a>>2]>>>((a&3)<<3)&255},ba:function(a,b){a&1&&J(this.h,b,64);b=a>>2;a=(a&3)<<3;var c=this.a[b]>>a;return 24>a?c&65535:c&255|(this.a[b+1]&255)<<8},sa:function(a,b){var c=a>>2;a=(a&3)<<3;this.a[c]=this.a[c]&~(255<<a)|b<<a;this.wa=!0},za:function(a,b,c){a&1&&J(this.h,c,64);c=a>>2;a=(a&3)<<3;24>a?this.a[c]=this.a[c]&~(65535<<a)|b<<a:(this.a[c]=this.a[c]&16777215|b<<24,c++,this.a[c]=this.a[c]&-256|
|
||||
b>>8);this.wa=!0},D:function(a,b){return this.I(a,b)},R:function(a,b){return this.Xb(a,b)},na:function(a,b,c){this.l?this.f(a,b,c):this.Lb(a,b,c)},ua:function(a,b,c){this.l?this.f(a,b,c):this.fc(a,b,c)},B:function(a){return this.o[a]},J:function(a){return this.o[a]},O:function(a,b){a&1&&J(this.h,b,64);return this.c.getUint16(a,!0)},aa:function(a,b){a&1&&J(this.h,b,64);return this.s[a>>1]},ma:function(a,b){this.o[a]=b;this.wa=!0},ra:function(a,b){this.o[a]=b;this.wa=!0},ta:function(a,b,c){a&1&&J(this.h,
|
||||
c,64);this.c.setUint16(a,b,!0);this.wa=!0},va:function(a,b,c){a&1&&J(this.h,c,64);this.s[a>>1]=b;this.wa=!0}};function Ab(a,b,c){a.F=b;a.i=a.m=0;c&&((a.i=c.i)&&nc(a,oc,!1),(a.m=c.m)&&pc(a,oc,!1))}function pc(a,b,c){c&&a.m||(a.Kb=!a.l&&b[1]||a.f,a.tb=!a.l&&b[3]||a.A);if(c||void 0===c)a.Lb=b[1]||a.f,a.fc=b[3]||a.A}function nc(a,b,c){c&&a.i||(a.Gb=b[0]||a.v,a.V=b[2]||a.w);if(c||void 0===c)a.I=b[0]||a.v,a.Xb=b[2]||a.w}function hc(a,b){b||(b=qc);nc(a,b,void 0);pc(a,b,void 0)}
|
||||
I.prototype={constructor:I,parent:null,save:function(){var a,b;if(this.controller)a=null;else if(Xa)for(a=Array(this.size>>2),b=0;b<a.length;b++)a[b]=this.c.getInt32(b<<2,!0);else a=this.a;return a},restore:function(a){if(this.controller)return!a;if(a&&this.size==a.length<<2){var b;if(Xa)for(b=0;b<a.length;b++)this.c.setInt32(b<<2,a[b],!0);else this.a=a;return this.wa=!0}return!1},v:function(a,b){J(this.h,b,32);return 255},g:function(a,b,c){J(this.h,c,32)},w:function(a,b){return this.Hb(a++,b++)|
|
||||
this.Hb(a,b)<<8},A:function(a,b,c){this.Lb(a++,b&255,c++);this.Lb(a,b>>8,c)},M:function(a){return this.a[a>>2]>>>((a&3)<<3)&255},ba:function(a,b){a&1&&J(this.h,b,64);b=a>>2;a=(a&3)<<3;var c=this.a[b]>>a;return 24>a?c&65535:c&255|(this.a[b+1]&255)<<8},sa:function(a,b){var c=a>>2;a=(a&3)<<3;this.a[c]=this.a[c]&~(255<<a)|b<<a;this.wa=!0},za:function(a,b,c){a&1&&J(this.h,c,64);c=a>>2;a=(a&3)<<3;24>a?this.a[c]=this.a[c]&~(65535<<a)|b<<a:(this.a[c]=this.a[c]&16777215|b<<24,c++,this.a[c]=this.a[c]&-256|
|
||||
b>>8);this.wa=!0},D:function(a,b){return this.I(a,b)},R:function(a,b){return this.Xb(a,b)},na:function(a,b,c){this.l?this.g(a,b,c):this.Mb(a,b,c)},ua:function(a,b,c){this.l?this.g(a,b,c):this.hc(a,b,c)},B:function(a){return this.o[a]},J:function(a){return this.o[a]},O:function(a,b){a&1&&J(this.h,b,64);return this.c.getUint16(a,!0)},aa:function(a,b){a&1&&J(this.h,b,64);return this.s[a>>1]},ma:function(a,b){this.o[a]=b;this.wa=!0},ra:function(a,b){this.o[a]=b;this.wa=!0},ta:function(a,b,c){a&1&&J(this.h,
|
||||
c,64);this.c.setUint16(a,b,!0);this.wa=!0},va:function(a,b,c){a&1&&J(this.h,c,64);this.s[a>>1]=b;this.wa=!0}};function Ab(a,b,c){a.F=b;a.i=a.m=0;c&&((a.i=c.i)&&nc(a,oc,!1),(a.m=c.m)&&pc(a,oc,!1))}function pc(a,b,c){c&&a.m||(a.Lb=!a.l&&b[1]||a.g,a.ub=!a.l&&b[3]||a.A);if(c||void 0===c)a.Mb=b[1]||a.g,a.hc=b[3]||a.A}function nc(a,b,c){c&&a.i||(a.Hb=b[0]||a.v,a.V=b[2]||a.w);if(c||void 0===c)a.I=b[0]||a.v,a.Xb=b[2]||a.w}function hc(a,b){b||(b=qc);nc(a,b,void 0);pc(a,b,void 0)}
|
||||
var qc=[],mc=[I.prototype.M,I.prototype.sa,I.prototype.ba,I.prototype.za],oc=[I.prototype.D,I.prototype.na,I.prototype.R,I.prototype.ua];if(Xa)var jc=[I.prototype.B,I.prototype.ma,I.prototype.O,I.prototype.ta],ic=[I.prototype.J,I.prototype.ra,I.prototype.aa,I.prototype.va];
|
||||
function rc(a,b){y.call(this,"CPU",a,rc,1);b=a.cycles||b;var c=a.multiplier||1;this.Ab=0;this.ob=b;this.ua=c;this.Cb=Math.round(this.ob/1E4)/100;this.Ha=this.Cb*this.ua;this.j.P=!1;this.j.Ib=!1;this.j.Wa=a.autoStart;this.j.ib=!1;this.kb=this.Ia=0;this.mb=a.csStart;this.Ta=a.csInterval;this.Ua=a.csStop;this.J=[];this.cc=this.sd.bind(this);F(this)}A(rc);var sc=["power","reset"];h=rc.prototype;
|
||||
function rc(a,b){y.call(this,"CPU",a,rc,1);b=a.cycles||b;var c=a.multiplier||1;this.Bb=0;this.ob=b;this.ua=c;this.Db=Math.round(this.ob/1E4)/100;this.Ha=this.Db*this.ua;this.j.P=!1;this.j.Jb=!1;this.j.Wa=a.autoStart;this.j.ib=!1;this.kb=this.Ia=0;this.mb=a.csStart;this.Ta=a.csInterval;this.Ua=a.csStop;this.J=[];this.ec=this.ud.bind(this);F(this)}A(rc);var sc=["power","reset"];h=rc.prototype;
|
||||
h.ja=function(a,b,c,d){this.l=a;this.h=b;this.F=d;this.w=a.w;for(b=0;b<sc.length;b++)(c=this.o[sc[b]])&&this.l.$(null,sc[b],c);a=tc(a,"autoStart");null!=a&&(this.j.Wa="true"==a?!0:"false"==a?!1:!!a);F(this)};h.reset=function(){};h.save=function(){return null};h.restore=function(){return!1};h.la=function(a,b){if(!b){if(a&&this.restore){uc(this);if(!this.restore(a))return!1;vc(this)}else this.reset();this.T("No debugger detected")}return!0};h.ka=function(a){return a?this.save():!0};
|
||||
h.Wa=function(){return this.j.Wa||void 0===this.o.run?(mb(this),!0):!1};h.Pb=function(){return 0};function vc(a){void 0===a.mb&&(a.mb=0);void 0===a.Ta&&(a.Ta=-1);void 0===a.Ua&&(a.Ua=-1);a.j.ib=0<=a.mb&&0<a.Ta;a.j.ib&&(a.kb=0,a.Ia=a.mb-a.va)}function pb(a,b){if(a.j.ib){var c=!1;a.kb=a.kb+a.Pb()|0;a.Ia-=b;0>=a.Ia&&(a.Ia+=a.Ta,c=!0);0<=a.Ua&&a.Ua<=wc(a)&&(a.Ta=a.Ua=-1,vc(a),G(a),c=!0);c&&a.T(wc(a)+" cycles: checksum="+m(a.kb))}}
|
||||
h.Wa=function(){return this.j.Wa||void 0===this.o.run?(mb(this),!0):!1};h.Qb=function(){return 0};function vc(a){void 0===a.mb&&(a.mb=0);void 0===a.Ta&&(a.Ta=-1);void 0===a.Ua&&(a.Ua=-1);a.j.ib=0<=a.mb&&0<a.Ta;a.j.ib&&(a.kb=0,a.Ia=a.mb-a.va)}function pb(a,b){if(a.j.ib){var c=!1;a.kb=a.kb+a.Qb()|0;a.Ia-=b;0>=a.Ia&&(a.Ia+=a.Ta,c=!0);0<=a.Ua&&a.Ua<=wc(a)&&(a.Ta=a.Ua=-1,vc(a),G(a),c=!0);c&&a.T(wc(a)+" cycles: checksum="+m(a.kb))}}
|
||||
h.$=function(a,b,c){var d=this;switch(b){case "power":case "reset":return this.o[b]=c,!0;case "run":return this.o[b]=c,c.onclick=function(){var a;if(a=d.l)if(a=d.l,a.j.N)a=!0;else{var b=null,c,k=B(a.id);for(c=0;c<k.length&&(b=k[c],b===a||b.j.ready);c++);if(c==k.length)for(c=0;c<k.length&&(b=k[c],b===a||b.j.N);c++);c==k.length&&(b=a);t("The "+b.type+" component ("+b.id+") is not "+(b.j.ready?"powered yet":"ready yet"+(b.nb?" (waiting for notification)":""))+".");a=!1}a&&(d.j.P?G(d):mb(d))},!0;case "speed":return this.o[b]=
|
||||
c,!0;case "setSpeed":return this.o[b]=c,c.onclick=function(){xc(d,d.ua<<1,!0)},c.textContent=this.Ha.toFixed(2)+"Mhz",!0}return!1};h.ya=function(a){this.l&&this.l.ya(a)};function ob(a,b,c){a.va+=b;c&&(a.ta=a.a=a.I=0)}function yc(a,b){var c=1;b&&1<a.ua&&a.Ga&&(c=a.Ga/a.Cb);a.Vb=Math.round(1E3/30);a.pb=Math.floor(a.ob/30*c);b||(a.Ra=a.pb);a.Db=0}function wc(a){return a.va+a.na+a.ta-a.a}function uc(a){a.Ga=0;a.bc=0;a.va=a.na=a.ta=a.a=a.I=0;vc(a);xc(a,1)}
|
||||
function xc(a,b,c){if(void 0!==b){.8>a.Ga/a.Ha&&(b=1);a.ua=b;b=a.Cb*a.ua;if(a.Ha!=b){a.Ha=b;b=a.Ha.toFixed(2)+"Mhz";var d=a.o.setSpeed;d&&(d.textContent=b);a.T("target speed: "+b)}c&&a.l&&zc(a.l)}ob(a,a.na);a.na=0;a.ba=ra();a.sa=0;yc(a)}function Sb(a,b){var c=a.J.length;a.J.push([-1,b]);return c}function Ub(a,b,c,d){0<=b&&b<a.J.length&&(d||0>a.J[b][0])&&(c=a.ob*a.ua/1E3*c|0,a.j.P&&(c+=Ac(a)),a.J[b][0]=c)}
|
||||
c,!0;case "setSpeed":return this.o[b]=c,c.onclick=function(){xc(d,d.ua<<1,!0)},c.textContent=this.Ha.toFixed(2)+"Mhz",!0}return!1};h.ya=function(a){this.l&&this.l.ya(a)};function ob(a,b,c){a.va+=b;c&&(a.ta=a.a=a.I=0)}function yc(a,b){var c=1;b&&1<a.ua&&a.Ga&&(c=a.Ga/a.Db);a.cc=Math.round(1E3/30);a.pb=Math.floor(a.ob/30*c);b||(a.Ra=a.pb);a.Eb=0}function wc(a){return a.va+a.na+a.ta-a.a}function uc(a){a.Ga=0;a.dc=0;a.va=a.na=a.ta=a.a=a.I=0;vc(a);xc(a,1)}
|
||||
function xc(a,b,c){if(void 0!==b){.8>a.Ga/a.Ha&&(b=1);a.ua=b;b=a.Db*a.ua;if(a.Ha!=b){a.Ha=b;b=a.Ha.toFixed(2)+"Mhz";var d=a.o.setSpeed;d&&(d.textContent=b);a.T("target speed: "+b)}c&&a.l&&zc(a.l)}ob(a,a.na);a.na=0;a.ba=ra();a.sa=0;yc(a)}function Sb(a,b){var c=a.J.length;a.J.push([-1,b]);return c}function Ub(a,b,c,d){0<=b&&b<a.J.length&&(d||0>a.J[b][0])&&(c=a.ob*a.ua/1E3*c|0,a.j.P&&(c+=Ac(a)),a.J[b][0]=c)}
|
||||
function nb(a,b){for(var c=a.J.length-1;0<=c;c--){var d=a.J[c];0>d[0]||(d[0]-=b,0>=d[0]&&(d[0]=-1,d[1]()))}}function Ac(a,b){var c=a.ta-=a.a;a.a=a.I=0;b&&(a.ta=0);return c}
|
||||
h.sd=function(){if(this.j.P){this.Db>=this.ob&&yc(this,!0);this.Va=0;this.jb=ra();if(this.sa){var a=this.jb-this.sa;a>this.Vb&&(this.ba+=a,this.ba>this.jb&&(this.ba=this.jb))}try{do{for(var b,c=this.j.ib?1:this.pb,d=this.J.length-1;0<=d;d--){var e=this.J[d];0>e[0]||c>e[0]&&(c=e[0])}b=c;try{this.rb(b)}catch(f){if("number"!=typeof f)throw f;}b=Ac(this,!0);this.Va+=b;this.na+=b;pb(this,b);nb(this,b);this.Ra-=b;if(0>=this.Ra){this.Ra+=this.pb;15<=++this.bc&&(this.ya(),this.bc=0);break}}while(this.j.P)}catch(f){G(this);
|
||||
this.l&&this.l.stop(ra(),wc(this));Wa(this,f.stack||f.message);return}if(this.j.P){a=setTimeout;b=this.cc;this.sa=ra();c=this.Vb;this.Va&&(c=Math.round(c*this.Va/this.pb));c-=this.sa-this.jb;if(d=this.sa-this.ba)this.Ga=Math.round(this.na/(10*d))/100,864E5<=d&&(this.va=0,xc(this));if(0>c||this.Ga<this.Ha)-1E3>c&&(this.ba-=c),c=0;this.Db+=this.Va;this.sa+=c;a(b,c)}}};
|
||||
function mb(a){var b;a.j.error?(a.T(a.toString()+" error"),b=!0):b=!1;if(!b)if(a.j.P)a.T(a.toString()+" busy");else{xc(a);a.j.P=!0;a.j.Ib=!0;if(b=a.o.run)b.textContent="Halt";a.l&&a.l.start(a.ba,wc(a));setTimeout(a.cc,0)}}h.rb=function(){return 0};function G(a){var b=!1;if(a.j.P){Ac(a);ob(a,a.na);a.na=0;a.j.P=!1;if(b=a.o.run)b.textContent="Run";a.l&&a.l.stop(ra(),wc(a));b=!0}a.j.complete=void 0;return b}
|
||||
function Bc(a){this.La=+a.model||1170;this.Tb=a.addrReset||0;rc.call(this,a,6666667);1120==this.La?(this.decode=Cc.bind(this),this.za=this.kc):(this.decode=Dc.bind(this),this.za=this.lc);Ec(this);this.ma=0;this.O=null;this.j.complete=!1}A(Bc,rc);h=Bc.prototype;h.reset=function(){this.status("model "+this.La);this.j.P&&G(this);Ec(this);uc(this);this.j.error=!1;this.parent.reset.call(this)};
|
||||
function Ec(a){a.m=65536;a.f=32768;a.i=65535;a.s=32768;a.C=15;a.g=[0,0,0,0,0,0,0,a.Tb];a.Ea=[0,0,0,0,0,0];a.qa=[0,0,0,0];a.v=0;a.hb=0;a.vd=[4,2,0,1];a.H=[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];a.Y=[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];a.fb=
|
||||
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];a.$b=[0,0,0,0,0,0,0,0];a.Zb=0;a.u=0;a.B=a.D=0;a.c=a.b=a.Bb=0;a.Ja=-1;lb(a)}function lb(a){a.W=0;a.Eb=0;a.Fb=0;a.Ba=0;a.fa=0;a.Hb=0;a.bb=255;a.aa=0;a.gb=0;a.Sa=262143;a.Za=0;a.A=0;a.O=null;a.h&&Yb(a)}function Yb(a){a.aa?(a.R=65536,a.Sb=a.Ba&16?4186112:253952,a.M=a.qc,a.V=a.pd,a.tb=a.ke,Cb(a.h,a.Ba&16?22:18)):(a.R=0,a.Sb=57344,a.M=a.pc,a.V=a.Yb,a.tb=a.gc,Cb(a.h,16))}
|
||||
function Xb(a,b){b&=-3073;if(a.W!=b){b&57344&&!(a.W&57344)&&(a.Eb=a.A>>16&65535,a.Fb=a.A&65535);a.W=b;a.gb=b>>5&3;a.hb=b>>1&15;var c=0;b&257&&(c=4,b&1&&(c|=2));a.aa!=c&&(a.aa=c,Yb(a))}}h.Pb=function(){return 0};h.save=function(){var a=new O(this);a.set(0,[]);a.set(1,[this.va,this.ua]);a.set(2,Pb(this.h));return a.data()};
|
||||
h.restore=function(a){var b=a[1];this.va=b[1];xc(this,b[3]);a:{b=this.h;a=a[2];var c;for(c=0;c<a.length-1;c+=2){var d=a[c],e=a[c+1];if(e&&e.length<b.D){for(var f=0,g=Array(b.D),k=0;k<e.length-1;)for(var l=e[k++],n=e[k++];l--;)g[f++]=n;e=g}f=b.h[d];if(!f||!f.restore(e)){t("Unable to restore memory block "+d);b=!1;break a}}b=!0}return b};function P(a){return a.m&65536?1:0}function Fc(a){return a.s&32768?8:0}function Gc(a){var b=a.g[7];a.A=b;var c=a.V(b);a.g[7]=b+2&65535;return c}
|
||||
function Hc(a,b){var c=a.g[7];a.g[7]=c+b&65535;return c}function Q(a,b){a.g[7]=b&65535}function Vb(a,b){return{wd:a,Ma:b,next:null}}function Ic(a,b){var c=a.O;if(c==b)a.O=b.next;else for(;c;){a=c.next;if(a==b){c.next=a.next;break}c=a}}function Tb(a,b){if(b!=a.O){var c=a.O;if(!c||c.Ma<=b.Ma)b.next=c,a.O=b;else{do{var d=c.next;if(!d||d.Ma<=b.Ma){b.next=d;c.next=b;break}c=d}while(c)}}a.u|=1}function Jc(a){return a.u&64?(K(a,168,64,-5),!0):a.u&32?(K(a,4,32,-4),!0):a.u&16?(K(a,12,16,-6),!0):!1}
|
||||
function Zb(a){return a.C=a.C&63728|Fc(a)|(a.i&65535?0:4)|(a.f&32768?2:0)|P(a)}function $b(a,b){a.s=b<<12;a.i=~b&4;a.f=b<<14;a.m=b<<16;if((b^a.C)&2048)for(var c=a.Ea.length;0<=--c;){var d=a.g[c];a.g[c]=a.Ea[c];a.Ea[c]=d}a.v=b>>14&3;c=a.C>>14&3;a.v!=c&&(a.qa[c]=a.g[6],a.g[6]=a.qa[a.v]);a.C=b;a.u|=2}function R(a,b){a.u&128||(a.s=a.i=b,a.f=0)}function Kc(a,b,c){a.u&128||(a.s=a.i=a.m=b,a.f=c||0)}function Lc(a,b,c,d){a.u&128||(a.s=a.i=a.m=b,a.f=(c^b)&(d^b))}
|
||||
function Mc(a,b){a.u&128||(a.s=a.i=a.m=b,a.f=a.s^a.m>>1)}function Nc(a,b,c,d){a.u&128||(a.s=a.i=a.m=b,a.f=(c^d)&(d^b))}function K(a,b,c,d){if(!a.ma){0>a.Ja?a.Ja=Zb(a):a.v||(d=-3);var e=!1;-3==d&&(b=4,a.fa|=4,a.g[6]=4,e=!0);a.A=b|4143316992;a.v=0;var f=a.V(b|a.R),g=a.V(b+2&65535|a.R);$b(a,g&-12289|a.Ja>>2&12288);Oc(a,a.Ja,e);Oc(a,a.g[7],e);Q(a,f);a.u&=~(c|18);a.u|=9;a.Ja=-1;if(-3<=d)throw b;}}function Pc(a){var b=Qc(a),c=Qc(a)&-1793;a.C&49152&&(c=c&-225|a.C&63712);Q(a,b);$b(a,c);a.u&=-17}
|
||||
h.ud=function(){if(this.j.P){this.Eb>=this.ob&&yc(this,!0);this.Va=0;this.jb=ra();if(this.sa){var a=this.jb-this.sa;a>this.cc&&(this.ba+=a,this.ba>this.jb&&(this.ba=this.jb))}try{do{for(var b,c=this.j.ib?1:this.pb,d=this.J.length-1;0<=d;d--){var e=this.J[d];0>e[0]||c>e[0]&&(c=e[0])}b=c;try{this.sb(b)}catch(f){if("number"!=typeof f)throw f;}b=Ac(this,!0);this.Va+=b;this.na+=b;pb(this,b);nb(this,b);this.Ra-=b;if(0>=this.Ra){this.Ra+=this.pb;15<=++this.dc&&(this.ya(),this.dc=0);break}}while(this.j.P)}catch(f){G(this);
|
||||
this.l&&this.l.stop(ra(),wc(this));Wa(this,f.stack||f.message);return}if(this.j.P){a=setTimeout;b=this.ec;this.sa=ra();c=this.cc;this.Va&&(c=Math.round(c*this.Va/this.pb));c-=this.sa-this.jb;if(d=this.sa-this.ba)this.Ga=Math.round(this.na/(10*d))/100,864E5<=d&&(this.va=0,xc(this));if(0>c||this.Ga<this.Ha)-1E3>c&&(this.ba-=c),c=0;this.Eb+=this.Va;this.sa+=c;a(b,c)}}};
|
||||
function mb(a){var b;a.j.error?(a.T(a.toString()+" error"),b=!0):b=!1;if(!b)if(a.j.P)a.T(a.toString()+" busy");else{xc(a);a.j.P=!0;a.j.Jb=!0;if(b=a.o.run)b.textContent="Halt";a.l&&a.l.start(a.ba,wc(a));setTimeout(a.ec,0)}}h.sb=function(){return 0};function G(a){var b=!1;if(a.j.P){Ac(a);ob(a,a.na);a.na=0;a.j.P=!1;if(b=a.o.run)b.textContent="Run";a.l&&a.l.stop(ra(),wc(a));b=!0}a.j.complete=void 0;return b}
|
||||
function Bc(a){this.La=+a.model||1170;this.Ub=a.addrReset||0;rc.call(this,a,6666667);this.qb=0;this.bc=255;1120==this.La?(this.decode=Cc.bind(this),this.za=this.mc,this.qb=8,this.bc=-1):(this.decode=Dc.bind(this),this.za=this.nc);Ec(this);this.ma=0;this.O=null;this.j.complete=!1}A(Bc,rc);h=Bc.prototype;h.reset=function(){this.status("model "+this.La);this.j.P&&G(this);Ec(this);uc(this);this.j.error=!1;this.parent.reset.call(this)};
|
||||
function Ec(a){a.m=65536;a.g=32768;a.i=65535;a.s=32768;a.C=15;a.f=[0,0,0,0,0,0,0,a.Ub,-1,-2,-3,-4,-5,-6,-7,-8];a.Ea=[0,0,0,0,0,0];a.qa=[0,0,0,0];a.v=0;a.hb=0;a.ne=[4,2,0,1];a.H=[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];a.Y=[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0]];a.fb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];a.$b=[0,0,0,0,0,0,0,0];a.Zb=0;a.u=0;a.B=a.D=0;a.c=a.b=a.Cb=0;a.Ja=-1;lb(a)}function lb(a){a.W=0;a.Fb=0;a.Gb=0;a.Ba=0;a.fa=0;a.Ib=0;a.bb=255;a.aa=0;a.gb=0;a.Sa=262143;a.Za=0;a.A=0;a.O=null;a.h&&Yb(a)}function Yb(a){a.aa?(a.R=65536,a.Tb=a.Ba&16?4186112:253952,a.M=a.sc,a.V=a.rd,a.ub=a.ke,Cb(a.h,a.Ba&16?22:18)):(a.R=0,a.Tb=57344,a.M=a.rc,a.V=a.Yb,a.ub=a.ic,Cb(a.h,16))}
|
||||
function Xb(a,b){b&=-3073;if(a.W!=b){b&57344&&!(a.W&57344)&&(a.Fb=a.A>>16&65535,a.Gb=a.A&65535);a.W=b;a.gb=b>>5&3;a.hb=b>>1&15;var c=0;b&257&&(c=4,b&1&&(c|=2));a.aa!=c&&(a.aa=c,Yb(a))}}h.Qb=function(){return 0};h.save=function(){var a=new O(this);a.set(0,[]);a.set(1,[this.va,this.ua]);a.set(2,Pb(this.h));return a.data()};
|
||||
h.restore=function(a){var b=a[1];this.va=b[1];xc(this,b[3]);a:{b=this.h;a=a[2];var c;for(c=0;c<a.length-1;c+=2){var d=a[c],e=a[c+1];if(e&&e.length<b.D){for(var f=0,g=Array(b.D),k=0;k<e.length-1;)for(var l=e[k++],n=e[k++];l--;)g[f++]=n;e=g}f=b.h[d];if(!f||!f.restore(e)){t("Unable to restore memory block "+d);b=!1;break a}}b=!0}return b};function P(a){return a.m&65536?1:0}function Fc(a){return a.s&32768?8:0}function Gc(a){var b=a.f[7];a.A=b;var c=a.V(b);a.f[7]=b+2&65535;return c}
|
||||
function Hc(a,b){var c=a.f[7];a.f[7]=c+b&65535;return c}function Q(a,b){a.f[7]=b&65535}function Vb(a,b){return{wd:a,Ma:b,next:null}}function Ic(a,b){var c=a.O;if(c==b)a.O=b.next;else for(;c;){a=c.next;if(a==b){c.next=a.next;break}c=a}}function Tb(a,b){if(b!=a.O){var c=a.O;if(!c||c.Ma<=b.Ma)b.next=c,a.O=b;else{do{var d=c.next;if(!d||d.Ma<=b.Ma){b.next=d;c.next=b;break}c=d}while(c)}}a.u|=1}function Jc(a){return a.u&64?(K(a,168,64,-5),!0):a.u&32?(K(a,4,32,-4),!0):a.u&16?(K(a,12,16,-6),!0):!1}
|
||||
function Zb(a){return a.C=a.C&63728|Fc(a)|(a.i&65535?0:4)|(a.g&32768?2:0)|P(a)}function $b(a,b){a.s=b<<12;a.i=~b&4;a.g=b<<14;a.m=b<<16;if((b^a.C)&2048)for(var c=a.Ea.length;0<=--c;){var d=a.f[c];a.f[c]=a.Ea[c];a.Ea[c]=d}a.v=b>>14&3;c=a.C>>14&3;a.v!=c&&(a.qa[c]=a.f[6],a.f[6]=a.qa[a.v]);a.C=b;a.u|=2}function R(a,b){a.u&128||(a.s=a.i=b,a.g=0)}function Kc(a,b,c){a.u&128||(a.s=a.i=a.m=b,a.g=c||0)}function Lc(a,b,c,d){a.u&128||(a.s=a.i=a.m=b,a.g=(c^b)&(d^b))}
|
||||
function Mc(a,b){a.u&128||(a.s=a.i=a.m=b,a.g=a.s^a.m>>1)}function Nc(a,b,c,d){a.u&128||(a.s=a.i=a.m=b,a.g=(c^d)&(d^b))}function K(a,b,c,d){if(!a.ma){0>a.Ja?a.Ja=Zb(a):a.v||(d=-3);var e=!1;-3==d&&(b=4,a.fa|=4,a.f[6]=4,e=!0);a.A=b|4143316992;a.v=0;var f=a.V(b|a.R),g=a.V(b+2&65535|a.R);$b(a,g&-12289|a.Ja>>2&12288);Oc(a,a.Ja,e);Oc(a,a.f[7],e);Q(a,f);a.u&=~(c|18);a.u|=9;a.Ja=-1;if(-3<=d)throw b;}}function Pc(a){var b=Qc(a),c=Qc(a)&-1793;a.C&49152&&(c=c&-225|a.C&63712);Q(a,b);$b(a,c);a.u&=-17}
|
||||
function Lb(a,b){var c=b>>13&31;31>c&&(b=a.Ba&32?a.fb[c]+(b&8190)&4194302:b&-3932161);return b}
|
||||
function Rc(a,b,c){var d,e,f;if(!(c&a.aa))return f=b&65535,57344<=f&&(f|=a.Sb),f;d=b>>13;a.Ba&a.vd[a.v]||(d&=7);e=a.H[a.v][d];f=(a.Y[a.v][d]<<6)+(b&8191)&a.Sa;if(a.ma)return f;f&1&&!(c&1)&&(a.fa|=64,K(a,4,0,f));var g=0;switch(e&7){case 1:g=4096;case 2:e|=128;c&4&&(g=8192);break;case 4:g=4096;case 5:c&4&&(g=4096);case 6:e|=c&4?192:128;break;default:g=32768}32512!=(e&32520)&&(e&8?e&32512&&(b&8128)<(e>>2&8128)&&(g|=16384):(b&8128)>(e>>2&8128)&&(g|=16384));a.H[a.v][d]=e;if(f!=(4194170&a.Sa)||a.v)a.gb=
|
||||
a.v,a.hb=d;g&&(g&57344&&(0<=a.Ja&&(g|=128),a.W&57344||(g|=a.W&4096|a.gb<<5|a.hb<<1,Xb(a,a.W&-61695|g&61694)),K(a,168,64,-1)),a.W&61440||!(f<(4191360&a.Sa)||f>(4194239&a.Sa))||(a.W|=4096,a.W&512&&(a.u|=64)));return f}function Qc(a){var b=a.V(a.g[6]|a.R);a.g[6]=a.g[6]+2&65535;return b}function Oc(a,b,c){var d=a.g[6]-2&65535;a.g[6]=d;a.A=a.A&65535|(a.A&-65536)<<8|16121856;c||a.za(4,-2,d);a.tb(d,b)}
|
||||
function Sc(a,b,c,d){var e,f,g=d&8?0:a.R;switch(b){case 0:return K(a,4,0,-2),0;case 1:return 6==c&&a.za(d,0,a.g[6]),a.a-=3,7==c?a.g[c]:a.g[c]|g;case 2:f=2;e=a.g[c];6==c&&a.za(d,f,e);7!=c&&(e|=g,6>c&&d&1&&(f=1));a.a-=3;break;case 3:f=2;e=a.g[c];7!=c&&(e|=g);e=a.V(e);e|=g;a.a-=7;break;case 4:f=-2;6>c&&d&1&&(f=-1);e=a.g[c]+f&65535;6==c&&a.za(d,f,e);7!=c&&(e|=g);a.a-=4;break;case 5:f=-2;e=a.g[c]-2&65535;7!=c&&(e|=g);e=a.V(e)|g;a.a-=8;break;case 6:return e=a.V(Hc(a,2)),e=e+a.g[c]&65535,6==c&&a.za(d,0,
|
||||
e),a.a-=6,e|g;case 7:return e=a.V(Hc(a,2)),e=e+a.g[c]&65535,e=a.V(e|a.R),a.a-=10,e|g}a.g[c]=a.g[c]+f&65535;a.A=a.A&65535|(a.A&-65536)<<8|(f<<3&248|c)<<16;return e}h.kc=function(a,b,c){!this.v&&0>=b&&c<=this.bb&&(this.u|=32)};h.lc=function(a,b,c){!this.v&&a&4&&c<=this.bb&&(c<=this.bb-32?K(this,4,0,-3):(this.fa|=8,this.u|=32))};h.Ya=function(a){if(!this.aa)return this.h.Ya(a);this.ma++;a=this.Yb(Rc(this,a,2));this.ma--;return a};
|
||||
h.cb=function(a,b){this.aa?(this.ma++,a=Rc(this,a,5),a&1&&this.a--,Nb(this.h,a,b),this.ma--):this.h.cb(a,b)};h.eb=function(a,b){this.aa?(this.ma++,this.gc(Rc(this,a,4),b),this.ma--):this.h.eb(a,b)};h.pc=function(a,b,c){return Sc(this,a,b,c)};h.qc=function(a,b,c){return Rc(this,Sc(this,a,b,c),c)};h.Yb=function(a){return Mb(this.h,this.Za=a)};h.pd=function(a){return Mb(this.h,this.Za=Rc(this,a,2))};h.gc=function(a,b){Ob(this.h,this.Za=a,b&65535)};h.ke=function(a,b){Ob(this.h,this.Za=Rc(this,a,4),b)};
|
||||
function Tc(a,b,c){var d=a.b=b&7;(b=a.c=(b&56)>>3)?(d=Sc(a,b,d,2),c&65536||61440!==(a.C&61440)&&(d&=65535),a.v=a.C>>12&3,c=a.V(d|c&a.R),a.v=a.C>>14&3):c=6!=d||(a.C>>2&12288)===(a.C&12288)?a.g[d]:a.qa[a.C>>12&3];return c}function Uc(a,b,c,d){a.A=a.A&65535|1441792;var e=a.b=b&7;(b=a.c=(b&56)>>3)?(e=Sc(a,b,e,4),c&65536||(e&=65535),a.v=a.C>>12&3,e=Rc(a,e|c&65536,4),a.v=a.C>>14&3,Ob(a.h,e,d)):6!=e||(a.C>>2&12288)===(a.C&12288)?a.g[e]=d:a.qa[a.C>>12&3]=d}
|
||||
function Vc(a,b){b>>=6;var c=a.D=b&7;(b=a.B=(b&56)>>3)?(c=a.M(b,c,3),a=Kb(a.h,c)):a=-c-1;return a}function Wc(a,b){var c;b>>=6;var d=a.D=b&7;(b=a.B=(b&56)>>3)?c=Mb(a.h,a.M(b,d,2)):c=-d-1;return c}function Xc(a,b){var c=a.b=b&7;b=a.c=(b&56)>>3;return Sc(a,b,c,8)}function Yc(a,b){var c=a.b=b&7;(b=a.c=(b&56)>>3)?(c=a.M(b,c,3),a=Kb(a.h,c)):a=a.g[c]&255;return a}function Zc(a,b){var c=a.b=b&7;return(b=a.c=(b&56)>>3)?Mb(a.h,a.M(b,c,2)):a.g[c]}
|
||||
function S(a,b,c,d){var e=a.b=b&7;(b=a.c=(b&56)>>3)?(e=a.Bb=a.M(b,e,7),c=0>c?a.g[-c-1]&255:c,c=d.call(a,c,Kb(a.h,e)),e&1&&a.a--,Nb(a.h,e,c)):(b=a.g[e],c=0>c?a.g[-c-1]&255:c,a.g[e]=b&65280|d.call(a,c,b&255))}function U(a,b,c,d){var e=a.b=b&7;(b=a.c=(b&56)>>3)?(e=a.M(b,e,6),Ob(a.h,e,d.call(a,0>c?a.g[-c-1]:c,Mb(a.h,e)))):a.g[e]=d.call(a,0>c?a.g[-c-1]:c,a.g[e])}
|
||||
function $c(a,b,c,d){var e=a.b=b&7;(b=a.c=(b&56)>>3)?(d=a.M(b,e,5),e=c=0>c?a.g[-c-1]&255:c,d&1&&a.a--,Nb(a.h,d,e)):c?(c=0>c?a.g[-c-1]&255:c,a.g[e]=a.g[e]&~d|c<<24>>24&d):a.g[e]&=~d;return c}function ad(a,b,c){var d=a.b=b&7;(b=a.c=(b&56)>>3)?(d=a.M(b,d,4),Ob(a.h,d,c=0>c?a.g[-c-1]:c)):a.g[d]=c=0>c?a.g[-c-1]:c;return c}function V(a,b,c){c&&(Q(a,a.g[7]+(b<<24>>23)),a.a-=2);a.a-=3}
|
||||
h.rb=function(a){this.j.complete=!0;var b=a?this.j.Ib?0:1:-1;this.j.Ib=!1;this.ta=this.a=a;do{if(this.u){if(a=this.u&7){a=!1;if(this.u&2){this.u&=-3;var c=160,d=(this.Hb&224)>>5,e=this.O&&this.O.Ma>d?this.O:null;e&&(c=e.wd,d=e.Ma);d>(this.C&224)>>5?(this.u&4&&(Hc(this,2),this.u&=-5),K(this,c,0,-9),d=!0):d=!1;d&&(e&&Ic(this,e),a=!0)}else this.u&1&&this.u++;a=a&&0>b}if(a)break;if(this.u&112&&Jc(this)&&0>b)break}this.u=this.u&7|this.C&16;this.decode(Gc(this))}while(0<this.a);return this.j.complete?this.ta-
|
||||
function Rc(a,b,c){var d,e,f;if(!(c&a.aa))return f=b&65535,57344<=f&&(f|=a.Tb),f;d=b>>13;a.Ba&a.ne[a.v]||(d&=7);e=a.H[a.v][d];f=(a.Y[a.v][d]<<6)+(b&8191)&a.Sa;if(a.ma)return f;f&1&&!(c&1)&&(a.fa|=64,K(a,4,0,f));var g=0;switch(e&7){case 1:g=4096;case 2:e|=128;c&4&&(g=8192);break;case 4:g=4096;case 5:c&4&&(g=4096);case 6:e|=c&4?192:128;break;default:g=32768}32512!=(e&32520)&&(e&8?e&32512&&(b&8128)<(e>>2&8128)&&(g|=16384):(b&8128)>(e>>2&8128)&&(g|=16384));a.H[a.v][d]=e;if(f!=(4194170&a.Sa)||a.v)a.gb=
|
||||
a.v,a.hb=d;g&&(g&57344&&(0<=a.Ja&&(g|=128),a.W&57344||(g|=a.W&4096|a.gb<<5|a.hb<<1,Xb(a,a.W&-61695|g&61694)),K(a,168,64,-1)),a.W&61440||!(f<(4191360&a.Sa)||f>(4194239&a.Sa))||(a.W|=4096,a.W&512&&(a.u|=64)));return f}function Qc(a){var b=a.V(a.f[6]|a.R);a.f[6]=a.f[6]+2&65535;return b}function Oc(a,b,c){var d=a.f[6]-2&65535;a.f[6]=d;a.A=a.A&65535|(a.A&-65536)<<8|16121856;c||a.za(4,-2,d);a.ub(d,b)}
|
||||
function Sc(a,b,c,d){var e,f,g=d&8?0:a.R;switch(b){case 0:return K(a,4,0,-2),0;case 1:return 6==c&&a.za(d,0,a.f[6]),a.a-=3,7==c?a.f[c]:a.f[c]|g;case 2:f=2;e=a.f[c];6==c&&a.za(d,f,e);7!=c&&(e|=g,6>c&&d&1&&(f=1));a.a-=3;break;case 3:f=2;e=a.f[c];7!=c&&(e|=g);e=a.V(e);e|=g;a.a-=7;break;case 4:f=-2;6>c&&d&1&&(f=-1);e=a.f[c]+f&65535;6==c&&a.za(d,f,e);7!=c&&(e|=g);a.a-=4;break;case 5:f=-2;e=a.f[c]-2&65535;7!=c&&(e|=g);e=a.V(e)|g;a.a-=8;break;case 6:return e=a.V(Hc(a,2)),e=e+a.f[c]&65535,6==c&&a.za(d,0,
|
||||
e),a.a-=6,e|g;case 7:return e=a.V(Hc(a,2)),e=e+a.f[c]&65535,e=a.V(e|a.R),a.a-=10,e|g}a.f[c]=a.f[c]+f&65535;a.A=a.A&65535|(a.A&-65536)<<8|(f<<3&248|c)<<16;return e}h.mc=function(a,b,c){!this.v&&0>=b&&c<=this.bb&&(this.u|=32)};h.nc=function(a,b,c){!this.v&&a&4&&c<=this.bb&&(c<=this.bb-32?K(this,4,0,-3):(this.fa|=8,this.u|=32))};h.Ya=function(a){if(!this.aa)return this.h.Ya(a);this.ma++;a=this.Yb(Rc(this,a,2));this.ma--;return a};
|
||||
h.cb=function(a,b){this.aa?(this.ma++,a=Rc(this,a,5),a&1&&this.a--,Nb(this.h,a,b),this.ma--):this.h.cb(a,b)};h.eb=function(a,b){this.aa?(this.ma++,this.ic(Rc(this,a,4),b),this.ma--):this.h.eb(a,b)};h.rc=function(a,b,c){return Sc(this,a,b,c)};h.sc=function(a,b,c){return Rc(this,Sc(this,a,b,c),c)};h.Yb=function(a){return Mb(this.h,this.Za=a)};h.rd=function(a){return Mb(this.h,this.Za=Rc(this,a,2))};h.ic=function(a,b){Ob(this.h,this.Za=a,b&65535)};h.ke=function(a,b){Ob(this.h,this.Za=Rc(this,a,4),b)};
|
||||
function Tc(a,b,c){var d=a.b=b&7;(b=a.c=(b&56)>>3)?(d=Sc(a,b,d,2),c&65536||61440!==(a.C&61440)&&(d&=65535),a.v=a.C>>12&3,c=a.V(d|c&a.R),a.v=a.C>>14&3):c=6!=d||(a.C>>2&12288)===(a.C&12288)?a.f[d]:a.qa[a.C>>12&3];return c}function Uc(a,b,c,d){a.A=a.A&65535|1441792;var e=a.b=b&7;(b=a.c=(b&56)>>3)?(e=Sc(a,b,e,4),c&65536||(e&=65535),a.v=a.C>>12&3,e=Rc(a,e|c&65536,4),a.v=a.C>>14&3,Ob(a.h,e,d)):6!=e||(a.C>>2&12288)===(a.C&12288)?a.f[e]=d:a.qa[a.C>>12&3]=d}
|
||||
function Vc(a,b){b>>=6;var c=a.D=b&7;(b=a.B=(b&56)>>3)?(c=a.M(b,c,3),a=Kb(a.h,c)):a=a.f[c+a.qb]&a.bc;return a}function Wc(a,b){b>>=6;var c=a.D=b&7;return(b=a.B=(b&56)>>3)?Mb(a.h,a.M(b,c,2)):a.f[c+a.qb]}function Xc(a,b){var c=a.b=b&7;b=a.c=(b&56)>>3;return Sc(a,b,c,8)}function Yc(a,b){var c=a.b=b&7;(b=a.c=(b&56)>>3)?(c=a.M(b,c,3),a=Kb(a.h,c)):a=a.f[c]&255;return a}function Zc(a,b){var c=a.b=b&7;return(b=a.c=(b&56)>>3)?Mb(a.h,a.M(b,c,2)):a.f[c]}
|
||||
function S(a,b,c,d){var e=a.b=b&7;(b=a.c=(b&56)>>3)?(e=a.Cb=a.M(b,e,7),c=0>c?a.f[-c-1]&255:c,c=d.call(a,c,Kb(a.h,e)),e&1&&a.a--,Nb(a.h,e,c)):(b=a.f[e],c=0>c?a.f[-c-1]&255:c,a.f[e]=b&65280|d.call(a,c,b&255))}function U(a,b,c,d){var e=a.b=b&7;(b=a.c=(b&56)>>3)?(e=a.M(b,e,6),Ob(a.h,e,d.call(a,0>c?a.f[-c-1]:c,Mb(a.h,e)))):a.f[e]=d.call(a,0>c?a.f[-c-1]:c,a.f[e])}
|
||||
function $c(a,b,c,d){var e=a.b=b&7;(b=a.c=(b&56)>>3)?(d=a.M(b,e,5),e=c=0>c?a.f[-c-1]&255:c,d&1&&a.a--,Nb(a.h,d,e)):c?(c=0>c?a.f[-c-1]&255:c,a.f[e]=a.f[e]&~d|c<<24>>24&d):a.f[e]&=~d;return c}function ad(a,b,c){var d=a.b=b&7;(b=a.c=(b&56)>>3)?(d=a.M(b,d,4),Ob(a.h,d,c=0>c?a.f[-c-1]:c)):a.f[d]=c=0>c?a.f[-c-1]:c;return c}function V(a,b,c){c&&(Q(a,a.f[7]+(b<<24>>23)),a.a-=2);a.a-=3}
|
||||
h.sb=function(a){this.j.complete=!0;var b=a?this.j.Jb?0:1:-1;this.j.Jb=!1;this.ta=this.a=a;do{if(this.u){if(a=this.u&7){a=!1;if(this.u&2){this.u&=-3;var c=160,d=(this.Ib&224)>>5,e=this.O&&this.O.Ma>d?this.O:null;e&&(c=e.wd,d=e.Ma);d>(this.C&224)>>5?(this.u&4&&(Hc(this,2),this.u&=-5),K(this,c,0,-9),d=!0):d=!1;d&&(e&&Ic(this,e),a=!0)}else this.u&1&&this.u++;a=a&&0>b}if(a)break;if(this.u&112&&Jc(this)&&0>b)break}this.u=this.u&7|this.C&16;this.decode(Gc(this))}while(0<this.a);return this.j.complete?this.ta-
|
||||
this.a:void 0===this.j.complete?0:-1};Ga(function(){for(var a=E(document,"pdp11","cpu"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new Bc(d);D(d,c)}});function bd(a,b){var c=b+a;Lc(this,c,a,b);return c&65535}function cd(a,b){var c=b+a;Lc(this,c<<8,a<<8,b<<8);return c&255}function dd(a,b){a=b<<1;Mc(this,a);return a&65535}function ed(a,b){a=b<<1;Mc(this,a<<8);return a&255}function fd(a,b){a=b&32768|b>>1|b<<16;Mc(this,a);return a&65535}function gd(a,b){a=b&128|b>>1|b<<8;Mc(this,a<<8);return a&255}
|
||||
function hd(a,b){a=b&~a;R(this,a);return a}function id(a,b){a=b&~a;R(this,a<<8);return a}function jd(a,b){a|=b;R(this,a);return a}function kd(a,b){a|=b;R(this,a<<8);return a}function ld(a,b){a=~b|65536;Kc(this,a);return a&65535}function md(a,b){a=~b|256;Kc(this,a<<8);return a&255}function nd(a,b){a=b-a;this.u&128||(this.s=this.i=a,this.f=b&(b^a));return a&65535}function od(a,b){a=b-a;var c=a<<8;b<<=8;this.u&128||(this.s=this.i=c,this.f=b&(b^c));return a&255}
|
||||
function pd(a,b){a=b+a;this.u&128||(this.s=this.i=a,this.f=a&(b^a));return a&65535}function qd(a,b){a=b+a;var c=a<<8;this.u&128||(this.s=this.i=c,this.f=c&(b<<8^c));return a&255}function rd(a,b){a=-b;Kc(this,a,a&b&32768);return a&65535}function sd(a,b){a=-b;Kc(this,a<<8,(a&b&128)<<8);return a&255}function td(a,b){a=b<<1|this.m>>16&1;Mc(this,a);return a&65535}function ud(a,b){a=b<<1|this.m>>16&1;Mc(this,a<<8);return a&255}function vd(a,b){a=(this.m&65536|b)>>1|b<<16;Mc(this,a);return a&65535}
|
||||
function wd(a,b){a=((this.m&65536)>>8|b)>>1|b<<8;Mc(this,a<<8);return a&255}function xd(a,b){var c=b-a;Nc(this,c,a,b);return c&65535}function yd(a,b){var c=b-a;Nc(this,c<<8,a<<8,b<<8);return c&255}function zd(a,b){this.u&128||(this.s=this.i=b&65280,this.f=this.m=0);return(b<<8|b>>8)&65535}function Ad(a,b){a^=b;R(this,a);return a&65535}function Bd(a){U(this,a,Wc(this,a),bd);this.a-=this.c?9+(this.D&&6<=this.b?1:0):(this.B?5:3)+(7==this.b?2:0)}
|
||||
function Cd(a){var b=Zc(this,a);a=a>>6&7;var c=this.g[a];c&32768&&(c|=4294901760);this.m=this.f=0;b&=63;if(b&32)b=64-b,16<b&&(b=16),this.m=c<<17-b,c>>=b;else if(b)if(16<b)this.f=c,c=0;else{this.m=c<<=b;var d=c>>15&65535;d&&65535!==d&&(this.f=32768)}this.g[a]=c&65535;this.s=this.i=c;this.a-=(this.c?6:7)+b}
|
||||
function Dd(a){var b=Zc(this,a);a=a>>6&7;var c=this.g[a]<<16|this.g[a|1];this.m=this.f=0;b&=63;if(b&32){b=64-b;32<b&&(b=32);var d=c>>b-1;this.m=d<<16;d>>=1;c&2147483648&&(d|=4294967295<<32-b)}else b?(d=c<<b-1,this.m=d>>15,d<<=1,32<b&&(b=32),(c>>=32-b)&&4294967295!==(c|4294967295<<b&4294967295)&&(this.f=32768)):d=c;this.g[a]=d>>16&65535;this.g[a|1]=d&65535;this.s=d>>16;this.i=d>>16|d;this.a-=(this.c?6:7)+b}function Ed(a){V(this,a,!P(this))}function Fd(a){V(this,a,P(this))}
|
||||
function hd(a,b){a=b&~a;R(this,a);return a}function id(a,b){a=b&~a;R(this,a<<8);return a}function jd(a,b){a|=b;R(this,a);return a}function kd(a,b){a|=b;R(this,a<<8);return a}function ld(a,b){a=~b|65536;Kc(this,a);return a&65535}function md(a,b){a=~b|256;Kc(this,a<<8);return a&255}function nd(a,b){a=b-a;this.u&128||(this.s=this.i=a,this.g=b&(b^a));return a&65535}function od(a,b){a=b-a;var c=a<<8;b<<=8;this.u&128||(this.s=this.i=c,this.g=b&(b^c));return a&255}
|
||||
function pd(a,b){a=b+a;this.u&128||(this.s=this.i=a,this.g=a&(b^a));return a&65535}function qd(a,b){a=b+a;var c=a<<8;this.u&128||(this.s=this.i=c,this.g=c&(b<<8^c));return a&255}function rd(a,b){a=-b;Kc(this,a,a&b&32768);return a&65535}function sd(a,b){a=-b;Kc(this,a<<8,(a&b&128)<<8);return a&255}function td(a,b){a=b<<1|this.m>>16&1;Mc(this,a);return a&65535}function ud(a,b){a=b<<1|this.m>>16&1;Mc(this,a<<8);return a&255}function vd(a,b){a=(this.m&65536|b)>>1|b<<16;Mc(this,a);return a&65535}
|
||||
function wd(a,b){a=((this.m&65536)>>8|b)>>1|b<<8;Mc(this,a<<8);return a&255}function xd(a,b){var c=b-a;Nc(this,c,a,b);return c&65535}function yd(a,b){var c=b-a;Nc(this,c<<8,a<<8,b<<8);return c&255}function zd(a,b){this.u&128||(this.s=this.i=b&65280,this.g=this.m=0);return(b<<8|b>>8)&65535}function Ad(a,b){a^=b;R(this,a);return a&65535}function Bd(a){U(this,a,Wc(this,a),bd);this.a-=this.c?9+(this.D&&6<=this.b?1:0):(this.B?5:3)+(7==this.b?2:0)}
|
||||
function Cd(a){var b=Zc(this,a);a=a>>6&7;var c=this.f[a];c&32768&&(c|=4294901760);this.m=this.g=0;b&=63;if(b&32)b=64-b,16<b&&(b=16),this.m=c<<17-b,c>>=b;else if(b)if(16<b)this.g=c,c=0;else{this.m=c<<=b;var d=c>>15&65535;d&&65535!==d&&(this.g=32768)}this.f[a]=c&65535;this.s=this.i=c;this.a-=(this.c?6:7)+b}
|
||||
function Dd(a){var b=Zc(this,a);a=a>>6&7;var c=this.f[a]<<16|this.f[a|1];this.m=this.g=0;b&=63;if(b&32){b=64-b;32<b&&(b=32);var d=c>>b-1;this.m=d<<16;d>>=1;c&2147483648&&(d|=4294967295<<32-b)}else b?(d=c<<b-1,this.m=d>>15,d<<=1,32<b&&(b=32),(c>>=32-b)&&4294967295!==(c|4294967295<<b&4294967295)&&(this.g=32768)):d=c;this.f[a]=d>>16&65535;this.f[a|1]=d&65535;this.s=d>>16;this.i=d>>16|d;this.a-=(this.c?6:7)+b}function Ed(a){V(this,a,!P(this))}function Fd(a){V(this,a,P(this))}
|
||||
function Gd(a){U(this,a,Wc(this,a),hd);this.a-=this.c?9+(this.D&&6<=this.b?1:0):(this.B?5:3)+(7==this.b?2:0)}function Hd(a){S(this,a,Vc(this,a),id);this.a-=this.c?9+(this.D&&6<=this.b?1:0):(this.B?5:3)+(7==this.b?2:0)}function Id(a){U(this,a,Wc(this,a),jd);this.a-=this.c?9+(this.D&&6<=this.b?1:0):(this.B?5:3)+(7==this.b?2:0)}function Jd(a){S(this,a,Vc(this,a),kd);this.a-=this.c?9+(this.D&&6<=this.b?1:0):(this.B?5:3)+(7==this.b?2:0)}
|
||||
function Kd(a){var b=Wc(this,a);a=Zc(this,a);R(this,(0>b?this.g[-b-1]:b)&a);this.a-=this.c?4+(this.D&&6<=this.b?1:0):(this.B?4:3)+(7==this.b?2:0)}function Ld(a){var b=Vc(this,a);a=Yc(this,a);R(this,((0>b?this.g[-b-1]&255:b)&a)<<8);this.a-=this.c?4+(this.D&&6<=this.b?1:0):(this.B?4:3)+(7==this.b?2:0)}function Md(a){V(this,a,this.i&65535?0:4)}function Nd(a){V(this,a,!Fc(this)==!(this.f&32768))}function Od(a){V(this,a,!!(this.i&65535)&&!Fc(this)==!(this.f&32768))}
|
||||
function Pd(a){V(this,a,!P(this)&&!!(this.i&65535))}function Qd(a){V(this,a,(this.i&65535?0:4)||!Fc(this)!=!(this.f&32768))}function Rd(a){V(this,a,P(this)||(this.i&65535?0:4))}function Sd(a){V(this,a,!Fc(this)!=!(this.f&32768))}function Td(a){V(this,a,Fc(this))}function Ud(a){V(this,a,!!(this.i&65535))}function Vd(a){V(this,a,!Fc(this))}function Wd(){K(this,12,0,-8);this.a-=5}function Xd(a){V(this,a,!0)}function Yd(a){V(this,a,!(this.f&32768))}function Zd(a){V(this,a,this.f&32768?2:0)}
|
||||
function W(a){a&1&&(this.m=0);a&2&&(this.f=0);a&4&&(this.i=1);a&8&&(this.s=0);this.a-=5}function $d(a){var b=Wc(this,a);a=Zc(this,a);var c=(b=0>b?this.g[-b-1]:b)-a;Nc(this,c,a,b);this.a-=this.c?4+(this.D&&6<=this.b?1:0):(this.B?4:3)+(7==this.b?2:0)}function ae(a){var b=Vc(this,a);a=Yc(this,a);var c=(b=(0>b?this.g[-b-1]&255:b)<<8)-(a<<=8);Nc(this,c,a,b);this.a-=this.c?4+(this.D&&6<=this.b?1:0):(this.B?4:3)+(7==this.b?2:0)}
|
||||
function be(a){var b=Zc(this,a);if(b){a=a>>6&7;var c=this.g[a]<<16|this.g[a|1];this.m=this.f=0;b&32768&&(b|=-65536);var d=~~(c/b);-32768<=d&&32767>=d?(this.g[a]=d&65535,this.g[a|1]=c-d*b&65535,this.i=d>>16|d,this.s=d>>16):(this.f=32768,this.i=d>>15|d,this.s=c>>16,-1===b&&65534===this.g[a]&&(this.g[a]=this.g[a|1]=1));this.a-=53}else this.i=this.s=0,this.f=32768,this.m=65536,this.a-=7}function ce(){K(this,24,0,-8);this.a-=25}
|
||||
function de(){this.C&49152?(this.fa|=128,K(this,4,0,-7)):(this.w&&1120==this.La&&this.w.setData(this.g[0],!0),this.F?this.F.b():G(this));this.a-=7}function ee(){K(this,16,0,-8);this.a-=25}var fe=[0,7,7,10,7,11,9,13];function ge(a){this.I=this.a;Q(this,Xc(this,a));this.a=this.I-fe[this.c]}var he=[0,14,14,17,14,18,16,20];function ie(a){this.I=this.a;var b=Xc(this,a);a=a>>6&7;Oc(this,this.g[a]);this.g[a]=this.g[7];Q(this,b);this.a=this.I-he[this.c]}var je=[3,9,9,13,10,14,12,16,4,9,9,13,10,14,13,17];
|
||||
function Kd(a){var b=Wc(this,a);a=Zc(this,a);R(this,(0>b?this.f[-b-1]:b)&a);this.a-=this.c?4+(this.D&&6<=this.b?1:0):(this.B?4:3)+(7==this.b?2:0)}function Ld(a){var b=Vc(this,a);a=Yc(this,a);R(this,((0>b?this.f[-b-1]&255:b)&a)<<8);this.a-=this.c?4+(this.D&&6<=this.b?1:0):(this.B?4:3)+(7==this.b?2:0)}function Md(a){V(this,a,this.i&65535?0:4)}function Nd(a){V(this,a,!Fc(this)==!(this.g&32768))}function Od(a){V(this,a,!!(this.i&65535)&&!Fc(this)==!(this.g&32768))}
|
||||
function Pd(a){V(this,a,!P(this)&&!!(this.i&65535))}function Qd(a){V(this,a,(this.i&65535?0:4)||!Fc(this)!=!(this.g&32768))}function Rd(a){V(this,a,P(this)||(this.i&65535?0:4))}function Sd(a){V(this,a,!Fc(this)!=!(this.g&32768))}function Td(a){V(this,a,Fc(this))}function Ud(a){V(this,a,!!(this.i&65535))}function Vd(a){V(this,a,!Fc(this))}function Wd(){K(this,12,0,-8);this.a-=5}function Xd(a){V(this,a,!0)}function Yd(a){V(this,a,!(this.g&32768))}function Zd(a){V(this,a,this.g&32768?2:0)}
|
||||
function W(a){a&1&&(this.m=0);a&2&&(this.g=0);a&4&&(this.i=1);a&8&&(this.s=0);this.a-=5}function $d(a){var b=Wc(this,a);a=Zc(this,a);var c=(b=0>b?this.f[-b-1]:b)-a;Nc(this,c,a,b);this.a-=this.c?4+(this.D&&6<=this.b?1:0):(this.B?4:3)+(7==this.b?2:0)}function ae(a){var b=Vc(this,a);a=Yc(this,a);var c=(b=(0>b?this.f[-b-1]&255:b)<<8)-(a<<=8);Nc(this,c,a,b);this.a-=this.c?4+(this.D&&6<=this.b?1:0):(this.B?4:3)+(7==this.b?2:0)}
|
||||
function be(a){var b=Zc(this,a);if(b){a=a>>6&7;var c=this.f[a]<<16|this.f[a|1];this.m=this.g=0;b&32768&&(b|=-65536);var d=~~(c/b);-32768<=d&&32767>=d?(this.f[a]=d&65535,this.f[a|1]=c-d*b&65535,this.i=d>>16|d,this.s=d>>16):(this.g=32768,this.i=d>>15|d,this.s=c>>16,-1===b&&65534===this.f[a]&&(this.f[a]=this.f[a|1]=1));this.a-=53}else this.i=this.s=0,this.g=32768,this.m=65536,this.a-=7}function ce(){K(this,24,0,-8);this.a-=25}
|
||||
function de(){this.C&49152?(this.fa|=128,K(this,4,0,-7)):(this.w&&1120==this.La&&this.w.setData(this.f[0],!0),this.F?this.F.b():G(this));this.a-=7}function ee(){K(this,16,0,-8);this.a-=25}var fe=[0,7,7,10,7,11,9,13];function ge(a){this.I=this.a;Q(this,Xc(this,a));this.a=this.I-fe[this.c]}var he=[0,14,14,17,14,18,16,20];function ie(a){this.I=this.a;var b=Xc(this,a);a=a>>6&7;Oc(this,this.f[a]);this.f[a]=this.f[7];Q(this,b);this.a=this.I-he[this.c]}var je=[3,9,9,13,10,14,12,16,4,9,9,13,10,14,13,17];
|
||||
function ke(a){var b=Wc(this,a);this.I=this.a;R(this,ad(this,a,b));this.a=this.I-je[(this.B?8:0)+this.c]+(7!=this.b||this.c?0:2)}function le(a){var b=Vc(this,a);R(this,$c(this,a,b,65535)<<8);this.a-=this.c?9+(this.D&&6<=this.b?1:0):(this.B?5:3)+(7==this.b?2:0)}var me=[7,13,13,17,14,18,17,21];
|
||||
function ne(a){var b=Zc(this,a);a=a>>6&7;b&32768&&(b|=-65536);var c=this.g[a];c&32768&&(c|=-65536);b=~~(b*c);this.g[a]=b>>16&65535;this.g[a|1]=b&65535;this.u&128||(this.s=b>>16,this.i=this.s|b,this.f=0,this.m=-32768>b||32767<b?65536:0);this.a-=23}function oe(){this.a-=5}function pe(){this.C&49152||(this.h.reset(),lb(this),this.w&&this.w.setData(this.g[0],!0));this.a-=667}function qe(a){if(a&8)K(this,8,0,-8);else{var b=Qc(this);a&=7;7==a?Q(this,b):(Q(this,this.g[a]),this.g[a]=b);this.a-=9}}
|
||||
function re(){Pc(this);this.a-=13}function X(a){a&1&&(this.m=65536);a&2&&(this.f=32768);a&4&&(this.i=0);a&8&&(this.s=32768);this.a-=5}function se(a){var b=(a&448)>>6;if(this.g[b]=this.g[b]-1&65535)Q(this,this.g[7]-((a&63)<<1)),this.a+=1;this.a-=6}function te(a){U(this,a,Wc(this,a),xd);this.a-=this.c?9+(this.D&&6<=this.b?1:0):(this.B?5:3)+(7==this.b?2:0)}function ue(a){U(this,a,0,zd);this.a-=this.c?9:3+(7==this.b?2:0)}function ve(){K(this,28,0,-8);this.a-=5}
|
||||
function we(){this.w&&(this.w.ea=this.g[7],this.w.setData(this.g[0],!0));this.u|=4;Hc(this,-2);this.a-=3}function xe(a){U(this,a,-(a>>6&7)-1,Ad);this.a-=this.c?9:3+(7==this.b?2:0)}function Y(){K(this,8,0,-8)}function Cc(a){ye[a>>12].call(this,a)}function ze(a){Ae[a>>6&3].call(this,a)}function Be(a){Ce[a>>6&3].call(this,a)}function De(a){Ee[a>>6&3].call(this,a)}function Fe(a){Ge[a&15].call(this,a)}function He(a){Ie[a&15].call(this,a)}function Je(a){Ke[a>>6&3].call(this,a)}
|
||||
function ne(a){var b=Zc(this,a);a=a>>6&7;b&32768&&(b|=-65536);var c=this.f[a];c&32768&&(c|=-65536);b=~~(b*c);this.f[a]=b>>16&65535;this.f[a|1]=b&65535;this.u&128||(this.s=b>>16,this.i=this.s|b,this.g=0,this.m=-32768>b||32767<b?65536:0);this.a-=23}function oe(){this.a-=5}function pe(){this.C&49152||(this.h.reset(),lb(this),this.w&&this.w.setData(this.f[0],!0));this.a-=667}function qe(a){if(a&8)K(this,8,0,-8);else{var b=Qc(this);a&=7;7==a?Q(this,b):(Q(this,this.f[a]),this.f[a]=b);this.a-=9}}
|
||||
function re(){Pc(this);this.a-=13}function X(a){a&1&&(this.m=65536);a&2&&(this.g=32768);a&4&&(this.i=0);a&8&&(this.s=32768);this.a-=5}function se(a){var b=(a&448)>>6;if(this.f[b]=this.f[b]-1&65535)Q(this,this.f[7]-((a&63)<<1)),this.a+=1;this.a-=6}function te(a){U(this,a,Wc(this,a),xd);this.a-=this.c?9+(this.D&&6<=this.b?1:0):(this.B?5:3)+(7==this.b?2:0)}function ue(a){U(this,a,0,zd);this.a-=this.c?9:3+(7==this.b?2:0)}function ve(){K(this,28,0,-8);this.a-=5}
|
||||
function we(){this.w&&(this.w.ea=this.f[7],this.w.setData(this.f[0],!0));this.u|=4;Hc(this,-2);this.a-=3}function xe(a){U(this,a,this.f[(a>>6&7)+this.qb],Ad);this.a-=this.c?9:3+(7==this.b?2:0)}function Y(){K(this,8,0,-8)}function Cc(a){ye[a>>12].call(this,a)}function ze(a){Ae[a>>6&3].call(this,a)}function Be(a){Ce[a>>6&3].call(this,a)}function De(a){Ee[a>>6&3].call(this,a)}function Fe(a){Ge[a&15].call(this,a)}function He(a){Ie[a&15].call(this,a)}function Je(a){Ke[a>>6&3].call(this,a)}
|
||||
function Le(a){Me[a>>6&3].call(this,a)}function Ne(a){Oe[a>>6&3].call(this,a)}
|
||||
var ye=[function(a){Pe[a>>8&15].call(this,a)},ke,$d,Kd,Gd,Id,Bd,Y,function(a){Qe[a>>8&15].call(this,a)},le,ae,Ld,Hd,Jd,te,Y],Pe=[function(a){Re[a>>4&15].call(this,a)},Xd,Ud,Md,Nd,Sd,Od,Qd,ie,ie,ze,Be,De,Y,Y,Y],Ae=[function(a){Kc(this,ad(this,a,0));this.a-=this.c?9:3+(7==this.b?2:0)},function(a){U(this,a,0,ld);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){U(this,a,1,pd);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){U(this,a,1,nd);this.a-=this.c?9:3+(7==this.b?2:0)}],Ce=[function(a){U(this,a,0,
|
||||
rd);this.a-=this.c?11:6},function(a){U(this,a,P(this)?1:0,bd);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){U(this,a,P(this)?1:0,xd);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){a=Zc(this,a);Kc(this,a);this.a-=this.c?4:3+(7==this.b?2:0)}],Ee=[function(a){U(this,a,0,vd);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){U(this,a,0,td);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){U(this,a,0,fd);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){U(this,a,0,dd);this.a-=this.c?9:3+(7==this.b?2:0)}],
|
||||
Re=[function(a){Se[a&15].call(this,a)},Y,Y,Y,ge,ge,ge,ge,qe,Y,Fe,He,ue,ue,ue,ue],Se=[de,we,re,Wd,ee,pe,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y],Ge=[oe,function(){this.m=0;this.a-=5},function(){this.f=0;this.a-=5},W,function(){this.i=1;this.a-=5},W,W,W,function(){this.s=0;this.a-=5},W,W,W,W,W,W,W],Ie=[oe,function(){this.m=65536;this.a-=5},function(){this.f=32768;this.a-=5},X,function(){this.i=0;this.a-=5},X,X,X,function(){this.s=32768;this.a-=5},X,X,X,X,X,X,X],Qe=[Vd,Td,Pd,Rd,Yd,Zd,Ed,Fd,ce,ve,Je,Le,Ne,Y,Y,Y],Ke=[function(a){Kc(this,
|
||||
Re=[function(a){Se[a&15].call(this,a)},Y,Y,Y,ge,ge,ge,ge,qe,Y,Fe,He,ue,ue,ue,ue],Se=[de,we,re,Wd,ee,pe,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y],Ge=[oe,function(){this.m=0;this.a-=5},function(){this.g=0;this.a-=5},W,function(){this.i=1;this.a-=5},W,W,W,function(){this.s=0;this.a-=5},W,W,W,W,W,W,W],Ie=[oe,function(){this.m=65536;this.a-=5},function(){this.g=32768;this.a-=5},X,function(){this.i=0;this.a-=5},X,X,X,function(){this.s=32768;this.a-=5},X,X,X,X,X,X,X],Qe=[Vd,Td,Pd,Rd,Yd,Zd,Ed,Fd,ce,ve,Je,Le,Ne,Y,Y,Y],Ke=[function(a){Kc(this,
|
||||
$c(this,a,0,255));this.a-=this.c?9:3+(7==this.b?2:0)},function(a){S(this,a,0,md);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){S(this,a,1,qd);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){S(this,a,1,od);this.a-=this.c?9:3+(7==this.b?2:0)}],Me=[function(a){S(this,a,0,sd);this.a-=this.c?11:6},function(a){S(this,a,P(this)?1:0,cd);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){S(this,a,P(this)?1:0,yd);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){a=Yc(this,a);Kc(this,a<<8);this.a-=this.c?4:3+(7==
|
||||
this.b?2:0)}],Oe=[function(a){S(this,a,0,wd);this.a-=this.c?9+(this.Bb&1):3+(7==this.b?2:0)},function(a){S(this,a,0,ud);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){S(this,a,0,gd);this.a-=this.c?9+(this.Bb&1):3+(7==this.b?2:0)},function(a){S(this,a,0,ed);this.a-=this.c?9:3+(7==this.b?2:0)}];function Dc(a){Te[a>>12].call(this,a)}
|
||||
var Te=[function(a){Ue[a>>8&15].call(this,a)},ke,$d,Kd,Gd,Id,Bd,function(a){Ve[a>>8&15].call(this,a)},function(a){We[a>>8&15].call(this,a)},le,ae,Ld,Hd,Jd,te,Y],Ue=[function(a){Xe[a>>4&15].call(this,a)},Xd,Ud,Md,Nd,Sd,Od,Qd,ie,ie,ze,Be,De,function(a){Ye[a>>6&3].call(this,a)},Y,Y],Ye=[function(a){a=this.g[7]+((a&63)<<1)&65535;var b=this.V(a|this.R);Q(this,this.g[5]);this.g[6]=a+2&65535;this.g[5]=b;this.a-=8},function(a){a=Tc(this,a,0);Oc(this,a);R(this,a);this.a-=11},function(a){var b=Qc(this);this.I=
|
||||
this.b?2:0)}],Oe=[function(a){S(this,a,0,wd);this.a-=this.c?9+(this.Cb&1):3+(7==this.b?2:0)},function(a){S(this,a,0,ud);this.a-=this.c?9:3+(7==this.b?2:0)},function(a){S(this,a,0,gd);this.a-=this.c?9+(this.Cb&1):3+(7==this.b?2:0)},function(a){S(this,a,0,ed);this.a-=this.c?9:3+(7==this.b?2:0)}];function Dc(a){Te[a>>12].call(this,a)}
|
||||
var Te=[function(a){Ue[a>>8&15].call(this,a)},ke,$d,Kd,Gd,Id,Bd,function(a){Ve[a>>8&15].call(this,a)},function(a){We[a>>8&15].call(this,a)},le,ae,Ld,Hd,Jd,te,Y],Ue=[function(a){Xe[a>>4&15].call(this,a)},Xd,Ud,Md,Nd,Sd,Od,Qd,ie,ie,ze,Be,De,function(a){Ye[a>>6&3].call(this,a)},Y,Y],Ye=[function(a){a=this.f[7]+((a&63)<<1)&65535;var b=this.V(a|this.R);Q(this,this.f[5]);this.f[6]=a+2&65535;this.f[5]=b;this.a-=8},function(a){a=Tc(this,a,0);Oc(this,a);R(this,a);this.a-=11},function(a){var b=Qc(this);this.I=
|
||||
this.a;Uc(this,a,0,b);R(this,b);this.a=this.I-me[this.c]},function(a){R(this,ad(this,a,Fc(this)?65535:0));this.a-=this.c?9:3+(7==this.b?2:0)}],Xe=[function(a){Ze[a&15].call(this,a)},Y,Y,Y,ge,ge,ge,ge,qe,function(a){a&8?(this.C&49152||(this.C=this.C&-2017|(a&7)<<5,this.u|=1),this.a-=5):K(this,8,0,-8)},Fe,He,ue,ue,ue,ue],Ze=[de,we,function(){Pc(this);this.u|=this.C&16;this.a-=13},Wd,ee,pe,re,function(){K(this,8,0,-8)},Y,Y,Y,Y,Y,Y,Y,Y],Ve=[ne,ne,be,be,Cd,Cd,Dd,Dd,xe,xe,Y,Y,Y,Y,se,se],We=[Vd,Td,Pd,Rd,
|
||||
Yd,Zd,Ed,Fd,ce,ve,Je,Le,Ne,function(a){$e[a>>6&3].call(this,a)},Y,Y],$e=[Y,function(a){a=Tc(this,a,65536);Oc(this,a);R(this,a);this.a-=11},function(a){var b=Qc(this);this.I=this.a;Uc(this,a,65536,b);R(this,b);this.a=this.I-me[this.c]},Y];
|
||||
function af(a){y.call(this,"ROM",a,af,512);this.X=this.c=null;this.i=a.addr;this.b=a.size;this.m=!1;this.f=a.alias;this.l=a.file;this.s=q(this.l);if(this.l){a=this.l;var b=la(this.s);"json"!=b&&"hex"!=b&&(a=v()+"/api/v1/dump?file="+this.l+"&format=bytes&decimal=true");var c=this;r(a,null,!0,function(a,b,f){f?(c.G("Unable to load ROM resource (error "+f+": "+a+")"),c.l=null):(Ra(c.ra,a,b),(a=ta(a,b))?(c.c=a.K,c.X=a.X):c.l=null);bf(c)})}}A(af);h=af.prototype;
|
||||
function af(a){y.call(this,"ROM",a,af,512);this.X=this.c=null;this.i=a.addr;this.b=a.size;this.m=!1;this.g=a.alias;this.l=a.file;this.s=q(this.l);if(this.l){a=this.l;var b=la(this.s);"json"!=b&&"hex"!=b&&(a=v()+"/api/v1/dump?file="+this.l+"&format=bytes&decimal=true");var c=this;r(a,null,!0,function(a,b,f){f?(c.G("Unable to load ROM resource (error "+f+": "+a+")"),c.l=null):(Ra(c.ra,a,b),(a=ta(a,b))?(c.c=a.K,c.X=a.X):c.l=null);bf(c)})}}A(af);h=af.prototype;
|
||||
h.ja=function(a,b,c,d){this.h=b;this.a=c;this.F=d;bf(this)};h.la=function(){this.X&&(this.F&&this.F.a(this.id,this.i,this.b,this.X),delete this.X);return!0};h.ka=function(){return!0};
|
||||
function bf(a){if(!Va(a)){if(a.l){if(!a.c||!a.h)return;a.b||(a.b=a.c.length);if(a.c.length!=a.b)Wa(a,"ROM size ("+m(a.c.length,8,!0)+") does not match specified size ("+m(a.b,8,!0)+")");else{var b;a:{b=a.i;a.status(a.b+"-byte ROM at "+ka(b));if(57344<=b&&b<57344+H){var c={};b=(c[b]=[af.prototype.cd,af.prototype.Zd,null,null,null,a.b>>1],c);if(cb(a.h,a,b)){b=a.m=!0;break a}}else if(Fb(a.h,b,a.b,gc)){for(c=0;c<a.c.length;c++)a.h.cb(b+c,a.c[c]);b=!0;break a}b=!1}if(b){b=[];"number"==typeof a.f?b.push(a.f):
|
||||
null!=a.f&&a.f.length&&(b=a.f);for(c=0;c<b.length;c++){var d=a,e=b[c],f=Eb(d.h,d.i,d.b);Db(d.h,e,d.b,f)}a.m||delete a.c}}}F(a)}}h.cd=function(a){return this.c[a-this.i]};h.Zd=function(){};Ga(function(){for(var a=E(document,"pdp11","rom"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new af(d);D(d,c)}});
|
||||
function cf(a){y.call(this,"RAM",a,cf);this.X=this.c=null;this.l=a.addr;this.i=a.size;this.ha=a.load;this.ga=a.exec;this.f=!1;this.b=a.file;this.m=q(this.b);if(this.b){a=this.b;var b=la(this.m);"json"!=b&&"hex"!=b&&(a=v()+"/api/v1/dump?file="+this.b+"&format=bytes&decimal=true");var c=this;r(a,null,!0,function(a,b,f){f?(c.G("Unable to load RAM resource (error "+f+": "+a+")"),c.b=null):(Ra(c.ra,a,b),(a=ta(a,b))?(c.c=a.K,c.X=a.X,null==c.ha&&(c.ha=a.ha),null==c.ga&&(c.ga=a.ga)):c.b=null);df(c)})}}A(cf);
|
||||
cf.prototype.ja=function(a,b,c,d){this.h=b;this.a=c;this.F=d;df(this)};cf.prototype.la=function(){this.X&&(this.F&&this.F.a(this.id,this.l,this.i,this.X),delete this.X);return!0};cf.prototype.ka=function(){return!0};function df(a){if(a.h&&(!a.f&&a.i&&Fb(a.h,a.l,a.i,Ib)&&(a.f=!0),!Va(a))){if(!a.f)t("No RAM allocated");else if(a.b){if(!a.c||!a.h)return;ef(a,a.c,a.ha,a.ga,a.l)}F(a)}}
|
||||
cf.prototype.reset=function(){if(this.f){for(var a=this.h,b=this.l,c=this.i,d=b&a.l,b=b>>>a.c;0<c&&b<a.h.length;){var e=a.h[b];if(e.controller&&a.i&&a.i.length==a.v.length){var f=a.i.indexOf(e);0<=f&&(e=a.v[f])}if(e){var f=c,g=0,k,d=d||0,g=g&255;void 0===f&&(f=e.size);if(Xa&&e.o)for(k=d;f--&&k<e.o.length;k++)e.o[k]=g;else for(k=d;f--&&k<e.size;k++)e.Lb(d,g,e.Ka+d)}c-=a.b;b++;d=0}this.c&&ef(this,this.c,this.ha,this.ga,this.l,!0)}};
|
||||
function bf(a){if(!Va(a)){if(a.l){if(!a.c||!a.h)return;a.b||(a.b=a.c.length);if(a.c.length!=a.b)Wa(a,"ROM size ("+m(a.c.length,8,!0)+") does not match specified size ("+m(a.b,8,!0)+")");else{var b;a:{b=a.i;a.status(a.b+"-byte ROM at "+ka(b));if(57344<=b&&b<57344+H){var c={};b=(c[b]=[af.prototype.ed,af.prototype.Zd,null,null,null,a.b>>1],c);if(cb(a.h,a,b)){b=a.m=!0;break a}}else if(Fb(a.h,b,a.b,gc)){for(c=0;c<a.c.length;c++)a.h.cb(b+c,a.c[c]);b=!0;break a}b=!1}if(b){b=[];"number"==typeof a.g?b.push(a.g):
|
||||
null!=a.g&&a.g.length&&(b=a.g);for(c=0;c<b.length;c++){var d=a,e=b[c],f=Eb(d.h,d.i,d.b);Db(d.h,e,d.b,f)}a.m||delete a.c}}}F(a)}}h.ed=function(a){return this.c[a-this.i]};h.Zd=function(){};Ga(function(){for(var a=E(document,"pdp11","rom"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new af(d);D(d,c)}});
|
||||
function cf(a){y.call(this,"RAM",a,cf);this.X=this.c=null;this.l=a.addr;this.i=a.size;this.ha=a.load;this.ga=a.exec;this.g=!1;this.b=a.file;this.m=q(this.b);if(this.b){a=this.b;var b=la(this.m);"json"!=b&&"hex"!=b&&(a=v()+"/api/v1/dump?file="+this.b+"&format=bytes&decimal=true");var c=this;r(a,null,!0,function(a,b,f){f?(c.G("Unable to load RAM resource (error "+f+": "+a+")"),c.b=null):(Ra(c.ra,a,b),(a=ta(a,b))?(c.c=a.K,c.X=a.X,null==c.ha&&(c.ha=a.ha),null==c.ga&&(c.ga=a.ga)):c.b=null);df(c)})}}A(cf);
|
||||
cf.prototype.ja=function(a,b,c,d){this.h=b;this.a=c;this.F=d;df(this)};cf.prototype.la=function(){this.X&&(this.F&&this.F.a(this.id,this.l,this.i,this.X),delete this.X);return!0};cf.prototype.ka=function(){return!0};function df(a){if(a.h&&(!a.g&&a.i&&Fb(a.h,a.l,a.i,Ib)&&(a.g=!0),!Va(a))){if(!a.g)t("No RAM allocated");else if(a.b){if(!a.c||!a.h)return;ef(a,a.c,a.ha,a.ga,a.l)}F(a)}}
|
||||
cf.prototype.reset=function(){if(this.g){for(var a=this.h,b=this.l,c=this.i,d=b&a.l,b=b>>>a.c;0<c&&b<a.h.length;){var e=a.h[b];if(e.controller&&a.i&&a.i.length==a.v.length){var f=a.i.indexOf(e);0<=f&&(e=a.v[f])}if(e){var f=c,g=0,k,d=d||0,g=g&255;void 0===f&&(f=e.size);if(Xa&&e.o)for(k=d;f--&&k<e.o.length;k++)e.o[k]=g;else for(k=d;f--&&k<e.size;k++)e.Mb(d,g,e.Ka+d)}c-=a.b;b++;d=0}this.c&&ef(this,this.c,this.ha,this.ga,this.l,!0)}};
|
||||
function ef(a,b,c,d,e,f){var g=!1;if(null==c)for(var k=0;k<b.length-1;){var l=b[k]&255|(b[k+1]&255)<<8;if(l)if(l&255){if(1!=l)break;if(k+6>=b.length)break;for(var k=k+2,n=b[k++]&255|(b[k++]&255)<<8,p=b[k++]&255|(b[k++]&255)<<8,l=l+((n&255)+(n>>8)+(p&255)+(p>>8)),u=k,w=n-=6;0<n&&k<b.length;)l+=b[k++]&255,n--;if(n||k>=b.length)break;l+=b[k++]&255;if(l&255)break;if(w)for(;w--;)a.a.cb(p++,b[u++]&255);else p&1?G(a.a):null==d&&(d=p);g=!0}else k++;else k+=2}if(!g&&(null==c&&(c=e),null!=c)){for(g=0;g<b.length;g++)a.a.cb(c+
|
||||
g,b[g]);g=!0}g&&null!=d&&(a=a.a,a.Tb=d,a.h.reset(),lb(a),Q(a,d),$b(a,0),!f&&a.F&&(G(a)||a.F.c()));return g}Ga(function(){for(var a=E(document,"pdp11","ram"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new cf(d);D(d,c)}});function ff(a){y.call(this,"Keyboard",a,ff,65536);F(this)}A(ff);ff.prototype.$=function(){return!1};ff.prototype.ja=function(a,b,c,d){this.l=a;this.a=c;this.F=d};Ga(function(){for(var a=E(document,"pdp11","keyboard"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new ff(d);D(d,c)}});
|
||||
function Z(a){this.D=a.baudReceive||9600;this.R=a.baudTransmit||9600;this.O=a.upperCase;this.f=this.m=null;this.J=a.tabSize;this.I=a.charBOL;this.s=0;y.call(this,"SerialPort",a,Z,16777216);var b=a.binding;if("console"==b)this.m="";else{var c;a=gf;b&&(void 0===c&&(c="Panel"),(c=Ta(c,this.id))&&(b=c.o[b])&&this.$(null,a,b))}this.v=this.A=null;this.exports={connect:this.Qb,receiveData:this.qb}}A(Z);var gf="buffer";h=Z.prototype;
|
||||
h.$=function(a,b,c){var d=this;switch(b){case gf:return this.o[b]=this.f=c,c.onkeydown=function(a){a=a||window.event;var b=a.keyCode;if(8===b||a.ctrlKey&&65<=b&&90>=b)a.preventDefault&&a.preventDefault(),64<b&&(b-=64),d.qb(b);return!0},c.onkeypress=function(a){a=a||window.event;d.qb(a.which||a.keyCode);a.preventDefault&&a.preventDefault();return!0},c.onpaste=function(a){a.stopPropagation&&a.stopPropagation();a.preventDefault&&a.preventDefault();(a=a.clipboardData||window.clipboardData)&&d.qb(a.getData("Text"))},
|
||||
g,b[g]);g=!0}g&&null!=d&&(a=a.a,a.Ub=d,a.h.reset(),lb(a),Q(a,d),$b(a,0),!f&&a.F&&(G(a)||a.F.c()));return g}Ga(function(){for(var a=E(document,"pdp11","ram"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new cf(d);D(d,c)}});function ff(a){y.call(this,"Keyboard",a,ff,65536);F(this)}A(ff);ff.prototype.$=function(){return!1};ff.prototype.ja=function(a,b,c,d){this.l=a;this.a=c;this.F=d};Ga(function(){for(var a=E(document,"pdp11","keyboard"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new ff(d);D(d,c)}});
|
||||
function Z(a){this.D=a.baudReceive||9600;this.R=a.baudTransmit||9600;this.O=a.upperCase;this.g=this.m=null;this.J=a.tabSize;this.I=a.charBOL;this.s=0;y.call(this,"SerialPort",a,Z,16777216);var b=a.binding;if("console"==b)this.m="";else{var c;a=gf;b&&(void 0===c&&(c="Panel"),(c=Ta(c,this.id))&&(b=c.o[b])&&this.$(null,a,b))}this.v=this.A=null;this.exports={connect:this.Rb,receiveData:this.rb}}A(Z);var gf="buffer";h=Z.prototype;
|
||||
h.$=function(a,b,c){var d=this;switch(b){case gf:return this.o[b]=this.g=c,c.onkeydown=function(a){a=a||window.event;var b=a.keyCode;if(8===b||a.ctrlKey&&65<=b&&90>=b)a.preventDefault&&a.preventDefault(),64<b&&(b-=64),d.rb(b);return!0},c.onkeypress=function(a){a=a||window.event;d.rb(a.which||a.keyCode);a.preventDefault&&a.preventDefault();return!0},c.onpaste=function(a){a.stopPropagation&&a.stopPropagation();a.preventDefault&&a.preventDefault();(a=a.clipboardData||window.clipboardData)&&d.rb(a.getData("Text"))},
|
||||
c.removeAttribute("readonly"),!0}return!1};h.ja=function(a,b,c,d){this.l=a;this.h=b;this.a=c;this.F=d;var e=this;this.ba=Vb(48,4);this.M=Sb(this.a,function(){e.b&128||!e.i.length||(e.w=e.i.shift()&255,e.O&&97<=e.w&&122>e.w&&(e.w-=32),e.b|=128,e.b&64&&Tb(e.a,e.ba))});this.B=Vb(52,4);this.aa=Sb(this.a,function(){e.c|=128;e.c&64&&Tb(e.a,e.B)});cb(b,this,hf);eb(b,this.reset.bind(this));F(this)};
|
||||
h.Qb=function(){if(!this.v){var a=tc(this.l,"connection");if(a){var b=a.split("->");if(2==b.length){var c=pa(b[0]);if(c!=this.Fa)return;b=pa(b[1]);if(this.v=Sa(b)){var d=this.v.exports;if(d){var e=d.connect;e&&e.call(this.v);if(this.A=d.receiveData){this.status(this.ra+"."+c+" connected to "+b);return}}}}this.status("Unable to establish connection: "+a)}}};h.la=function(a,b){if(!b)if(this.Qb(),!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};
|
||||
h.ka=function(a){return a?this.save():!0};h.reset=function(){jf(this)};h.save=function(){var a=new O(this);a.set(0,[]);return a.data()};h.restore=function(){return jf(this)};function jf(a){a.w=0;a.b=0;a.c=128;a.i=[];return!0}h.qb=function(a){if("number"==typeof a)this.i.push(a);else if("string"==typeof a)for(var b=0,c,d=0;d<a.length;d++){c=b;b=a.charCodeAt(d);if(10==b){if(13==c)continue;b=13}this.i.push(b)}else this.i=this.i.concat(a);Ub(this.a,this.M,1E3/Math.round(this.D/10));return!0};
|
||||
h.Xc=function(){return this.b&65534};h.Td=function(a){this.b=this.b&-112|a&111};h.Wc=function(){this.b&=-129;0<this.i.length&&Ub(this.a,this.M,1E3/Math.round(this.D/10));return this.w};h.Sd=function(){};h.rd=function(){return this.c};h.me=function(a){this.c&128&&(a&64?Tb(this.a,this.B):Ic(this.a,this.B));this.c=this.c&-70|a&69};h.qd=function(){return 0};
|
||||
h.le=function(a){if(a&=255){this.A&&this.A.call(this.v,a);a&=127;if(this.f)if(13==a)this.s=0;else if(8==a)this.f.value=this.f.value.slice(0,-1),0<this.s&&this.s--;else{var b;b=(b=qa[a])?"<"+b+">":String.fromCharCode(a);var c=b.length;32>a&&1==c&&(c=0);9==a&&(a=this.J||8,c=a-this.s%a,this.J&&(b=" ".slice(0,c)));this.I&&!this.s&&c&&(b=String.fromCharCode(this.I)+b);this.f.value+=b;this.f.scrollTop=this.f.scrollHeight;this.s+=c}else if(null!=this.m){if(10==a||1024<=
|
||||
this.m.length)this.T(this.m),this.m="";10!=a&&(this.m+=String.fromCharCode(a))}this.c&=-129;Ub(this.a,this.aa,1E3/Math.round(this.R/10))}};var kf={},hf=(kf[65392]=[null,null,Z.prototype.Xc,Z.prototype.Td,"RCSR"],kf[65394]=[null,null,Z.prototype.Wc,Z.prototype.Sd,"RBUF"],kf[65396]=[null,null,Z.prototype.rd,Z.prototype.me,"XCSR"],kf[65398]=[null,null,Z.prototype.qd,Z.prototype.le,"XBUF"],kf);Ga(function(){for(var a=E(document,"pdp11","serial"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new Z(d);D(d,c)}});
|
||||
function ac(a){y.call(this,"PC11",a,ac);this.c=a.autoMount||null;this.m=0;this.O=a.baudReceive||3600;this.w=this.A=this.b=0;this.v=[];this.s=lf;this.f=mf;this.B=this.i="";this.K=this.ha=this.ga=null;this.I=-1;this.D=!Ba("Mobi")&&window&&"FileReader"in window}A(ac);var lf="",mf=0;h=ac.prototype;
|
||||
h.Rb=function(){if(!this.v){var a=tc(this.l,"connection");if(a){var b=a.split("->");if(2==b.length){var c=pa(b[0]);if(c!=this.Fa)return;b=pa(b[1]);if(this.v=Sa(b)){var d=this.v.exports;if(d){var e=d.connect;e&&e.call(this.v);if(this.A=d.receiveData){this.status(this.ra+"."+c+" connected to "+b);return}}}}this.status("Unable to establish connection: "+a)}}};h.la=function(a,b){if(!b)if(this.Rb(),!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};
|
||||
h.ka=function(a){return a?this.save():!0};h.reset=function(){jf(this)};h.save=function(){var a=new O(this);a.set(0,[]);return a.data()};h.restore=function(){return jf(this)};function jf(a){a.w=0;a.b=0;a.c=128;a.i=[];return!0}h.rb=function(a){if("number"==typeof a)this.i.push(a);else if("string"==typeof a)for(var b=0,c,d=0;d<a.length;d++){c=b;b=a.charCodeAt(d);if(10==b){if(13==c)continue;b=13}this.i.push(b)}else this.i=this.i.concat(a);Ub(this.a,this.M,1E3/Math.round(this.D/10));return!0};
|
||||
h.Zc=function(){return this.b&65534};h.Td=function(a){this.b=this.b&-112|a&111};h.Yc=function(){this.b&=-129;0<this.i.length&&Ub(this.a,this.M,1E3/Math.round(this.D/10));return this.w};h.Sd=function(){};h.td=function(){return this.c};h.me=function(a){this.c&128&&(a&64?Tb(this.a,this.B):Ic(this.a,this.B));this.c=this.c&-70|a&69};h.sd=function(){return 0};
|
||||
h.le=function(a){if(a&=255){this.A&&this.A.call(this.v,a);a&=127;if(this.g)if(13==a)this.s=0;else if(8==a)this.g.value=this.g.value.slice(0,-1),0<this.s&&this.s--;else{var b;b=(b=qa[a])?"<"+b+">":String.fromCharCode(a);var c=b.length;32>a&&1==c&&(c=0);9==a&&(a=this.J||8,c=a-this.s%a,this.J&&(b=" ".slice(0,c)));this.I&&!this.s&&c&&(b=String.fromCharCode(this.I)+b);this.g.value+=b;this.g.scrollTop=this.g.scrollHeight;this.s+=c}else if(null!=this.m){if(10==a||1024<=
|
||||
this.m.length)this.T(this.m),this.m="";10!=a&&(this.m+=String.fromCharCode(a))}this.c&=-129;Ub(this.a,this.aa,1E3/Math.round(this.R/10))}};var kf={},hf=(kf[65392]=[null,null,Z.prototype.Zc,Z.prototype.Td,"RCSR"],kf[65394]=[null,null,Z.prototype.Yc,Z.prototype.Sd,"RBUF"],kf[65396]=[null,null,Z.prototype.td,Z.prototype.me,"XCSR"],kf[65398]=[null,null,Z.prototype.sd,Z.prototype.le,"XBUF"],kf);Ga(function(){for(var a=E(document,"pdp11","serial"),b=0;b<a.length;b++){var c=a[b],d=C(c),d=new Z(d);D(d,c)}});
|
||||
function ac(a){y.call(this,"PC11",a,ac);this.c=a.autoMount||null;this.m=0;this.O=a.baudReceive||3600;this.w=this.A=this.b=0;this.v=[];this.s=lf;this.g=mf;this.B=this.i="";this.K=this.ha=this.ga=null;this.I=-1;this.D=!Ba("Mobi")&&window&&"FileReader"in window}A(ac);var lf="",mf=0;h=ac.prototype;
|
||||
h.$=function(a,b,c){var d=this,e=mf;switch(b){case "listTapes":return this.o[b]=c,c.onchange=function(){var a=d.o.descTape,b=c.options[c.selectedIndex];if(a&&b){var e={};if(b=b.getAttribute("data-value"))try{e=eval("("+b+")")}catch(l){t("PC11 option error: "+l.message)}b=e.desc;void 0===b&&(b="");e=e.href;void 0!==e&&(b='<a href="'+e+'" target="_blank">'+b+"</a>");a.innerHTML=b}},!0;case "descTape":return this.o[b]=c,!0;case "loadTape":e=2;case "attachTape":return e||(e=1),this.o[b]=c,c.onclick=function(){var a=
|
||||
d.o.listTapes;a&&nf(d,a.options[a.selectedIndex].text,a.value,e)},!0;case "mountTape":if(!this.D){c.parentNode.removeChild(c);break}this.o[b]=c;c.addEventListener("change",function(){var a=c.children[0];a.children[1].disabled=!a.children[0].files.length});c.onsubmit=function(a){if(a=a.currentTarget[1].files[0]){var b=a.name;nf(d,q(b,!0),b,1,a)}return!1};return!0;case "readProgress":return this.o[b]=c,!0}return!1};
|
||||
h.ja=function(a,b,c,d){this.l=a;this.h=b;this.a=c;this.F=d;this.J=of(a);var e=this;if((this.c=tc(this.l,"autoMount")||this.c)&&"string"==typeof this.c)try{this.c=eval("("+this.c+")")}catch(f){t("PC11 auto-mount error: "+f.message+" ("+this.c+")"),this.c=null}this.M=Vb(56,4);this.R=Sb(this.a,function(){1==(e.b&32769)&&!(e.b&128)&&e.w<e.v.length&&(e.A=e.v[e.w++]&255,pf(e,e.w/e.v.length*100),e.b|=128,e.b&=-2049,e.b&64&&Tb(e.a,e.M))});cb(b,this,qf);eb(b,this.reset.bind(this));rf(this,"None",lf,!0);this.D&&
|
||||
rf(this,"Local Tape","?");rf(this,"Remote Tape","??");sf(this)||F(this)};h.la=function(a,b){if(!b)if(!a||!this.restore)this.reset();else if(!this.restore(a))return!1;return!0};h.ka=function(a){return a?this.save():!0};h.reset=function(){this.b&=-2241;this.A=0};function sf(a){a.m=0;if(a.c){var b=a.c.path||"",c;if(!(c=a.c.name))a:{if((c=a.o.listTapes)&&c.options)for(var d=0;d<c.options.length;d++){var e=c.options[d];if(e.value==b){c=e.text;break a}}c=q(b,!0)}b&&c?tf(a,c,b,1,!0):uf(a)}return!!a.m}
|
||||
function nf(a,b,c,d,e){if(c)if("?"==c)a.G('Use "Choose File" and "Mount" to select and load a local tape.');else{if("??"==c){c=window.prompt("Enter the URL of a remote tape image.","")||"";if(!c)return;b=q(c);a.status("Attempting to load "+c+' as "'+b+'"');a.s="??"}else a.s=c;tf(a,b,c,d,!1,e)}else vf(a,!1)}function tf(a,b,c,d,e,f){var g=-1;if(a.i.toLowerCase()!=c.toLowerCase()||a.f!=d)g++,vf(a,!0),a.j.Da?a.G("PC11 busy"):(e&&a.m++,wf(a,b,c,d,f)?g++:a.j.Da=!0);g&&xf(a,a.B,a.i,a.f,a.K,a.ha,a.ga)}
|
||||
function nf(a,b,c,d,e){if(c)if("?"==c)a.G('Use "Choose File" and "Mount" to select and load a local tape.');else{if("??"==c){c=window.prompt("Enter the URL of a remote tape image.","")||"";if(!c)return;b=q(c);a.status("Attempting to load "+c+' as "'+b+'"');a.s="??"}else a.s=c;tf(a,b,c,d,!1,e)}else vf(a,!1)}function tf(a,b,c,d,e,f){var g=-1;if(a.i.toLowerCase()!=c.toLowerCase()||a.g!=d)g++,vf(a,!0),a.j.Da?a.G("PC11 busy"):(e&&a.m++,wf(a,b,c,d,f)?g++:a.j.Da=!0);g&&xf(a,a.B,a.i,a.g,a.K,a.ha,a.ga)}
|
||||
function wf(a,b,c,d,e){var f=c;if(e){var g=new FileReader;g.onload=function(){var e=g.result;e&&(e=new Uint8Array(e,0,e.byteLength),xf(a,b,c,d,e),a.s="?");uf(a)};g.readAsArrayBuffer(e);return!0}0>c.indexOf("/api/v1/dump")&&(e=la(c),f="json"==e||"gz"==e?encodeURI(c):v()+"/api/v1/dump?path="+encodeURIComponent(c)+"&format=json");return!!r(f,null,!0,function(e,f,g){var k=0>g&&a.l&&!a.l.j.N;g?a.G('Unable to load tape "'+b+'" (error '+g+": "+e+")",k):(Ra(a.ra,e,f),(e=ta(e,f))&&xf(a,b,c,d,e.K,e.ha,e.ga));
|
||||
a.j.Da=!1;a.m&&(a.m--,a.m||F(a));uf(a)})}function rf(a,b,c,d){if((a=a.o.listTapes)&&a.options){for(var e=0;e<a.options.length;e++)if(a.options[e].value==c)return;e=document.createElement("option");e.text=b;e.value=c;d&&a.childNodes[0]?a.insertBefore(e,a.childNodes[0]):a.appendChild(e)}}function uf(a){var b=a.o.listTapes;if(b&&b.options){a=a.s||a.i;for(var c=0;c<b.options.length;c++)if(b.options[c].value==a){b.selectedIndex!=c&&(b.selectedIndex=c);break}c==b.options.length&&(b.selectedIndex=0)}}
|
||||
function pf(a,b){b|=0;if(b!==a.I){var c=a.o.readProgress;c&&(c=(c=E(c,"pcjs-progress-bar"))&&c[0])&&c.style&&(c.style.width=b+"%");a.I=b}}function xf(a,b,c,d,e,f,g){a.B=b;a.i=c;a.f=d;a.K=e;a.ha=f;a.ga=g;2==d?a.J&&ef(a.J,e,f,g)?a.status("tape loaded: "+b):(a.B="",a.i="",a.s=lf,a.f=mf,a.G("No load address available for tape: "+b)):(a.w=0,a.v=e,a.status("tape attached: "+b),pf(a,0))}
|
||||
function vf(a,b){if(a.i||!1===b)a.B="",a.i="",b||(a.f&&a.status(1==a.f?"tape detached":"tape unloaded"),a.s=lf,a.f=mf,uf(a))}h.save=function(){return(new O(this)).data()};h.restore=function(){return!0};h.Qc=function(){return this.b&65534};h.Md=function(a){a&1&&(this.b&32768?(a&=-2,this.b&64&&Tb(this.a,this.M)):(this.b&=-129,this.b|=2048,this.A=0,Ub(this.a,this.R,1E3/Math.round(this.O/10))));this.b=this.b&-66|a&65};h.Pc=function(){this.b&=-129;this.b|=2048;return this.A};h.Ld=function(){};
|
||||
var yf={},qf=(yf[65384]=[null,null,ac.prototype.Qc,ac.prototype.Md,"PRS"],yf[65386]=[null,null,ac.prototype.Pc,ac.prototype.Ld,"PRB"],yf);function zf(a,b,c){y.call(this,"Disk",{id:a.ra+".disk"+m(++Af,4)},zf,4194304);this.controller=a;this.l=a.l;this.F=a.F;this.f=b;this.xa=b.name;this.yb=b.yb;Bf(this,c,b.U,b.Z,b.S,b.ia);F(this)}var Af=0;A(zf);h=zf.prototype;h.ja=function(a,b,c,d){this.F=d};
|
||||
function pf(a,b){b|=0;if(b!==a.I){var c=a.o.readProgress;c&&(c=(c=E(c,"pcjs-progress-bar"))&&c[0])&&c.style&&(c.style.width=b+"%");a.I=b}}function xf(a,b,c,d,e,f,g){a.B=b;a.i=c;a.g=d;a.K=e;a.ha=f;a.ga=g;2==d?a.J&&ef(a.J,e,f,g)?a.status("tape loaded: "+b):(a.B="",a.i="",a.s=lf,a.g=mf,a.G("No load address available for tape: "+b)):(a.w=0,a.v=e,a.status("tape attached: "+b),pf(a,0))}
|
||||
function vf(a,b){if(a.i||!1===b)a.B="",a.i="",b||(a.g&&a.status(1==a.g?"tape detached":"tape unloaded"),a.s=lf,a.g=mf,uf(a))}h.save=function(){return(new O(this)).data()};h.restore=function(){return!0};h.Sc=function(){return this.b&65534};h.Md=function(a){a&1&&(this.b&32768?(a&=-2,this.b&64&&Tb(this.a,this.M)):(this.b&=-129,this.b|=2048,this.A=0,Ub(this.a,this.R,1E3/Math.round(this.O/10))));this.b=this.b&-66|a&65};h.Rc=function(){this.b&=-129;this.b|=2048;return this.A};h.Ld=function(){};
|
||||
var yf={},qf=(yf[65384]=[null,null,ac.prototype.Sc,ac.prototype.Md,"PRS"],yf[65386]=[null,null,ac.prototype.Rc,ac.prototype.Ld,"PRB"],yf);function zf(a,b,c){y.call(this,"Disk",{id:a.ra+".disk"+m(++Af,4)},zf,4194304);this.controller=a;this.l=a.l;this.F=a.F;this.g=b;this.xa=b.name;this.zb=b.zb;Bf(this,c,b.U,b.Z,b.S,b.ia);F(this)}var Af=0;A(zf);h=zf.prototype;h.ja=function(a,b,c,d){this.F=d};
|
||||
function Bf(a,b,c,d,e,f){a.mode=b;a.U=c;a.Z=d;a.S=e;a.ia=f;a.a=[];if("preload"!=a.mode){b=Array(a.U);for(c=0;c<b.length;c++){d=Array(a.Z);for(e=0;e<d.length;e++){f=Array(a.S);for(var g=1;g<=f.length;g++)f[g-1]=Cf(null,c,e,g,a.ia,0);d[e]=f}b[c]=d}a.a=b}a.b=null}
|
||||
function Df(a,b,c,d,e){var f=c;if(a.h)return!0;a.xa=b;a.Ca=c;a.ac=q(c);a.h=e;a.i=a.controller;if(d){var g=new FileReader;g.onload=function(){var b=g.result,c,d=b?b.byteLength:0,e=ia[d];if(e){a.U=e[0];a.Z=e[1];a.S=e[2];a.ia=e[3]||512;c=a.ia>>2;var f=e=0,b=new DataView(b,0,d);a.a=Array(a.U);for(d=0;d<a.a.length;d++)for(var w=a.a[d]=Array(a.Z),T=0;T<w.length;T++)for(var va=w[T]=Array(a.S),wa=0;wa<va.length;wa++){for(var kc=Cf(null,d,T,wa+1,a.ia,0),eg=kc.data,lc=0;lc<c;lc++,f+=4)var fg=eg[lc]=b.getInt32(f,
|
||||
!0),e=e+fg&-1;kc.ca=c;va[wa]=kc}a.b=e;c=a}else a.G("Unrecognized disk format ("+d+" bytes)");a.h&&(a.h.call(a.controller,a.f,c,a.xa,a.Ca),a.h=null)};g.readAsArrayBuffer(d);return!0}0>c.indexOf("/api/v1/dump")&&(b=la(c),"json"==b||"gz"==b?f=encodeURI(c):(d="path",e="&mbhd=10",!c.indexOf("http:")||!c.indexOf("ftp:")||0<="dsk ima img 360 720 12 144".split(" ").indexOf(b)?(d="disk",e="&mbhd=0"):ma(c,"/")&&(d="dir"),f=v()+"/api/v1/dump?"+d+"="+encodeURIComponent(c)+(a.yb?"":e)+"&format=json"));return!!r(f,
|
||||
!0),e=e+fg&-1;kc.ca=c;va[wa]=kc}a.b=e;c=a}else a.G("Unrecognized disk format ("+d+" bytes)");a.h&&(a.h.call(a.controller,a.g,c,a.xa,a.Ca),a.h=null)};g.readAsArrayBuffer(d);return!0}0>c.indexOf("/api/v1/dump")&&(b=la(c),"json"==b||"gz"==b?f=encodeURI(c):(d="path",e="&mbhd=10",!c.indexOf("http:")||!c.indexOf("ftp:")||0<="dsk ima img 360 720 12 144".split(" ").indexOf(b)?(d="disk",e="&mbhd=0"):ma(c,"/")&&(d="dir"),f=v()+"/api/v1/dump?"+d+"="+encodeURIComponent(c)+(a.zb?"":e)+"&format=json"));return!!r(f,
|
||||
null,!0,function(b,c,d){Ef(a,b,c,d)})}
|
||||
function Ef(a,b,c,d){var e=null;a.c=!1;var f=0>d&&a.l&&!a.l.j.N;if(d)a.controller.G('Unable to load disk "'+a.xa+'" (error '+d+": "+b+")",f);else{Ra(a.controller.ra,b,c);try{if(0<q(a.ac,!0).toLowerCase().indexOf("-readonly"))a.c=!0;else{var g=c.indexOf("\n");0<g&&1024>g&&0<c.substring(0,g).indexOf("write-protected")&&(a.c=!0)}var k;"<"==c.substr(0,1)?k=["Missing disk image: "+a.xa]:k=0>c.indexOf("0x")&&'["'!=c.substr(0,2)?JSON.parse(c.replace(/([a-z]+):/gm,'"$1":').replace(/\/\/[^\n]*/gm,"")):eval("("+
|
||||
c+")");if(k.length)if(1==k.length)t(k[0]);else{a.U=k.length;a.Z=k[0].length;a.S=k[0][0].length;var l=k[0][0][0];a.ia=l&&l.length||512;for(d=c=0;d<a.U;d++)for(f=0;f<a.Z;f++)for(g=0;g<a.S;g++)if(l=k[d][f][g]){var n=l.length;void 0===n&&(n=l.length=512);var n=n>>2,p=l.pattern;void 0===p&&(p=l.pattern=0);var u=l.data;if(void 0===u){var w=l.bytes;if(void 0!==w&&w.length){for(var T=n<<2,va=w.length;va<T;va++)w[va]=p;Ff(l,w)}else u=[],p=l.pattern=p|p<<8|p<<16|p<<24,l.data=u;delete l.bytes}Cf(l,d,f);for(T=
|
||||
0;T<u.length;T++)c=c+u[T]&-1}a.a=k;a.b=c;e=a}else t("Empty disk image: "+a.xa)}catch(wa){t("Disk image error ("+b+"): "+wa.message)}}a.h&&(a.h.call(a.i,a.f,e,a.xa,a.Ca),a.h=null)}function Cf(a,b,c,d,e,f){a||(a={sector:d,length:e,data:[],pattern:f});a.pe=b;a.qe=c;a.oa=a.ca=0;a.wa=!1;return a}
|
||||
h.seek=function(a,b,c,d,e){d=null;var f=this.f,g=this.a[a];if(g){var k=g[b];if(!k&&f.ic&&b<f.Z)for(k=g[b]=Array(f.jc),g=0;g<k.length;g++)k[g]=Cf(null,a,b,g+1,f.Rb,0);if(k){for(g=0;g<k.length;g++)if(k[g]&&k[g].sector==c){d=k[g];break}!d&&f.ic&&9==f.Mb&&(d=k[g]=Cf(null,a,b,f.Mb,f.Rb,0))}}e&&e(d,!1);return d};function Ff(a,b){for(var c=0,d=a.length>>2,e=Array(d),f=0;f<d;f++)e[f]=b[c]|b[c+1]<<8|b[c+2]<<16|b[c+3]<<24,c+=4;a.data=e}
|
||||
0;T<u.length;T++)c=c+u[T]&-1}a.a=k;a.b=c;e=a}else t("Empty disk image: "+a.xa)}catch(wa){t("Disk image error ("+b+"): "+wa.message)}}a.h&&(a.h.call(a.i,a.g,e,a.xa,a.Ca),a.h=null)}function Cf(a,b,c,d,e,f){a||(a={sector:d,length:e,data:[],pattern:f});a.re=b;a.se=c;a.oa=a.ca=0;a.wa=!1;return a}
|
||||
h.seek=function(a,b,c,d,e){d=null;var f=this.g,g=this.a[a];if(g){var k=g[b];if(!k&&f.kc&&b<f.Z)for(k=g[b]=Array(f.lc),g=0;g<k.length;g++)k[g]=Cf(null,a,b,g+1,f.Sb,0);if(k){for(g=0;g<k.length;g++)if(k[g]&&k[g].sector==c){d=k[g];break}!d&&f.kc&&9==f.Nb&&(d=k[g]=Cf(null,a,b,f.Nb,f.Sb,0))}}e&&e(d,!1);return d};function Ff(a,b){for(var c=0,d=a.length>>2,e=Array(d),f=0;f<d;f++)e[f]=b[c]|b[c+1]<<8|b[c+2]<<16|b[c+3]<<24,c+=4;a.data=e}
|
||||
h.read=function(a,b){var c=-1;if(a&&b<a.length)var c=a.data,d=b>>2,c=(d<c.length?c[d]:a.pattern)>>((b&3)<<3)&255;return c};h.write=function(a,b,c){if(this.c)return!1;if(b<a.length){if(c!=this.read(a,b,!0)){var d=a.data,e=a.pattern,f=b>>2;b=(b&3)<<3;for(var g=d.length;g<=f;g++)d[g]=e;a.ca?f<a.oa?(a.ca+=a.oa-f,a.oa=f):f>=a.oa+a.ca&&(a.ca+=f-(a.oa+a.ca)+1):(a.oa=f,a.ca=1);d[f]=d[f]&~(255<<b)|c<<b}return!0}return null};
|
||||
function Gf(a,b){var c=a.Z*a.S,d=b/c|0;return d<a.U?(b%=c,a.seek(d,b/a.S|0,b%a.S+1)):null}function Hf(a,b,c){for(var d=1,e=0,f=0;d--;){var g=a.read(b,c++);if(0>g)break;e|=g<<f;f+=8}return e}h.save=function(){var a=0,b=[];b[a++]=[this.Ca,this.b,this.U,this.Z,this.S,this.ia];if(!this.c)for(var c=this.a,d=0;d<c.length;d++)for(var e=0;e<c[d].length;e++)for(var f=0;f<c[d][e].length;f++){var g=c[d][e][f];if(g&&g.ca){for(var k=[],l=0,n=g.oa,p=g.oa+g.ca;n<p;)k[l++]=g.data[n++];b[a++]=[d,e,f,g.oa,k]}}return b};
|
||||
h.restore=function(a){var b=0,c="unsupported restore format";if(a&&0<a.length){var d=0,e=a[d++];e&&2<=e.length&&(!this.a.length&&6<=e.length?Bf(this,"local",e[2],e[3],e[4],e[5]):null!=e[1]&&null!=this.b&&e[1]!=this.b&&(c="original checksum ("+e[1]+") differs from current checksum ("+this.b+")",b=-2));for(this.a.length||(b=-1);d<a.length&&0<=b;){var f=0,g=a[d++],k=g[f++],l=g[f++],n=g[f++];if(k>=this.a.length||l>=this.a[k].length||n>=this.a[k][l].length){c="sector (CHS="+k+":"+l+":"+n+") out of range ("+
|
||||
b+" changes applied)";b=-1;break}if(this.c){c="unable to modify write-protected disk";b=-1;break}e=g[f++];f=g[f++];g=e+f.length;if(k=this.a[k][l][n]){for(l=k.data.length;l<e;)k.data[l++]=k.pattern;l=0;k.oa=e;for(k.ca=f.length;e<g;)k.data[e++]=f[l++];b++}}}0>b&&-2!=b&&this.controller.G("Unable to restore disk '"+this.xa+": "+c);return b};
|
||||
h.toJSON=function(){var a;a=0;for(var b;b=Gf(this,a++);)If(b);a=JSON.stringify(this.a,function(a,b){if("file"!=a)return b});a=a.replace(/,"length":512/gm,"").replace(/,"pattern":0/gm,"");a=a.replace(/"(sector|length|data|pattern)":/gm,"$1:");a=a.replace(/,"[^"]*":([0-9]+|true|false)/gm,"");a=a.replace(/(sector|length|data|pattern):/gm,'"$1":');return a=a.replace(/([\]}]),/gm,"$1,\n")};
|
||||
function If(a){var b=a.data,c=b.length;if(c<<2==a.length){for(var d=c-1,e=b[d],f=0;d--&&b[d]===e;)f++;f++&&(b.length=c-f,a.pattern=e)}}function N(a){y.call(this,"RL11",a,N,8388608);this.f=a.autoMount||null;this.s=0;this.b=Array(4);this.A=!Ba("Mobi")&&window&&"FileReader"in window}A(N);h=N.prototype;
|
||||
function If(a){var b=a.data,c=b.length;if(c<<2==a.length){for(var d=c-1,e=b[d],f=0;d--&&b[d]===e;)f++;f++&&(b.length=c-f,a.pattern=e)}}function N(a){y.call(this,"RL11",a,N,8388608);this.g=a.autoMount||null;this.s=0;this.b=Array(4);this.A=!Ba("Mobi")&&window&&"FileReader"in window}A(N);h=N.prototype;
|
||||
h.$=function(a,b,c){var d=this;switch(b){case "listDisks":return this.o[b]=c,c.onchange=function(){var a=d.o.descDisk,b=c.options[c.selectedIndex];if(a&&b){var g={};if(b=b.getAttribute("data-value"))try{g=eval("("+b+")")}catch(k){t("RL11 option error: "+k.message)}b=g.desc;void 0===b&&(b="");g=g.href;void 0!==g&&(b='<a href="'+g+'" target="_blank">'+b+"</a>");a.innerHTML=b}},!0;case "descDisk":case "listDrives":return this.o[b]=c,c.onchange=function(){var a=ja(c.value);null!=a&&Jf(d,a)},!0;case "loadDrive":return this.o[b]=
|
||||
c,c.onclick=function(){var a=d.o.listDisks;a&&Kf(d,a.options[a.selectedIndex].text,a.value)},!0;case "saveDrive":if(!this.A){c.parentNode.removeChild(c);break}this.o[b]=c;c.onclick=function(){var a=d.o.listDrives;if(a&&a.options&&d.b)if(a=d.b[ja(a.value)||0])if(a=a.da){var b;b="";for(var c=0,k;k=Gf(a,c++);)for(var l=0,n=k.length;l<n;l++)b+=String.fromCharCode(Hf(a,k,l));b=btoa(b);a=a.ac.replace(".json",".img");c=null;b="data:application/octet-stream;base64,"+b;a&&(c=document.createElement("a"),"string"!=
|
||||
typeof c.download&&(c=null));c?(c.href=b,c.download=a,document.body.appendChild(c),c.click(),document.body.removeChild(c),a="Check your Downloads folder for "+a+"."):(window.open(b),a="Check your browser for a new window/tab containing the requested data"+(a?" ("+a+")":"")+".");t(a)}else d.G("No disk loaded in drive.");else d.G("No disk drive selected.")};return!0;case "mountDrive":if(this.A)return this.o[b]=c,c.addEventListener("change",function(){var a=c.children[0];a.children[1].disabled=!a.children[0].files.length}),
|
||||
c.onsubmit=function(a){if(a=a.currentTarget[1].files[0]){var b=a.name;Kf(d,q(b,!0),b,a)}return!1},!0;c.parentNode.removeChild(c)}return!1};
|
||||
h.ja=function(a,b,c,d){this.l=a;this.h=b;this.a=c;this.F=d;if((this.f=tc(this.l,"autoMount")||this.f)&&"string"==typeof this.f)try{this.f=eval("("+this.f+")")}catch(e){t("RL11 auto-mount error: "+e.message+" ("+this.f+")"),this.f=null}Lf(this);this.D=Vb(112,5);cb(b,this,Mf);eb(b,this.reset.bind(this));Nf(this,"None","",!0);this.A&&Nf(this,"Local Disk","?");Nf(this,"Remote Disk","??");Of(this)||F(this)};
|
||||
h.la=function(a,b){if(!b){if(!a||!this.restore){if(this.reset(),this.l.Ob){for(a=0;a<this.b.length;a++)Pf(this,a,!0);Of(this,!0)}}else if(!this.restore(a))return!1;if(a=this.o.listDrives){for(;a.firstChild;)a.removeChild(a.firstChild);a.value="";for(b=0;4>b;b++){var c=document.createElement("option");c.value=b;c.text="RL"+b;a.appendChild(c)}a.value="0";Jf(this,0)}}return!0};h.ka=function(a){return a?this.save():!0};h.reset=function(){Lf(this)};h.save=function(){return(new O(this)).data()};
|
||||
h.restore=function(a){return Lf(this,a[0])};function Of(a,b){b||(a.s=0);if(a.f)for(var c in a.f){var d=a.f[c],e=d.path||"",f;if(!(f=d.name))a:{if((f=a.o.listDisks)&&f.options)for(var g=0;g<f.options.length;g++){var k=f.options[g];if(k.value==e){f=k.text;break a}}f=q(e,!0)}if(e&&f&&(g=-1,c&&(g=c.charCodeAt(c.length-1)-48,0>g||9<g)&&(g=-1),0<=g&&g<a.b.length)){!Qf(a,g,f,e,!0)&&b&&F(a,!1);continue}a.G("Incorrect auto-mount settings for drive "+c+" ("+JSON.stringify(d)+")")}return!!a.s}
|
||||
h.ja=function(a,b,c,d){this.l=a;this.h=b;this.a=c;this.F=d;if((this.g=tc(this.l,"autoMount")||this.g)&&"string"==typeof this.g)try{this.g=eval("("+this.g+")")}catch(e){t("RL11 auto-mount error: "+e.message+" ("+this.g+")"),this.g=null}Lf(this);this.D=Vb(112,5);cb(b,this,Mf);eb(b,this.reset.bind(this));Nf(this,"None","",!0);this.A&&Nf(this,"Local Disk","?");Nf(this,"Remote Disk","??");Of(this)||F(this)};
|
||||
h.la=function(a,b){if(!b){if(!a||!this.restore){if(this.reset(),this.l.Pb){for(a=0;a<this.b.length;a++)Pf(this,a,!0);Of(this,!0)}}else if(!this.restore(a))return!1;if(a=this.o.listDrives){for(;a.firstChild;)a.removeChild(a.firstChild);a.value="";for(b=0;4>b;b++){var c=document.createElement("option");c.value=b;c.text="RL"+b;a.appendChild(c)}a.value="0";Jf(this,0)}}return!0};h.ka=function(a){return a?this.save():!0};h.reset=function(){Lf(this)};h.save=function(){return(new O(this)).data()};
|
||||
h.restore=function(a){return Lf(this,a[0])};function Of(a,b){b||(a.s=0);if(a.g)for(var c in a.g){var d=a.g[c],e=d.path||"",f;if(!(f=d.name))a:{if((f=a.o.listDisks)&&f.options)for(var g=0;g<f.options.length;g++){var k=f.options[g];if(k.value==e){f=k.text;break a}}f=q(e,!0)}if(e&&f&&(g=-1,c&&(g=c.charCodeAt(c.length-1)-48,0>g||9<g)&&(g=-1),0<=g&&g<a.b.length)){!Qf(a,g,f,e,!0)&&b&&F(a,!1);continue}a.G("Incorrect auto-mount settings for drive "+c+" ("+JSON.stringify(d)+")")}return!!a.s}
|
||||
function Kf(a,b,c,d){var e=a.o.listDrives,e=e&&ja(e.value);if(void 0===e||0>e||e>=a.b.length)a.G("Unable to load the selected drive");else if(c)if("?"==c)a.G('Use "Choose File" and "Mount" to select and load a local disk.');else{if("??"==c){c=window.prompt("Enter the URL of a remote disk image.","")||"";if(!c)return;b=q(c);a.status("Attempting to load "+c+' as "'+b+'"')}Qf(a,e,b,c,!1,d)}else Pf(a,e)}
|
||||
function Qf(a,b,c,d,e,f){var g=-1,k=a.b[b];k.Ca.toLowerCase()!=d.toLowerCase()&&(g++,Pf(a,b,!0),k.xb?a.G("RL11 busy"):(k.xb=!0,e&&(k.wb=!0,a.s++),k.lb=!!f,Df(new zf(a,k,"preload"),c,d,f,a.oc)&&g++));return g}
|
||||
h.oc=function(a,b,c,d,e){var f;a.xb=!1;b&&(f=b.a.length?[b.a.length,b.a[0].length,b.a[0][0].length,b.a[0][0][0].length]:[0,0,0,0],b&&f[0]>a.U||f[1]>a.Z)&&(this.G('Disk "'+c+'" too large for drive '+("RL"+a.zb)),b=null);b?(a.da=b,a.xa=c,a.Ca=d,this.G('Mounted disk "'+c+'" in drive '+("RL"+a.zb),a.wb||e),this.l&&zc(this.l)):a.lb=!1;a.wb&&(a.wb=!1,--this.s||F(this));Jf(this,a.zb)};
|
||||
function Qf(a,b,c,d,e,f){var g=-1,k=a.b[b];k.Ca.toLowerCase()!=d.toLowerCase()&&(g++,Pf(a,b,!0),k.yb?a.G("RL11 busy"):(k.yb=!0,e&&(k.xb=!0,a.s++),k.lb=!!f,Df(new zf(a,k,"preload"),c,d,f,a.qc)&&g++));return g}
|
||||
h.qc=function(a,b,c,d,e){var f;a.yb=!1;b&&(f=b.a.length?[b.a.length,b.a[0].length,b.a[0][0].length,b.a[0][0][0].length]:[0,0,0,0],b&&f[0]>a.U||f[1]>a.Z)&&(this.G('Disk "'+c+'" too large for drive '+("RL"+a.Ab)),b=null);b?(a.da=b,a.xa=c,a.Ca=d,this.G('Mounted disk "'+c+'" in drive '+("RL"+a.Ab),a.xb||e),this.l&&zc(this.l)):a.lb=!1;a.xb&&(a.xb=!1,--this.s||F(this));Jf(this,a.Ab)};
|
||||
function Nf(a,b,c,d){if((a=a.o.listDisks)&&a.options){for(var e=0;e<a.options.length;e++)if(a.options[e].value==c)return;e=document.createElement("option");e.text=b;e.value=c;d&&a.childNodes[0]?a.insertBefore(e,a.childNodes[0]):a.appendChild(e)}}
|
||||
function Jf(a,b){if(0<=b&&b<a.b.length){var c=a.b[b],d=a.o.listDisks;a=a.o.listDrives;if(d&&a&&d.options&&a.options&&(a=ja(a.value),c=c.lb?"?":c.Ca,!isNaN(a)&&a==b)){for(b=0;b<d.options.length;b++)if(d.options[b].value==c){d.selectedIndex!=b&&(d.selectedIndex=b);break}b==d.options.length&&(d.selectedIndex=0)}}}function Pf(a,b,c){var d=a.b[b];if(d.da||!1===c)d.xa="",d.Ca="",d.da=null,d.lb=!1,c||(a.G("Drive RL"+b+" unloaded",c),Jf(a,b))}
|
||||
function Lf(a,b){var c=0;b||(b=[]);a.L=b[c++]||0;a.v=b[c++]||0;a.c=b[c++]||0;a.i=b[c++]||0;a.m=b[c++]||0;a.w=b[c]||0;for(b=0;b<a.b.length;b++){var d=a.b[b];void 0===d&&(d=a.b[b]={});c=a;d.zb=b;d.xb=d.lb=!1;d.name=c.Fa;d.U=512;d.Z=2;d.S=40;d.ia=256;d.yb=!0;d.oe=0;d.ne=0;d.Mb=1;d.jc=d.S;d.Rb=d.ia;d.re=0;d.se=null;d.da||(d.Ca="");d.status=29|(512==d.U?128:0)}return!0}
|
||||
h.mc=function(a,b,c,d,e,f){this.v=f&65535;this.L=this.L&-49|f>>12&48;this.w=f>>16&63;this.i=this.c=b<<7|(c?64:0)|d&63;this.m=65536-e&65535;a&&(this.L=this.L|a|32768);return!0};
|
||||
h.Dc=function(a,b,c,d,e,f,g){var k=0,l=a.da,n=null,p;l||(k=5120,e=0);for(;e--;){if(!n){n=a.da.seek(b,c,d+1);if(!n){k=5120;break}p=0}var u,w;if(0>(u=a.da.read(n,p++))||0>(w=a.da.read(n,p++))){k=5120;break}this.h.eb(f,u|w<<8);if(Rb(this.h)){k=8192;break}f+=2;if(p>=l.ia&&(n=null,++d>=l.S&&(d=0,++c>=l.Z&&(c=0,++b>=l.U)))){k=5120;break}}return g(k,b,c,d,e,f)};
|
||||
h.Bd=function(a,b,c,d,e,f,g){var k=0,l=a.da,n=null,p;l||(k=5120,e=0);for(;e--;){var u=this.h.Ya(f);if(Rb(this.h)){k=8192;break}f+=2;if(!n){n=a.da.seek(b,c,d+1,!0);if(!n){k=5120;break}p=0}if(!a.da.write(n,p++,u&255)||!a.da.write(n,p++,u>>8)){k=5120;break}if(p>=l.ia&&(n=null,++d>=l.S&&(d=0,++c>=l.Z&&(c=0,++b>=l.U)))){k=5120;break}}return g(k,b,c,d,e,f)};h.$c=function(){return this.L&65535};
|
||||
h.Wd=function(a){this.L=this.L&-1023|a&1022;this.B=this.B&-4|(a&48)>>4;if(!(this.L&128)){var b;a=!0;var c=this.b[(this.L&768)>>8],d,e,f,g;this.L&=-2;switch(this.L&14){case 4:this.c&8&&(this.L&=63);this.m=c.status|this.i&64;break;case 6:1==(this.c&3)&&(b=this.c&65408,c=(this.c&16)<<2,this.i=this.c&4?this.i+b:this.i-b,this.c=this.i=this.i&65408|c);break;case 8:this.m=this.i;break;case 12:b=this.Dc;case 10:b||(b=this.Bd),d=this.c>>7,e=this.c&64?1:0,f=this.c&63,d>=c.U||f>=c.S?this.L|=37888:(g=(this.w&
|
||||
63)<<16|this.v,a=65536-this.m&65535,a=b.call(this,c,d,e,f,a,g,this.mc.bind(this)))}a&&(this.L|=129,this.L&64&&Tb(this.a,this.D))}};h.Yc=function(){return this.v};h.Ud=function(a){this.v=a&65534};h.ad=function(){return this.c};h.Xd=function(a){this.c=a};h.bd=function(){return this.m};h.Yd=function(a){this.m=a};h.Zc=function(){return this.w};h.Vd=function(a){this.w=a&63};
|
||||
var Rf={},Mf=(Rf[63744]=[null,null,N.prototype.$c,N.prototype.Wd,"RLCS"],Rf[63746]=[null,null,N.prototype.Yc,N.prototype.Ud,"RLBA"],Rf[63748]=[null,null,N.prototype.ad,N.prototype.Xd,"RLDA"],Rf[63750]=[null,null,N.prototype.bd,N.prototype.Yd,"RLMP"],Rf[63752]=[null,null,N.prototype.Zc,N.prototype.Vd,"RLBE"],Rf);
|
||||
function Lf(a,b){var c=0;b||(b=[]);a.L=b[c++]||0;a.v=b[c++]||0;a.c=b[c++]||0;a.i=b[c++]||0;a.m=b[c++]||0;a.w=b[c]||0;for(b=0;b<a.b.length;b++){var d=a.b[b];void 0===d&&(d=a.b[b]={});c=a;d.Ab=b;d.yb=d.lb=!1;d.name=c.Fa;d.U=512;d.Z=2;d.S=40;d.ia=256;d.zb=!0;d.qe=0;d.pe=0;d.Nb=1;d.lc=d.S;d.Sb=d.ia;d.te=0;d.ue=null;d.da||(d.Ca="");d.status=29|(512==d.U?128:0)}return!0}
|
||||
h.oc=function(a,b,c,d,e,f){this.v=f&65535;this.L=this.L&-49|f>>12&48;this.w=f>>16&63;this.i=this.c=b<<7|(c?64:0)|d&63;this.m=65536-e&65535;a&&(this.L=this.L|a|32768);return!0};
|
||||
h.Fc=function(a,b,c,d,e,f,g){var k=0,l=a.da,n=null,p;l||(k=5120,e=0);for(;e--;){if(!n){n=a.da.seek(b,c,d+1);if(!n){k=5120;break}p=0}var u,w;if(0>(u=a.da.read(n,p++))||0>(w=a.da.read(n,p++))){k=5120;break}this.h.eb(f,u|w<<8);if(Rb(this.h)){k=8192;break}f+=2;if(p>=l.ia&&(n=null,++d>=l.S&&(d=0,++c>=l.Z&&(c=0,++b>=l.U)))){k=5120;break}}return g(k,b,c,d,e,f)};
|
||||
h.Bd=function(a,b,c,d,e,f,g){var k=0,l=a.da,n=null,p;l||(k=5120,e=0);for(;e--;){var u=this.h.Ya(f);if(Rb(this.h)){k=8192;break}f+=2;if(!n){n=a.da.seek(b,c,d+1,!0);if(!n){k=5120;break}p=0}if(!a.da.write(n,p++,u&255)||!a.da.write(n,p++,u>>8)){k=5120;break}if(p>=l.ia&&(n=null,++d>=l.S&&(d=0,++c>=l.Z&&(c=0,++b>=l.U)))){k=5120;break}}return g(k,b,c,d,e,f)};h.bd=function(){return this.L&65535};
|
||||
h.Wd=function(a){this.L=this.L&-1023|a&1022;this.B=this.B&-4|(a&48)>>4;if(!(this.L&128)){var b;a=!0;var c=this.b[(this.L&768)>>8],d,e,f,g;this.L&=-2;switch(this.L&14){case 4:this.c&8&&(this.L&=63);this.m=c.status|this.i&64;break;case 6:1==(this.c&3)&&(b=this.c&65408,c=(this.c&16)<<2,this.i=this.c&4?this.i+b:this.i-b,this.c=this.i=this.i&65408|c);break;case 8:this.m=this.i;break;case 12:b=this.Fc;case 10:b||(b=this.Bd),d=this.c>>7,e=this.c&64?1:0,f=this.c&63,d>=c.U||f>=c.S?this.L|=37888:(g=(this.w&
|
||||
63)<<16|this.v,a=65536-this.m&65535,a=b.call(this,c,d,e,f,a,g,this.oc.bind(this)))}a&&(this.L|=129,this.L&64&&Tb(this.a,this.D))}};h.$c=function(){return this.v};h.Ud=function(a){this.v=a&65534};h.cd=function(){return this.c};h.Xd=function(a){this.c=a};h.dd=function(){return this.m};h.Yd=function(a){this.m=a};h.ad=function(){return this.w};h.Vd=function(a){this.w=a&63};
|
||||
var Rf={},Mf=(Rf[63744]=[null,null,N.prototype.bd,N.prototype.Wd,"RLCS"],Rf[63746]=[null,null,N.prototype.$c,N.prototype.Ud,"RLBA"],Rf[63748]=[null,null,N.prototype.cd,N.prototype.Xd,"RLDA"],Rf[63750]=[null,null,N.prototype.dd,N.prototype.Yd,"RLMP"],Rf[63752]=[null,null,N.prototype.ad,N.prototype.Vd,"RLBE"],Rf);
|
||||
function Sf(a,b,c){y.call(this,"Computer",a,Sf,67108864);this.j.N=!1;Tf(this,b);this.A=tc(this,"autoPower",a);this.l=0;this.M=a.busWidth||a.buswidth;this.b=Uf;this.s=null;this.i=this.I=!1;this.O=tc(this,"url")||"";(Math.random()+.1).toString(36);this.c=Vf(this);if(this.a=Ta("CPU",this.id)){this.F=Ta("Debugger",this.id);this.h=new vb({id:this.ra+".bus",busWidth:this.M},this.a,this.F);var d,e=B(this.id);if((this.w=Ta("Panel",this.id))&&this.w.Xa)for(b=0;b<e.length;b++)d=e[b],d.G=this.w.G,d.T=this.w.T,
|
||||
d.Xa=this.w.Xa;this.T("PDPjs v1.30.3\nCopyright \u00a9 2012-2016 Jeff Parsons <Jeff@pcjs.org>\nLicense: GPL version 3 or later <http://gnu.org/licenses/gpl.html>");this.T("Portions adapted from the PDP-11/70 Emulator v1.4 by Paul Nankervis <paulnank@hotmail.com>");for(b=0;b<e.length;b++)d=e[b],d.ja&&d.ja(this,this.h,this.a,this.F);b=null;d=a.resume;void 0!==d&&(1<d.length?b=this.m=d:this.b=parseInt(d,10));var f;if(a=tc(this,"state")||(f=!0,a.state))b=this.B=a,f||(this.i=!0,this.b=Uf),this.b&&(this.v=
|
||||
new O(this,"1.30.3"),Wf(this.v)?b=null:delete this.v);!b&&this.b&&(b=Xf(this))&&(this.i=!0);if(b){var g=this;r(b,null,!0,function(a,b,c){c?(g.m=null,g.i=!1,g.G("Unable to load machine state from server (error "+c+(b?": "+pa(b):"")+")")):(g.s=b,g.I=!0);F(g)})}else F(this);this.o.power||(this.A=!0);!c&&this.A&&Yf(this,this.ab)}else t("Unable to find CPU component")}A(Sf);var Uf=0;
|
||||
function Tf(a,b){if(!b){var c;if("object"==typeof resources&&(c=resources.parms))try{b=eval("("+c+")")}catch(d){t(d.message+" ("+c+")")}}a.J=b}function tc(a,b,c){var d=b.toLowerCase(),d=La[b]||La[d];void 0===d&&a.J&&(d=a.J[b]);void 0===d&&c&&(d=c[b]);void 0===d&&"object"==typeof resources&&resources[b]&&(d=b);return d}function Yf(a,b,c){for(var d=B(a.id),e=0;e<=d.length;e++){var f=e<d.length?d[e]:a;if(!Va(f)){Va(f,function(){Yf(a,b,c)});return}}b.call(a,c)}
|
||||
function Zf(a,b){var c=new O(a,"1.30.3","validate");if(Wf(c)&&$f(c)){var d=c.get("timestamp"),e=b?b.get("timestamp"):"unknown";d!=e&&(a.G("Machine state may be out-of-date\n("+d+" vs. "+e+")\nCheck your browser's local storage limits"),b||c.clear())}}h=Sf.prototype;
|
||||
h.ab=function(a){void 0===a&&(a=this.b||(this.s?1:Uf));if(!this.l){this.l++;var b=!1,c=!1;this.D=!1;var d=this.v||new O(this,"1.30.3");if(-1==a)b=!0;else if(a>Uf){if(Wf(d,this.s)){this.f=new O(this,"1.30.3","failsafe");Wf(this.f)&&(ag(this,d),a=2,bg(this.f));this.f.set("timestamp",sa());cg(this.f);var e=this.b&&!this.i;if(1==a||ua("Click OK to restore the previous PDPjs machine state, or CANCEL to reset the machine.")){if(c=$f(d)){var f=d.get("code"),g=d.get("data");f&&("ok"==f?Wf(d,g):("error"==
|
||||
f&&"no machine state"!=g?(this.G("Error: "+g),"unable to verify user"==g&&(Aa("user",""),this.c=null)):this.T(f+": "+g),bg(d),Wf(d)?(c=$f(d),e=!0):c=!1))}e&&Zf(this,c?d:null)}else 2==a&&d.clear()}else Zf(this);delete this.s;delete this.v}e=B(this.id);for(f=0;f<e.length;f++)g=e[f],g!==this&&g!=this.a&&(c=dg(this,g,d,b,c));b=[d,a,c];-1!=a?Yf(this,this.Nb,b):this.Nb(b)}};
|
||||
function dg(a,b,c,d,e){if(!b.j.N){b.j.N=!0;if(b.la){var f=null;e&&((f=c.get(b.id))||(f=c.get(b.id.replace(/[a-z0-9]\./i,"."))));"string"===typeof f&&(f=null);!b.la(f,d)&&f&&(t("Unable to restore state for "+b.type),a.B&&!a.I?(c.clear(),a.b=Uf,window&&window.location.reload()):a.D=!0,b.la(null),e=!1)}if(!d&&b.Ub)for(a=b.Ub.split("|"),c=0;c<a.length;c++)b.status(a[c])}return e}
|
||||
h.Nb=function(a){var b=a[0],c=0>a[1];a=a[2];this.R=!0;this.j.N=!0;var d=this.o.power;d&&(d.textContent="Shutdown");this.a&&(dg(this,this.a,b,c,a),this.ya(),this.a.Wa());this.D&&(ag(this,b),b.clear());!c&&this.f&&(this.f.clear(),delete this.f);this.l=0};
|
||||
h.ab=function(a){void 0===a&&(a=this.b||(this.s?1:Uf));if(!this.l){this.l++;var b=!1,c=!1;this.D=!1;var d=this.v||new O(this,"1.30.3");if(-1==a)b=!0;else if(a>Uf){if(Wf(d,this.s)){this.g=new O(this,"1.30.3","failsafe");Wf(this.g)&&(ag(this,d),a=2,bg(this.g));this.g.set("timestamp",sa());cg(this.g);var e=this.b&&!this.i;if(1==a||ua("Click OK to restore the previous PDPjs machine state, or CANCEL to reset the machine.")){if(c=$f(d)){var f=d.get("code"),g=d.get("data");f&&("ok"==f?Wf(d,g):("error"==
|
||||
f&&"no machine state"!=g?(this.G("Error: "+g),"unable to verify user"==g&&(Aa("user",""),this.c=null)):this.T(f+": "+g),bg(d),Wf(d)?(c=$f(d),e=!0):c=!1))}e&&Zf(this,c?d:null)}else 2==a&&d.clear()}else Zf(this);delete this.s;delete this.v}e=B(this.id);for(f=0;f<e.length;f++)g=e[f],g!==this&&g!=this.a&&(c=dg(this,g,d,b,c));b=[d,a,c];-1!=a?Yf(this,this.Ob,b):this.Ob(b)}};
|
||||
function dg(a,b,c,d,e){if(!b.j.N){b.j.N=!0;if(b.la){var f=null;e&&((f=c.get(b.id))||(f=c.get(b.id.replace(/[a-z0-9]\./i,"."))));"string"===typeof f&&(f=null);!b.la(f,d)&&f&&(t("Unable to restore state for "+b.type),a.B&&!a.I?(c.clear(),a.b=Uf,window&&window.location.reload()):a.D=!0,b.la(null),e=!1)}if(!d&&b.Vb)for(a=b.Vb.split("|"),c=0;c<a.length;c++)b.status(a[c])}return e}
|
||||
h.Ob=function(a){var b=a[0],c=0>a[1];a=a[2];this.R=!0;this.j.N=!0;var d=this.o.power;d&&(d.textContent="Shutdown");this.a&&(dg(this,this.a,b,c,a),this.ya(),this.a.Wa());this.D&&(ag(this,b),b.clear());!c&&this.g&&(this.g.clear(),delete this.g);this.l=0};
|
||||
function ag(a,b){if(ua("There may be a problem with your PDPjs machine.\n\nTo help us diagnose it, click OK to send this PDPjs machine state to http://www.pcjs.org.")){var c=a.c||"";b=b.toString();var d={app:"PDPjs",ver:"1.30.3"};d.url=a.O;d.user=c;d.type="bug";d.data=b;r("http://www.pcjs.org/api/v1/report",d,!0)}}
|
||||
function gg(a,b,c){var d,e="none";if(a.l)return null;a.l--;var f=new O(a,"1.30.3"),g=new O(a,"1.30.3","validate"),k=sa();g.set("timestamp",k);f.set("timestamp",k);f.set("version","1.30.3");f.set("url",window?window.location.href:null);f.set("browser",window?window.navigator.userAgent:"");a.a&&a.a.ka&&(c&&G(a.a),d=a.a.ka(b,c),"object"===typeof d&&f.set(a.a.id,d),c&&(a.a.j.N=!1,!1===d&&(e=null)));for(var k=B(a.id),l=0;l<k.length;l++){var n=k[l];n.j.N&&(n.ka&&(d=n.ka(b,c),"object"===typeof d&&f.set(n.id,
|
||||
d)),c&&(n.j.N=!1,!1===d&&(e=null)))}e&&(c?(k=d=!1,b?(a.c&&hg(a,a.c,f.toString()),cg(g)&&cg(f)||(e=null,d=k=!0)):a.b&&(d=!0,k=3==a.b),d&&f.clear(k)):e=f.toString());c&&(a.j.N=!1,b=a.o.power)&&(b.textContent="Power");a.l=0;return e}h.reset=function(){this.h&&this.h.reset&&this.h.reset();this.a&&this.a.reset&&this.a.reset();for(var a=B(this.id),b=0;b<a.length;b++){var c=a[b];c!==this&&c!==this.h&&c!==this.a&&c.reset&&c.reset()}this.ya(-1)};
|
||||
h.start=function(a,b){for(var c=B(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.start&&e.start(a,b)}this.ya(-1)};h.stop=function(a,b){for(var c=B(this.id),d=0;d<c.length;d++){var e=c[d];"CPU"!=e.type&&e!==this&&e.stop&&e.stop(a,b)}this.ya(-1)};
|
||||
h.ya=function(a){if(this.a){var b=this.a,c=a||0,d=b.o.speed;d&&(0>=c||30<=(b.Ab+=c))&&(d.textContent=b.j.P?b.Ga.toFixed(2)+"Mhz":"Stopped",b.Ab=0)}if(this.w&&(b=this.w,a=a||0,b.v)){c=b.a.j.P;d=!!(b.a.u&4);if(0>=a||60<=(b.s+=a)){for(var e=0;e<b.a.g.length;e++)kb(b,"R"+e,b.a.g[e]);e=Zb(b.a);kb(b,"PS",e);kb(b,"NF",e&8?1:0,1);kb(b,"ZF",e&4?1:0,1);kb(b,"VF",e&2?1:0,1);kb(b,"CF",e&1?1:0,1);b.s=0}sb(b,0<a&&c&&!d?b.a.Za:b.ea);rb(b,b.m);a=b.a;a=a.aa?a.Ba&16?1:2:4;tb(b,"B22",a&1);tb(b,"B18",a&2);tb(b,"B16",
|
||||
h.ya=function(a){if(this.a){var b=this.a,c=a||0,d=b.o.speed;d&&(0>=c||30<=(b.Bb+=c))&&(d.textContent=b.j.P?b.Ga.toFixed(2)+"Mhz":"Stopped",b.Bb=0)}if(this.w&&(b=this.w,a=a||0,b.v)){c=b.a.j.P;d=!!(b.a.u&4);if(0>=a||60<=(b.s+=a)){for(var e=0;e<b.a.f.length;e++)kb(b,"R"+e,b.a.f[e]);e=Zb(b.a);kb(b,"PS",e);kb(b,"NF",e&8?1:0,1);kb(b,"ZF",e&4?1:0,1);kb(b,"VF",e&2?1:0,1);kb(b,"CF",e&1?1:0,1);b.s=0}sb(b,0<a&&c&&!d?b.a.Za:b.ea);rb(b,b.m);a=b.a;a=a.aa?a.Ba&16?1:2:4;tb(b,"B22",a&1);tb(b,"B18",a&2);tb(b,"B16",
|
||||
a&4)}};
|
||||
h.$=function(a,b,c){var d=this;switch(b){case "power":return this.o[b]=c,c.onclick=function(){d.l||(d.j.N?gg(d,!1,!0):Yf(d,d.ab))},!0;case "reset":return this.o[b]=c,c.onclick=function(){if(d.j.N&&!d.l)if(d.b&&!d.m){var a=ua("Click OK to save changes to this PDPjs machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded.");gg(d,a,!0);!a&&d.B?window&&window.location.reload():(a||(d.Ob=!0),d.ab(Uf),d.Ob=!1)}else d.reset(),d.a&&d.a.Wa()},!0;case "save":if(ma(v(),"pcjs.org"))c.parentNode.removeChild(c);else return this.o[b]=
|
||||
h.$=function(a,b,c){var d=this;switch(b){case "power":return this.o[b]=c,c.onclick=function(){d.l||(d.j.N?gg(d,!1,!0):Yf(d,d.ab))},!0;case "reset":return this.o[b]=c,c.onclick=function(){if(d.j.N&&!d.l)if(d.b&&!d.m){var a=ua("Click OK to save changes to this PDPjs machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded.");gg(d,a,!0);!a&&d.B?window&&window.location.reload():(a||(d.Pb=!0),d.ab(Uf),d.Pb=!1)}else d.reset(),d.a&&d.a.Wa()},!0;case "save":if(ma(v(),"pcjs.org"))c.parentNode.removeChild(c);else return this.o[b]=
|
||||
c,c.onclick=function(){var a=Vf(d,!0);if(a){var b=!!(d.b&&!d.m||d.B),c=gg(d,b);b?hg(d,a,c):d.G("Resume disabled, machine state not saved")}},!0}return!1};
|
||||
function Vf(a,b){var c=a.c;c||((c=za("user"),void 0!==c)?!c&&b&&(b=null,window&&(b=window.prompt("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below.","")),c=b)&&((c=ig(a,c))||a.G("The user ID is invalid.")):b&&a.G("Browser local storage is not available"));return c}
|
||||
function ig(a,b){a.c=null;b=r(v()+"/api/v1/user?req=verify&user="+b);var c=b[1];if(!b[0]&&c)try{b=eval("("+c+")"),b.code&&"ok"==b.code&&(Aa("user",b.data),a.c=b.data)}catch(d){t(d.message+" ("+c+")")}return a.c}function Xf(a){var b=null;a.c&&(b=v()+"/api/v1/user?req=load&user="+a.c+"&state="+jg(a,"1.30.3"));return b}
|
||||
function hg(a,b,c){if(c){var d={req:"store"};d.user=b;d.state=jg(a,"1.30.3");d.data=c;b=r(v()+"/api/v1/user",d);d=b[0];if(b[1]){if(d){var e=d.indexOf("\n");0<e&&(d=d.substr(0,e));d.indexOf("Error: ")||(d=d.substr(7))}d='{"code":'+b[1]+',"data":"'+d+'"}'}b=JSON.parse(d);b&&"ok"==b.code?a.G("Machine state saved to server"):c&&(c=b&&b.data||"unable to save machine state",c="error"==b.code?"Error: "+c:"Error "+b.code+": "+c,a.G(c),Aa("user",""),a.c=null)}}
|
||||
function of(a){var b;a=B(a.id);for(var c=0;c<a.length;c++){var d=a[c];if(b)b==d&&(b=null);else if("RAM"==d.type)return d}return null}function zc(a){if(a.Xa){var b=0,c=0;window&&(b=window.scrollX,c=window.scrollY);a.Xa.focus();window&&window.scrollTo(b,c)}}Ga(function(){for(var a=E(document,"pdp11-machine"),b=0;b<a.length;b++)for(var c=a[b],d=C(c),c=E(c,"pdp11","computer"),e=0;e<c.length;e++){var f=c[e],g=C(f),g=new Sf(g,d,!0);D(g,f);g.A&&Yf(g,g.ab)}});
|
||||
x.show.push(function(){for(var a=E(document,"pdp11","computer"),b=0;b<a.length;b++){var c=C(a[b]);(c=Ta("Computer",c.id))&&c.R&&!c.j.N&&c.ab(-1)}});x.exit.push(function(){for(var a=E(document,"pdp11","computer"),b=0;b<a.length;b++){var c=C(a[b]);(c=Ta("Computer",c.id))&&c.j.N&&gg(c,!(!c.b||c.m),!0)}});function O(a,b,c){this.id=a.id;this.key=jg(a,b,c);this.F=a.F;bg(this,a.xd)}function jg(a,b,c){a=a.id;if(b){var d=b.indexOf(".");0<d&&(a+=".v"+b.substr(0,d))}c&&(a+="."+c);return a}
|
||||
x.show.push(function(){for(var a=E(document,"pdp11","computer"),b=0;b<a.length;b++){var c=C(a[b]);(c=Ta("Computer",c.id))&&c.R&&!c.j.N&&c.ab(-1)}});x.exit.push(function(){for(var a=E(document,"pdp11","computer"),b=0;b<a.length;b++){var c=C(a[b]);(c=Ta("Computer",c.id))&&c.j.N&&gg(c,!(!c.b||c.m),!0)}});function O(a,b,c){this.id=a.id;this.key=jg(a,b,c);this.F=a.F;bg(this,a.oe)}function jg(a,b,c){a=a.id;if(b){var d=b.indexOf(".");0<d&&(a+=".v"+b.substr(0,d))}c&&(a+="."+c);return a}
|
||||
O.prototype={constructor:O,set:function(a,b){try{this[this.id][a]=b}catch(c){}},get:function(a){return this[this.id][a]||null},value:function(){return this[this.id]},data:function(){return this[this.id]},toString:function(){var a=this[this.id];return"string"==typeof a?a:JSON.stringify(a)},clear:function(a){bg(this);var b=[];try{for(var c=0,d=window.localStorage.length;c<d;c++)b.push(window.localStorage.key(c))}catch(e){}for(c=0;c<b.length;c++)if((d=b[c])&&(a||d.substr(0,this.key.length)==this.key)){try{window.localStorage.removeItem(d)}catch(e){}b.splice(c,
|
||||
1);c=0}}};function bg(a,b){a[a.id]={};b&&a.set("parms",b);a.a=!1}function cg(a){var b=!0;if(ya()){var c=JSON.stringify(a[a.id]);Aa(a.key,c)||(t("Unable to store "+c.length+" bytes in browser local storage"),b=!1)}return b}function $f(a){var b=!0;try{a[a.id]=JSON.parse(a[a.id])}catch(c){t(c.message||c),b=!1}return b}function Wf(a,b){return b?(a[a.id]=b,a.a=!0):a.a?!0:ya()&&(b=za(a.key))?(a[a.id]=b,a.a=!0):!1}var kg=0;
|
||||
function lg(a,b,c,d,e,f){e("Loading "+a+"...");r(a,null,!0,function(g,k,l){l?(k||(k="unable to load "+a+" ("+l+")"),f(k,null)):mg(k,a,b,c,d,e,f)})}
|
||||
|
|
|
|||
Loading…
Reference in a new issue