A BBC Micro emulator written in JavaScript and running in modern browsers. Emulates a 32K BBC B (with sideways RAM) and a 128K BBC Master, along with a number of different peripherals.
The BBC had a somewhat different-looking keyboard to a modern PC, and so it's useful to know some of the mappings:
F0
is F10
Break
key is F12
*
is on "
(if it doesn't work for you try shift-2)To play right now, visit https://bbc.xania.org/. To load the default disc image (Elite in this case), press shift-F12 (which is shift-Break on the BBC).
git clone https://github.com/mattgodbolt/jsbeeb.git
cd jsbeeb
npm install
npm start
http://localhost:8080/
in your browser.jsbeeb uses Node.js and webpack to afford simple and standard web development tooling and third-party library access without lots of painful copy/paste or wheel-reinventing, as well as the ability to better run tests, and "pack" up the site to make it smaller and faster to load when it's deployed to https://bbc.xania.org.
autoboot
- fakes a shift breakdisc1=XXX
- loads disc XXX (from the discs/
directory) into drive 1disc2=XXX
- as abovedisc1=local:YYY
- creates a local disk YYY which will be kept in browser local storagedisc1=sth:ZZZ
- loads disc ZZZ from the Stairway to Hell archivetape=XXX
- loads tape XXX (from the tapes/
directory)tape=sth:ZZZ
- loads tape ZZZ from the Stairway to Hell archivepatch=P
- applies a memory patch P
. See below.loadBasic=X
- loads 'X' (a resource on the webserver) as text, tokenises it and puts it in PAGE
as if you'd typed
it in to the emulatorembedBasic=X
- loads 'X' (a URI-encoded string) as text, tokenises it and puts it in PAGE
as if you'd typed it in
to the emulatorautorun
- types *TAPE
then */
to run from tape. In conjunction with loadBasic
it types RUN
.autochain
- types *TAPE
then CH.""
to run from tape.autotype
- types whatever you put after. e.g. &autotype=PRINT"Matt is cool"%0a
(return is URI escaped to %0a
)embed
- Remove the margins around the screen, hide most navigation entries and make the page background
transparent (intended for use when running within an iframe in a third-party site).cpuMultiplier=X
speeds up the CPU by a factor of X
. May be fractional or below one to slow the CPU down. NB disc
loads become unreliable with a too-slow CPU, and running too fast might cause the browser to hang.sbLeft
/ sbRight
/ sbBottom
- a URL to place left of, right of, or below the cub monitor. The left and right
should be around 648 high and the bottom image should be around 896 wide. Left and right wider than 300 will run into
problems on smaller screens; bottom taller than 100 or so similarly.videoCyclesBatch
- the number of video cycles to batch up before running the video emulation. Defaults to zero:
anything higher leads to emulation inaccuracies. Useful for showing why accuracy is important, even if less efficient.rom
- load the given URL or path as an extra ROM. If a URL is provided, that URL must allow cross-site requests.
Doesn't support the sth: pseudo URL unlike disc
and tape
, but if given a ZIP file will attempt to use the .rom
file assumed to be within.logFdcCommands
, logFdcStateChanges
- turn on logging in the disc controller.Patches can be applied by making a patch=P
URL parameter. P
is a sequence of semicolon-separated patches of the form
@XXXX,YYYY:ZZZZZ,...
where the @XXXX
specifies a PC address to breakpoint, the YYYY
is the address to patch and
the ZZZZ
is the data to write at address YYYY
. The @
part is optional, but is handy to ensure the code you want to
patch has actually loaded. For example: patch=@31a6,0769:6e4c4d48465a
which is a patch for the default Elite image.
Once the PC has reached $31a6
, the bytes at 0769
are replaced with 6e4c4d48465a
.
Note that every update you make means you need to make a new raw link.
If you're looking to help:
git grep -i todo
For general correctness, there are several tests in the tests
directory, including:
For timing correctness, we have:
discs/
directory.Tests can be run automatically if you have node
installed - just run make
and it'll ensure the relevant libraries
are installed, then it'll run the tests. Please note it can take a while to run the whole test suite.
jsbeeb was heavily based on Sarah Walker's C B-Em emulator -- thanks to her for her hard work and for open sourcing her code. B-em is now being maintained by a group of enthusiasts - thanks to them too!
Huge thanks to Richard Talbot-Watkins for his advice and help along the way in fathoming out the instruction timings, interrupt fun, video code rewrite and for being such a good pal all these many years!
Thanks to Michael Borcherds for his help; improving the keyboard layouts and handling in JavaScript, reporting issues, chasing down game bugs and much more.
Thanks to David Banks (hoglet) for his help in testing the gnarly BCD flag behaviour on real live BBCs.
Cheers to Ed Spittles for testing various interrupt timing code on a real BBC.
Thanks to Chris Jordan for his thorough testing, bug reports, ideas and help.
A lot of the early development used the amazing Visual 6502 as reference for intra-instruction timings. Amazing stuff.
Special shout out to the users of the 6502 Forums
I've written a lot about how the innards work on my blog in the emulation section. I gave a presentation on how it all fits together at work, and posted the video up on YouTube. I have another presentation at ABug.
This project is licensed under the MIT License - see the LICENSE file for details.
For support or questions, please contact Matt Godbolt at matt@godbolt.org.