badline 0.15.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +63 -0
- data/CLAUDE.md +7 -0
- data/README.md +40 -10
- data/doc/media.md +19 -0
- data/doc/snapshot-format.md +61 -13
- data/exe/badline-ruby +1 -1
- data/lib/badline/audio/machine_player.rb +2 -14
- data/lib/badline/c64/true_drives.rb +13 -1
- data/lib/badline/c64.rb +6 -0
- data/lib/badline/chips/tia.rb +16 -0
- data/lib/badline/chips/vic/register_log.rb +4 -1
- data/lib/badline/drives/datasette/keyed_state.rb +8 -3
- data/lib/badline/drives/engine/core.rb +6 -14
- data/lib/badline/drives/engine/idle.rb +42 -4
- data/lib/badline/drives/engine/idle_cpu.rb +18 -0
- data/lib/badline/drives/engine/serial_connection.rb +25 -0
- data/lib/badline/drives/engine/sleep.rb +1 -0
- data/lib/badline/drives/engine.rb +1 -0
- data/lib/badline/drives/model1541/byte_ready.rb +19 -3
- data/lib/badline/drives/model1541/mechanism.rb +10 -1
- data/lib/badline/drives/model1541.rb +1 -0
- data/lib/badline/drives/model1551/bus.rb +138 -0
- data/lib/badline/drives/model1551/cable.rb +104 -0
- data/lib/badline/drives/model1551/cpu.rb +14 -0
- data/lib/badline/drives/model1551/keyed_state.rb +65 -0
- data/lib/badline/drives/model1551/port.rb +74 -0
- data/lib/badline/drives/model1551/tia.rb +92 -0
- data/lib/badline/drives/model1551.rb +170 -0
- data/lib/badline/drives/model1571.rb +1 -0
- data/lib/badline/drives/model1581.rb +1 -0
- data/lib/badline/frontend/boot.rb +20 -1
- data/lib/badline/frontend/menu/menu_dialogs.rb +13 -5
- data/lib/badline/frontend/menu/menu_media.rb +92 -14
- data/lib/badline/frontend/menu/menu_pages.rb +11 -6
- data/lib/badline/frontend/player/player_controller.rb +11 -4
- data/lib/badline/machine.rb +9 -5
- data/lib/badline/media/true_drive.rb +7 -5
- data/lib/badline/options/help.rb +4 -2
- data/lib/badline/options/option.rb +2 -1
- data/lib/badline/options/table.rb +14 -2
- data/lib/badline/options/validation.rb +49 -9
- data/lib/badline/options.rb +34 -2
- data/lib/badline/plus4/acia/frames.rb +55 -0
- data/lib/badline/plus4/acia.rb +276 -16
- data/lib/badline/plus4/bus.rb +181 -45
- data/lib/badline/plus4/keyed_modules.rb +22 -5
- data/lib/badline/plus4/keyed_parts.rb +33 -4
- data/lib/badline/plus4/keyed_state.rb +5 -2
- data/lib/badline/plus4/ram_expansion.rb +145 -0
- data/lib/badline/plus4/sid_card.rb +95 -0
- data/lib/badline/plus4/sound_mix.rb +51 -0
- data/lib/badline/plus4/tcbm_drive.rb +120 -0
- data/lib/badline/plus4/user_port.rb +11 -2
- data/lib/badline/plus4.rb +103 -21
- data/lib/badline/roms/README +9 -0
- data/lib/badline/roms/dos1551.rom +0 -0
- data/lib/badline/snapshot/field_doc.rb +7 -5
- data/lib/badline/snapshot/plus4_setup.rb +52 -10
- data/lib/badline/storage/g64_image.rb +1 -1
- data/lib/badline/version.rb +1 -1
- metadata +15 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4083bb2ab34b03da1e8139771b512927b0dedf525fa101bc3960641fab81c45e
|
|
4
|
+
data.tar.gz: 8970b724e8e85d62220a8755ed24fb4403a75d2a612c51dd8d580c311fb0738b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0ea5ef78c667d3bc1208d3be9e70ca4b67fc449e840f6875f392eb315de472d2807840cab6a523f34baf18a9568e29b8ef1542de3c7c21fd68b9dd7e0b227331
|
|
7
|
+
data.tar.gz: 392a38d2997cfb3ee1726d7c76bd3fe0d05f073bd77179e588f7d2db0eb016eaee7732ba3340f88f13c3bf740f80764cde001124fee63d416cf07c8cc7febb41
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,68 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.15.1](https://github.com/elektronaut/badline/compare/v0.15.0...v0.15.1) (2026-10-12)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add the 1551 disk drive, booting its DOS headless ([db03667](https://github.com/elektronaut/badline/commit/db036672799acae2ea13a1b16780875547d74eb6))
|
|
9
|
+
* add the 1551 disk drive, booting its DOS headless ([1f4db55](https://github.com/elektronaut/badline/commit/1f4db555eeb86da755241870a40c75e5441f5894))
|
|
10
|
+
* emulate the Plus/4's 6551 ACIA ([8b1cc23](https://github.com/elektronaut/badline/commit/8b1cc236d7dc5c7e48c772c9256416c1011d2526))
|
|
11
|
+
* emulate the Plus/4's 6551 ACIA ([06bf40f](https://github.com/elektronaut/badline/commit/06bf40f1f618db8decb25fe4d95577a035e9e903))
|
|
12
|
+
* fit a Plus/4 or C16 with a Hannes or Csory RAM expansion ([14bc152](https://github.com/elektronaut/badline/commit/14bc15249914f4ecdb42212ab39d28dc4f2ee557))
|
|
13
|
+
* fit a Plus/4 or C16 with a Hannes or Csory RAM expansion ([85baeba](https://github.com/elektronaut/badline/commit/85baeba267ef6f8e0243444ecd849260a22588de))
|
|
14
|
+
* fit a Plus/4 or C16 with a SID card ([0ed886d](https://github.com/elektronaut/badline/commit/0ed886d5fe10e40223d9de330e38df8501bbbbfc))
|
|
15
|
+
* fit a Plus/4 or C16 with a SID card ([2ae2e19](https://github.com/elektronaut/badline/commit/2ae2e197f783465a8b85c74ca6c78afdc071a66c))
|
|
16
|
+
* machine_diff --family plus4 ([c479566](https://github.com/elektronaut/badline/commit/c479566180254a841d1b6e998089b8ca64ac6a48))
|
|
17
|
+
* machine_diff --family plus4 ([55702f1](https://github.com/elektronaut/badline/commit/55702f10deb8e4f3775d7387a531ef7dbf4a6834))
|
|
18
|
+
* make the 1551 the Plus/4's default true drive ([e3d3120](https://github.com/elektronaut/badline/commit/e3d312099478c71b59088ca4070cd839aabaac46))
|
|
19
|
+
* make the 1551 the Plus/4's default true drive ([e275808](https://github.com/elektronaut/badline/commit/e27580834142351c3bfb4a088b2128bc52885036))
|
|
20
|
+
* name the cartridge on the Expansion port page of every machine ([beab6e5](https://github.com/elektronaut/badline/commit/beab6e58a0aa9a374789645bb18e5c82d50fc0c8))
|
|
21
|
+
* name the cartridge on the Expansion port page of every machine ([6e08889](https://github.com/elektronaut/badline/commit/6e08889edc1de913289ddfd03b75d79b6c42d994))
|
|
22
|
+
* put a true 1551 on the Plus/4's TCBM with --drive-type 1551 ([1d0f9f4](https://github.com/elektronaut/badline/commit/1d0f9f42f622e5e00db1c63dd8413fb7484dd65a))
|
|
23
|
+
* put a true 1551 on the Plus/4's TCBM with --drive-type 1551 ([ba8b9a3](https://github.com/elektronaut/badline/commit/ba8b9a3816300840f6b6fe8138427b81814f3957))
|
|
24
|
+
* put the Plus/4's SID card at $FE80 with --sid-card-address ([da597a2](https://github.com/elektronaut/badline/commit/da597a240f77a870e610f3c186d1afd4f234695a))
|
|
25
|
+
* put the Plus/4's SID card at $FE80 with --sid-card-address ([893c5eb](https://github.com/elektronaut/badline/commit/893c5eb08ca1617c5bced97501e9b8bcae443bb5))
|
|
26
|
+
* save a 1551 in the Plus/4's snapshots ([8c2edad](https://github.com/elektronaut/badline/commit/8c2edadd246985d294b68ae5f46f572691d7045c))
|
|
27
|
+
* save a 1551 in the Plus/4's snapshots ([06313fe](https://github.com/elektronaut/badline/commit/06313fe5de493ff8d92047ea4b2adc815d84d7b7))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Bug Fixes
|
|
31
|
+
|
|
32
|
+
* clock the extra SIDs in C64#cycle! ([7fc8b71](https://github.com/elektronaut/badline/commit/7fc8b719702b90b43df822162c7fde48d1205409))
|
|
33
|
+
* clock the extra SIDs in C64#cycle! ([016a9c4](https://github.com/elektronaut/badline/commit/016a9c4517be052db809bfc42345eedf296f3fbc))
|
|
34
|
+
* read the register log's seed by index for Spinel ([d9b3c43](https://github.com/elektronaut/badline/commit/d9b3c43ef51c81faf471018a85721753450949e0))
|
|
35
|
+
* refuse a .crt with a chip in an unmapped bank on the command line ([15b4060](https://github.com/elektronaut/badline/commit/15b4060afe320df465da5f767c21d69ccf93d3bc))
|
|
36
|
+
* refuse a .crt with a chip in an unmapped bank on the command line ([c8c51fc](https://github.com/elektronaut/badline/commit/c8c51fc2f98deae8eaad1c671987c5b726cb4ba5))
|
|
37
|
+
* refuse a cartridge with a chip in a bank the machine doesn't map ([c2bee2a](https://github.com/elektronaut/badline/commit/c2bee2a4ee01b5959a465b7d72034a9be7ec3bf3))
|
|
38
|
+
* refuse a cartridge with a chip in a bank the machine doesn't map ([d08f37e](https://github.com/elektronaut/badline/commit/d08f37e2b2ff0207b1173aee2f467e4f9e71f685))
|
|
39
|
+
* save the datasette's recording state in snapshots ([ba8e5e8](https://github.com/elektronaut/badline/commit/ba8e5e8dbcf088449324d66f30f8bbfe15e80210))
|
|
40
|
+
* save the datasette's recording state in snapshots ([b155546](https://github.com/elektronaut/badline/commit/b1555467f70a1d2db4117ab43e623f8a060a4a3f))
|
|
41
|
+
* take --frames in the SID player ([b9a54f3](https://github.com/elektronaut/badline/commit/b9a54f3c7bb84edd67c69ee38efb4f5f79347760))
|
|
42
|
+
* take --frames in the SID player ([3483684](https://github.com/elektronaut/badline/commit/3483684fe8efdf2b828d85db98c9e4c1667293a4))
|
|
43
|
+
* take a Plus/4 .bin cartridge from Quick open and drag and drop ([214dcd6](https://github.com/elektronaut/badline/commit/214dcd63bc48956d0f2139d89bab63613dde78d7))
|
|
44
|
+
* take a Plus/4 .bin cartridge from Quick open and drag and drop ([32ec8d0](https://github.com/elektronaut/badline/commit/32ec8d0deb54000a1c2b956a02ad26b53ef2cf6d))
|
|
45
|
+
* type ACIA#feed's bytes for Spinel ([32b9f72](https://github.com/elektronaut/badline/commit/32b9f72a7ad24cd862531d19e545e117c7e8e340))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Performance Improvements
|
|
49
|
+
|
|
50
|
+
* check the init threshold and the ACIA with one compare ([b0050a7](https://github.com/elektronaut/badline/commit/b0050a7a4716e21551882f10c0811a6f0284686a))
|
|
51
|
+
* count the SID card's cycles when it is touched ([d0cec9c](https://github.com/elektronaut/badline/commit/d0cec9c9d9144bb2303d0cba0b182dcf705d1b32))
|
|
52
|
+
* look in on the ACIA's IRQ only when it is due ([d099091](https://github.com/elektronaut/badline/commit/d09909138087a305ce59384dafbece7ef08f340a))
|
|
53
|
+
* sleep the 1551 through its idle loop ([3fabf2a](https://github.com/elektronaut/badline/commit/3fabf2ab6f866bf088682b14e5f04e4dd9054d29))
|
|
54
|
+
* sleep the 1551 through its idle loop ([8d99fa3](https://github.com/elektronaut/badline/commit/8d99fa3ac22f862a51e967dc5a69471dece782da))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### Reverts
|
|
58
|
+
|
|
59
|
+
* find the longest G64 track with a splat again ([31a3df2](https://github.com/elektronaut/badline/commit/31a3df2d35ab79a072a46213d5996068eaa2d793))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
### Miscellaneous Chores
|
|
63
|
+
|
|
64
|
+
* release 0.15.1 ([23586fb](https://github.com/elektronaut/badline/commit/23586fbc26b2132c4a8afe04d44cbeaed6b0eb12))
|
|
65
|
+
|
|
3
66
|
## [0.15.0](https://github.com/elektronaut/badline/compare/v0.14.0...v0.15.0) (2026-10-12)
|
|
4
67
|
|
|
5
68
|
|
data/CLAUDE.md
CHANGED
|
@@ -239,6 +239,13 @@ the rows your change can't reach tell you nothing about it.
|
|
|
239
239
|
- For a change whose reach you can't bound to a set of filters, such as
|
|
240
240
|
reordering `C64#cycle!` or changing the LOAD trap every suite loads
|
|
241
241
|
through, push and let CI run the suites
|
|
242
|
+
- Each Spinel harness compiles only the code its own entry point reaches.
|
|
243
|
+
A method nothing in a harness calls, such as a host-side API only the
|
|
244
|
+
window uses, is compiled only by `native/badline.rb`, with untyped
|
|
245
|
+
arguments, and can fail there alone. A change that adds such a method
|
|
246
|
+
builds the native binary locally (`rake native:build`; on macOS with
|
|
247
|
+
`SPINEL_CC="cc -Wno-nullability-completeness"`) before it's pushed, or
|
|
248
|
+
types its arguments in `spinel/sig`
|
|
242
249
|
- The Regression workflow runs the suites on CRuby, started by hand from
|
|
243
250
|
the Actions tab, for a person checking that CRuby and Spinel agree.
|
|
244
251
|
Agents don't start it
|
data/README.md
CHANGED
|
@@ -81,11 +81,15 @@ differences noted in the table. `--help` lists the options for either.
|
|
|
81
81
|
| --- | --- |
|
|
82
82
|
| `--no-autostart` | Attach the media and stop at `READY.`, so you can type the `LOAD` yourself |
|
|
83
83
|
| `--writable` | Let the machine write to disk images. Without it, a disk goes in write-protected: the drive reports `26,WRITE PROTECT ON` for any write and the image file stays as it was |
|
|
84
|
-
| `--true-drive` | Put an emulated 1541 on device 8 instead of the KERNAL traps. See [Media](#media) |
|
|
84
|
+
| `--true-drive` | Put an emulated 1541 on device 8 instead of the KERNAL traps, or a 1551 on the Plus/4. See [Media](#media) |
|
|
85
|
+
| `--drive-type 1541` | On the Plus/4, make the true drive on device 8 an emulated 1541 on the serial bus in place of the 1551. It implies `--true-drive`. See [The Plus/4](#the-plus4) |
|
|
85
86
|
| `-s`, `--subtune N` | Pick a subtune of a `.sid` file, counting from 1 |
|
|
86
87
|
| `--sid 6581`, `--sid 8580` | Fit the older or newer SID. `--sid auto`, the default, takes a `.sid` tune's own |
|
|
87
88
|
| `--ram SIZE` | Give a VIC-20 the RAM expansion `SIZE`: `unexpanded`, `3k`, `8k`, `16k`, `24k`, `32k` or `all`. Without it, the VIC-20 gets the expansion its media needs. See [The VIC-20](#the-vic-20). On the Plus/4, `16k`, `32k` or `64k` of RAM in place of the model's own |
|
|
88
89
|
| `--c1lo FILE`, `--c1hi FILE`, `--c2lo FILE`, `--c2hi FILE` | Put a raw `.bin` ROM image in one of the Plus/4's cartridge slots: cartridge 1 or 2, low (`$8000`) or high (`$C000`). See [The Plus/4](#the-plus4) |
|
|
90
|
+
| `--sid-card 6581`, `--sid-card 8580` | Fit a Plus/4 or C16 with a SID card at `$FD40`. See [The Plus/4](#the-plus4) |
|
|
91
|
+
| `--sid-card-address fd40`, `--sid-card-address fe80` | Put the SID card at `$FD40` (the default) or at `$FE80` |
|
|
92
|
+
| `--ram-expansion NAME` | Fit a Plus/4 or C16 with a RAM expansion: `hannes256`, `hannes1m` or `csory256`. See [The Plus/4](#the-plus4) |
|
|
89
93
|
| `--reu SIZE` | Plug in a RAM Expansion Unit of `SIZE` K: 128, 256, 512 (a 1750) or up to 16384 |
|
|
90
94
|
| `--model NAME` | Run another model of the machine, named as in VICE. For the C64: `c64` (the default, a PAL C64 with the 6569 VIC-II, 6526 CIAs and the 6581 SID), `c64c` (the PAL C64C, with the 8565, 6526As and the 8580), `ntsc` (the 6567R8), `newntsc` (the NTSC C64C, with the 8562, 6526As and the 8580), `oldntsc` (the first NTSC C64s' 6567R56A), `drean` (the Drean C64 of Argentina, PAL-N with the 6572), `sx64` (the portable SX-64, with its own KERNAL and no datasette), `pet64` (the PET 64 or Educator 64, a PAL C64 in a PET's case with its own KERNAL and a green monochrome monitor) `c64gs` (the C64GS games console, a PAL C64C with its own BASIC and KERNAL, and no keyboard or datasette) or `ultimax` (the MAX Machine of Japan, NTSC with 2K of RAM, one CIA and no ROMs, which runs only a cartridge). `--sid` or a `.sid` tune's own SID takes the model's place. The VIC-20, the C128 and the Plus/4 have models of their own: see their sections |
|
|
91
95
|
| `--ntsc` | Run an NTSC C64, as `--model ntsc` does |
|
|
@@ -102,7 +106,7 @@ differences noted in the table. `--help` lists the options for either.
|
|
|
102
106
|
|
|
103
107
|
| Option | Effect |
|
|
104
108
|
| --- | --- |
|
|
105
|
-
| `--frames N` | Quit after N frames |
|
|
109
|
+
| `--frames N` | Quit after N frames, in the SID player as in the machine's window |
|
|
106
110
|
| `--unpaced` | Run as fast as it can, without vsync or pacing |
|
|
107
111
|
| `--at FRAME:EVENT` | Press keys, type, swap media, open the pause menu or take a screenshot once `FRAME` frames have run |
|
|
108
112
|
| `--script FILE` | Run the events in `FILE`, one `FRAME:EVENT` a line |
|
|
@@ -253,10 +257,29 @@ as xplus4's options do:
|
|
|
253
257
|
badline plus4 --c1lo game-low.bin --c1hi game-high.bin
|
|
254
258
|
```
|
|
255
259
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
+
`--sid-card 6581` or `--sid-card 8580` fits a SID card, as third
|
|
261
|
+
parties built for the 264s, with its SID at `$FD40`-`$FD5F`. The card
|
|
262
|
+
clocks the SID at the TED's single clock, 886,724 Hz on PAL, so a C64
|
|
263
|
+
tune plays about a semitone flat, as it did on those cards. Its sound
|
|
264
|
+
plays with the TED's, and the Sound page swaps its SID's model.
|
|
265
|
+
`--sid-card-address fe80` puts the SID at `$FE80`-`$FE9F` instead, as
|
|
266
|
+
Csory's card does, beside a 1551's TCBM interface at `$FEC0`.
|
|
267
|
+
|
|
268
|
+
`--ram-expansion hannes256` or `hannes1m` fits Hannes's 256K or 1M RAM
|
|
269
|
+
expansion, which banks 64K at a time through its register at `$FD16`,
|
|
270
|
+
above `$1000` or `$4000`, with the TED fetching from the CPU's bank or
|
|
271
|
+
the standard one. `csory256` fits the 256K board with Csory's mapping
|
|
272
|
+
as well, which puts one of 16 blocks of 16K in a window that `$FD15`
|
|
273
|
+
picks. Each needs 64K of the machine's own, and a C16 gets that much.
|
|
274
|
+
|
|
275
|
+
Disks go through the KERNAL traps or, with `--true-drive`, a 1551 on
|
|
276
|
+
device 8, on TCBM, the parallel cable to its interface in the expansion
|
|
277
|
+
port, on the C16 as on the Plus/4. `--drive-type 1541` puts a 1541 on
|
|
278
|
+
the serial bus there instead, and a `.d81` goes in a 1581 on the serial
|
|
279
|
+
bus. The pause menu's Power
|
|
280
|
+
page names the model, its RAM and a RAM expansion, and its Expansion port page names the
|
|
281
|
+
cartridges in, or the slot of one a snapshot put in, and takes them all
|
|
282
|
+
out. `F11` and the
|
|
260
283
|
Snapshots page save it as they do the others, but not for VICE.
|
|
261
284
|
[Input](#input) lists its keys.
|
|
262
285
|
|
|
@@ -368,7 +391,7 @@ too.
|
|
|
368
391
|
| Snapshots | Quicksave, save under a name, load a named save, and the latest quicksaves and autosaves |
|
|
369
392
|
| Drive 8 | The disk: insert, eject, the previous or next disk of its set, and whether it's writable |
|
|
370
393
|
| Datasette | The tape: insert, eject, PLAY and REWIND |
|
|
371
|
-
| Expansion port | The cartridge:
|
|
394
|
+
| Expansion port | The cartridge's name: a `.crt`'s own, or a raw image's file name. Insert, remove, and its freeze button if it has one. On the VIC-20, the cartridge and the RAM expansion |
|
|
372
395
|
| Ports | The device in each control port, and where the keys go |
|
|
373
396
|
| Sound | Mute, and the SID's model |
|
|
374
397
|
| Power | Reset, power cycle and quit, on a C128 its model and mode, and on a Plus/4 its model and RAM |
|
|
@@ -384,7 +407,9 @@ inserting or removing a cartridge does, since each power cycles the
|
|
|
384
407
|
machine.
|
|
385
408
|
|
|
386
409
|
A disk, list of disks or tape dropped on the window goes into its drive. A cartridge,
|
|
387
|
-
program or `.sid` dropped on it opens the menu to ask first.
|
|
410
|
+
program or `.sid` dropped on it opens the menu to ask first. On the Plus/4, a
|
|
411
|
+
`.bin` ROM image dropped or opened with Quick open is a cartridge, and goes
|
|
412
|
+
in cartridge 1 as it does from the command line.
|
|
388
413
|
|
|
389
414
|
## What's emulated
|
|
390
415
|
|
|
@@ -415,8 +440,10 @@ program or `.sid` dropped on it opens the menu to ask first.
|
|
|
415
440
|
timers and the CPU's single and double clock, 16K to 64K of RAM, ROM
|
|
416
441
|
banking with the 3-plus-1 function ROMs, the keyboard and both
|
|
417
442
|
joysticks, cartridges in both slots, the datasette and the serial bus
|
|
418
|
-
to device 8, PAL and NTSC (`badline plus4`). The ACIA
|
|
419
|
-
|
|
443
|
+
to device 8, PAL and NTSC (`badline plus4`). The 6551 ACIA sends and
|
|
444
|
+
receives at its baud rates, with nothing on the user port; Ruby code
|
|
445
|
+
driving the machine can plug in a terminal, whose bytes it feeds and
|
|
446
|
+
drains, or a loopback plug (`Plus4::ACIA#plug`).
|
|
420
447
|
- **1541**: an emulated drive running its own DOS (`--true-drive`).
|
|
421
448
|
- **1571**: the C128D's drive running DOS 3.0, in 1541 mode and in 1571
|
|
422
449
|
mode at 2 MHz with both sides of a `.d71` or `.g71`, and fast serial
|
|
@@ -424,6 +451,9 @@ program or `.sid` dropped on it opens the menu to ask first.
|
|
|
424
451
|
- **1581**: the 3.5" drive running its own DOS on its WD1772 and 8520,
|
|
425
452
|
reading and writing `.d81` images, on the C64, the VIC-20, the C128 and the Plus/4
|
|
426
453
|
(`--true-drive` with a `.d81`).
|
|
454
|
+
- **1551**: the 264 series' parallel drive, its 6510T running its own DOS
|
|
455
|
+
at 2 MHz with the 1541's mechanism, on TCBM to a Plus/4 or a C16
|
|
456
|
+
(`badline plus4 --true-drive`).
|
|
427
457
|
- **Cartridges**: standard 8K, 16K and Ultimax, Simons' BASIC, Ocean,
|
|
428
458
|
Fun Play / Power Play, Super Games, Epyx FastLoad, Westermann
|
|
429
459
|
Learning, Rex Utility, C64 Game System / System 3, Dinamic, Zaxxon /
|
data/doc/media.md
CHANGED
|
@@ -34,6 +34,10 @@ or directories. Loading runs at the speed of a real 1541, and the
|
|
|
34
34
|
drive's red activity LED and green power LED light in the bottom right
|
|
35
35
|
corner of the border. A 1581 flashes its power LED after an error.
|
|
36
36
|
|
|
37
|
+
On the Plus/4 and the C16, `--true-drive` puts an emulated 1551 there
|
|
38
|
+
instead, on TCBM, the parallel cable to its interface in the expansion
|
|
39
|
+
port, and `--drive-type 1541` a 1541 on the serial bus.
|
|
40
|
+
|
|
37
41
|
A `.g64` holds the disk's raw GCR, half tracks and all, so copy
|
|
38
42
|
protection and fast loaders that read it work.
|
|
39
43
|
|
|
@@ -99,6 +103,21 @@ the entries after a `UNIT 8` line, or before any `UNIT` line, count.
|
|
|
99
103
|
`Media.attach` and the command line take a list as media and attach its
|
|
100
104
|
first disk.
|
|
101
105
|
|
|
106
|
+
## Recording to tape
|
|
107
|
+
|
|
108
|
+
From Ruby, a blank tape made with
|
|
109
|
+
`Badline::Storage::TAP.create(path, platform:)` (0 for the C64, 1 for
|
|
110
|
+
the VIC-20, 2 for the Plus/4 and the C16) goes in the datasette with
|
|
111
|
+
`computer.datasette.insert`, `record!` presses RECORD and PLAY, and
|
|
112
|
+
`stop!` lets them up and writes the tape to its file. The C64 and the
|
|
113
|
+
VIC-20 record version 1 TAPs, and the Plus/4 and the C16 version 2 TAPs
|
|
114
|
+
of half waves.
|
|
115
|
+
|
|
116
|
+
A program SAVEd that way on the C64 loads and runs in VICE's x64sc, on
|
|
117
|
+
the VIC-20 in xvic, and on the Plus/4 or the C16 in xplus4 as a Plus/4.
|
|
118
|
+
Neither the Plus/4's tape nor the C16's ran on xplus4's C16 model.
|
|
119
|
+
Checked with VICE 3.10.
|
|
120
|
+
|
|
102
121
|
## The light pen
|
|
103
122
|
|
|
104
123
|
Control port 1's fire line is also the VIC-II's light pen input, so
|
data/doc/snapshot-format.md
CHANGED
|
@@ -31,7 +31,7 @@ Written by the C64, VIC-20, C128, Plus/4.
|
|
|
31
31
|
| `vic_model` | text: mos6569 mos8565 mos8566 mos8564 | C64: "mos6569" |
|
|
32
32
|
| `cia_model` | text: mos6526 mos6526a | C64: "mos6526" |
|
|
33
33
|
| `sid_model` | text: mos6581 mos8580 | C64: "mos6581"; C128: "mos6581" |
|
|
34
|
-
| `ram_expansion` | text: none plus60k plus256k | C64: "none" |
|
|
34
|
+
| `ram_expansion` | text: none plus60k plus256k | C64: "none"; Plus/4: "none" |
|
|
35
35
|
| `reu_kb` | int | C64: 0 |
|
|
36
36
|
| `kernal` | text: c64 sx64 pet64 gs | C64: "c64" |
|
|
37
37
|
| `datasette` | bool | C64: true |
|
|
@@ -62,7 +62,9 @@ Written by the C64, VIC-20, C128, Plus/4.
|
|
|
62
62
|
| `host.typist.wait` | int | C128: 0 |
|
|
63
63
|
| `host.typist.typing` | bool | C128: false |
|
|
64
64
|
| `ram_kb` | int | Plus/4: 64 or 16 |
|
|
65
|
+
| `sid_card` | text: none mos6581 mos8580 | Plus/4: "none" |
|
|
65
66
|
| `tcbm` | bool | Plus/4: false |
|
|
67
|
+
| `sid_card_address` | int | Plus/4: 64832 |
|
|
66
68
|
|
|
67
69
|
## BL-RAM
|
|
68
70
|
|
|
@@ -376,7 +378,7 @@ Written by the C64, C128.
|
|
|
376
378
|
|
|
377
379
|
## BL-SID
|
|
378
380
|
|
|
379
|
-
Written by the C64, C128.
|
|
381
|
+
Written by the C64, C128, Plus/4.
|
|
380
382
|
|
|
381
383
|
| Key | Type | Default |
|
|
382
384
|
| --- | --- | --- |
|
|
@@ -424,6 +426,9 @@ Written by the C64, VIC-20, C128, Plus/4.
|
|
|
424
426
|
| `playing` | bool | false |
|
|
425
427
|
| `motor` | bool | false |
|
|
426
428
|
| `countdown` | int | 0 |
|
|
429
|
+
| `recording` | bool | false |
|
|
430
|
+
| `since` | int | 0 |
|
|
431
|
+
| `write_high` | bool | C64: false; VIC-20: true; C128: false; Plus/4: true |
|
|
427
432
|
| `rise_at` | int | 0 |
|
|
428
433
|
| `low_recorded` | bool | false |
|
|
429
434
|
| `tape.bytes` | bytes | [] |
|
|
@@ -432,13 +437,16 @@ Written by the C64, VIC-20, C128, Plus/4.
|
|
|
432
437
|
|
|
433
438
|
## BL-RAMEXP
|
|
434
439
|
|
|
435
|
-
Written by the C64.
|
|
440
|
+
Written by the C64, Plus/4.
|
|
436
441
|
|
|
437
442
|
| Key | Type | Default |
|
|
438
443
|
| --- | --- | --- |
|
|
439
|
-
| `d100` | byte | 0 |
|
|
440
|
-
| `locked` | bool | false |
|
|
441
|
-
| `bank<N>` | bytes | 65536 × 0 |
|
|
444
|
+
| `d100` | byte | C64: 0 |
|
|
445
|
+
| `locked` | bool | C64: false |
|
|
446
|
+
| `bank<N>` | bytes | C64: 65536 × 0 |
|
|
447
|
+
| `control` | byte | Plus/4: 255 |
|
|
448
|
+
| `csory_latch` | byte | Plus/4: 0 |
|
|
449
|
+
| `ram` | bytes | Plus/4: 196608 × 0 |
|
|
442
450
|
|
|
443
451
|
## BL-REU
|
|
444
452
|
|
|
@@ -568,12 +576,14 @@ Written by the C64, C128, Plus/4.
|
|
|
568
576
|
|
|
569
577
|
| Key | Type | Default |
|
|
570
578
|
| --- | --- | --- |
|
|
571
|
-
| `model` | text: 1541 1571 1581 | C64: "1541" or "1581"; C128: "1541" or "1571"; Plus/4: "1541" |
|
|
579
|
+
| `model` | text: 1541 1551 1571 1581 | C64: "1541" or "1581"; C128: "1541" or "1571"; Plus/4: "1541" or "1551" |
|
|
572
580
|
| `phase` | int | 0 |
|
|
573
581
|
| `cycles` | int | 0 |
|
|
574
582
|
| `so_pending` | bool | false |
|
|
575
583
|
| `serial.host` | int | C64: 255; C128: 255; Plus/4: 0 |
|
|
576
584
|
| `atn` | bool | C64: true |
|
|
585
|
+
| `irq_timer` | int | Plus/4: 16660 |
|
|
586
|
+
| `latched_byte` | byte | Plus/4: 0 |
|
|
577
587
|
|
|
578
588
|
## BL-D8-RAM
|
|
579
589
|
|
|
@@ -581,7 +591,7 @@ Written by the C64, C128, Plus/4.
|
|
|
581
591
|
|
|
582
592
|
| Key | Type | Default |
|
|
583
593
|
| --- | --- | --- |
|
|
584
|
-
| `data` | byte | C64: 234 or 175; C128: 234; Plus/4: 234 |
|
|
594
|
+
| `data` | byte | C64: 234 or 175; C128: 234; Plus/4: 234 or 233 |
|
|
585
595
|
| `ram` | bytes | C64: 2048 × 0 or 8192 × 0; C128: 2048 × 0; Plus/4: 2048 × 0 |
|
|
586
596
|
|
|
587
597
|
## BL-D8-VIA1
|
|
@@ -686,7 +696,7 @@ Written by the C64, C128, Plus/4.
|
|
|
686
696
|
|
|
687
697
|
| Key | Type | Default |
|
|
688
698
|
| --- | --- | --- |
|
|
689
|
-
| `pc` | word | C64: 60064 or 44836; C128: 60064; Plus/4: 60064 |
|
|
699
|
+
| `pc` | word | C64: 60064 or 44836; C128: 60064; Plus/4: 60064 or 59829 |
|
|
690
700
|
| `sp` | byte | 255 |
|
|
691
701
|
| `a` | byte | 0 |
|
|
692
702
|
| `x` | byte | 0 |
|
|
@@ -727,10 +737,10 @@ Written by the C64, C128, Plus/4.
|
|
|
727
737
|
|
|
728
738
|
| Key | Type | Default |
|
|
729
739
|
| --- | --- | --- |
|
|
730
|
-
| `half_track` | int | C64: 35; C128: 37; Plus/4: 35 |
|
|
740
|
+
| `half_track` | int | C64: 35; C128: 37; Plus/4: 35 or 36 |
|
|
731
741
|
| `slip` | int & 0x3 | C64: 0; C128: 2; Plus/4: 0 |
|
|
732
742
|
| `side` | int | C64: 0 or 1; C128: 85; Plus/4: 0 |
|
|
733
|
-
| `zone` | int & 0x3 | 3 |
|
|
743
|
+
| `zone` | int & 0x3 | C64: 3; C128: 3; Plus/4: 3 or 0 |
|
|
734
744
|
| `time` | int | 0 |
|
|
735
745
|
| `read_clock_in` | int | 2097152 |
|
|
736
746
|
| `clocks` | int | 0 |
|
|
@@ -738,8 +748,8 @@ Written by the C64, C128, Plus/4.
|
|
|
738
748
|
| `ones` | int | 0 |
|
|
739
749
|
| `bits` | int | 0 |
|
|
740
750
|
| `write_shift` | int | 0 |
|
|
741
|
-
| `motor` | bool | C64: true or false; C128: true; Plus/4: true |
|
|
742
|
-
| `led` | bool | true |
|
|
751
|
+
| `motor` | bool | C64: true or false; C128: true; Plus/4: true or false |
|
|
752
|
+
| `led` | bool | C64: true; C128: true; Plus/4: true or false |
|
|
743
753
|
| `sync` | bool | false |
|
|
744
754
|
| `byte_ready` | bool | false |
|
|
745
755
|
| `byte_latched` | bool | false |
|
|
@@ -1175,6 +1185,15 @@ Written by the Plus/4.
|
|
|
1175
1185
|
| --- | --- | --- |
|
|
1176
1186
|
| `command` | byte | 0 |
|
|
1177
1187
|
| `control` | byte | 0 |
|
|
1188
|
+
| `errors` | int & 0x7 | 0 |
|
|
1189
|
+
| `receiver_full` | bool | false |
|
|
1190
|
+
| `transmitter_empty` | bool | true |
|
|
1191
|
+
| `irq` | bool | false |
|
|
1192
|
+
| `receive_data` | byte | 0 |
|
|
1193
|
+
| `transmit_data` | byte | 0 |
|
|
1194
|
+
| `shifting` | int | -1 |
|
|
1195
|
+
| `transmit_remainder` | int | 0 |
|
|
1196
|
+
| `transmit_at` | int, optional | absent |
|
|
1178
1197
|
|
|
1179
1198
|
## BL-TIA1
|
|
1180
1199
|
|
|
@@ -1195,3 +1214,32 @@ Written by the Plus/4.
|
|
|
1195
1214
|
| `ports` | ints | [0, 0, 0] |
|
|
1196
1215
|
| `directions` | ints | [0, 0, 0] |
|
|
1197
1216
|
| `inputs` | ints | [0, 0, 0] |
|
|
1217
|
+
|
|
1218
|
+
## BL-D8-PORT
|
|
1219
|
+
|
|
1220
|
+
Written by the Plus/4.
|
|
1221
|
+
|
|
1222
|
+
| Key | Type | Default |
|
|
1223
|
+
| --- | --- | --- |
|
|
1224
|
+
| `ddr` | byte | 0 |
|
|
1225
|
+
| `data` | byte | 0 |
|
|
1226
|
+
|
|
1227
|
+
## BL-D8-TIA
|
|
1228
|
+
|
|
1229
|
+
Written by the Plus/4.
|
|
1230
|
+
|
|
1231
|
+
| Key | Type | Default |
|
|
1232
|
+
| --- | --- | --- |
|
|
1233
|
+
| `ports` | ints | [0, 0, 0] |
|
|
1234
|
+
| `directions` | ints | [0, 0, 0] |
|
|
1235
|
+
| `inputs` | ints | [255, 255, 255] |
|
|
1236
|
+
|
|
1237
|
+
## BL-D8-HOSTTIA
|
|
1238
|
+
|
|
1239
|
+
Written by the Plus/4.
|
|
1240
|
+
|
|
1241
|
+
| Key | Type | Default |
|
|
1242
|
+
| --- | --- | --- |
|
|
1243
|
+
| `ports` | ints | [0, 0, 0] |
|
|
1244
|
+
| `directions` | ints | [0, 0, 0] |
|
|
1245
|
+
| `inputs` | ints | [255, 3, 192] |
|
data/exe/badline-ruby
CHANGED
|
@@ -39,7 +39,7 @@ if options.headless?
|
|
|
39
39
|
console = if options.player_window?
|
|
40
40
|
lambda do |input:, output:|
|
|
41
41
|
load_sdl
|
|
42
|
-
Badline::Frontend::PlayerController.new(input:, output:)
|
|
42
|
+
Badline::Frontend::PlayerController.new(input:, output:, frames: options.frames)
|
|
43
43
|
end
|
|
44
44
|
else
|
|
45
45
|
Badline::Audio::Console.method(:new)
|
|
@@ -19,8 +19,6 @@ module Badline
|
|
|
19
19
|
@subtune = subtune || tune.start_subtune
|
|
20
20
|
@computer = C64.new(sid_model: sid_models[0])
|
|
21
21
|
@stereo = Stereo.new(@computer.address_bus, tune, sid_models)
|
|
22
|
-
@extras = @stereo.extras
|
|
23
|
-
@multi = !@extras.empty?
|
|
24
22
|
region = @computer.region
|
|
25
23
|
@frame_cycles = region.cycles_per_line * region.lines_per_frame
|
|
26
24
|
@injected = false
|
|
@@ -30,7 +28,7 @@ module Badline
|
|
|
30
28
|
def start
|
|
31
29
|
@computer.on_init { inject }
|
|
32
30
|
@computer.cpu.install_trap(@tune.entry_address) { begin_playing }
|
|
33
|
-
|
|
31
|
+
@computer.cycle! until @started || @computer.cycles > START_LIMIT
|
|
34
32
|
end
|
|
35
33
|
|
|
36
34
|
attr_reader :stereo
|
|
@@ -56,23 +54,13 @@ module Badline
|
|
|
56
54
|
# Returns the cycles advanced.
|
|
57
55
|
def frame(budget, &)
|
|
58
56
|
cycles = [budget, @frame_cycles].min
|
|
59
|
-
|
|
60
|
-
cycles.times { step }
|
|
61
|
-
else
|
|
62
|
-
cycles.times { @computer.cycle! }
|
|
63
|
-
end
|
|
57
|
+
cycles.times { @computer.cycle! }
|
|
64
58
|
@stereo.mix(&)
|
|
65
59
|
cycles
|
|
66
60
|
end
|
|
67
61
|
|
|
68
62
|
private
|
|
69
63
|
|
|
70
|
-
# The extra SIDs clock ahead of the CPU, as the machine's own does.
|
|
71
|
-
def step
|
|
72
|
-
@extras.each(&:cycle!) if @multi
|
|
73
|
-
@computer.cycle!
|
|
74
|
-
end
|
|
75
|
-
|
|
76
64
|
def inject
|
|
77
65
|
@computer.ram.write(@tune.load_address, @tune.data)
|
|
78
66
|
@tune.boot_memory(subtune: @subtune).each { |address, bytes| @computer.ram.write(address, bytes) }
|
|
@@ -9,7 +9,7 @@ module Badline
|
|
|
9
9
|
include Drives::Model1581::Slot
|
|
10
10
|
|
|
11
11
|
# The true drive models a snapshot names.
|
|
12
|
-
DRIVE_MODELS = %w[1541 1571 1581].freeze
|
|
12
|
+
DRIVE_MODELS = %w[1541 1551 1571 1581].freeze
|
|
13
13
|
|
|
14
14
|
# Plugs in a Drives::Model1541, which then runs alongside the machine on its
|
|
15
15
|
# own clock and talks to it over the serial bus. The serial traps stop
|
|
@@ -44,6 +44,7 @@ module Badline
|
|
|
44
44
|
drive1581 = @drive1581
|
|
45
45
|
drive1581&.save_modules(sections, "BL-D#{drive1581.device}")
|
|
46
46
|
save_drive1571_modules(sections)
|
|
47
|
+
save_drive1551_modules(sections)
|
|
47
48
|
sections
|
|
48
49
|
end
|
|
49
50
|
|
|
@@ -63,6 +64,7 @@ module Badline
|
|
|
63
64
|
detach_drive1541 unless models.include?("1541")
|
|
64
65
|
detach_drive1581 unless models.include?("1581")
|
|
65
66
|
detach_drive1571 unless models.include?("1571")
|
|
67
|
+
detach_drive1551 unless models.include?("1551")
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
# Unplugs the Drives::Model1541, leaving the serial bus with nothing on it.
|
|
@@ -91,6 +93,7 @@ module Badline
|
|
|
91
93
|
case model
|
|
92
94
|
when "1581" then load_drive1581_modules(modules, input, device)
|
|
93
95
|
when "1571" then load_drive1571_modules(modules, input, device)
|
|
96
|
+
when "1551" then load_drive1551_modules(modules, input, device)
|
|
94
97
|
else load_drive1541_modules(modules, input, device)
|
|
95
98
|
end
|
|
96
99
|
end
|
|
@@ -115,6 +118,15 @@ module Badline
|
|
|
115
118
|
end
|
|
116
119
|
|
|
117
120
|
def detach_drive1571 = nil
|
|
121
|
+
|
|
122
|
+
# The 264 series' 1551, which only the Plus/4 has (Plus4::TCBMDrive).
|
|
123
|
+
def save_drive1551_modules(sections) = sections
|
|
124
|
+
|
|
125
|
+
def load_drive1551_modules(_modules, input, _device)
|
|
126
|
+
input.adjust("a 1551 doesn't plug into this machine, left out")
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def detach_drive1551 = nil
|
|
118
130
|
end
|
|
119
131
|
end
|
|
120
132
|
end
|
data/lib/badline/c64.rb
CHANGED
|
@@ -68,6 +68,7 @@ module Badline
|
|
|
68
68
|
@cia1 = @address_bus.cia1
|
|
69
69
|
@cia2 = @address_bus.cia2
|
|
70
70
|
@sid = @address_bus.sid
|
|
71
|
+
@extra_sids = @address_bus.extra_sids
|
|
71
72
|
@datasette = @address_bus.datasette
|
|
72
73
|
@cycles = 0
|
|
73
74
|
@nmi_asserted = false
|
|
@@ -100,6 +101,7 @@ module Badline
|
|
|
100
101
|
@cia1.cycle!
|
|
101
102
|
@cia2.cycle!
|
|
102
103
|
@sid.cycle!
|
|
104
|
+
clock_extra_sids unless @extra_sids.empty?
|
|
103
105
|
@datasette.cycle!
|
|
104
106
|
|
|
105
107
|
@cpu.irq = @cia1.interrupted? || @vic.interrupted? || @reu_irq
|
|
@@ -202,6 +204,10 @@ module Badline
|
|
|
202
204
|
reu
|
|
203
205
|
end
|
|
204
206
|
|
|
207
|
+
# The SIDs fitted past the first, which clock ahead of the CPU as the
|
|
208
|
+
# first does.
|
|
209
|
+
def clock_extra_sids = @extra_sids.each(&:cycle!)
|
|
210
|
+
|
|
205
211
|
# BA halts the CPU on a read cycle, and so does an REU holding the bus
|
|
206
212
|
# for a transfer.
|
|
207
213
|
def clock_cpu
|
data/lib/badline/chips/tia.rb
CHANGED
|
@@ -9,20 +9,28 @@ module Badline
|
|
|
9
9
|
#
|
|
10
10
|
# A pin read as an output returns what the port drives, and one read as
|
|
11
11
|
# an input returns what the other side drives, #inputs, per port.
|
|
12
|
+
#
|
|
13
|
+
# A cable plugged in (Drives::Model1551::Cable) hears every write and
|
|
14
|
+
# reset, which can move the pins it carries.
|
|
12
15
|
class TIA
|
|
13
16
|
attr_reader :ports, :directions
|
|
14
17
|
|
|
15
18
|
# What the other side drives onto each port's pins.
|
|
16
19
|
attr_reader :inputs
|
|
17
20
|
|
|
21
|
+
# The cable to the other side, or nil.
|
|
22
|
+
attr_accessor :cable
|
|
23
|
+
|
|
18
24
|
def initialize
|
|
19
25
|
@inputs = [0, 0, 0]
|
|
26
|
+
@cable = nil
|
|
20
27
|
reset!
|
|
21
28
|
end
|
|
22
29
|
|
|
23
30
|
def reset!
|
|
24
31
|
@ports = [0, 0, 0]
|
|
25
32
|
@directions = [0, 0, 0]
|
|
33
|
+
@cable&.moved
|
|
26
34
|
end
|
|
27
35
|
|
|
28
36
|
def peek(addr)
|
|
@@ -43,6 +51,14 @@ module Badline
|
|
|
43
51
|
else
|
|
44
52
|
@ports[register] = value
|
|
45
53
|
end
|
|
54
|
+
@cable&.moved
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# The levels on +port+'s pins as the chip leaves them: an output's
|
|
58
|
+
# level, and 1 for an input, which the chip doesn't drive.
|
|
59
|
+
def output(port)
|
|
60
|
+
direction = @directions[port]
|
|
61
|
+
(@ports[port] & direction) | (~direction & 0xff)
|
|
46
62
|
end
|
|
47
63
|
|
|
48
64
|
# The ports, their directions and what the other side drives, in a
|
|
@@ -43,7 +43,10 @@ module Badline
|
|
|
43
43
|
# register back at the value it held when the line started.
|
|
44
44
|
def rewind
|
|
45
45
|
@values.length.times { |reg| @values[reg] = @registers[reg] }
|
|
46
|
-
@seed.
|
|
46
|
+
@seed.each_index do |reg|
|
|
47
|
+
value = @seed[reg]
|
|
48
|
+
@values[reg] = value unless value.nil?
|
|
49
|
+
end
|
|
47
50
|
@cursor = 0
|
|
48
51
|
@next_x = @entries.empty? ? Float::INFINITY : @entries[0][0]
|
|
49
52
|
end
|
|
@@ -4,15 +4,17 @@ module Badline
|
|
|
4
4
|
module Drives
|
|
5
5
|
class Datasette
|
|
6
6
|
# The datasette's fields in a keyed snapshot module (Snapshot::Keyed,
|
|
7
|
-
# BL-TAPE): the keys, the motor, the countdown to the next pulse,
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
# BL-TAPE): the keys, the motor, the countdown to the next pulse,
|
|
8
|
+
# whether it records, the cycles since the write line's last edge and
|
|
9
|
+
# that line's level, and a tape in it under tape.*: its path, its
|
|
10
|
+
# bytes and how far it has played. A tape that isn't in leaves tape.* out. A datasette that
|
|
10
11
|
# times the read line's level adds when in the countdown the line
|
|
11
12
|
# rises, and whether a recording's low half wave is on the tape. The
|
|
12
13
|
# sense and flag handlers don't fire on load.
|
|
13
14
|
module KeyedState
|
|
14
15
|
def save_fields(out)
|
|
15
16
|
out.bool("playing", @playing).bool("motor", @motor).int("countdown", @countdown)
|
|
17
|
+
out.bool("recording", @recording).int("since", @since).bool("write_high", @write_high)
|
|
16
18
|
out.int("rise_at", @rise_at).bool("low_recorded", @low_recorded) if @level
|
|
17
19
|
tape = @tape
|
|
18
20
|
return out unless tape
|
|
@@ -26,6 +28,9 @@ module Badline
|
|
|
26
28
|
@playing = input.bool("playing", @playing)
|
|
27
29
|
@motor = input.bool("motor", @motor)
|
|
28
30
|
@countdown = input.int("countdown", @countdown)
|
|
31
|
+
@recording = input.bool("recording", @recording)
|
|
32
|
+
@since = input.int("since", @since)
|
|
33
|
+
@write_high = input.bool("write_high", @write_high)
|
|
29
34
|
@rise_at = input.int("rise_at", @rise_at)
|
|
30
35
|
@low_recorded = input.bool("low_recorded", @low_recorded)
|
|
31
36
|
bytes = input.bytes("tape.bytes", "".b).bytes
|
|
@@ -24,8 +24,11 @@ module Badline
|
|
|
24
24
|
# sleeps through them too (see Orbit).
|
|
25
25
|
#
|
|
26
26
|
# A model includes Core and builds its parts, sets @clock_hz and
|
|
27
|
-
# @idle_loop, and runs one drive cycle in step.
|
|
28
|
-
#
|
|
27
|
+
# @idle_loop, and runs one drive cycle in step. Its @serial_port faces
|
|
28
|
+
# the host: it says whether the host moved the lines the drive
|
|
29
|
+
# listens to (atn_moved?) and takes them for the next host cycle
|
|
30
|
+
# (latch_host), as the serial port does for ATN on the serial bus
|
|
31
|
+
# (SerialConnection) and the TCBM cable does on the 1551. The model
|
|
29
32
|
# answers Idle's and Orbit's questions about its chips, as VIAs does
|
|
30
33
|
# for the 1541 and the 1571.
|
|
31
34
|
module Core
|
|
@@ -33,7 +36,7 @@ module Badline
|
|
|
33
36
|
include Idle
|
|
34
37
|
include Orbit
|
|
35
38
|
|
|
36
|
-
attr_reader :device
|
|
39
|
+
attr_reader :device
|
|
37
40
|
|
|
38
41
|
def cpu
|
|
39
42
|
settle!
|
|
@@ -62,17 +65,6 @@ module Badline
|
|
|
62
65
|
@host_clock_hz = clock_hz
|
|
63
66
|
end
|
|
64
67
|
|
|
65
|
-
# Plugs the drive into a serial bus, leaving the one it was on. A drive
|
|
66
|
-
# starts out on a bus of its own, with nothing else on it.
|
|
67
|
-
def connect(serial_bus)
|
|
68
|
-
settle!
|
|
69
|
-
@serial_bus&.detach(self)
|
|
70
|
-
@serial_bus = serial_bus
|
|
71
|
-
@serial_port.bus = serial_bus
|
|
72
|
-
serial_bus.attach(self)
|
|
73
|
-
hear_atn
|
|
74
|
-
end
|
|
75
|
-
|
|
76
68
|
# Puts a Disk in the drive (Disk.from_d64 makes one from an image).
|
|
77
69
|
# Nil takes the disk out.
|
|
78
70
|
def insert(disk)
|