Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6e7a200
Made significant changes to get ACORN ATOM working within JSBEEB. Al…
Apr 23, 2025
b746a02
Added TV
Apr 25, 2025
e029bde
fixed soundchip to include ATOM speaker support.
May 7, 2025
721fe1d
Merge branch 'main' into jsatom
May 12, 2025
0e2bb46
tapes working again.
May 19, 2025
c5595cc
Merge remote-tracking branch 'origin/main' into jsatom
May 19, 2025
c1b2407
Fixed some tests.
May 25, 2025
eda5168
fixed the PASTE function for ATOM
May 26, 2025
763fc35
made jsatom invisible when selecting jsbeeb (and vice versa)
May 27, 2025
17efe79
fixed MMC so it shows directory correctly, and is a class
Jun 1, 2025
d4509e8
working versions of MMC saving. Still WIP and needs a progress bar …
Jun 3, 2025
6ed09c2
switching to jszip for compression/decompressoin
Jun 8, 2025
40bb671
Ability to delete files and folders.
Jun 10, 2025
b12d4ab
Merge remote-tracking branch 'upstream/main' into my_main
Jun 10, 2025
3ada9f4
Merge branch 'my_main' into jsatom
Jun 10, 2025
ff3ba53
hiding mousejoysticksettings on ATOM
Jun 10, 2025
bb9ee79
added an Acorn Atom README and updated the software archive
Jun 12, 2025
dae57a3
Fixed paste text, and autopopulating keypresses.
Jul 1, 2025
c039a6f
Some adjustments and a bug fix for PR
Jul 2, 2025
0a3011b
Update README-jsatom.md
CommanderCoder Oct 3, 2025
819069b
used Copilot to generate a save and load state. Seems to work straig…
CommanderCoder Oct 6, 2025
6a0ec33
saving model name and mmc data into managable strings.
CommanderCoder Oct 7, 2025
922b30c
Add teletext and Atom PPIA state serialization to saveState and resto…
CommanderCoder Oct 9, 2025
d4c5bef
moved load/save state to just ATOM
CommanderCoder Oct 10, 2025
2c12fb8
adding firebase hosting deploy
CommanderCoder Oct 11, 2025
9d17731
ignore src/lib/
CommanderCoder Oct 11, 2025
fa7b0b5
output is in dist folder, no need for firebase index html file
CommanderCoder Oct 11, 2025
49b3c6e
added interactive fiction SD card
CommanderCoder Oct 13, 2025
e8039bf
added firebase analytics
CommanderCoder Oct 13, 2025
1927451
the analytics didn't work
CommanderCoder Oct 13, 2025
186ca4e
reverting to google analytics
CommanderCoder Oct 13, 2025
c1326f8
fixed some links
CommanderCoder Oct 13, 2025
7adbdc7
Added more adventures to the IF Archive
CommanderCoder Oct 14, 2025
852fe39
archive needs all categories to be in the archive.
CommanderCoder Oct 14, 2025
8c70284
updated MMC and using patched FP rom for BRAN [ROM, UNLOCK] commands,…
CommanderCoder Oct 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .firebaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"projects": {
"default": "jsacorn-7d5bc"
}
}
20 changes: 20 additions & 0 deletions .github/workflows/firebase-hosting-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools

name: Deploy to Firebase Hosting on merge
on:
push:
branches:
- jsatom
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSACORN_7D5BC }}
channelId: live
projectId: jsacorn-7d5bc
21 changes: 21 additions & 0 deletions .github/workflows/firebase-hosting-pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools

name: Deploy to Firebase Hosting on PR
on: pull_request
permissions:
checks: write
contents: read
pull-requests: write
jobs:
build_and_preview:
if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSACORN_7D5BC }}
projectId: jsacorn-7d5bc
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ coverage
/dist

