From 383de1cd8a1177183d8220c8b34c04875e22e1d6 Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Sun, 28 Sep 2014 18:18:53 -0700 Subject: [PATCH] README updates (and some code inspection fixes) --- README.md | 243 ++++++---- my_modules/README.md | 646 +------------------------- my_modules/htmlout/lib/htmlout.js | 21 +- my_modules/markout/lib/markout.js | 1 + my_modules/pcjs-client/lib/README.md | 23 +- my_modules/pcjs-client/lib/chipset.js | 14 +- my_modules/pcjs-client/lib/defines.js | 31 +- my_modules/pcjs-client/lib/mouse.js | 30 +- my_modules/pcjs-client/lib/serial.js | 3 + my_modules/pcjs-client/lib/video.js | 6 + my_modules/pcjs-client/lib/x86help.js | 4 + my_modules/pcjs-client/lib/x86opxx.js | 68 +-- 12 files changed, 266 insertions(+), 824 deletions(-) diff --git a/README.md b/README.md index b201d7eaf..9aaa9c50f 100644 --- a/README.md +++ b/README.md @@ -50,70 +50,114 @@ and the original machine are available in the [C1Pjs Documentation](/docs/c1pjs/ -Updating PCjs -=== - -Developing +Installing PCjs --- -Let's say you just finished developing, testing and deploying version 1.12.1, and you want to start developing some -new features for version 1.13.0. Here are the recommended steps: - -1. Create and switch to a new Git development branch (eg, "node_dev") -2. Change the version number in [package.json](/package.json) (eg, to "1.13.0") -3. Run "grunt" (the default task will build fresh "1.13.0" copies of everything under "/versions") -4. Run "grunt promote" to bump the version in all the site's machine XML files to match (ie, to "1.13.0") - -You may not want to do the last step until you're ready to start testing the new version. In fact, you may want to -manually edit the version in only a few machine configuration files for testing, leaving the rest set to the previous -version to make comparison runs easier, and then run "grunt promote" when the new version is much closer to being -released. +The following instructions were written for OS X users. However, users of other operating systems should have +no problem following along. -Commit the development branch to GitHub as often as desired. I probably tend to "over-commit", checking in lots of -intermediate changes before I finally decide that the new version is "good enough". But having too much delta history is -probably better than too little. Note that the initial "node_dev" commit may not get pushed to GituHub without first -running: +Open Terminal and `cd` to a directory where you'd like to install *pcjs*, and run the following commands: - git push --set-upstream origin node_dev + git clone git@github.com:jeffpar/pcjs.git pcjs + cd pcjs + npm install + node server.js -One downside to intermediate commits to GitHub is that compiled versions of the sources (such as those in -[/docs/pcjs/demos/](/docs/pcjs/demos/)) may keep changing, and those particular commits are pretty useless. -To temporarily ignore changes to those files: +Now open a web browser and go to `http://localhost:8088/`. You're done! - cd docs/pcjs/demos - git update-index --assume-unchanged components.xsl pc.js pc-dbg.js samples.zip +It's assumed that the OS X Developer Tools (which include Git) have already been installed, as well as +Node and NPM. Node (which now includes NPM) should be downloaded from [nodejs.org](http://nodejs.org/download/). + +The current version of Node ([0.10.32](http://nodejs.org/dist/v0.10.32/node-v0.10.32.pkg) at the time of this +writing) should work fine, but version [0.10.26](http://nodejs.org/dist/v0.10.26/node-v0.10.26.pkg) +is what's been used to develop and test PCjs so far. + +Also, [server.js](server.js) was originally written using [Express](http://expressjs.com/) v3.x. Since then, +Express v4.x has been released, but `npm install` will make sure that v3.x is installed locally. + +The plan is to eventually move development to a newer version of Node, and migrate the PCjs server to a newer +version of Express; there's no desire to remain stuck in the past (well, ignoring the fact that PCjs is the +quintessential "stuck in the past" project), but there's also no urgency to update. + +### Building PCjs + +Unlike a typical project, where you have to *build* or *configure* or *make* something, PCjs is "ready to run". +That's because both the compiled and uncompiled versions of PCjs are checked into the project, making deployment +to a web server easy. + +However, in order to build and test PCjs modifications, you'll want to use [Grunt](http://gruntjs.com/) and the +Grunt tasks defined by [Gruntfile.js](Gruntfile.js). + +Although Grunt was installed locally when you ran `npm install`, you'll also want to install the command-line +interface to Grunt; you can install that locally as well, but it's recommended that you install it globally, with +the "-g" option: + + sudo npm install grunt-cli -g + +Now you can run `grunt` anywhere within the PCjs project to build an updated version. If no command-line arguments +are specified, `grunt` runs the "default" task defined by [Gruntfile.js](Gruntfile.js); that task runs Google's +[Closure Compiler](https://developers.google.com/closure/compiler/) if any of the target files (eg, pc.js, pc-dbg.js, +etc) are out-of date. + +To ensure identical compilation results for everyone, a copy of the Closure Compiler has been checked into the +[bin](bin/) folder. This version of Closure Compiler, in turn, requires Java v7.x or later. Use the following +commands to confirm that everything is working properly: + + java -version -To see a list of all files that are marked as "assume-unchanged", use this command: - - git ls-files -v | grep '^[[:lower:]]' +which should report a version >= 1.7.x; eg: -The same issue would exist for all new files created under "/versions", but fortunately, those files are ignored until -you explicitly add them to Git, which you'll want to do just prior to deployment: + java version "1.7.0_67" + Java(TM) SE Runtime Environment (build 1.7.0_67-b01) + Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode) - git add versions/pcjs/1.13.0/* - git add versions/c1pjs/1.13.0/* - -which is when you'll also want to do undo the "assume-unchanged" operation above: +Then run: - cd docs/pcjs/demos - git update-index --no-assume-unchanged components.xsl pc.js pc-dbg.js samples.zip + java -jar bin/compiler.jar --version -Testing +which should report: + + Closure Compiler (http://code.google.com/closure/compiler) + Version: v20140407 + Built on: 2014/04/07 14:04 + +If you don't have Java installed, it's recommended that you install the JDK (*not* the JRE), because the JRE may not +update your command-line tools properly. Note that Java is used *only* by the Closure Compiler; none of the PCjs +client or server components use Java. + +Newer versions of the Closure Compiler should work as well, and at some point, a newer version will be checked into the +project. + +Using PCjs --- -PCjs can now be run from the command-line mode using Node, making it possible to script the application, + +### From The Browser + +The PCjs web server is little more than a file/directory browser for the PCjs project, plus a collection of APIs. + +If a URL corresponds to a PCjs project folder and no "index.html" exists in that folder, the server loads an HTML +template ([common.html](my_modules/shared/templates/common.html)) and generates an "index.html" for that folder. + +The contents of the "index.html" will vary depending on the contents of the folder; for example, if the folder +contains a README.md, then that file is converted to HTML and embedded in the "index.html". Similarly, if the folder +contains a machine XML file, that is embedded as well. + +### From The Command-Line + +The PCjs client app can also be run from the command-line mode using Node, making it possible to script the application, run a series of automated tests, etc: cd ./my_modules/pcjs-client/bin node pcjs -The [pcjs](/my_modules/pcjs-client/bin/pcjs) script in the *bin* directory loads all the PCjs browser scripts listed -in [package.json](/package.json), and then it starts a Node REPL ("read-eval-print loop"). The REPL handles a few -special commands (eg, "load", "quit") and passes anything else to the PCjs Debugger component. If no Debugger component -has been created yet, or if the Debugger didn't recognize the command, then it's passed on to *eval()*, like a good -little REPL. +The [pcjs](my_modules/pcjs-client/bin/pcjs) script in [/my_modules/pcjs-client/bin](my_modules/pcjs-client/bin) loads +all the PCjs browser scripts listed in [package.json](/package.json), and then it starts a Node REPL ("read-eval-print loop"). +The REPL handles a few special commands (eg, "load", "quit") and passes anything else to the PCjs Debugger component. +If no Debugger component has been created yet, or if the Debugger didn't recognize the command, then it's passed on to *eval()*, +like a good little REPL. -Use the "load" command to load a JSON machine configuration file. A sample [machine.json](/my_modules/pcjs-client/bin/machine.json) -is provided in the *bin* directory, which is a "JSON-ified" version of the [machine.xml](/configs/pc/machines/5150/mda/64kb/machine.xml) -displayed on the [pcjs.org](http://www.pcjs.org/) home page. +Use the "load" command to load a JSON machine configuration file. A sample [machine.json](my_modules/pcjs-client/bin/machine.json) +is provided in the *bin* directory, which is a "JSON-ified" version of the [machine.xml](configs/pc/machines/5150/mda/64kb/machine.xml) +displayed on the [pcjs.org](/) home page. The command-line loader creates all the JSON-defined machine components in the same order that the browser creates XML-defined components. You can also issue the "load" command directly from the command-line: @@ -139,65 +183,72 @@ supports *only* JSON machine configuration files. I haven't decided whether I'll add support for JSON configuration files to the client, or add some XML-to-JSON conversion to the server, or both. -Deploying +Debugging PCjs --- -I like to use the AWS Elastic Beanstalk web interface to create a new "development" environment ("pcjs-dev") for testing: + +### Server Components + +To help test/debug changes to PCjs server components (eg, [DiskDump](my_modules/diskdump/), [HTMLOut](my_modules/htmlout/)), +you can start the server with some additional options; eg: + + node server.js --logging --console --debug + +The `--logging` option will create a [node.log](/logs/node.log) that records all the HTTP requests, `--debug` +will generate additional debug-only messages (which will also be logged if `--logging` is enabled), and `--console` +will replicate any messages to your console as well. + +A complete list of command-line options can be found in [server.js](server.js). + +### Client Components + +A special parameter ("gort") can be appended to the URL to request uncompiled client source files, making problems +much easier to debug: + + http://localhost:8088/?gort=debug + +However, the "gort=debug" parameter is unnecessary if the server was started with `--debug`; the server always +serves uncompiled files when running in "debug" mode. + +Conversely, if the server is running "debug" mode but you want to test a compiled version of PCjs, use: + + http://localhost:8088/?gort=release + +and the server will serve compiled JavaScript files, regardless whether the server is running in "debug" or "release" +mode. + +Updating PCjs +--- + +### Developing + +To start developing features for a new version of PCjs, here are the recommended steps: -1. Save the current production environment ("pcjs-env") as configuration "pcjs-config" -2. Create a new environment ("pcjs-dev") using the "pcjs-config" configuration -3. Wait for the new environment ("pcjs-dev") to start (ie, for its health to become "Green") -4. From Terminal, go to the `~/Sites/pcjs` folder and run `eb branch` followed by `git aws.push` +1. Change the version number in [package.json](/package.json) +2. Run the "grunt promote" task to bump the version in all machine XML files +3. Make changes +4. Run "grunt" to build new versions of the apps (eg, "/versions/pcjs/1.xx/pc.js") -The `eb branch` command will display: +However, you may want to skip step #2 until you're ready to start testing the new version. Depending on the nature +of your changes, it may be better to manually edit the version number in only a few machine XML files for testing, +leaving the rest of the XML files pointing to the previous version. Run "grunt promote" when the new version is much +closer to being released. - The current branch is "node_dev". - Enter an AWS Elastic Beanstalk environment name (auto-generated value is "pcjs-nodedev-env"): pcjs-dev - Do you want to copy the settings from environment "pcjs-env" for the new branch? [y/n]: y - -after which we're ready for `git aws.push` to the new "pcjs-dev" environment. +### Testing -See the "[Develop, Test, and Deploy](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_nodejs.sdlc.html)" -AWS documentation for more details. +In the course of testing PCjs, there may be stale "index.html" files that prevent you from seeing application +updates, changes to README.md files, etc. So, before running Node, you may want to "touch" the default HTML template: -On a local machine, the process is similar. If this is a "virgin" machine, you must first install Node and NPM; -see my notes on "[Installing Node (and NPM)](/my_modules/#installing-node-and-npm)" for more details. - -Then install and run the PCjs web server files: - - [iMac:~/Sites] git clone git@github.com:jeffpar/jsmachines.git pcjs - [iMac:~/Sites] cd pcjs - [iMac:~/Sites/pcjs] git checkout node_dev - [iMac:~/Sites/pcjs] npm install --production - [iMac:~/Sites/pcjs] export PORT=8086 (this is optional) - [iMac:~/Sites/pcjs] node server.js - -For a machine that is simply out-of-date, you can do something like this: - - [iMac:~/Sites/pcjs] git pull - [iMac:~/Sites/pcjs] npm update --production - [iMac:~/Sites/pcjs] export PORT=8086 (this is optional) - [iMac:~/Sites/pcjs] node server.js - -In the second scenario, there may be stale "index.html" files that prevent you from seeing the latest versions -of everything, so before running Node, you may want to do this first: - - [iMac:~/Sites/pcjs] touch my_modules/shared/templates/common.html + touch my_modules/shared/templates/common.html The [HTMLOut](/my_modules/htmlout/) module compares the timestamp of that template file to the timestamp of any -"index.html" and will regenerate the latter if it's out-of-date. There's a TODO to expand that check to include -the timestamp of any local README.md file, but there are many other factors that contribute to stale "index.html" -files, so the safest thing to do is touch the [common.html](/my_modules/shared/templates/common.html) template, -or delete all existing "index.html" files -- either by hand, or by using: +"index.html" and will regenerate the latter if it's out-of-date. - [iMac:~/Sites/pcjs] grunt clean - -However, if you included "--production" in your NPM install/update commands, you won't have the necessary grunt -task files. You may not even have grunt itself installed, unless you've previously run: +There's a TODO to expand that check to include the timestamp of any local README.md file, but there are many other +factors that can contribute to stale "index.html" files, so usually the safest thing to do is "touch" the +[common.html](/my_modules/shared/templates/common.html) template, or delete all existing "index.html" files, either +manually or with the Grunt "clean" task: - [iMac:~/Sites/pcjs] sudo npm install grunt-cli -g - -Stale "index.html" files may be a non-issue on AWS, because it appears to create a completely new directory -structure when it rebuilds the environment following a `git aws.push` -- but I'm not sure that's always true. + grunt clean diff --git a/my_modules/README.md b/my_modules/README.md index 6921a49f5..1c17a1705 100644 --- a/my_modules/README.md +++ b/my_modules/README.md @@ -1,649 +1,7 @@ Private Node Modules === -**my_modules** contains all the *private* **JSMachines** Node modules. It is the counterpart to +**my_modules** contains all the *private* **PCjs** Node modules. It is the counterpart to **node_modules**, where all the *public* Node modules are installed. Only private Node modules are checked -into GitHub; if we later decide to publish any or all of these on [npmjs.org](http://npmjs.org), then they will +into GitHub; if any of these are later published on [npmjs.org](http://npmjs.org), then they will be moved to **node_modules** and removed from this folder. - -The rest of this file documents some of the early steps involved in porting the **JSMachines** project, -which required a web server running PHP, to the new **PCjs** web server running Node. That includes setting up -my first Node web server and then extending its functionality with these private Node modules. - -For more details on the private Node modules stored here, refer to the README.md for each module (which, alas, -may be nothing more than placeholders at this point, but I have good intentions). - -Creating My First Node Project -=== - -Plan A: Fork jsmachines.net -> pcjs.org ---- -The original **JSMachines** project assumed a web server running PHP -(eg, [http://jsmachines.net](http://jsmachines.net)). However, to improve client-server integration, reduce -the number of languages/frameworks used, and implement some new features, such as socket-based disk I/O interfaces, -I decided to create a fork, **PCjs**, and port all the server-side PHP to JavaScript, running on a Node web server. - -Unfortunately, when I tried to fork my private **JSMachines** project on GitHub, I discovered that you're -not allowed to [fork](https://help.github.com/articles/fork-a-repo) your own projects. Adding to the confusion: GitHub -displays the "Fork" button on my project's home page, and even lets me click it, but then quietly does nothing. - -The recommended work-around (as per [this post](http://bitdrift.com/post/4534738938/fork-your-own-project-on-github)) -seemed to be: - -- Create new project on GitHub -- Clone old project with new name -- Replace new project's "origin URL" with URL for new GitHub project -- Add original project as an "upstream source" -- Push new project to GitHub - -Plan B: Branch jsmachines -> node_dev ---- -The above seemed a bit clunky, so I decided to branch instead of fork. This new development branch was called -**node_pcjs**, but I've since branched to **node_dev**. I should probably remove the original **node_pcjs** branch, -but for now, it's still there. - -Then I pushed the **node_dev** branch to the remote, as per [GitHub](https://help.github.com/articles/pushing-to-a-remote): - - [~/Sites/jsmachines] git push origin node_dev - Total 0 (delta 0), reused 0 (delta 0) - To git@github.com:jeffpar/jsmachines.git - * [new branch] node_dev -> node_dev - [~/Sites/jsmachines] - -That seemed to work fine, so I then created a new folder and cloned the project, as per -[GitHub](https://help.github.com/articles/fetching-a-remote): - - [~/Sites] git clone git@github.com:jeffpar/jsmachines.git pcjs - Cloning into 'pcjs'... - remote: Reusing existing pack: 2725, done. - remote: Total 2725 (delta 0), reused 0 (delta 0) - Receiving objects: 100% (2725/2725), 59.48 MiB | 2.67 MiB/s, done. - Resolving deltas: 100% (1543/1543), done. - Checking connectivity... done - -Then I checked-out the new branch: - - [~/Sites] cd pcjs - [~/Sites/pcjs] git checkout node_dev - Branch node_dev set up to track remote branch node_dev from origin. - Switched to a new branch 'node_dev' - -If I have to make any changes to the "master" branch (ie, the original jsmachines project) in the interim, -then after I've pushed those changes to GitHub, I can pull them into the **node_dev** branch like so: - - [~/Sites/pcjs] git pull origin master - -Installing Node (and NPM) ---- -I downloaded the latest Node installation package for my MacBook from [nodejs.org](http://nodejs.org/), -which provided the usual `node` and `npm` commands. Here are the versions they reported: - - [~/Sites/pcjs] node -v - v0.10.26 - [~/Sites/pcjs] npm -v - 1.4.3 - -I also installed a Node helper on my MacBook called `n` that makes it easy to keep Node up-to-date, per this tip on -[stackoverflow](http://stackoverflow.com/questions/8191459/how-to-update-node-js-npm-and-all-other-dependencies): - -1) Clear NPM's cache: - - [~/Sites/pcjs] sudo npm cache clean -f - -2) Install a little helper called 'n': - - [~/Sites/pcjs] sudo npm install -g n - -3) Install latest stable NodeJS version: - - [~/Sites/pcjs] sudo n stable - -Alternatively pick a specific version and install like so: - - [~/Sites/pcjs] sudo n 0.8.20 - -I'm not sure I like the generic name for this command ("n"); what would have been wrong with "node-update" -or "update-node"? Oh well. - -Next, I wanted to make sure `npm` was up-to-date. According to -[FAQ on npmjs.org](https://npmjs.org/doc/faq.html#How-do-I-update-npm), that's as easy as: - - [~/Sites/pcjs] sudo npm update npm -g - -although occasionally `npm` won't be able to update itself, in which case the fallback is: - - [~/Sites/pcjs] curl https://npmjs.org/install.sh | sh - -So, I made sure `npm` itself, along with `n` and all my other globally installed packages, were up-to-date, -and then I used `n` to make sure I was running the latest stable version of Node: - - [~/Sites/pcjs] sudo npm update -g - [~/Sites/pcjs] sudo n stable - [~/Sites/pcjs] node -v - v0.10.26 - -I've also seen suggestions to run this command before the preceding commands, but I don't know how often this is -recommended: - - [~/Sites/pcjs] sudo npm cache clean -f - -Next, I ran `npm init`: - - [~/Sites/pcjs] npm adduser - Username: jeffpar - Password: - Email: (this IS public) jeff@pcjs.org - npm http PUT http://registry.npmjs.org/-/user/org.couchdb.user:jeffpar - npm http 201 http://registry.npmjs.org/-/user/org.couchdb.user:jeffpar - - [~/Sites/pcjs] npm init - This utility will walk you through creating a package.json file. - It only covers the most common items, and tries to guess sane defaults. - - See `npm help json` for definitive documentation on these fields - and exactly what they do. - - Use `npm install --save` afterwards to install a package and - save it as a dependency in the package.json file. - - Press ^C at any time to quit. - name: (pcjs) - version: (0.0.0) 0.1.0 - description: Node-enabled version of PCjs - entry point: (server.js) - test command: - git repository: (git://github.com/jeffpar/jsmachines.git) - keywords: pcjs,ibm pc,emulator - author: Jeff Parsons - license: (ISC) - About to write to /Users/Jeff/Sites/pcjs/package.json: - - { - "name": "pcjs", - "version": "0.1.0", - "description": "Node-enabled version of PCjs", - "main": "server.js", - "directories": { - "doc": "docs", - "test": "tests" - }, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "git://github.com/jeffpar/jsmachines.git" - }, - "keywords": [ - "pcjs", - "ibm", - "pc", - "emulator" - ], - "author": "Jeff Parsons ", - "license": "ISC", - "bugs": { - "url": "https://github.com/jeffpar/jsmachines/issues" - }, - "homepage": "https://github.com/jeffpar/jsmachines" - } - - Is this ok? (yes) - -Next, I installed `express` using `npm install --save express`: - - [~/Sites/pcjs] npm install --save express - npm http GET http://registry.npmjs.org/express - ... - express@3.4.8 node_modules/express - ├── methods@0.1.0 - ├── merge-descriptors@0.0.1 - ├── range-parser@0.0.4 - ├── cookie-signature@1.0.1 - ├── fresh@0.2.0 - ├── debug@0.7.4 - ├── buffer-crc32@0.2.1 - ├── cookie@0.1.0 - ├── mkdirp@0.3.5 - ├── commander@1.3.2 (keypress@0.1.0) - ├── send@0.1.4 (mime@1.2.11) - └── connect@2.12.0 (uid2@0.0.3, pause@0.0.1, qs@0.6.6, bytes@0.2.1, raw-body@1.1.2, batch@0.5.0, negotiator@0.3.0, multiparty@2.2.0) - -This added the following lines to my "package.json" file: - - "dependencies": { - "express": "~3.4.8" - } - -Then I created a test "server.js" in the root of the project: - - var http = require("http"); - var express = require("express"); - var app = express(); - app.get("/", function(req, res) { - res.end("Testing"); - }); - http.createServer(app).listen(3000); - -and ran `node server.js` and verified that all was working as expected. - -Creating My First Node Module ---- -The first module I decided to write was a port of the diskconv.php script I'd written to convert disk images to/from -JSON. I decided to call this new module **DiskDump**, since it will output disk images in a variety of formats, although -initially only as JSON. - - [~/Sites/pcjs/my_modules] mkdir diskdump - [~/Sites/pcjs/my_modules] cd diskdump - [~/Sites/pcjs/my_modules/diskdump] npm init - This utility will walk you through creating a package.json file. - It only covers the most common items, and tries to guess sane defaults. - - See `npm help json` for definitive documentation on these fields - and exactly what they do. - - Use `npm install --save` afterwards to install a package and - save it as a dependency in the package.json file. - - Press ^C at any time to quit. - name: (diskdump) - version: (0.0.0) 0.1.0 - description: Convert disk images to/from JSON - entry point: (index.js) - test command: - git repository: - keywords: - author: Jeff Parsons - license: (ISC) - About to write to /Users/Jeff/Sites/pcjs/my_modules/diskdump/package.json: - - { - "name": "diskdump", - "version": "0.1.0", - "description": "Convert disk images to/from JSON", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Jeff Parsons ", - "license": "ISC" - } - - Is this ok? (yes) - -Next, I followed the steps outlined [here](http://www.anupshinde.com/posts/how-to-create-nodejs-npm-package/) to -create a package skeleton with a CLI (command-line interface). - -Filtering Web Server Requests ---- -The next module I created was [HTMLOut](/my_modules/htmlout/), which provides a filter() function for the Express module, -taking an early crack at the server's HTTP requests. - -If the request is for a directory, **HTMLOut** builds an "index.html" from a common HTML template file, and then saves -the file in that directory, so that future requests can be served by the Express static() function. The HTML template -file can specify a variety of replacement tokens, including a reference to a "README.md" file in the same directory, -which **HTMLOut** will load and pass to the private **MarkOut** Node module for conversion from Markdown to HTML. - -Similarly, if the URL is an API request, **HTMLOut** will direct the request to the appropriate private Node module -(eg, **DiskDump** or **FileDump**). - -What's The Right Way To Incorporate Node Module Fixes? ---- -My current version of Express was 3.4.8, and looking at its dependencies in package.json, it wanted "fresh" v0.2.0. - -Unfortunately, there seemed to be a problem with Safari and that version of "fresh", occasionally resulting in -blank pages, as discussed [here](http://stackoverflow.com/questions/18811286/nodejs-express-cache-and-304-status-code): - - Safari sends Cache-Control: max-age=0 on reload. Express (or more specifically, Express's dependency, node-fresh) - considers the cache stale when Cache-Control: no-cache headers are received, but it doesn't do the same for - Cache-Control: max-age=0. - -Further investigation revealed that [node-fresh](https://github.com/visionmedia/node-fresh) v0.2.1 added a fix for -that problem. But what was the right (or best) way to incorporate that fix into my local Express installation? - -I decided to hand-edit the "fresh" dependency in Express' package.json and then run "npm update" in the Express folder. -That pulled in the newer "fresh" module. But I noticed that other modules that Express depends on include their OWN -version of "fresh", which were also locked at v0.2.0. Even after creating an "npm-shrinkwrap.json" and hand-editing -it, "npm update" refused to upgrade them from v0.2.0. I could edit the package.json files in each of the Express -"connect" and "send" folders, run "npm update" in those folders, and force v0.2.1 that way, but as soon as I ran another -"npm update" in the root, those folders reverted to v0.2.0 again. - -However, this all turned out to be moot. The "Cache-Control: max-age=0" work-around added to "fresh" v0.2.1 was later -backed-out in v0.2.2. And I discovered that the "blank page" problem went away at the same time I added trailing-slash -redirects (see below), so there was likely a connection. The underlying issue with Safari is discussed in more detail -[here](https://github.com/visionmedia/node-fresh/issues/8); it seems likely the problem wasn't related to "fresh" after all. - -Problems With Directory URLs and Slashes ---- -I discovered that I needed to install "express-slash", enable Express "strict routing", and make HTMLOut.filter() -pass on directory requests that didn't include a trailing slash, so that the Node web server could call slash() and -trigger a trailing-slash redirect. This is apparently what apache's "mod_dir" module does automatically, and why -I never had a problem with apache. Without trailing slashes on directories, client-side requests for files relative to -those "slash-less" directories can fail. More details on this issue can be found in [htmlout.js](htmlout/lib/htmlout.js). - - npm install express-slash --save - -Moving from Make to Grunt ---- -Step 1: - - sudo npm install grunt-cli -g - -Step 2: - - npm install grunt --save-dev - -which automatically adds the following to my package.json: - - "devDependencies": { - "grunt": "^0.4.3" - } - -Step 3: Create a basic Gruntfile.js: - - module.exports = function(grunt) { - grunt.initConfig({ - }); - grunt.registerTask("default", []); - }; - -Step 4: Install some grunt modules; eg: - - npm install grunt-contrib-uglify --save-dev - -Step 5: Add a task (eg, uglify): - - module.exports = function(grunt) { - grunt.initConfig({ - uglify: { - dist: { - src: "dist/myfile.js", - dest: "dist/myfile.min.js" - } - } - }); - grunt.loadNpmTasks("grunt-contrib-uglify"); - grunt.registerTask("default", ["uglify"]); - }; - -However, while all of the above is a very nice example, I'm not really interested in uglify. - -I use Google's Closure Compiler, so I needed to do this instead: - - npm install grunt-closure-tools --save-dev - -There was also an NPM module called "grunt-closure-compiler", but it hadn't been updated as recently, and from -the examples it provided, it wasn't clear that it included support for all the Closure Compiler options, like -"output_wrapper", so I went with "grunt-closure-tools", even though it also contains support for other tools that -I'm not currently using. - -So now my package.json includes: - - "devDependencies": { - "grunt": "^0.4.3", - "grunt-closure-tools": "^0.9.4" - } - -Optional Node Modules -=== - -replace ---- -I use the Node "replace" module to perform project-wide search-and-replace operations on files; eg: - - node node_modules/replace/bin/replace.js '( "node node_modules/replace/bin/replace.js") instead of cluttering my system-level directories. - -Testing with Azure -=== -> NOTE: I've since abandoned Azure in favor of AWS Elastic Beanstalk, because Amazon's service has a simpler UI, -provides more control over the virtual machine environment (you can even log into the machine via SSH), and -the logging services for Node on AWS are more reliable. I also wrote a short [blog post](/blog/2014/03/30/) -on some of my frustrations with Azure. - -I subscribed to Azure (formerly Windows Azure, now [Microsoft Azure](http://azure.microsoft.com/)), and started -watching this YouTube video "[Lightning nodejs dev in Windows Azure](http://www.youtube.com/watch?v=WbtV1bX_m2I)" -by Glenn Block ([@gblock](http://twitter.com/gblock)). I was glad to see that he used a Mac, because a number of -other Azure videos on Youtube were made using Windows. - -The first recommendation was to install the "azure-cli" command-line tools: - - sudo npm install azure-cli -g - -To display available commands: - - azure - -To connect the command-line tools to my Azure account (after setting my default browser to Chrome, since I used -Chrome to set up my Azure account and browse the Azure portal): - - azure account download - -To import my acount info: - - azure account import ~/Downloads/Pay-As-You-Go-3-30-2014-credentials.publishsettings - -To create a site, the video recommends: - - azure site create pcjs --git - -However, I'm holding off until I understand how to link a new Azure site deployment with an existing GitHub repository, -as discussed [here](http://www.windowsazure.com/en-us/documentation/articles/web-sites-publish-source-control/), -because the above command appears intended for new project folders, which are then associated with a remote Azure-hosted -Git repository -- not what I need or want. - -The following command would show the remote Azure repository: - - git remote -v - -In my case, that command shows: - - origin git@github.com:jeffpar/jsmachines.git (fetch) - origin git@github.com:jeffpar/jsmachines.git (push) - -The following command would then be used to push updates to Azure: - - git push azure master - -Although in my case, I'm guessing it would be: - - git push origin master - -Or, rather: - - git push origin node_dev - -Since my local "pcjs" project is based on the **node_dev** branch. - -If I was using an Azure-hosted Git repository, I could then run: - - azure site browse - -because the `git push azure master` command would have triggered a website update. - -The video goes on to show how I can specify the version Node I want Azure to use, by adding the -following to my "package.json": - - "engines": { - "node": "0.8.x" - } - -This command: - - azure site deployment list - -will list all the deployments so far, any one of which can be redeployed like so: - - azure site deployment redeploy xxx - -The video finally gets that what I *really* care about, which is deploying via GitHub. This command -lists some of the commands we care about: - - azure site create --help - -To create a site from a repository on GitHub: - - azure site create pcjs --github - -JavaScript Coding Conventions -=== - -This is not intended to be an exhaustive list. It just lists a few things that came to mind, and I'll -probably update it over time. - -Tabs ---- -I've configured my IDE (PhpStorm) 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, so in those cases, I opt for smaller files and use real tabs. - -Moreover, most of the JavaScript delivered by a production server will have been pre-compiled by Google's -Closure Compiler, which completely eliminates all non-essential whitespace, so this is really 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 know that 2-column tab stops have -recently become "all the rage," especially in Node projects; NPM, for example, will rewrite package.json -files, replacing all the 4-column tabs with 2-column tabs, and I don't fight that trend -- I just ignore it. - -JSDoc ---- -I've taken a great deal of care to "[JSDoc](http://usejsdoc.org/)-ify" nearly all my JavaScript code, 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 Google's Closure Compiler and my IDE (PhpStorm) exactly what data -types are passed into/out of every function. 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", sometimes called "uglification"), every function and its parameters needs to -be fully typed; otherwise, the Compiler will generate WAY too many warnings/errors -- at least, that was the -case when I first started using it a couple of years ago. - -So, I've adopted a zero-tolerance policy for warnings: no check-ins allowed if the Closure Compiler generates -even a SINGLE warning. - -I'm not sure the [JSDoc](http://usejsdoc.org/) folks and the -[Closure Compiler](https://developers.google.com/closure/compiler/docs/js-for-compiler) are totally in sync on -everything. And then there's [PhpStorm](http://www.jetbrains.com/phpstorm/webhelp/creating-jsdoc-comments.html), -whose code inspections occasionally fail; sometimes a bogus code inspection warning can be fixed with some -additional JSDoc @name or @class annotations, but not always. - -In any case, the subset of variable and function type declarations I use works pretty well across the board; -code inspection warnings are allowed in the IDE, as long as they are clearly erroneous (or clearly innocuous). - -Braces, Parentheses, etc. ---- -Most of my 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 of my opening parentheses are also preceded by a single space, -except when following "function" or a function name, in which case there is NO space. This is just an historical -preference, dating back to my BASIC and C programming days; it's not that those preferences matter anymore, it's just -that I see no reason to change them. - -I'm not obsessed with these conventions. Sometimes, for example, I'll write a bunch of code where the opening -brace of every function body begins underneath the "function" keyword, because the extra whitespace can make the -file a bit more readable. It may sometimes depend on my mood, but I do try to be consistent within a given file -at least. - -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. I know lots of people sneer at -those conventions and think they're useless, and all I can say is, they're wrong: they are not useless to ME. -I admit they may be useless to anyone who has a phenomenal memory and can remember that an obscure variable named -"foo" was initialized with a string or a number, or who has an IDE that can answer that question with the press -of a key (or two), but for me, with my non-phenomenal memory and lazy fingers, I prefer being able to simply -look at a variable to immediately know what *type* of data it contains, if nothing else. - -I rarely name a string or numeric variable something vague like "foo." At worst, I would name it "sFoo" if it -was a string or "iFoo" if it was a number (or possibly "nFoo" or "cFoo" if it represented a total of Foos or a -counter of Foos). And if a string or numeric variable has a very short-term use, I often just call it "s" or "i" -(or "n"). - -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, these letter prefixes like "s" and "n" are irrelevant if you already give your variables meaningful -names like "nameOfPerson" or "numberOfPeople". And that's fine -- I do that sometimes, too. 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 about Arrays though: I prefix array variables -with "a", arrays of strings and numbers with "as" and "ai" (or "an"), and arrays of arrays with "aa". As for Arrays -of anything else, I usually don't bother with anything more than an "a" prefix. - -Quotation Marks ---- -Coming from a long 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 knowingly deals with -single characters, I like to reinforce that distinction with single quotes. - -Also, to emphasize that an object property name isn't really a string, I tend to use single quotes around property -names as well. I realize that the JSON standard insists on property names with double-quotes, but functions like -JSON.stringify() take care of that for us -- besides, I find that aspect of the JSON standard to be rather annoying -(not to mention JSON's disapproval of comments). - -Obviously, it's possible to set and get object properties without any quotes at all, as in: - - obj.prop = true; - -instead of: - - obj['prop'] = true; - -but that works only if the property name conforms to the same syntax that variable names use. Also, the "dot" -syntax can create problems for code compiled with Google's Closure Compiler (using ADVANCED_OPTIMIZATIONS), -because it likes to rename "dot" property names to smaller "minified" property names. Which means if you -need to export your objects as JSON later, or if you ever need to access a property using an externally defined -string, you must avoid the "dot" syntax. - -However, if an object and all its properties are purely internal, there's usually no reason not to use it: - - obj = {foo: "old", modified: false}; - obj.foo = "new"; - obj.modified = true; - -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 was originally written 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, the -first restriction isn't true, and the second isn't even a feature of the language, so they have no bearing on the use -of single-quoted strings in JavaScript. - -Arrays ---- -In [this article](http://stackoverflow.com/questions/8668174/indexof-method-in-an-object-array), it's asserted, -without disagreement, that searching arrays of objects for a particular object is best performed with code that looks -like this: - - pos = myArray.map(function(e) { return e.hello; }).indexOf('stevie'); - -I disagree. Depending on how often that function is called, creating a new array by iterating over every element -of the original array, and doing that every time you want to search for an array object with a property (eg, `hello`) -equal to some value (eg, 'stevie'), is a bad idea; I don't care how fast your JavaScript engine is or how fantastic -your garbage collector is. - -My preferred approach is to create parallel arrays: one array for each property that you might want to search on, and -another array of objects that contain all the other object properties. Then searching doesn't involve creating new -arrays: - - pos = myArrayOfHello.indexOf('stevie'); - -Yes, it's not quite as *clean* as one, unified array of objects, and yes, it would be nicer if the JavaScript Array -class had better search methods, but I think this is the right trade-off given the current reality. \ No newline at end of file diff --git a/my_modules/htmlout/lib/htmlout.js b/my_modules/htmlout/lib/htmlout.js index e1d21c671..31eb2d18d 100644 --- a/my_modules/htmlout/lib/htmlout.js +++ b/my_modules/htmlout/lib/htmlout.js @@ -72,8 +72,8 @@ var fCache = true; var fConsole = false; /* - * fServerDebug controls debug console messages; it is false by default and can be enabled using the setOptions() - * 'debug' property (or from the command-line interface using "--debug"). + * fServerDebug controls server-related debug features; it is false by default and can be enabled using the + * setOptions() 'debug' property (or from the command-line interface using "--debug"). */ var fServerDebug = false; @@ -262,8 +262,11 @@ function HTMLOut(sDir, sFile, fRebuild, req, done) * of fDebug to simply never cache, instead of always rebuilding the cache. * * if (this.fDebug) this.fRebuild = true; + * + * Note that a production server should not need the GORT_REBUILD command, so we accept + * it only if fServerDebug is true. */ - if (net.hasParm(net.GORT_COMMAND, net.GORT_REBUILD, req)) { + if (fServerDebug && net.hasParm(net.GORT_COMMAND, net.GORT_REBUILD, req)) { req.query[net.GORT_COMMAND] = undefined; this.fRebuild = true; } @@ -887,9 +890,15 @@ HTMLOut.prototype.getVersion = function(sToken, sIndent, aParms) { /* * Use the same test that processMachines() uses for setting fCompiled: if we're not using compiled code, - * then we should be using "current" CSS and template files (as opposed to version-specific template files) as well. + * then we should be using "current" CSS and template files (as opposed to version-specific template files). + * + * NOTE: I used to create a symlink in each app's "versions" directory (eg, /versions/pcjs/current -> + * ../../my_modules/shared/templates), so that when fDebug was true, I could simply insert "current" in + * place of a version number. However, that symlink didn't get added to the repository, and I'm not sure + * all operating systems would deal with it properly even if was added, so now I'm treating the "version" + * token as the equivalent of a symlink here. */ - this.aTokens[sToken] = this.fDebug? "current" : pkg.version; + this.aTokens[sToken] = this.fDebug? "../../my_modules/shared/templates" : pkg.version; }; /** @@ -1432,6 +1441,8 @@ HTMLOut.prototype.getManifestXML = function(sToken, sIndent, aParms) case "default": sDefault = matchParams[2]; break; + default: + break; } } if (sLabel) { diff --git a/my_modules/markout/lib/markout.js b/my_modules/markout/lib/markout.js index d9df54e80..47c726e58 100644 --- a/my_modules/markout/lib/markout.js +++ b/my_modules/markout/lib/markout.js @@ -386,6 +386,7 @@ MarkOut.prototype.convertMD = function(sIndent) */ var aMatch; var re = /(^|\n)( ? ?)([\*+-]|[0-9]+\.)([^\n]*\n)([ \t]+[^\n]*\n|\n)+([ \t]+[^\n]+)/g; + //noinspection UnnecessaryLocalVariableJS var sMDOrig = sMD; while ((aMatch = re.exec(sMDOrig))) { var sReplace = aMatch[0].replace(/\n\n/g, "\n\t\n"); diff --git a/my_modules/pcjs-client/lib/README.md b/my_modules/pcjs-client/lib/README.md index 9db068b7d..52812990f 100644 --- a/my_modules/pcjs-client/lib/README.md +++ b/my_modules/pcjs-client/lib/README.md @@ -6,12 +6,12 @@ Structure All the code for PCjs is contained in the following JavaScript files, which roughly divide the functionality into major PC components, aka "devices". However, not every file implements a device, and "component" is an overloaded term, since *[Component](/docs/pcjs/component/)* is also the name of -the shared base class used for most PCjs objects (see [component.js](../../shared/lib/component.js)). +the shared base class used for most PCjs devices (see [component.js](../../shared/lib/component.js)). So it's best to refer to these files generically as "modules", and more specifically as "device modules" whenever they implement a specific device (or set of devices, in the case of [*Chipset*](/docs/pcjs/chipset/)). Examples of non-device modules include UI modules like [panel.js](panel.js) and [debugger.js](debugger.js), -and sub-modules like [x86code.js](x86code.js), [x86mode.js](x86mode.js) and [x86help.js](x86help.js) +and sub-modules like [x86opxx.js](x86opxx.js), [x86mods.js](x86mods.js) and [x86help.js](x86help.js) that separate the CPU functionality of [x86.js](x86.js) into more manageable pieces. These modules should always be loaded or compiled in the order listed by the *pcJSFiles* property in @@ -32,11 +32,14 @@ At the time of this writing, the order is: * [pcjs-client/bus.js](bus.js) * [pcjs-client/mem.js](mem.js) * [pcjs-client/cpu.js](cpu.js) -* [pcjs-client/x86defs.js](x86defs.js) -* [pcjs-client/x86help.js](x86help.js) -* [pcjs-client/x86code.js](x86code.js) -* [pcjs-client/x86mode.js](x86mode.js) * [pcjs-client/x86.js](x86.js) +* [pcjs-client/x86seg.js](x86seg.js) +* [pcjs-client/x86cpu.js](x86cpu.js) +* [pcjs-client/x86grps.js](x86grps.js) +* [pcjs-client/x86help.js](x86help.js) +* [pcjs-client/x86mods.js](x86mods.js) +* [pcjs-client/x86op0f.js](x86op0f.js) +* [pcjs-client/x86opxx.js](x86opxx.js) * [pcjs-client/chipset.js](chipset.js) * [pcjs-client/rom.js](rom.js) * [pcjs-client/ram.js](ram.js) @@ -55,16 +58,10 @@ At the time of this writing, the order is: Some of the modules *can* be reordered or even omitted (eg, [debugger.js](debugger.js) or [embed.js](../../shared/lib/embed.js)), but you should observe the following: -* [component.js](../../shared/lib/component.js) should be listed before any module that extends [*Component*](/docs/pcjs/component/) +* [component.js](../../shared/lib/component.js) must be listed before any module that extends [*Component*](/docs/pcjs/component/) * [panel.js](panel.js) should be loaded early to initialize the Control Panel (if any) as soon as possible * [computer.js](computer.js) should be the last device module, as it supervises and notifies all the other device modules To minimize ordering requirements, the init() handlers and constructors of all modules should avoid referencing other modules. Device modules should define an initBus() notification handler, which the [*Computer*](/docs/pcjs/computer/) will call after it has created/initialized the *Bus* object. - -What's Next ---- -EGA support. I've added the infrastructure for EGA I/O operations, but there's no "meat" yet. All the EGA -code is in [video.js](video.js), alongside the CGA and MDA support, but EGA functionality is pretty isolated; you have -to set the "model" attribute of the video component to "ega" to enable it. diff --git a/my_modules/pcjs-client/lib/chipset.js b/my_modules/pcjs-client/lib/chipset.js index 51249863c..2ea65d0e6 100644 --- a/my_modules/pcjs-client/lib/chipset.js +++ b/my_modules/pcjs-client/lib/chipset.js @@ -1713,12 +1713,14 @@ ChipSet.prototype.toggleSwitch = function(control) var asParts = sID.split("-"); var b = (0x1 << (parseInt(asParts[1], 10) - 1)); switch (asParts[0]) { - case "sw1": - this.sw1Init = (this.sw1Init & ~b) | (f? 0 : b); - break; - case "sw2": - this.sw2Init = (this.sw2Init & ~b) | (f? 0 : b); - break; + case "sw1": + this.sw1Init = (this.sw1Init & ~b) | (f? 0 : b); + break; + case "sw2": + this.sw2Init = (this.sw2Init & ~b) | (f? 0 : b); + break; + default: + break; } this.updateSwitchDesc(); }; diff --git a/my_modules/pcjs-client/lib/defines.js b/my_modules/pcjs-client/lib/defines.js index b07fbd6ac..243c97866 100644 --- a/my_modules/pcjs-client/lib/defines.js +++ b/my_modules/pcjs-client/lib/defines.js @@ -72,34 +72,37 @@ var PREFETCH = false; /** * @define {boolean} * - * FASTDISABLE turns on memory-function switching to dynamically disable - * memory accesses whenever the CPU wants to disable spurious memory reads - * (or stale memory writes, which are worse). If FASTDISABLE is false, then - * the code falls back to setting/testing internal OP_NOREAD and OP_NOWRITE - * CPU opFlags as needed. + * FASTDISABLE turns on memory-function switching to dynamically disable memory accesses whenever the CPU wants + * to disable spurious memory reads (which are mostly harmless) or stale memory writes (which tend to be destructive + * and are NOT mostly harmless). * - * At the moment, it seems that FASTDISABLE is a bit slower than relying on - * the OP_NOREAD/OP_NOWRITE flags, so it's turned off. + * If FASTDISABLE is false, then the code falls back to setting/testing internal OP_NOREAD and OP_NOWRITE opFlags + * as needed. + * + * At the moment, it seems that FASTDISABLE is a bit slower than relying on the OP_NOREAD/OP_NOWRITE flags, so it's + * turned off; apparently, I was a bit too optimistic calling it "FAST". But your mileage may vary, depending on the + * browser and its version. * - * See the Bus component for details. + * See the X86CPU component for details, since it is the CPU, not the underlying Bus or Memory components, that needs + * to be able to do this. */ var FASTDISABLE = false; /** * @define {boolean} * - * FATARRAYS is a Closure Compiler compile-time option that allocates 1 number per byte - * for Memory blocks; wasteful, but slightly faster. + * FATARRAYS is a Closure Compiler compile-time option that allocates 1 number per byte for Memory blocks; + * wasteful, but potentially slightly faster. * * See the Memory component for details. */ var FATARRAYS = false; /** - * TYPEDARRAYS enables use of typed arrays for Memory blocks. This used to be a compile-time - * option, but since I've added memory access functions for typed arrays (see Memory.afnTArray), - * I can turn the support on dynamically now. Originally, I didn't see much of a speed increase - * over the original (non-typed) implementation, but that will probably change over time. + * TYPEDARRAYS enables use of typed arrays for Memory blocks. This used to be a compile-time * option, but since I've + * added memory access functions for typed arrays (see Memory.afnTArray), I can turn the support on dynamically now. + * Originally, I didn't see much of a speed increase over the original (non-typed) implementation, but that will probably + * change over time. * * See the Memory component for details. */ diff --git a/my_modules/pcjs-client/lib/mouse.js b/my_modules/pcjs-client/lib/mouse.js index ab9234ddc..a490ae623 100644 --- a/my_modules/pcjs-client/lib/mouse.js +++ b/my_modules/pcjs-client/lib/mouse.js @@ -439,20 +439,22 @@ Mouse.prototype.clickMouse = function(iButton, fDown) { if (this.isActive()) { var sDiag; switch (iButton) { - case 0: - if (this.fButton1 != fDown) { - this.fButton1 = fDown; - sDiag = DEBUGGER ? ("mouse button1 " + (fDown ? "dn" : "up")) : null; - this.sendPacket(sDiag); - } - break; - case 2: - if (this.fButton2 != fDown) { - this.fButton2 = fDown; - sDiag = DEBUGGER ? ("mouse button2 " + (fDown ? "dn" : "up")) : null; - this.sendPacket(sDiag); - } - break; + case 0: + if (this.fButton1 != fDown) { + this.fButton1 = fDown; + sDiag = DEBUGGER ? ("mouse button1 " + (fDown ? "dn" : "up")) : null; + this.sendPacket(sDiag); + } + break; + case 2: + if (this.fButton2 != fDown) { + this.fButton2 = fDown; + sDiag = DEBUGGER ? ("mouse button2 " + (fDown ? "dn" : "up")) : null; + this.sendPacket(sDiag); + } + break; + default: + break; } } }; diff --git a/my_modules/pcjs-client/lib/serial.js b/my_modules/pcjs-client/lib/serial.js index d078987b3..6176804a2 100644 --- a/my_modules/pcjs-client/lib/serial.js +++ b/my_modules/pcjs-client/lib/serial.js @@ -316,6 +316,9 @@ SerialPort.prototype.setBinding = function(sHTMLClass, sHTMLType, sBinding, cont serial.sendRBR([charCode]); }; return true; + + default: + break; } return false; }; diff --git a/my_modules/pcjs-client/lib/video.js b/my_modules/pcjs-client/lib/video.js index 114d3a447..4475b0f2c 100644 --- a/my_modules/pcjs-client/lib/video.js +++ b/my_modules/pcjs-client/lib/video.js @@ -3158,6 +3158,8 @@ Video.prototype.getAccess = function() case Card.GRC.DATAROT.XOR: nWriteAccess = Card.ACCESS.WRITE.MODE0XOR; break; + default: + break; } card.nDataRotate = regDataRotate & Card.GRC.DATAROT.COUNT; } @@ -3463,6 +3465,8 @@ Video.prototype.checkMode = function(fForce) card.sizeBuffer = cbBufferText; nMode = (this.nMonitorType == ChipSet.MONITOR.MONO? Video.MODES.CGA_80X25_BW : Video.MODES.CGA_80X25); break; + default: + break; } var fSEQDotClock = (card.aSEQRegs[Card.SEQ.CLK.INDX] & Card.SEQ.CLK.DOTCLOCK); @@ -4532,6 +4536,8 @@ Video.prototype.outGRCData = function(port, bOut, addrFrom) case Card.GRC.BITMASK.INDX: this.cardEGA.nBitMapMask = bOut | (bOut << 8) | (bOut << 16) | (bOut << 24); break; + default: + break; } }; diff --git a/my_modules/pcjs-client/lib/x86help.js b/my_modules/pcjs-client/lib/x86help.js index ba2d5611c..da035f181 100644 --- a/my_modules/pcjs-client/lib/x86help.js +++ b/my_modules/pcjs-client/lib/x86help.js @@ -344,6 +344,8 @@ var X86Help = { case 0x7: // BH this.regBX = (this.regBX & 0xff) | (dst << 8); break; + default: + break; // there IS no other case, but JavaScript inspections don't know that } this.nStepCycles -= this.nOpCyclesXchgRR; } else { @@ -390,6 +392,8 @@ var X86Help = { case 0x7: // DI this.regDI = dst; break; + default: + break; // there IS no other case, but JavaScript inspections don't know that } this.nStepCycles -= this.nOpCyclesXchgRR; } else { diff --git a/my_modules/pcjs-client/lib/x86opxx.js b/my_modules/pcjs-client/lib/x86opxx.js index 06a728961..7a7730dfd 100644 --- a/my_modules/pcjs-client/lib/x86opxx.js +++ b/my_modules/pcjs-client/lib/x86opxx.js @@ -1807,43 +1807,47 @@ var X86OpXX = { case 0x7: // this form of MOV to DS is undocumented on 8086/8088/80186/80188, invalid on 80286 and up temp = this.regDI; break; + default: + break; } break; } X86Mods.aOpModsRegWord[bModRM].call(this, X86Help.opHelpMOV); switch (reg) { - case 0x0: - this.setES(this.regAX); - this.regAX = temp; - break; - case 0x1: - this.setCS(this.regCX); - this.regCX = temp; - break; - case 0x2: - this.setSS(this.regDX); - this.regDX = temp; - break; - case 0x3: - this.setDS(this.regBX); - this.regBX = temp; - break; - case 0x4: - this.setES(this.regSP); - this.regSP = temp; - break; - case 0x5: - this.setCS(this.regBP); - this.regBP = temp; - break; - case 0x6: - this.setSS(this.regSI); - this.regSI = temp; - break; - case 0x7: - this.setDS(this.regDI); - this.regDI = temp; - break; + case 0x0: + this.setES(this.regAX); + this.regAX = temp; + break; + case 0x1: + this.setCS(this.regCX); + this.regCX = temp; + break; + case 0x2: + this.setSS(this.regDX); + this.regDX = temp; + break; + case 0x3: + this.setDS(this.regBX); + this.regBX = temp; + break; + case 0x4: + this.setES(this.regSP); + this.regSP = temp; + break; + case 0x5: + this.setCS(this.regBP); + this.regBP = temp; + break; + case 0x6: + this.setSS(this.regSI); + this.regSI = temp; + break; + case 0x7: + this.setDS(this.regDI); + this.regDI = temp; + break; + default: + break; // there IS no other case, but JavaScript inspections don't know that } }, /**