C1Pjs is a simulation of the Challenger 1P micro-computer, a 6502-based system built by Ohio Scientific in the late 1970's. This simulation is implemented entirely in JavaScript, and it is built from the following files:
The Component file defines a generic Component object with some common functionality, and each of the other files copy and extend the Component object to define new components that simulate various pieces of computer hardware, such as the 6502 CPU, the keyboard, the video display, etc. Each file implements exactly one type of component, which are all "compiled" into a single JavaScript file using Google's Closure Compiler.
Most of the components are optional. You assemble them into a virtual machine by creating a virtual machine definition file, which is an XML file that lists the components to be used, along with the HTML elements that will visually represent those components, and all the "bindings" that connect the components to the visual elements.
Here are some working examples:
Here's what a machine definition XML file typically looks like:
?xml version="1.0" encoding="UTF-8"? ?xml-stylesheet type="text/xsl" href="/versions/c1pjs/1.12.1/machine.xsl"? machine id="c1psim" type="c1p" border="1" width="272px" name Challenger 1P Simulation /name computer id="c1p" name="Challenger 1P" module type="cpu" refid="cpu6502" start="0x0000" end="0xffff"/ module type="ram" refid="ram8K" start="0x0000" end="0x1fff"/ module type="rom" refid="romNull" start="0x2000" end="0x9fff"/ module type="rom" refid="romBasic" start="0xa000" end="0xbfff"/ module type="video" refid="video" start="0xd000" end="0xd3ff"/ module type="keyboard" refid="keyboard" start="0xdf00" end="0xdfff"/ module type="rom" refid="romSystem" start="0xf800" end="0xffff"/ /computer cpu id="cpu6502"/ ram id="ram8K" size="0x2000"/ rom id="romNull" size="0x8000"/ rom id="romBasic" size="0x2000" image="/devices/c1p/rom/basic-gcpatch.hex"/ rom id="romSystem" size="0x0800" image="/devices/c1p/rom/system.hex"/ video id="video" screenwidth="256" screenheight="192" cols="32" rows="32" charset="/devices/c1p/video/chargen1x.png" width="256px" padding="8px"/ keyboard id="keyboard" control type="button" binding="ctrl-c" CTRL-C /control control type="button" binding="ctrl-o" CTRL-O /control control type="button" binding="break" BREAK /control /keyboard /machine
The order of the components (and any controls they define) determines the order in which the corresponding HTML elements are laid out on the page. It has no bearing on the initialization sequence of the JavaScript components, which is determined entirely by the order in which the JavaScript files were "compiled" (or by the order the individual JavaScript files are listed on the page).
NOTE: If you're debugging a simulation using the browser's Developer Tools, then obviously you'll want to load the original, individual JavaScript files, but in general, you'll get much better performance -- both load-time and run-time -- by loading a single "compiled" JavaScript file.
Jeff Parsons
August 28, 2012