Updated aspect ratio for CGA configs and added experimental 'aspect' URL parameter
This commit is contained in:
parent
d0480ecb90
commit
d50f0ebb1a
44 changed files with 6634 additions and 318 deletions
|
|
@ -1,8 +1,26 @@
|
|||
PCjs Node Modules
|
||||
---
|
||||
layout: page
|
||||
title: PCjs Project Modules
|
||||
permalink: /modules/
|
||||
---
|
||||
|
||||
Project Modules
|
||||
===
|
||||
|
||||
This folder contains all the **PCjs** JavaScript source code, organized into Node modules. It is the counterpart to
|
||||
**node_modules**, where all the *public* Node modules are installed.
|
||||
This folder contains all the JavaScript source code for the PCjs Project, organized into Node modules.
|
||||
It is the counterpart to **node_modules**, where all the *public* Node modules are installed.
|
||||
|
||||
The project includes these Emulation Modules:
|
||||
|
||||
* C1Pjs, the 6502-based C1P Emulation Module
|
||||
* [PCjs](pcjs/), the x86-based IBM PC Emulation Module
|
||||
|
||||
along with variety of support modules, such as:
|
||||
|
||||
* [DiskDump](diskdump/)
|
||||
* [FileDump](filedump/)
|
||||
* [HTMLOut](htmlout/)
|
||||
* [MarkOut](markout/)
|
||||
|
||||
Only private Node modules are checked into this project. If any of these modules are later published on
|
||||
[npmjs.org](http://npmjs.org), then they will be moved to **node_modules** and removed from this folder.
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
---
|
||||
layout: page
|
||||
title: DiskDump
|
||||
title: DiskDump Module
|
||||
permalink: /modules/diskdump/
|
||||
---
|
||||
|
||||
DiskDump
|
||||
DiskDump Module
|
||||
===
|
||||
|
||||
**DiskDump** is a Node module with both a command-line interface and a web server API for converting disk images
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
---
|
||||
layout: page
|
||||
title: FileDump
|
||||
title: FileDump Module
|
||||
permalink: /modules/filedump/
|
||||
---
|
||||
|
||||
FileDump
|
||||
FileDump Module
|
||||
===
|
||||
|
||||
Module (and command-line utility) for converting the contents of files to JSON.
|
||||
This module (and command-line utility) is used to convert the contents of binary files to JSON.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
HTMLOut
|
||||
---
|
||||
layout: page
|
||||
title: HTMLOut Module
|
||||
permalink: /modules/htmlout/
|
||||
---
|
||||
|
||||
HTMLOut Module
|
||||
===
|
||||
|
||||
This module provides a filter() function for [server.js](../../../server.js),
|
||||
our Express-based web server. The function is installed like so:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
MarkOut
|
||||
---
|
||||
layout: page
|
||||
title: MarkOut Module
|
||||
permalink: /modules/markout/
|
||||
---
|
||||
|
||||
MarkOut Module
|
||||
===
|
||||
This modules transforms a subset of Markdown into HTML. It's used by the
|
||||
|
||||
This module transforms a subset of Markdown into HTML. It's used by the
|
||||
[HTMLOut](../htmlout) module to process README.md files and incorporate their
|
||||
contents into the "index.html" files that we generate when browsing directories.
|
||||
|
|
|
|||
113
modules/pcjs/README.md
Normal file
113
modules/pcjs/README.md
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
---
|
||||
layout: page
|
||||
title: IBM PC Emulation Module
|
||||
permalink: /modules/pcjs/
|
||||
---
|
||||
|
||||
IBM PC Emulation Module
|
||||
===
|
||||
|
||||
Structure
|
||||
---
|
||||
The PCjs IBM PC Emulation Module divides PC functionality into variety of logical and visual components.
|
||||
In general, each JavaScript file is responsible for a single component or set of related components (eg,
|
||||
[chipset.js](lib/chipset.js)). Most components represent familiar PC devices, such as video cards, disk
|
||||
controllers, etc.
|
||||
|
||||
*Component* is an overloaded term, since **Component** is also the name of the shared base class in
|
||||
[component.js](../shared/lib/component.js) used by most machine components. A few low-level components
|
||||
(eg, the **Memory** and **State** components, the Card class of the **Video** component, the Color and Rectangle
|
||||
classes of the **Panel** component, etc) do not extend **Component**, so don't assume that every PCjs object has
|
||||
access to [component.js](../shared/lib/component.js) methods.
|
||||
|
||||
Examples of non-device components include visual components like [panel.js](lib/panel.js) and
|
||||
[debugger.js](lib/debugger.js), and sub-components like [x86ops.js](lib/x86ops.js) and [x86func.js](lib/x86func.js),
|
||||
which separate the CPU functionality of [x86.js](lib/x86.js) into more manageable pieces.
|
||||
|
||||
These components should always be loaded or compiled in the order listed by the *pcJSFiles* property in
|
||||
[package.json](../../package.json), which includes all the necessary *shared* components as well.
|
||||
At the time of this writing, the recommended order is:
|
||||
|
||||
* [shared/defines.js](../shared/lib/defines.js)
|
||||
* [shared/diskapi.js](../shared/lib/diskapi.js)
|
||||
* [shared/dumpapi.js](../shared/lib/dumpapi.js)
|
||||
* [shared/reportapi.js](../shared/lib/reportapi.js)
|
||||
* [shared/userapi.js](../shared/lib/userapi.js)
|
||||
* [shared/strlib.js](../shared/lib/strlib.js)
|
||||
* [shared/usrlib.js](../shared/lib/usrlib.js)
|
||||
* [shared/weblib.js](../shared/lib/weblib.js)
|
||||
* [shared/component.js](../shared/lib/component.js)
|
||||
* [pcjs/defines.js](lib/defines.js)
|
||||
* [pcjs/x86.js](lib/x86.js)
|
||||
* [pcjs/interrupts.js](lib/interrupts.js)
|
||||
* [pcjs/messages.js](lib/messages.js)
|
||||
* [pcjs/panel.js](lib/panel.js)
|
||||
* [pcjs/bus.js](lib/bus.js)
|
||||
* [pcjs/memory.js](lib/memory.js)
|
||||
* [pcjs/cpu.js](lib/cpu.js)
|
||||
* [pcjs/x86seg.js](lib/x86seg.js)
|
||||
* [pcjs/x86cpu.js](lib/x86cpu.js)
|
||||
* [pcjs/x86fpu.js](lib/x86fpu.js)
|
||||
* [pcjs/x86func.js](lib/x86func.js)
|
||||
* [pcjs/x86help.js](lib/x86help.js)
|
||||
* [pcjs/x86mods.js](lib/x86mods.js)
|
||||
* [pcjs/x86ops.js](lib/x86ops.js)
|
||||
* [pcjs/x86op0f.js](lib/x86op0f.js)
|
||||
* [pcjs/chipset.js](lib/chipset.js)
|
||||
* [pcjs/rom.js](lib/rom.js)
|
||||
* [pcjs/ram.js](lib/ram.js)
|
||||
* [pcjs/keyboard.js](lib/keyboard.js)
|
||||
* [pcjs/video.js](lib/video.js)
|
||||
* [pcjs/parallelport.js](lib/parallelport.js)
|
||||
* [pcjs/serialport.js](lib/serialport.js)
|
||||
* [pcjs/mouse.js](lib/mouse.js)
|
||||
* [pcjs/disk.js](lib/disk.js)
|
||||
* [pcjs/fdc.js](lib/fdc.js)
|
||||
* [pcjs/hdc.js](lib/hdc.js)
|
||||
* [pcjs/debugger.js](lib/debugger.js)
|
||||
* [pcjs/state.js](lib/state.js)
|
||||
* [pcjs/computer.js](lib/computer.js)
|
||||
* [shared/embed.js](../shared/lib/embed.js)
|
||||
* [shared/save.js](../shared/lib/save.js)
|
||||
|
||||
Some of the components *can* be reordered or even omitted (eg, [debugger.js](lib/debugger.js) or
|
||||
[embed.js](../shared/lib/embed.js)), but you should observe the following:
|
||||
|
||||
* [component.js](../shared/lib/component.js) must be listed before any component that extends **Component**
|
||||
* [panel.js](lib/panel.js) should be loaded early to initialize the Control Panel (if any) as soon as possible
|
||||
* [computer.js](lib/computer.js) should be the last device component, as it supervises and notifies all the other device components
|
||||
|
||||
To minimize ordering requirements, the init() handlers and constructors of all components should avoid
|
||||
referencing other components. Device components should define an initBus() notification handler, which the
|
||||
*Computer* component will call after it has created/initialized the *Bus* component.
|
||||
|
||||
Features
|
||||
---
|
||||
|
||||
[List of major existing features goes here]
|
||||
|
||||
### BackTrack Support
|
||||
|
||||
One major PCjs feature is known as BackTrack Support, or simply BackTracks. When BackTracks are enabled, every
|
||||
memory location (at the byte level) and every general-purpose byte register may have an optional link back to its
|
||||
source. These links are called BackTrack indexes.
|
||||
|
||||
All the code that a virtual machine initially executes enters the machine either via ROM or disk sectors, and as that
|
||||
code executes, the machine is loading data into registers from memory locations and/or I/O ports and writing the results
|
||||
to other memory locations and/or I/O ports. BackTracks keep track of that data flow, allowing us to examine the history
|
||||
of any piece of data at any time, down to the byte level; while this feature could be extended to the bit level, it
|
||||
would make the feature dramatically more expensive, both in terms of size and speed.
|
||||
|
||||
A BackTrack index is encoded as a 32-bit value with three parts:
|
||||
|
||||
- Bits 0-8: 9-bit BackTrack object offset (0-511)
|
||||
- Bits 9-15: 7-bit type and access info
|
||||
- Bits 16-30: 15-bit BackTrack object number (1-32767, 0 reserved for dynamic data)
|
||||
|
||||
This represents a total of 31 bits, with bit 31 reserved.
|
||||
|
||||
For example, look at one of the last things a ROM does during boot: loading a disk sector into RAM. It will be up to the
|
||||
disk controller (or DMA controller, if used) to create a BackTrack object representing the sector that was read,
|
||||
adding that object to the global BackTrack object array, and then associating the corresponding BackTrack index with
|
||||
the first byte of RAM where the sector was loaded. Subsequent bytes of RAM containing the rest of the sector will refer
|
||||
to the same BackTrack object, using BackTrack indexes containing offsets 1-511.
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
PCjs Sources
|
||||
===
|
||||
|
||||
Structure
|
||||
---
|
||||
These JavaScript files divide PCjs functionality into major PC components. Most of the files are device
|
||||
components, implementing a specific device (or set of devices, in the case of [chipset.js](chipset.js)).
|
||||
|
||||
Be aware that *component* is an overloaded term, since **Component** is also the name of the
|
||||
shared base class in [component.js](../../shared/lib/component.js) used by most machine components.
|
||||
A few low-level components (eg, the **Memory** and **State** components, the Card class of the **Video**
|
||||
component, the Color and Rectangle classes of the **Panel** component, etc) do not extend **Component**,
|
||||
so don't assume that every PCjs object has access to [component.js](../../shared/lib/component.js) methods.
|
||||
|
||||
Examples of non-device components include UI components like [panel.js](panel.js) and [debugger.js](debugger.js),
|
||||
and sub-components like [x86ops.js](x86ops.js) and [x86func.js](x86func.js) that separate the CPU
|
||||
functionality of [x86.js](x86.js) into more manageable pieces.
|
||||
|
||||
These components should always be loaded or compiled in the order listed by the *pcJSFiles* property in
|
||||
[package.json](../../../package.json), which includes all the necessary *shared* components as well.
|
||||
At the time of this writing, the recommended order is:
|
||||
|
||||
* [shared/defines.js](../../shared/lib/defines.js)
|
||||
* [shared/diskapi.js](../../shared/lib/diskapi.js)
|
||||
* [shared/dumpapi.js](../../shared/lib/dumpapi.js)
|
||||
* [shared/reportapi.js](../../shared/lib/reportapi.js)
|
||||
* [shared/userapi.js](../../shared/lib/userapi.js)
|
||||
* [shared/strlib.js](../../shared/lib/strlib.js)
|
||||
* [shared/usrlib.js](../../shared/lib/usrlib.js)
|
||||
* [shared/weblib.js](../../shared/lib/weblib.js)
|
||||
* [shared/component.js](../../shared/lib/component.js)
|
||||
* [pcjs/defines.js](defines.js)
|
||||
* [pcjs/x86.js](x86.js)
|
||||
* [pcjs/interrupts.js](interrupts.js)
|
||||
* [pcjs/messages.js](messages.js)
|
||||
* [pcjs/panel.js](panel.js)
|
||||
* [pcjs/bus.js](bus.js)
|
||||
* [pcjs/memory.js](memory.js)
|
||||
* [pcjs/cpu.js](cpu.js)
|
||||
* [pcjs/x86seg.js](x86seg.js)
|
||||
* [pcjs/x86cpu.js](x86cpu.js)
|
||||
* [pcjs/x86cpu.js](x86fpu.js)
|
||||
* [pcjs/x86func.js](x86func.js)
|
||||
* [pcjs/x86ops.js](x86ops.js)
|
||||
* [pcjs/x86op0f.js](x86op0f.js)
|
||||
* [pcjs/x86modb.js](x86modb.js)
|
||||
* [pcjs/x86modw.js](x86modw.js)
|
||||
* [pcjs/x86modb16.js](x86modb16.js)
|
||||
* [pcjs/x86modw16.js](x86modw16.js)
|
||||
* [pcjs/x86modb32.js](x86modb32.js)
|
||||
* [pcjs/x86modw32.js](x86modw32.js)
|
||||
* [pcjs/x86modsib.js](x86modsib.js)
|
||||
* [pcjs/chipset.js](chipset.js)
|
||||
* [pcjs/rom.js](rom.js)
|
||||
* [pcjs/ram.js](ram.js)
|
||||
* [pcjs/keyboard.js](keyboard.js)
|
||||
* [pcjs/video.js](video.js)
|
||||
* [pcjs/serialport.js](serialport.js)
|
||||
* [pcjs/mouse.js](mouse.js)
|
||||
* [pcjs/disk.js](disk.js)
|
||||
* [pcjs/fdc.js](fdc.js)
|
||||
* [pcjs/hdc.js](hdc.js)
|
||||
* [pcjs/debugger.js](debugger.js)
|
||||
* [pcjs/state.js](state.js)
|
||||
* [pcjs/computer.js](computer.js)
|
||||
* [shared/embed.js](../../shared/lib/embed.js)
|
||||
|
||||
Some of the components *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) must be listed before any component that extends **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 component, as it supervises and notifies all the other device components
|
||||
|
||||
To minimize ordering requirements, the init() handlers and constructors of all components should avoid
|
||||
referencing other components. Device components should define an initBus() notification handler, which the
|
||||
*Computer* component will call after it has created/initialized the *Bus* component.
|
||||
|
||||
Features
|
||||
---
|
||||
|
||||
[List of major existing features goes here]
|
||||
|
||||
### BackTrack Support
|
||||
|
||||
The next major feature to be implemented is referred to as BackTrack Support, or simply BackTracks. When BackTracks
|
||||
are enabled, every memory location (at the byte level) and every general-purpose byte register may have an optional link
|
||||
back to its source. These links are called BackTrack indexes.
|
||||
|
||||
All the code that a virtual machine initially executes enters the machine either via ROM or disk sectors, and as that
|
||||
code executes, the machine is loading data into registers from memory locations and/or I/O ports and writing the results
|
||||
to other memory locations and/or I/O ports. BackTracks keep track of that data flow, allowing us to examine the history
|
||||
of any piece of data at any time, down to the byte level; while this feature could be extended to the bit level, it
|
||||
would make the feature dramatically more expensive, both in terms of size and speed.
|
||||
|
||||
A BackTrack index is encoded as a 32-bit value with three parts:
|
||||
|
||||
- Bits 0-8: 9-bit BackTrack object offset (0-511)
|
||||
- Bits 9-15: 7-bit type and access info
|
||||
- Bits 16-30: 15-bit BackTrack object number (1-32767, 0 reserved for dynamic data)
|
||||
|
||||
This represents a total of 31 bits, with bit 31 reserved.
|
||||
|
||||
For example, look at one of the last things a ROM does during boot: loading a disk sector into RAM. It will be up to the
|
||||
disk controller (or DMA controller, if used) to create a BackTrack object representing the sector that was read,
|
||||
adding that object to the global BackTrack object array, and then associating the corresponding BackTrack index with
|
||||
the first byte of RAM where the sector was loaded. Subsequent bytes of RAM containing the rest of the sector will refer
|
||||
to the same BackTrack object, using BackTrack indexes containing offsets 1-511.
|
||||
|
|
@ -394,7 +394,7 @@ Computer.prototype.getMachineParm = function(sParm, parmsComponent)
|
|||
* but there are limits to my paranoia.
|
||||
*/
|
||||
var sParmLC = sParm.toLowerCase();
|
||||
var value = Component.parmsURL && (Component.parmsURL[sParm] || Component.parmsURL[sParmLC]);
|
||||
var value = Component.parmsURL[sParm] || Component.parmsURL[sParmLC];
|
||||
|
||||
if (value === undefined && this.parmsMachine) {
|
||||
value = this.parmsMachine[sParm];
|
||||
|
|
|
|||
|
|
@ -7260,7 +7260,10 @@ Video.init = function()
|
|||
*
|
||||
* HACK: A canvas style of "auto" provides for excellent responsive canvas scaling in EVERY browser
|
||||
* except IE9/IE10, so I recalculate the appropriate CSS height every time the parent DIV is resized;
|
||||
* IE11 works without this hack, so we take advantage of the fact that IE11 doesn't report itself as "MSIE".
|
||||
* IE11 works without this hack, so we take advantage of the fact that IE11 doesn't identify as "MSIE".
|
||||
*
|
||||
* The other reason it's good to keep this particular hack limited to IE9/IE10 is that most other
|
||||
* browsers don't actually support an 'onresize' handler on anything but the window object.
|
||||
*/
|
||||
eCanvas.style.height = "auto";
|
||||
if (web.getUserAgent().indexOf("MSIE") >= 0) {
|
||||
|
|
@ -7271,6 +7274,33 @@ Video.init = function()
|
|||
}(eVideo, eCanvas, parmsVideo['screenWidth'], parmsVideo['screenHeight']);
|
||||
eVideo.onresize();
|
||||
}
|
||||
/*
|
||||
* The following is a related hack that allows the user to force the machine to use a particular aspect
|
||||
* ratio if an 'aspect' URL parameter is set. Initially, it's just for testing purposes until we figure
|
||||
* out a better UI. And note that we use our web.onPageEvent() helper function to make sure we don't
|
||||
* trample on any other 'onresize' handler(s) attached to the window object.
|
||||
*/
|
||||
var aspect = +Component.parmsURL['aspect'];
|
||||
if (aspect) {
|
||||
web.onPageEvent('onresize', function(eParent, eChild, aspectRatio) {
|
||||
return function onResizeWindow() {
|
||||
/*
|
||||
* Since aspectRatio is the target width/height, we have:
|
||||
*
|
||||
* eParent.clientWidth / eChild.style.height = aspectRatio
|
||||
*
|
||||
* which means that:
|
||||
*
|
||||
* eChild.style.height = eParent.clientWidth / aspectRatio
|
||||
*
|
||||
* so for example, if aspectRatio is 16:9, or 1.78, and clientWidth = 640,
|
||||
* then the calculated height should approximately 360.
|
||||
*/
|
||||
eChild.style.height = ((eParent.clientWidth / aspectRatio)|0) + "px";
|
||||
};
|
||||
}(eVideo, eCanvas, aspect));
|
||||
window['onresize']();
|
||||
}
|
||||
eVideo.appendChild(eCanvas);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ function Component(type, parms, constructor, bitsMessage)
|
|||
*
|
||||
* Initialized to the set of URL parameters, if any, for the current web page.
|
||||
*
|
||||
* @type {Object|null}
|
||||
* @type {Object}
|
||||
*/
|
||||
Component.parmsURL = web.getURLParameters();
|
||||
|
||||
|
|
|
|||
|
|
@ -750,7 +750,7 @@ web.fPageEventsEnabled = true;
|
|||
* @param {string} sFunc
|
||||
* @param {function()} fn
|
||||
*
|
||||
* Use this instead of setting window['onunload'], window['onunload'], etc.
|
||||
* Use this instead of setting window['onload'], window['onunload'], etc.
|
||||
* Allows multiple JavaScript modules to define a handler for the same event.
|
||||
*
|
||||
* Moreover, it's risky to refer to obscure event handlers with "dot" names, because
|
||||
|
|
|
|||
Loading…
Reference in a new issue