See also the Github Page
This is a fork of the wonderful JSSpeccy3 by Matt Westcott, incorporating a few improvements:
I’m planning to maintain this fork for as long as I need it (until/unless I’m finished adding new features, and all of these features get merged back into the original project).
JSSpeccy 3 is a complete rewrite of JSSpeccy to make full use of the web technologies and APIs available as of 2021 for high-performance web apps. The emulation runs in a Web Worker, freeing up the UI thread to handle screen and audio updates, with the emulator core (consisting of the Z80 processor emulation and any auxiliary processes that are likely to interrupt its execution multiple times per frame, such as constructing the video output, reading the keyboard and generating audio) running in WebAssembly, compiled from AssemblyScript (with a custom preprocessor).
These days, releasing open source code tends to come with an unspoken social contract, so I'd like to set some expectations...
This is a personal project, created for my own enjoyment, and my act of publishing the code does not come with any commitment to provide technical support or assistance. I'm always happy to hear of other people getting similar enjoyment from hacking on the code, and pull requests are welcome, but I can't promise to review them or shepherd them into an "official" release on any sort of timescale. Managing external contributions is often the point at which a "fun" project stops being fun. If there's a feature you need in the project - feel free to fork.
[These are Matt Westcott’s words… but the same applies to me, and to this fork!]
JSSpeccy is designed with embedding in mind. To include it in your own site, download a release archive and copy the contents of the
jsspeccy folder somewhere web-accessible. Be sure to keep the .js and .wasm files and the
subdirectories in the same place relative to jsspeccy.js.
In the <head> of your HTML page, include the tag
<script src="/path/to/jsspeccy.js"></script>
replacing /path/to/jsspeccy.js with (yes!) the path to jsspeccy.js. At the point in the page
where you want the emulator to show, place the code:
<div id="jsspeccy"></div> <script>JSSpeccy(document.getElementById('jsspeccy'))</script>
If you're suitably confident with JavaScript, you can put the call to JSSpeccy anywhere else
that runs on page load, or in response to any user action.
You can also pass configuration options as a second argument to JSSpeccy:
<script>JSSpeccy(document.getElementById('jsspeccy'), {zoom: 2, machine: 48})</script>
The available configuration options are:
autoStart: if true, the emulator will start immediately with no need to press the play button. Bear
in mind that browser policies usually don't allow enabling audio without a user interaction, so if you enable
this option (and don't put the JSSpeccy call behind an onclick event or similar), expect things to
be silent.autoLoadTapes: if true, any tape files opened (either manually or through the openUrl option) will
be loaded automatically without the user having to enter LOAD "" or select the Tape Loader menu option.tapeAutoLoadMode: specifies the mode that the machine should be set to before auto-loading tape
files. When set to 'default' (the default), this is equivalent to selecting the Tape Loader menu option on
machines that support it; when set to 'usr0', this is equivalent to entering 'usr0' in 128 BASIC then LOAD ""
from the resulting 48K BASIC prompt (which leaves 128K memory paging available without the extra housekeeping of
the 128K ROM - this mode is commonly used for launching demos).machine: specifies the machine to emulate. Can be 16 (for a 16K Spectrum),
48 (for a 48K Spectrum), 128 (for a 128K Spectrum), or 5 (for a Pentagon
128).openUrl: specifies a URL, or an array of URLs, to a file (or files) to load on startup, in any
supported snapshot, tape or archive format. Standard browser security restrictions apply for loading remote
files: if the URL being loaded is not on the same domain as the calling page, it must serve CORS HTTP headers to be
loadable.roms: a JS struct which provides an optional map of logical ROM names to ROM file URLs. (May be
omitted or partial.) The keys are listed below, and each value is a URL (CORS comments above apply here too).
JSSpeccy3 has default values for each of these:
Spectrum48K: Single 16K ROM used when machine type is 16 or 48
Spectrum128K_0 & Spectrum128K_1: The two ROMs to use when machine type is
128Pentagon_0: The first ROM to use when machine type is 5. (The Pentagon uses
Spectrum128K_1 as its second ROM.)BetaDisk: The TRDOS ROM to use when machine type is 5, and the BetaDisk ROM is
paged in.zoom: specifies the size of the emulator window; 1 for 100% size (one Spectrum pixel per screen
pixel), 2 for 200% size and so on.sandbox: if true, all UI options for opening a new file are disabled - useful if you're showcasing
a specific bit of Spectrum software on your page.tapeTrapsEnabled: if true (the default), the emulator will recognise when the tape loading routine
in the ROM is called, and load tape files instantly instead.keyboardEnabled: True by default; if false, the emulator will not respond to keypresses.uiEnabled: True by default; if false, the menu bar and toolbar will not be shown.keyboardMap: if this is set to the value "recreated", the emulator will accept
keypresses in the encoded format emitted by the Recreated ZX Spectrum keyboard in "game mode". If it is unset or set to any other value,
the emulator will accept keypresses as normal.features: Additional (emulated) hardware features. Currently only 'ulaplus' is
supported, and the setting defaults to ['ulaplus']. To disable ULAplus functionality, set
to [].For additional JavaScript hackery, the return value of the JSSpeccy function call is an object exposing a number of functions for controlling the running emulator:
<script> let emu = JSSpeccy(document.getElementById('jsspeccy')); emu.openFileDialog(); </script>
emu.setZoom(zoomLevel) - set the zoom level of the emulatoremu.enterFullscreen() - activate full-screen modeemu.exitFullscreen() - exit full-screen modeemu.toggleFullscreen() - enter or exit full-screen modeemu.setMachine(machine) - set the emulated machine typeemu.openFileDialog() - open the file chooser dialogemu.openUrl(url) - open the file at the given URLemu.loadSnapshotFromStruct(snapshot) - load a snapshot from the given data structure; the data
format is currently undocumented but runtime/snapshot.js should give you a decent idea of it...emu.onReady(callback) - call the given callback once the emulator is fully initialisedemu.exit() - immediately stop the emulator and remove it from the documentJSSpeccy-ALT is licensed under the GPL version 3