* Add tests for the DiskII card
This change adds basic read tests for nibble-based disks for the
DiskII card and fixes a few minor errors.
These tests are in preparation for refactoring.
* Add write tests
These are some basic tests of writing to nibble disks. In the process,
one minor bug was found, fixed and documented.
* Fix the write tests
I misinterpreted something from Sather and thought that the high bit
had to be set on the data for writing to happen at all. This is not
true. Instead, there is a flux transition every time the high bit is
set as the data is left-shifted out of the data register. The
erroneous test has been removed.
At the same time, I finally understand what `skip` does and documented
that.
* Add tests for saving and restoring Disk II state
These are not exhaustive tests, but they ensure that some basic state
is saved and restored.
* Add `spawn` as a way of calling promise-returning blocks
This change adds `spawn` which takes a no-argument, promise-returning
function, calls it, and returns `void`. This makes it easy to call
async blocks from `useEffect` and other places that don't take async
functions, but also makes such calls explicit.
* Adds interruptability to `spawn`
Now, the task function passed to `spawn` can take an `Interrupted`
argument, which is merely a method that returns `true` if the task
should stop doing work. Likewise, `spawn` returns an `Interrupt`
function that causes the `Interrupted` function to return `true`.
* Change to using `AbortController` and `AbortSignal`
Before, `spawn` used functions to interrupt and determine interruption
state. Now, based on feedback from @whscullin, it uses
`AbortController` and `AbortSignal`.
Tests now show how the controller can be used to abort long-running
tasks and API calls in the `spawn`. The also show how signals can be
chained using `addEventListener`.
* Fix `Apple2.tsx`
Forgot to change it to use `AbortController` and `AbortSignal`.
Co-authored-by: Will Scullin <scullin@scullin.com>
This change adds `spawn` which takes a no-argument, promise-returning
function, calls it, and returns `void`. This makes it easy to call
async blocks from `useEffect` and other places that don't take async
functions, but also makes such calls explicit.
Before, the offset for `FLAGS` in `2mg.ts` was `0x0A`, which is
incorrect according to the spec at:
https://apple2.org.za/gswv/a2zine/Docs/DiskImage_2MG_Info.txt
Now, all of the fields in the 2mg header are described, including
their lengths and any constraints. These constraints are enforced by
`read2MGHeader` and tested by new tests.
This removes the `FileSystemFileHandleLike` interface in preference to
just implementing the correct interface. The advantage of the
`FileSystemFileHandle` interface is that it can be passed to the
worker directly to load the file.
This adds both the recommended TypeScript checks, plus the recommended
TypeScript checks that require type checking. This latter addition
means that eslint essentially has to compile all of the TypeScript in
the project, causing it to be slower. This isn't much of a problem in
VS Code because there's a lot of caching being done, but it's clearly
slower when run on the commandline.
All of the errors are either fixed or suppressed. Some errors are
suppressed because fixing them would be too laborious for the little
value gained.
The eslint config is also slightly refactored to separate the strictly
TypeScript checks from the JavaScript checks.
* Create a FileChooser component using showOpenFilePicker
Before, `FileModal` always used a file input control for selecting
local files. This allowed the emulator to read from the file, but
precluded writing back to the file.
With this change, the `FileModal` delegates to the new `FileChooser`
component. The `FileChooser` will use `showOpenFilePicker` if it is
available and a regular file input if it's not.
Using `showOpenFilePicker` has the advantage of allowing the emulator
to write back to the file (if the user grants permission). While the
emulator does not yet take advantage of this write capability, that
will come.
* Addressed comments
* useState() instead of direct DOM manipulation
* backed out eslint changes in favor of suppressing the warning