**/.claude/settings.local.json
.vscode/*

4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ dist
tests/6502_65C02_functional_tests
tests/integration/dp111_6502Timing
package-lock.json
*.png
*.zip
.prettierignore
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't put the file in itself here. prettier can format its own configuration file just fine :)

Why did you have to ignore png and zip here? prettier shouldn't have tried to format anything it didn't understand, and that includes binary files.

Can you recall why you added these?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During commit, the pre-commit process was stopping me commit. I was probably tired and overzealous.

.firebaserc
20 changes: 15 additions & 5 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"name": "Launch Chrome against localhost:5173",
"type": "pwa-chrome",
"request": "launch",
"name": "Debug a running dev server",
"url": "http://localhost:8080?logFdcStateChanges&logFdcCommands&model=MasterADFS&disc=CodenameDroid-ADFS_E.adf",
"webRoot": "${workspaceFolder}",
"url": "http://localhost:5173/?model=Atom",
"webRoot": "${workspaceFolder}/src",
"userDataDir": "${workspaceFolder}/.vscode/chrome-profile",
"sourceMaps": true,
"trace": true
"trace": false
},
{
"name": "Attach to Chrome (remote debugging)",
"type": "pwa-chrome",
"request": "attach",
"port": 9222,
"webRoot": "${workspaceFolder}/src",
"sourceMaps": true,
"trace": false
}
]
}
164 changes: 164 additions & 0 deletions README-jsatom.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
[![jsbeeb tests](https://github.com/mattgodbolt/jsbeeb/actions/workflows/test-and-deploy.yml/badge.svg)](https://github.com/mattgodbolt/jsbeeb/actions/workflows/test-and-deploy.yml)

# jsatom - JavaScript Acorn Atom Emulator

[![jsatom](public/images/jsatom-snapper.png)](https://jsatom.commandercoder.com/)

An Acorn Atom emulator written in JavaScript and running in modern browsers. Emulates a standard Atom with 12K RAM,
along with various expansion options and peripherals.

To get Acorn Atom running in the browser you can use `model=atom` to run the emulator with pre-inserted AtomMMC zip file. Use `model=atom-tape` for just the Acorn Atom without MMC.

## Table of Contents

- [Keyboard Mappings](#keyboard-mappings)
- [Getting Set Up to Run Locally](#getting-set-up-to-run-locally)
- [URL Parameters](#url-parameters)
- [Patches](#patches)
- [Loading BASIC Files from GitHub Gists](#loading-basic-files-from-github-gists)
- [Things Left to Do](#things-left-to-do)
- [Tests](#tests)
- [Thanks](#thanks)
- [More Information](#more-information)
- [License](#license)
- [Contact](#contact)

## Keyboard Mappings

The Atom had a somewhat different keyboard layout to a modern PC, and so it's useful to know some of the mappings:

- Atom `BREAK` key is `F12`
- Atom `COPY` key is `TAB`, `F11`
- Atom `SHIFT LOCK` is `F1`
- Atom `REPT` key is mapped to `RIGHT SHIFT`
- Atom `CTRL` key is mapped to `LEFT SHIFT`
- Atom `SHIFT` key is mapped to `CTRL`

To play right now, visit [https://atom.commandercoder.com/](https://atom.commandercoder.com/). The Atom will boot directly to the BASIC prompt, ready for programming.

<img src="https://retrorepairsandrefurbs.com/wp-content/uploads/2021/09/img_6435-1.jpg?w=3136" width="400px" >

### Joystick Support

Unsupported.

## Getting Set Up to Run Locally

### Prerequisites

- Node.js (https://nodejs.org/)
- npm (comes with Node.js)

### Installation

1. Clone the repository:
```sh
git clone https://github.com/CommanderCoder/jsbeeb.git
cd jsbeeb
```
2. Install dependencies:
```sh
npm install
```
3. Start the local webserver:
```sh
npm start
```
4. Visit `http://localhost:5173/?model=atom` in your browser.

jsatom uses Node.js and vite 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://atom.commandercoder.com/](https://atom.commandercoder.com/).

## URL Parameters

**_These are mostly untested on the Acorn Atom implementation._**

- `autoboot` - automatically starts the system [MMC or Disc]
- [untested] `disc=XXX` - loads disc XXX (from the `discs/atom/` directory) into the drive, forces `model=ATOM-DOS`

- [untested] `mmc=XXX` - inserts SDCard as a zip file (from the `mmc\` directory), forces `model=ATOM`
- [untested] `mmc=local:YYY` - creates a local SDCard which will be kept in browser local storage (empty cards can be created from the menu)
- [untested] `tape=XXX` - loads tape XXX (from the `tapes/atom/` directory), forces `model=ATOM-TAPE`
- [untested] `tape=local:YYY` - creates a local tape YYY which will be kept in browser local storage
- [untested] `patch=P` - applies a memory patch `P`. See below.
- [untested] `loadBasic=X` - loads 'X' (a resource on the webserver) as text, tokenises it and puts it in memory as if you'd typed
it in to the emulator
- [untested] `embedBasic=X` - loads 'X' (a URI-encoded string) as text, tokenises it and puts it in memory as if you'd typed it in
to the emulator
- `autorun` - types `RUN` after loading BASIC code.
- `autochain` - types `CHAIN""` to run from tape.
- `autotype` - types whatever you put after. e.g. `&autotype=PRINT"Hello User"%0a` (return is URI escaped to `%0a`)
- [untested] `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).
- [untested] `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.
- [untested] `sbLeft` / `sbRight` / `sbBottom` - a URL to place left of, right of, or below the Atom monitor. The left and right
should be around 480 high and the bottom image should be around 512 wide. Left and right wider than 300 will run into
problems on smaller screens; bottom taller than 100 or so similarly.
- [untested] `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.
- [untested] `rom` - load the given URL or path as an extra ROM.
- [untested] `audioDebug=true` turns on some audio debug graphs.

## Patches

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=@f000,0200:a9ff8d0002` which patches the Atom's memory at startup.
Once the PC has reached `$f000`, the bytes at `0200` are replaced with `a9ff8d0002`.

## Loading BASIC Files from GitHub Gists

1. Create a gist with your code. https://gist.github.com/ - here's
an [example](https://gist.github.com/mattgodbolt/fc8d6f3d6e5e015dce399013719c8341)
2. Get the "Raw" link by clicking "raw" and copying the URL. In the case above
that's: https://gist.githubusercontent.com/mattgodbolt/fc8d6f3d6e5e015dce399013719c8341/raw/bd5cb4314bfc3ee4330783ecf82cb329a36b915c/foo.bas
3. Add that after "https://atom.xania.org/?autorun&loadBasic=" or similar, for
example, [this link](https://atom.xania.org/?loadBasic=https://gist.githubusercontent.com/mattgodbolt/fc8d6f3d6e5e015dce399013719c8341/raw/bd5cb4314bfc3ee4330783ecf82cb329a36b915c/foo.bas&autorun)

Note that every update you make means you need to make a new raw link.

## Things Left to Do

If you're looking to help:

- Testing
- Play lots of games and report issues either on [GitHub](https://github.com/CommanderCoder/jsbeeb/issues) or by email (
andrew@commandercoder.com).
- Joystick support
- SID support
- couple of SID players in javascript already so probably link to one of these
- https://github.com/jhohertz/jsSID
- https://github.com/og2t/jsSID
- Save state ability
- Once we have this I'd love to get some "reverse step" debugging support
- Memory expansion support
- 32K RAM expansion emulation
- `git grep -i todo`

## Tests

See [jsbeeb tests](README.md#tests)

## Thanks

The Acorn Atom emulator was inspired by and makes heavy use of the 6502 emulator in jsbeeb. It benefits from the wealth of knowledge in the retro computing community.

Many thanks to David Banks for open sourcing the [Atomulator](http://acornatom.co.uk/) emulator. Also thanks to the Acorn Atom source on [Mame](https://github.com/mamedev/mame) and [Phil's Place](http://phils-place.co.uk/HTeMuLator/atom/) for unwittingly helping me with jsatom. The MMC loaded by default is the amazing [Acorn Atom Software Archive](https://github.com/hoglet67/AtomSoftwareArchive) created by David Banks.

Special shout out to the members of the [Stardot Forums](https://stardot.org.uk/forums/).

## More Information

I gave a very rough presentation in 2020 at
[ABug](https://www.youtube.com/watch?v=ga0F0FWfyeo). I'm happy to write up anything that you want to know about it on the [commandercoder](https://www.commandercoder.com/) website.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Contact

For support or questions, please contact Andrew Hague at andrew@commandercoder.com.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[![jsbeeb tests](https://github.com/mattgodbolt/jsbeeb/actions/workflows/test-and-deploy.yml/badge.svg)](https://github.com/mattgodbolt/jsbeeb/actions/workflows/test-and-deploy.yml)

# jsbeeb - JavaScript BBC Micro Emulator
# jsbeeb - JavaScript BBC Micro Emulator (and Acorn Atom Emulator)

[![jsbeeb](public/images/jsbeeb-example.png)](https://bbc.xania.org/)

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.
and a 128K BBC Master, along with a number of different peripherals. Hidden within is the [Acorn Atom emulator](README-jsatom.md).

## Table of Contents

Expand Down Expand Up @@ -98,6 +98,7 @@ site to make it smaller and faster to load when it's deployed to [https://bbc.xa
file assumed to be within.
- (mostly internal use) `logFdcCommands`, `logFdcStateChanges` - turn on logging in the disc controller.
- `audioDebug=true` turns on some audio debug graphs.
- `model=atom` jumps into the hidden [Acorn Atom emulator](README-jsatom.md) with pre-inserted AtomMMC zip file. Use `model=atom-tape` for just the Acorn Atom without MMC.

## Patches

Expand Down
2 changes: 1 addition & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import globals from "globals";

export default [
{
ignores: ["lib/", "out/", "dist/", "coverage/"],
ignores: ["lib/", "out/", "dist/", "coverage/", ".firebaserc", "src/lib/"],
},
js.configs.recommended,
eslintConfigPrettier,
Expand Down
6 changes: 6 additions & 0 deletions firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"hosting": {
"public": "dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
}
}
Loading