badline 0.8.0 → 0.10.0
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 +58 -0
- data/CLAUDE.md +6 -4
- data/README.md +60 -19
- data/doc/library.md +10 -3
- data/doc/media.md +11 -2
- data/doc/pinned-behaviour.md +199 -9
- data/doc/sid-player.md +8 -4
- data/doc/snapshots.md +79 -33
- data/lib/badline/address_bus/pla.rb +130 -0
- data/lib/badline/address_bus/roms.rb +32 -0
- data/lib/badline/address_bus.rb +13 -92
- data/lib/badline/audio/bare_player.rb +24 -0
- data/lib/badline/audio/checkpoints.rb +42 -0
- data/lib/badline/audio/jukebox.rb +11 -4
- data/lib/badline/audio/machine_player.rb +16 -0
- data/lib/badline/audio/renderer.rb +80 -9
- data/lib/badline/audio/stereo.rb +3 -5
- data/lib/badline/audio.rb +1 -0
- data/lib/badline/chrout_trap.rb +4 -3
- data/lib/badline/computer/attachments.rb +52 -12
- data/lib/badline/computer/saved_state.rb +1 -0
- data/lib/badline/computer.rb +50 -33
- data/lib/badline/control_ports.rb +10 -3
- data/lib/badline/core.rb +51 -0
- data/lib/badline/data_path.rb +37 -0
- data/lib/badline/datasette.rb +63 -10
- data/lib/badline/drive1541/disk.rb +3 -3
- data/lib/badline/drive1541/disk_state.rb +14 -5
- data/lib/badline/drive1541/serial_port.rb +5 -8
- data/lib/badline/drive1541/sleep.rb +5 -6
- data/lib/badline/drive1541.rb +3 -3
- data/lib/badline/frontend/app.rb +63 -64
- data/lib/badline/frontend/boot.rb +34 -4
- data/lib/badline/frontend/confirmation.rb +17 -11
- data/lib/badline/frontend/controls.rb +12 -6
- data/lib/badline/frontend/drive_led.rb +9 -10
- data/lib/badline/frontend/frame_rate.rb +4 -4
- data/lib/badline/frontend/machine_window.rb +87 -0
- data/lib/badline/frontend/menu_dialogs.rb +52 -14
- data/lib/badline/frontend/menu_media.rb +70 -16
- data/lib/badline/frontend/menu_pages.rb +47 -42
- data/lib/badline/frontend/menu_ports.rb +69 -0
- data/lib/badline/frontend/name_field.rb +88 -0
- data/lib/badline/frontend/pacer.rb +6 -5
- data/lib/badline/frontend/pause_menu.rb +52 -37
- data/lib/badline/frontend/player_screen.rb +1 -1
- data/lib/badline/frontend/player_window.rb +4 -4
- data/lib/badline/frontend/screen.rb +39 -37
- data/lib/badline/frontend/sid_view.rb +1 -1
- data/lib/badline/frontend/snapshots.rb +145 -17
- data/lib/badline/frontend/sound.rb +17 -9
- data/lib/badline/frontend/timeline.rb +36 -5
- data/lib/badline/frontend.rb +3 -0
- data/lib/badline/iec_bus.rb +16 -28
- data/lib/badline/kernal_trap/drive.rb +3 -0
- data/lib/badline/kernal_trap/file.rb +1 -1
- data/lib/badline/kernal_trap/layout.rb +112 -0
- data/lib/badline/kernal_trap/load.rb +24 -25
- data/lib/badline/kernal_trap/routine.rb +17 -5
- data/lib/badline/kernal_trap/save.rb +13 -23
- data/lib/badline/kernal_trap/serial.rb +38 -24
- data/lib/badline/kernal_trap.rb +1 -0
- data/lib/badline/keyboard.rb +17 -14
- data/lib/badline/machine.rb +60 -0
- data/lib/badline/media/disk_list.rb +75 -0
- data/lib/badline/media/disk_set.rb +13 -3
- data/lib/badline/media/vic20_basic.rb +54 -0
- data/lib/badline/media/vic20_cartridge.rb +74 -0
- data/lib/badline/media/vic20_media.rb +132 -0
- data/lib/badline/media.rb +39 -20
- data/lib/badline/model.rb +62 -0
- data/lib/badline/options/event.rb +10 -6
- data/lib/badline/options/help.rb +25 -13
- data/lib/badline/options/table.rb +15 -1
- data/lib/badline/options/validation.rb +63 -3
- data/lib/badline/options.rb +37 -34
- data/lib/badline/region.rb +16 -4
- data/lib/badline/reu/ram.rb +27 -0
- data/lib/badline/reu/saved_state.rb +27 -0
- data/lib/badline/roms/README +37 -0
- data/lib/badline/roms/kernal-sx64.rom +0 -0
- data/lib/badline/roms/vic20/basic.rom +0 -0
- data/lib/badline/roms/vic20/character.rom +0 -0
- data/lib/badline/roms/vic20/kernal-ntsc.rom +0 -0
- data/lib/badline/roms/vic20/kernal-pal.rom +0 -0
- data/lib/badline/sid/decimator.rb +13 -0
- data/lib/badline/sid/filter.rb +6 -3
- data/lib/badline/sid.rb +19 -0
- data/lib/badline/snapshot/container.rb +2 -0
- data/lib/badline/snapshot/fields.rb +1 -0
- data/lib/badline/snapshot/image.rb +15 -0
- data/lib/badline/snapshot/setup.rb +20 -8
- data/lib/badline/snapshot/state.rb +15 -7
- data/lib/badline/snapshot/vice/main_cpu.rb +1 -1
- data/lib/badline/snapshot/vice/peripherals.rb +12 -2
- data/lib/badline/snapshot/vice/restore.rb +3 -1
- data/lib/badline/snapshot/vice/reu1764.rb +55 -0
- data/lib/badline/snapshot/vice/vicii.rb +59 -13
- data/lib/badline/snapshot/vice/vicii_import.rb +14 -3
- data/lib/badline/snapshot/vice.rb +25 -23
- data/lib/badline/snapshot.rb +10 -0
- data/lib/badline/storage/crt_file.rb +16 -5
- data/lib/badline/storage/disk_image.rb +3 -0
- data/lib/badline/storage/host_directory.rb +3 -0
- data/lib/badline/storage/t64.rb +10 -4
- data/lib/badline/storage/tap.rb +44 -8
- data/lib/badline/storage/unavailable.rb +3 -1
- data/lib/badline/storage.rb +5 -5
- data/lib/badline/timing.rb +12 -0
- data/lib/badline/version.rb +1 -1
- data/lib/badline/via/shift_register.rb +43 -16
- data/lib/badline/vic/bank.rb +53 -16
- data/lib/badline/vic/registers.rb +20 -4
- data/lib/badline/vic/sprite/timing.rb +5 -9
- data/lib/badline/vic/sprite.rb +4 -3
- data/lib/badline/vic.rb +34 -15
- data/lib/badline/vic20/attachments.rb +103 -0
- data/lib/badline/vic20/bus.rb +308 -0
- data/lib/badline/vic20/cpu.rb +10 -0
- data/lib/badline/vic20/keyboard_via_ports.rb +53 -0
- data/lib/badline/vic20/port_wiring.rb +50 -0
- data/lib/badline/vic20/saved_state.rb +152 -0
- data/lib/badline/vic20/sound/output.rb +83 -0
- data/lib/badline/vic20/sound.rb +233 -0
- data/lib/badline/vic20/user_via_ports.rb +47 -0
- data/lib/badline/vic20/vic/painter.rb +239 -0
- data/lib/badline/vic20/vic/saved_state.rb +55 -0
- data/lib/badline/vic20/vic/text_window.rb +71 -0
- data/lib/badline/vic20/vic.rb +267 -0
- data/lib/badline/vic20.rb +220 -0
- data/lib/badline.rb +2 -38
- metadata +37 -2
- data/lib/badline/address_bus/ultimax_pages.rb +0 -38
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bd764dccd3b8af3f8e0dcbb7d17debc3fceb24a9899f80871ebbf184ffefd65b
|
|
4
|
+
data.tar.gz: 46a62d801813476242a407c09ab3ff4fec1126d10bfee134047f18e90fd86955
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 82a62fb4a3de3ef65e123bacf22ba300efe628f1bde38815dc950a39034d8c2b9423de79b3805fce84e19bcbaa8100a3e67488d5ef0a3ecb2de6434689886883
|
|
7
|
+
data.tar.gz: 595b19f034d708db60089e707507e74281059d271527fe61e0a205d9e8e0853a4f6b4d077aeed648f59a86d06bf31d3ee6e5902345fdb52d5fb36ded8de94da3
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.0](https://github.com/elektronaut/badline/compare/v0.9.0...v0.10.0) (2026-10-08)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add the VIC-20's bus and CPU ([184f4c2](https://github.com/elektronaut/badline/commit/184f4c28c609fe0d46358c0143fabe2beba2fa70))
|
|
9
|
+
* name the machine family with a c64 or vic20 subcommand ([586a02f](https://github.com/elektronaut/badline/commit/586a02fbd80c6e6351d85c91263b5a39438ba13e))
|
|
10
|
+
* open the pause menu from the timeline and screenshot it ([63dc744](https://github.com/elektronaut/badline/commit/63dc74468432397c1ec0273a64fcd28ff46008d2))
|
|
11
|
+
* paint the VIC-20's display from the VIC-I's fetches ([76f67c3](https://github.com/elektronaut/badline/commit/76f67c3709363f682715681d17ea799441412f12))
|
|
12
|
+
* play the VIC-20's sound from the VIC-I's voices ([c490a86](https://github.com/elektronaut/badline/commit/c490a86959e18e0fecdcf21bf0139b63be25d9a9))
|
|
13
|
+
* read the VIC-20 .crt signature and the .tap platform byte ([fc0b130](https://github.com/elektronaut/badline/commit/fc0b130ad3a9481e7a9e61d909286281026797b1))
|
|
14
|
+
* run the VIC-20 in the window, in both builds ([24c056c](https://github.com/elektronaut/badline/commit/24c056c531fb356d3d47a9aad94c50ba0a0b0031))
|
|
15
|
+
* run the VIC-20 with its VIC-I registers and VIAs ([6089cee](https://github.com/elektronaut/badline/commit/6089ceee361e65d59c33a1eaeb3395f315eeed2d))
|
|
16
|
+
* save and restore the VIC-20 in badline's own snapshots ([8620849](https://github.com/elektronaut/badline/commit/8620849be5177069e16a559a35b239d75d7cc82a))
|
|
17
|
+
* serve the VIC-20's device 8 through the KERNAL traps and autostart its media ([356695e](https://github.com/elektronaut/badline/commit/356695e7529f999acf4bdc82951b107460ecdf39))
|
|
18
|
+
* wire the VIC-20's datasette and serial bus to its VIAs, with a true 1541 ([2f06e88](https://github.com/elektronaut/badline/commit/2f06e88cf5276780cc03f7d8121480e95b05480f))
|
|
19
|
+
* wire the VIC-20's keyboard, joystick and RESTORE to its VIAs ([32139f6](https://github.com/elektronaut/badline/commit/32139f647aeb3f5e7601928150b85973db6b9b5e))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
* show the disk device 8 holds on the menu's Drive page ([c8b0eaf](https://github.com/elektronaut/badline/commit/c8b0eaf05573246114af6b6f8404095424a1981c))
|
|
25
|
+
* start the VIA shift register only when idle, on the 6522's clock ([bdcb1c8](https://github.com/elektronaut/badline/commit/bdcb1c88bb729e48ffdaaffd91e1274778c4ee29))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Performance Improvements
|
|
29
|
+
|
|
30
|
+
* type Memory's storage as Array[Integer] for Spinel ([797c9b1](https://github.com/elektronaut/badline/commit/797c9b1cab26e6ace4f0d0a20011a3a084e73bc9))
|
|
31
|
+
|
|
32
|
+
## [0.9.0](https://github.com/elektronaut/badline/compare/v0.8.0...v0.9.0) (2026-10-05)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Features
|
|
36
|
+
|
|
37
|
+
* add a per-user data folder for badline's own files ([27bdf0e](https://github.com/elektronaut/badline/commit/27bdf0edc16d95fc57dea940741cc0b7de74bbb1))
|
|
38
|
+
* add the Drean C64, PAL-N with the 6572, as --model drean ([0562d8e](https://github.com/elektronaut/badline/commit/0562d8eb5b11239039eac934fd21eb7824868f98))
|
|
39
|
+
* add the SX-64 as --model sx64 ([e947cba](https://github.com/elektronaut/badline/commit/e947cba8ff46f0f01eeb6e1a49c0bd4bf91324ea))
|
|
40
|
+
* autosave, and a Snapshots page in the pause menu ([78aede9](https://github.com/elektronaut/badline/commit/78aede9a6052ce6c32184952a7b1d380e7c129e2))
|
|
41
|
+
* keep five quicksave slots in the data folder ([6043543](https://github.com/elektronaut/badline/commit/6043543632aa61a42ff69bdff8ea15ae354ce810))
|
|
42
|
+
* pick the C64 to run with --model ([d5539c8](https://github.com/elektronaut/badline/commit/d5539c8ade245b1e96e78765f15906ce4a80da5b))
|
|
43
|
+
* restore snapshots without their tape, .t64 or true drive disk files ([0c0733a](https://github.com/elektronaut/badline/commit/0c0733a5c7eaf9c217466f7569769eb005c5248f))
|
|
44
|
+
* run the testlist's Drean rows as testbench-drean ([dc8a075](https://github.com/elektronaut/badline/commit/dc8a07524168d399fb7c0305c661ab694c53bc2c))
|
|
45
|
+
* save NTSC, Drean and REU machines as .vsf snapshots ([c4126cf](https://github.com/elektronaut/badline/commit/c4126cfa878d8efe7aaaa9e5113c4ee2a4886e6b))
|
|
46
|
+
* seek within a subtune from checkpoints kept as it plays ([3ac57be](https://github.com/elektronaut/badline/commit/3ac57beac448a43a76387a0ff1f370cd07d06d81))
|
|
47
|
+
* take disk sets from .m3u and .vfl lists ([b4e6845](https://github.com/elektronaut/badline/commit/b4e6845eb04cde80f87c1fcb372987311bf1dd97))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Bug Fixes
|
|
51
|
+
|
|
52
|
+
* describe F11's quicksave slots, F12 and the autosave in --help ([6cbf148](https://github.com/elektronaut/badline/commit/6cbf148d327699070ef4fba4f2b3e3dd39d41348))
|
|
53
|
+
* keep the board's low-pass stable for long filter steps ([c5af022](https://github.com/elektronaut/badline/commit/c5af0224aad60dbb665e6804bb536746e354da96))
|
|
54
|
+
* leave CIA 1's timer B and the serial lines as the KERNAL's LOAD does ([b4f1a41](https://github.com/elektronaut/badline/commit/b4f1a4173b9413fd59b05bab12d173e0679c4c17))
|
|
55
|
+
* play an NTSC machine's sound at its own clock ([510aab1](https://github.com/elektronaut/badline/commit/510aab1052a58a54b1790802e2a5705fcb208c5c))
|
|
56
|
+
* put CIA 2's port A on the serial bus without a drive ([31f8a4f](https://github.com/elektronaut/badline/commit/31f8a4fad0ea210d4272b4672a84414527b68e31))
|
|
57
|
+
* run the 6567R8 and 6572 X counter over $180-$187 twice ([08a4da3](https://github.com/elektronaut/badline/commit/08a4da33d4bd68a85d61895dcf8c1ea5fa5b539c))
|
|
58
|
+
* set CIA 1's timer B for each byte the serial traps stand in for ([f98e6d7](https://github.com/elektronaut/badline/commit/f98e6d7666d2326ce4d8d3ab7f938dc4fd60cbd1))
|
|
59
|
+
* take .m3u and .vfl lists of disks in --at's insert ([d1e771e](https://github.com/elektronaut/badline/commit/d1e771e6781fc5560dda2e10e6d76abb53be0807))
|
|
60
|
+
|
|
3
61
|
## [0.8.0](https://github.com/elektronaut/badline/compare/v0.7.0...v0.8.0) (2026-10-03)
|
|
4
62
|
|
|
5
63
|
|
data/CLAUDE.md
CHANGED
|
@@ -50,7 +50,7 @@ requires only the namespace file.
|
|
|
50
50
|
| rspec (`spec/`) | `bundle exec rspec` | Unit behaviour, all of `lib/` |
|
|
51
51
|
| SingleStepTests 65x02 | `rake test` (100 sampled cases per opcode) | CPU, per-cycle bus traces |
|
|
52
52
|
| Wolfgang Lorenz suite | `bin/lorenz` | CPU, CIA, interrupts |
|
|
53
|
-
| VICE testbench | `bin/testbench <subtree>` | `VICII/`, `CIA/`, `interrupts/`, `CPU/`, cartridges with `--carts`,
|
|
53
|
+
| VICE testbench | `bin/testbench <subtree>` | `VICII/`, `CIA/`, `interrupts/`, `CPU/`, cartridges with `--carts`, the true 1541 drive with `--drive`, and the VIC-20 with `--vic20` |
|
|
54
54
|
| VICE SID testprogs | `bin/sidtests` | SID |
|
|
55
55
|
| Drive scenarios | `bin/drive_scenarios` | The true 1541 running the DOS ROM: save, format, the error channel, idle, write protect and autostart |
|
|
56
56
|
| CIA offline grids | `bundle exec rspec --tag slow spec/badline/cia` | CIA timers and shift register, against a bare CIA in about 2 min |
|
|
@@ -144,7 +144,7 @@ overrides that, capped by the core count, but keep the default, because
|
|
|
144
144
|
other worktrees share the machine. Whole runs at 4 shards on an M-series
|
|
145
145
|
laptop take 15 min for `testbench` (`VICII/`), 11 for `testbench-cia`, 1 for
|
|
146
146
|
`testbench-interrupts`, 37 for `testbench-irqdma`, 11 for
|
|
147
|
-
`testbench-cpu`, 2 for `testbench-carts` and
|
|
147
|
+
`testbench-cpu`, 2 for `testbench-carts`, about 25 for `testbench-expansions` and under 1 for `testbench-vic20`. `sid` takes about 12 min. `lorenz` chains itself and takes
|
|
148
148
|
about 2.5 h on CI whole. `rake regression:lorenz-1` to `lorenz-4` run it as
|
|
149
149
|
four stretches of about 40 min each, and they can run side by side.
|
|
150
150
|
`test/baselines/README.md` has the full table. A killed `bin/testbench` run
|
|
@@ -187,14 +187,16 @@ the rows your change can't reach tell you nothing about it.
|
|
|
187
187
|
Pick the filters from the suites your change can move: VIC → `testbench`,
|
|
188
188
|
plus `testbench-vicii-new` (`bin/testbench --vicii-new`, the 8565) for
|
|
189
189
|
anything the VIC model reaches, and `testbench-ntsc` (`bin/testbench --ntsc`,
|
|
190
|
-
the 6567R8 and 6567R56A)
|
|
190
|
+
the 6567R8 and 6567R56A) and `testbench-drean` (`bin/testbench --drean`,
|
|
191
|
+
the 6572) for anything a region's timing reaches;
|
|
191
192
|
CPU, interrupts or timing → the matching `testbench-*` suite, plus
|
|
192
193
|
`rake test` for CPU; CIA → the slow CIA specs first, then the matching
|
|
193
194
|
`testbench-cia` rows, plus `testbench-cia-new` (`bin/testbench --cia-new`,
|
|
194
195
|
the 6526A) for anything the interrupt register or the CIA model reaches; cartridge mappers, banking or power-on state →
|
|
195
196
|
`testbench-carts`, plus `testbench-expansions` for banking; GEO-RAM, +60K,
|
|
196
197
|
+256K, the REU or the VIC's BA line the REU follows → `testbench-expansions`; the 1541 drive, VIA or IEC bus →
|
|
197
|
-
`testbench-drive` (`bin/testbench --drive`) and `drive-scenarios` (`bin/drive_scenarios <filter>`)
|
|
198
|
+
`testbench-drive` (`bin/testbench --drive`) and `drive-scenarios` (`bin/drive_scenarios <filter>`), plus `testbench-vic20` for the VIA; the VIC-20 (`vic20/`) →
|
|
199
|
+
`testbench-vic20` (`bin/testbench --vic20`); SID → `sid`, plus `sid-8580` for anything the 8580
|
|
198
200
|
model reaches (`bin/sidtests --sid 8580`). Leave the Lorenz chain to CI,
|
|
199
201
|
unless your code has a rule in `doc/pinned-behaviour.md` that names Lorenz
|
|
200
202
|
tests: the interrupt polling, CPU port and CIA timer rules. Run just the
|
data/README.md
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
# Badline
|
|
5
5
|
|
|
6
|
+

|
|
7
|
+
|
|
6
8
|
Badline is a Commodore 64 emulator written in Ruby. It emulates a PAL
|
|
7
9
|
or NTSC machine one clock cycle at a time, stepping the 6510, the VIC-II, both
|
|
8
10
|
CIAs and the SID together, so raster timing, bad lines and sprite DMA
|
|
@@ -10,8 +12,8 @@ are modelled at the cycle level.
|
|
|
10
12
|
|
|
11
13
|
It runs programs, disk and tape images, cartridges and SID tunes, and
|
|
12
14
|
the SDL2 front end supports the keyboard, joysticks, game controllers,
|
|
13
|
-
paddles and a 1351 mouse.
|
|
14
|
-
details.
|
|
15
|
+
paddles and a 1351 mouse. It also runs a PAL VIC-20, as
|
|
16
|
+
`badline vic20`. See [What's emulated](#whats-emulated) for the details.
|
|
15
17
|
|
|
16
18
|
It comes in two builds of the same emulator:
|
|
17
19
|
|
|
@@ -65,6 +67,10 @@ Programs, disk and tape images and SID tunes start automatically, and
|
|
|
65
67
|
a cartridge starts itself. A mounted directory waits for you to `LOAD`
|
|
66
68
|
from it.
|
|
67
69
|
|
|
70
|
+
The first argument can name the machine, as in `badline c64 game.prg`.
|
|
71
|
+
The C64 is the default, and `--model` picks which C64. See
|
|
72
|
+
[The VIC-20](#the-vic-20) for `badline vic20`.
|
|
73
|
+
|
|
68
74
|
`badline-ruby` takes the same media and the same options, with the
|
|
69
75
|
differences noted in the table. `--help` lists the options for either.
|
|
70
76
|
|
|
@@ -77,8 +83,10 @@ differences noted in the table. `--help` lists the options for either.
|
|
|
77
83
|
| `--true-drive` | Put an emulated 1541 on device 8 instead of the KERNAL traps. See [Media](#media) |
|
|
78
84
|
| `-s`, `--subtune N` | Pick a subtune of a `.sid` file, counting from 1 |
|
|
79
85
|
| `--sid 6581`, `--sid 8580` | Fit the older or newer SID. `--sid auto`, the default, takes a `.sid` tune's own |
|
|
86
|
+
| `--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) |
|
|
80
87
|
| `--reu SIZE` | Plug in a RAM Expansion Unit of `SIZE` K: 128, 256, 512 (a 1750) or up to 16384 |
|
|
81
|
-
| `--
|
|
88
|
+
| `--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) or `sx64` (the portable SX-64, with its own KERNAL and no datasette). `--sid` or a `.sid` tune's own SID takes the model's place |
|
|
89
|
+
| `--ntsc` | Run an NTSC C64, as `--model ntsc` does |
|
|
82
90
|
| `--no-sound` | Don't play the SID (`badline` only, where sound is on by default) |
|
|
83
91
|
| `--sound` | Play the SID (`badline-ruby`, where sound is off by default) |
|
|
84
92
|
| `--no-vsync` | Pace the window by a timer, or by the sound while it plays, instead of the display's vsync |
|
|
@@ -93,7 +101,7 @@ differences noted in the table. `--help` lists the options for either.
|
|
|
93
101
|
| --- | --- |
|
|
94
102
|
| `--frames N` | Quit after N frames |
|
|
95
103
|
| `--unpaced` | Run as fast as it can, without vsync or pacing |
|
|
96
|
-
| `--at FRAME:EVENT` | Press keys, type, swap media or take a screenshot once `FRAME` frames have run |
|
|
104
|
+
| `--at FRAME:EVENT` | Press keys, type, swap media, open the pause menu or take a screenshot once `FRAME` frames have run |
|
|
97
105
|
| `--script FILE` | Run the events in `FILE`, one `FRAME:EVENT` a line |
|
|
98
106
|
| `--screenshot FILE` | Save the last frame as a `.bmp` |
|
|
99
107
|
| `--save-snapshot FILE` | Save the machine as a `.vsf` snapshot after the last frame |
|
|
@@ -117,6 +125,7 @@ library, are covered in [doc/library.md](doc/library.md).
|
|
|
117
125
|
| `.prg`, `.p00` | Loaded into memory after boot. A program at the BASIC start (`$0801`) is `RUN`, anything else is left for you to `SYS` |
|
|
118
126
|
| `.d64`, `.d71`, `.d81` | Mounted as device 8, then `LOAD"*",8,1` and `RUN`. Write-protected unless `--writable` |
|
|
119
127
|
| `.g64` | Put in a true 1541, then `LOAD"*",8,1` and `RUN`. It holds the disk's raw GCR, so copy protection that reads it works. Write-protected unless `--writable` |
|
|
128
|
+
| `.m3u`, `.vfl` | A list of disk images, one path a line, relative to the list: an `.m3u` playlist, or a VICE flip list, which only unit 8's entries are taken from. Its first disk goes in as above, and the list is its set for the pause menu |
|
|
120
129
|
| `.t64` | Mounted read-only as device 8 and loaded like a disk image. The files load by name, and no tape is involved |
|
|
121
130
|
| `.tap` | Inserted in the datasette with PLAY pressed, then `LOAD` and `RUN`. It loads at the speed of a real tape |
|
|
122
131
|
| `.crt` | The hardware types listed under [Cartridges](#whats-emulated). Other types are rejected |
|
|
@@ -132,14 +141,38 @@ red LED lights in the bottom right corner of the border.
|
|
|
132
141
|
[doc/media.md](doc/media.md) has the details, and how to attach media
|
|
133
142
|
from Ruby.
|
|
134
143
|
|
|
144
|
+
## The VIC-20
|
|
145
|
+
|
|
146
|
+
`badline vic20` runs a PAL VIC-20, and takes the same media as the C64
|
|
147
|
+
apart from SID tunes:
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
badline vic20 # READY.
|
|
151
|
+
badline vic20 game.prg # Load and run a program
|
|
152
|
+
badline vic20 game.d64 # Mount a disk image as device 8 and load it
|
|
153
|
+
badline vic20 game.tap # Insert a tape and load it
|
|
154
|
+
badline vic20 game.crt # Attach a cartridge
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Without `--ram`, it picks the RAM expansion from where the program, or
|
|
158
|
+
the first program on a disk, loads: a BASIC program gets the expansion
|
|
159
|
+
its start of BASIC comes with, and more of BLK1 to BLK3 when it runs
|
|
160
|
+
past `$3FFF`. A program that loads at `$A000` is a cartridge's ROM, and
|
|
161
|
+
goes in as a `.crt` does. Disks go through the KERNAL traps or, with
|
|
162
|
+
`--true-drive`, a 1541, as on the C64. `F11`, `F12` and the pause menu
|
|
163
|
+
save and load the VIC-20 too, in badline's own snapshots: xvic's `.vsf`
|
|
164
|
+
files don't load.
|
|
165
|
+
|
|
135
166
|
## Snapshots
|
|
136
167
|
|
|
137
|
-
`F11`
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
168
|
+
`F11` quicksaves the whole machine to the next of five slots in
|
|
169
|
+
badline's data folder, replacing the oldest, and `F12` restores the
|
|
170
|
+
newest, even after badline has quit and started again. badline also
|
|
171
|
+
autosaves every two minutes of play, and the pause menu's Snapshots page
|
|
172
|
+
saves under a name and loads any of them. Snapshots use
|
|
173
|
+
VICE's `.vsf` format: badline opens those x64sc saves, and x64sc opens
|
|
174
|
+
badline's. See [doc/snapshots.md](doc/snapshots.md) for where they're
|
|
175
|
+
kept, what they hold and how far the two agree.
|
|
143
176
|
|
|
144
177
|
## Playing and rendering SID tunes
|
|
145
178
|
|
|
@@ -215,8 +248,11 @@ through the rows, Right goes into a page and Left back out, and Return or
|
|
|
215
248
|
Space presses a row. A row with choices steps to the next. The mouse works
|
|
216
249
|
too.
|
|
217
250
|
|
|
251
|
+

|
|
252
|
+
|
|
218
253
|
| Page | What it holds |
|
|
219
254
|
|------|---------------|
|
|
255
|
+
| Snapshots | Quicksave, save under a name, load a named save, and the latest quicksaves and autosaves |
|
|
220
256
|
| Drive 8 | The disk: insert, eject, the previous or next disk of its set, and whether it's writable |
|
|
221
257
|
| Datasette | The tape: insert, eject, PLAY and REWIND |
|
|
222
258
|
| Expansion port | The cartridge: insert, remove, and its freeze button if it has one |
|
|
@@ -224,15 +260,17 @@ too.
|
|
|
224
260
|
| Sound | Mute, and the SID's model |
|
|
225
261
|
| Power | Reset, power cycle and quit |
|
|
226
262
|
|
|
227
|
-
INSERT opens a file browser. A disk's set
|
|
228
|
-
|
|
229
|
-
|
|
263
|
+
INSERT opens a file browser. A disk's set is the `.m3u` or `.vfl` list it
|
|
264
|
+
was opened from, or one in its folder that lists it. Without one, it comes
|
|
265
|
+
from the names in its folder: `Disk 1`, `Side B`, `d2`, TOSEC's
|
|
266
|
+
`(Disk 1 of 2)`, or a trailing `_1`, `_2` when the first of the set is
|
|
267
|
+
there. WRITABLE starts as
|
|
230
268
|
`--writable` sets it and stays as set for the next disk. Quick open starts
|
|
231
269
|
a file in a new machine, as the command line does. It asks first, as
|
|
232
270
|
inserting or removing a cartridge does, since each power cycles the
|
|
233
271
|
machine.
|
|
234
272
|
|
|
235
|
-
A disk or tape dropped on the window goes into its drive. A cartridge,
|
|
273
|
+
A disk, list of disks or tape dropped on the window goes into its drive. A cartridge,
|
|
236
274
|
program or `.sid` dropped on it opens the menu to ask first.
|
|
237
275
|
|
|
238
276
|
## What's emulated
|
|
@@ -242,8 +280,8 @@ program or `.sid` dropped on it opens the menu to ask first.
|
|
|
242
280
|
[65x02 single step tests](https://github.com/SingleStepTests/65x02).
|
|
243
281
|
- **Memory**: banking through the 6510 port, the cartridge lines and
|
|
244
282
|
Ultimax mode, and the +60K and +256K RAM expansions.
|
|
245
|
-
- **VIC-II**: the PAL 6569, the C64C's 8565,
|
|
246
|
-
and
|
|
283
|
+
- **VIC-II**: the PAL 6569, the C64C's 8565, NTSC's 6567R8, 8562 and
|
|
284
|
+
6567R56A, and the Drean's PAL-N 6572 (`--model`): every graphics mode, sprites, collisions, bad lines,
|
|
247
285
|
sprite DMA, the border and the light pen.
|
|
248
286
|
- **CIA 1 and 2**: the 6526 and the C64C's 6526A, with timers,
|
|
249
287
|
time-of-day clocks, the serial shift register, the keyboard matrix
|
|
@@ -252,6 +290,10 @@ program or `.sid` dropped on it opens the menu to ask first.
|
|
|
252
290
|
- **REU**: the 1700, 1764 and 1750 and bigger units up to 16M
|
|
253
291
|
(`--reu`), with DMA timed against the VIC's bad lines and sprites.
|
|
254
292
|
- **Datasette**: `.tap` playback.
|
|
293
|
+
- **VIC-20**: the 6502, the PAL 6561 VIC-I with its picture and sound,
|
|
294
|
+
both 6522 VIAs, the keyboard, the joystick and RESTORE, RAM
|
|
295
|
+
expansions up to 35K (`--ram`), cartridges, the datasette and the
|
|
296
|
+
serial bus to device 8 (`badline vic20`).
|
|
255
297
|
- **1541**: an emulated drive running its own DOS (`--true-drive`).
|
|
256
298
|
- **Cartridges**: standard 8K, 16K and Ultimax, Simons' BASIC, Ocean,
|
|
257
299
|
Fun Play / Power Play, Super Games, Epyx FastLoad, Westermann
|
|
@@ -261,8 +303,8 @@ program or `.sid` dropped on it opens the menu to ask first.
|
|
|
261
303
|
Power / Nordic Power, Retro Replay / Nordic Replay, Final Cartridge III
|
|
262
304
|
/ III+ and the KCS Power Cartridge. Flash writes stay in memory.
|
|
263
305
|
|
|
264
|
-
|
|
265
|
-
built from Ruby: see [doc/library.md](doc/library.md).
|
|
306
|
+
Chip combinations `--model` doesn't name, and the cartridges' jumpers,
|
|
307
|
+
are built from Ruby: see [doc/library.md](doc/library.md).
|
|
266
308
|
|
|
267
309
|
Known gaps:
|
|
268
310
|
|
|
@@ -270,7 +312,6 @@ Known gaps:
|
|
|
270
312
|
turns on, stutters: it plays in bursts with silent gaps between them.
|
|
271
313
|
- Without `--true-drive`, fast loaders and anything else that runs code
|
|
272
314
|
on the drive won't work.
|
|
273
|
-
- No PAL-N (Drean) machine.
|
|
274
315
|
|
|
275
316
|
## Contributing
|
|
276
317
|
|
data/doc/library.md
CHANGED
|
@@ -19,7 +19,9 @@ computer.address_bus.peek(0x0400) # screen RAM starts at $0400
|
|
|
19
19
|
## Building a machine
|
|
20
20
|
|
|
21
21
|
`Badline::Computer.new` builds the default machine: a PAL C64 with the
|
|
22
|
-
6569 VIC-II, 6526 CIAs and a 6581 SID. Its keywords build others
|
|
22
|
+
6569 VIC-II, 6526 CIAs and a 6581 SID. Its keywords build others, and
|
|
23
|
+
`Badline::Model.named("c64c")` gives the ones `--model` names for each
|
|
24
|
+
model (`Badline::Model::ALL`):
|
|
23
25
|
|
|
24
26
|
- `vic_model: :mos8565` fits the C64C's 8565, with its grey dots on
|
|
25
27
|
colour register writes and its own timing for mode splits, sprite
|
|
@@ -28,7 +30,8 @@ computer.address_bus.peek(0x0400) # screen RAM starts at $0400
|
|
|
28
30
|
65 cycles by 263 lines at 1,022,727 Hz, with its later sprite fetches
|
|
29
31
|
and its X counter, and TOD clocks on 60 Hz mains.
|
|
30
32
|
`Badline::Region::NTSC_OLD` is the first NTSC C64s' 6567R56A, 64 cycles
|
|
31
|
-
by 262 lines
|
|
33
|
+
by 262 lines, and `Badline::Region::DREAN` the Drean C64's PAL-N
|
|
34
|
+
6572, 65 cycles by 312 lines at 1,023,440 Hz. The stock KERNAL tells them from PAL by the raster, so
|
|
32
35
|
every region boots the same ROMs.
|
|
33
36
|
- `cia_model: :mos6526a` fits the C64C's 6526As, whose interrupt
|
|
34
37
|
register timing differs.
|
|
@@ -36,6 +39,9 @@ computer.address_bus.peek(0x0400) # screen RAM starts at $0400
|
|
|
36
39
|
- `ram_expansion: :plus60k` or `:plus256k` fits the +60K or +256K RAM
|
|
37
40
|
expansion, banked through its register at `$D100`.
|
|
38
41
|
- `reu: 512` plugs in a RAM Expansion Unit of that many K.
|
|
42
|
+
- `kernal: :sx64` fits the SX-64's KERNAL, and `datasette: false`
|
|
43
|
+
leaves the cassette port empty, so inserting a tape raises
|
|
44
|
+
`Badline::Datasette::Missing`. The SX-64 has both.
|
|
39
45
|
|
|
40
46
|
## Cartridges
|
|
41
47
|
|
|
@@ -57,6 +63,7 @@ Its contents are lost when the emulator quits.
|
|
|
57
63
|
The KERNAL, BASIC and character ROMs come with the gem. To run other
|
|
58
64
|
images, such as a patched KERNAL, point `BADLINE_ROM_PATH` at a
|
|
59
65
|
directory that holds `kernal.rom`, `basic.rom` and `character.rom`, plus
|
|
60
|
-
`eapi/eapi-am29f040-14` if you
|
|
66
|
+
`kernal-sx64.rom` for the SX-64 and `eapi/eapi-am29f040-14` if you
|
|
67
|
+
attach EasyFlash cartridges.
|
|
61
68
|
`Badline.rom_path = dir` does the same before a `Badline::Computer` is
|
|
62
69
|
built, and `nil` restores the bundled set.
|
data/doc/media.md
CHANGED
|
@@ -59,8 +59,17 @@ traps, so `LOAD` and `SAVE` reach the 1541 too. With the 1541 in device
|
|
|
59
59
|
8, a `.d64` goes in its drive as well.
|
|
60
60
|
|
|
61
61
|
`Badline::Media::DiskSet.around(path)` lists the disks of the set a disk
|
|
62
|
-
image belongs to,
|
|
63
|
-
|
|
62
|
+
image belongs to, which the pause menu's PREVIOUS DISK and NEXT DISK step
|
|
63
|
+
through. An `.m3u` or `.vfl` list in the disk's folder that names it
|
|
64
|
+
gives the set. Without one, the set is found by name in the folder.
|
|
65
|
+
Given a list, it returns the disks the list names.
|
|
66
|
+
|
|
67
|
+
A list names one disk image a line, as a path relative to the list or an
|
|
68
|
+
absolute one. Blank lines and lines starting with `#` are skipped, and
|
|
69
|
+
entries that aren't there are left out. In a VICE `.vfl` flip list, only
|
|
70
|
+
the entries after a `UNIT 8` line, or before any `UNIT` line, count.
|
|
71
|
+
`Media.attach` and the command line take a list as media and attach its
|
|
72
|
+
first disk.
|
|
64
73
|
|
|
65
74
|
## The light pen
|
|
66
75
|
|
data/doc/pinned-behaviour.md
CHANGED
|
@@ -26,11 +26,16 @@ only catches the rows that happen to move.
|
|
|
26
26
|
- [VIC light pen](#vic-light-pen)
|
|
27
27
|
- [VIC-II 8565](#vic-ii-8565)
|
|
28
28
|
- [VIC-II NTSC](#vic-ii-ntsc)
|
|
29
|
+
- [VIC-II 6572 (Drean)](#vic-ii-6572-drean)
|
|
29
30
|
- [CIA 6526 timer pipeline](#cia-6526-timer-pipeline)
|
|
30
31
|
- [CIA 6526A interrupt register](#cia-6526a-interrupt-register)
|
|
31
32
|
- [CIA serial shift register](#cia-serial-shift-register)
|
|
33
|
+
- [VIA shift register](#via-shift-register)
|
|
32
34
|
- [6510 I/O port](#6510-io-port)
|
|
33
35
|
- [RAM power-on pattern](#ram-power-on-pattern)
|
|
36
|
+
- [VIC-20 RAM power-on pattern](#vic-20-ram-power-on-pattern)
|
|
37
|
+
- [VIC-I fetches and the V-bus](#vic-i-fetches-and-the-v-bus)
|
|
38
|
+
- [VIC-I sound](#vic-i-sound)
|
|
34
39
|
- [1541 serial port](#1541-serial-port)
|
|
35
40
|
- [1541 disk mechanism](#1541-disk-mechanism)
|
|
36
41
|
- [REU DMA](#reu-dma)
|
|
@@ -293,7 +298,9 @@ only catches the rows that happen to move.
|
|
|
293
298
|
early in the next one for 3–7.
|
|
294
299
|
- A sprite still shifting at K loses the rest of its row. Its output
|
|
295
300
|
holds its last pixel from K through **K+6**, then goes dark.
|
|
296
|
-
- A comparator hit in K..K+11 shows nothing.
|
|
301
|
+
- A comparator hit in K..K+11 shows nothing. Where K falls in the
|
|
302
|
+
last 11 pixels of the line, as sprite 3's does on a 65-cycle line,
|
|
303
|
+
the twelve run on into the next line's first pixels.
|
|
297
304
|
- A hit from K+12 on shows the row the reload brought. For sprites 0–2
|
|
298
305
|
that is the *next* line's row, a line early. For sprites 3–7 it is the
|
|
299
306
|
current row, and a hit ahead of their K shows the previous line's row.
|
|
@@ -307,6 +314,11 @@ only catches the rows that happen to move.
|
|
|
307
314
|
`spritex/demusinterruptus` and `spritegap2` pass on it too.
|
|
308
315
|
- Spec guard: *the reload* in
|
|
309
316
|
[`vic/sprite_spec.rb`](../spec/badline/vic/sprite_spec.rb).
|
|
317
|
+
- The run into the next line is pinned by `spritescan_drean`'s 6572
|
|
318
|
+
dump, where sprite 3 shows nothing for X = $193 to $19e, the twelve
|
|
319
|
+
pixels from K = 515 on a 520-pixel line. Without it a hit at $198 to
|
|
320
|
+
$19e collides. Spec guard: *the reload near the end of a 65-cycle
|
|
321
|
+
line*. The `testbench-ntsc` sprite rows pass either way.
|
|
310
322
|
- The hold's length is pinned by `spritefetchbug/test-136-2a`, whose
|
|
311
323
|
X-expanded sprite 0 sits at X = $136 and is still shifting at 459. Its
|
|
312
324
|
reference holds the last pixel through 465. Holding it for one pixel
|
|
@@ -941,14 +953,22 @@ region moves the sprites. The positions live in `Region::Profile` and
|
|
|
941
953
|
- Spec guard: *sprite DMA cycle stealing on NTSC* and *#phi1_data on
|
|
942
954
|
NTSC* in [`vic_spec.rb`](../spec/badline/vic_spec.rb), and
|
|
943
955
|
[`timing_spec.rb`](../spec/badline/vic/sprite/timing_spec.rb).
|
|
944
|
-
- **Display compare
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
956
|
+
- **Display compare.** The 6567R8 turns a sprite's display on and off in
|
|
957
|
+
cycle 59 (`sprite_display_cycle`), where the 6567R56A keeps the 6569's
|
|
958
|
+
cycle 58. This isn't pinned yet: moving the 6567R8's to 58 or the
|
|
959
|
+
6567R56A's to 59 fails no row of those subsets.
|
|
960
|
+
- **X counter.** The 6567R8's X counter spends 8 pixels more on a line
|
|
961
|
+
(`x_hold`): after $187 it runs over $180-$187 a second time, then on
|
|
962
|
+
from $188, so it reaches $1ff on a 520-pixel line. The 6567R56A's runs
|
|
963
|
+
straight through 512 pixels.
|
|
964
|
+
- Pinned for the 6572, which shares the line, by `spritescan_drean`'s
|
|
965
|
+
dump (see [VIC-II 6572 (Drean)](#vic-ii-6572-drean)).
|
|
966
|
+
- The 6567R8's own lightpen dump (`split-tests/lightpen`'s
|
|
967
|
+
`dump6567.prg`, run by hand on `--model ntsc`) agrees: the sample the
|
|
968
|
+
test takes 8 pixels into the hold reads $c2 ($180-$181). Reading
|
|
969
|
+
$184-$187 there instead, as badline did before, gives $c4. The 6572's
|
|
970
|
+
`dump6572.prg` has the same values. The `testbench-ntsc` rows pass
|
|
971
|
+
either way.
|
|
952
972
|
- **Blanking and crop.** The blanked lines are the ones VICE's NTSC view
|
|
953
973
|
leaves out, 12-27 on the 6567R8 and 13-27 on the 6567R56A, so the
|
|
954
974
|
`testbench-ntsc` screenshots, VICE's 247 lines from line 28 running on
|
|
@@ -970,6 +990,34 @@ What the NTSC references don't settle, and so what stays as it is:
|
|
|
970
990
|
readme says it was matched against screenshots, and the one 6567R8
|
|
971
991
|
photograph in the testprogs is of revision R01.
|
|
972
992
|
|
|
993
|
+
## VIC-II 6572 (Drean)
|
|
994
|
+
|
|
995
|
+
The 6572 of the Drean C64 (`Region::DREAN`) runs the 6567R8's line, 65
|
|
996
|
+
cycles with its sprite fetches in cycle 59, its display compare in cycle
|
|
997
|
+
59 and its X counter running over $180-$187 twice, on PAL-N's 312 lines at
|
|
998
|
+
1,023,440 Hz. The oracle is `split-tests/spritescan/spritescan_drean.prg`,
|
|
999
|
+
which checks itself against its `dump6572.bin`, from a real 6572R1. The
|
|
1000
|
+
testlist comments that row out, and `testbench-drean`
|
|
1001
|
+
(`bin/testbench --drean`) runs it.
|
|
1002
|
+
|
|
1003
|
+
- Pinned by that dump: every byte the test compares matches, and the
|
|
1004
|
+
test passes.
|
|
1005
|
+
- The X counter's second run over $180-$187 is pinned by sprite 1,
|
|
1006
|
+
pattern C (a one-pixel sprite against one shifted a pixel left), which
|
|
1007
|
+
collides for X = $180 to $186 on the 6572. Those are inside sprite 1's
|
|
1008
|
+
twelve dead pixels (K = 483), so the sprite only shows from the second
|
|
1009
|
+
time the counter reads its X. Repeating $184-$187 in the hold instead
|
|
1010
|
+
misses $180-$183 (4 bytes), repeating $180-$183 misses $184-$186 (3),
|
|
1011
|
+
and repeating $17c-$183 or $184-$18b moves 18 bytes. Spec guard: the
|
|
1012
|
+
6567R8 and 6572 examples in
|
|
1013
|
+
[`timing_spec.rb`](../spec/badline/vic/sprite/timing_spec.rb).
|
|
1014
|
+
- The display compare isn't pinned: the dump matches with it in cycle
|
|
1015
|
+
58 as well as 59.
|
|
1016
|
+
- Not matched: `spritegap3`'s 6572 dump has sprite 0 at X = 0 miss the
|
|
1017
|
+
sprite at X = 1 for every pair it is in, where badline, like the
|
|
1018
|
+
6567R8 dump, has them collide. The test still passes, because it
|
|
1019
|
+
accepts the 6567R8's dump too.
|
|
1020
|
+
|
|
973
1021
|
## CIA 6526 timer pipeline
|
|
974
1022
|
|
|
975
1023
|
- Start and stop go through two stages. A force load lands one tick after
|
|
@@ -1152,6 +1200,43 @@ and each was knocked out: removing it fails the rows named.
|
|
|
1152
1200
|
[`cia_spec.rb`](../spec/badline/cia_spec.rb) covers the flag timing, the
|
|
1153
1201
|
waiting byte, both mode-change reports and the zero-latch stall.
|
|
1154
1202
|
|
|
1203
|
+
## VIA shift register
|
|
1204
|
+
|
|
1205
|
+
- A read or write of SR starts a byte only while the register is idle
|
|
1206
|
+
and enabled. An access in mode 0 starts nothing, even once the mode
|
|
1207
|
+
changes, and an access before the eighth bit is in leaves the count
|
|
1208
|
+
alone. The byte in progress runs on, and the first access after it
|
|
1209
|
+
ends starts the next.
|
|
1210
|
+
- In the φ2 modes (2 and 6) CB1 falls on the second cycle after the
|
|
1211
|
+
access, rises on the third, and so on. Mode 6 puts a bit out on cycles
|
|
1212
|
+
+2, +4 … +16, mode 2 takes one in on cycles +3, +5 … +17, and the flag
|
|
1213
|
+
rises with the eighth rising edge, on cycle +17.
|
|
1214
|
+
- In the timer 2 modes (1, 4 and 5) each clock edge comes two cycles
|
|
1215
|
+
after the timer 2 low byte underflows, on the cycle after the low byte
|
|
1216
|
+
reloads from its latch. The half period stays N + 2 cycles.
|
|
1217
|
+
- Pinned by the `VIC20/via_sr` rows, each checked by breaking the rule and
|
|
1218
|
+
rerunning all 32. The plain and `exp` rows dump SR every 7 cycles, the
|
|
1219
|
+
`ifr` and `iex` rows dump IFR, and the SR write comes before the ACR
|
|
1220
|
+
write that sets the mode:
|
|
1221
|
+
- Mode 0 starts nothing: `viasr08` and `viasr18`, and the `ifr`/`iex`
|
|
1222
|
+
rows of modes 04, 08, 14 and 18, which would see the SR flag.
|
|
1223
|
+
- No restart before the eighth bit: `viasr14` and `viasr18`. Their
|
|
1224
|
+
reads come every 7 cycles, faster than a byte.
|
|
1225
|
+
- The φ2 start a cycle late: `viasr08` and `viasr18`. Ticking from the
|
|
1226
|
+
first cycle, or from the third, fails both.
|
|
1227
|
+
- The timer 2 edge two cycles late: `viasr04`, `viasr10` and `viasr14`.
|
|
1228
|
+
A delay of 0, 1 or 3 cycles fails all three.
|
|
1229
|
+
- Every rule also fails the row's `exp` twin, the same test on an
|
|
1230
|
+
expanded VIC-20.
|
|
1231
|
+
- Nothing pins whether the timer 2 delay keeps running while the register
|
|
1232
|
+
is idle. It does, and freezing it passes every row too. Nothing pins
|
|
1233
|
+
the flag's cycle in the φ2 modes either: no row starts a byte and then
|
|
1234
|
+
reads IFR.
|
|
1235
|
+
- Spec guard: the mode blocks in
|
|
1236
|
+
[`shift_register_spec.rb`](../spec/badline/via/shift_register_spec.rb)
|
|
1237
|
+
and *the shift register* in
|
|
1238
|
+
[`via_spec.rb`](../spec/badline/via_spec.rb).
|
|
1239
|
+
|
|
1155
1240
|
## 6510 I/O port
|
|
1156
1241
|
|
|
1157
1242
|
- DDR at `$00`/`$01`: inputs are pulled up, bit 5 reads low, and bits 3, 6
|
|
@@ -1195,6 +1280,111 @@ and each was knocked out: removing it fails the rows named.
|
|
|
1195
1280
|
[`address_bus_spec.rb`](../spec/badline/address_bus_spec.rb).
|
|
1196
1281
|
- The RAM expansions' extra banks still power on at `$00`.
|
|
1197
1282
|
|
|
1283
|
+
## VIC-20 RAM power-on pattern
|
|
1284
|
+
|
|
1285
|
+
- The VIC-20's RAM powers on in alternating bytes, `$ff` at the even
|
|
1286
|
+
addresses and `$00` at the odd ones, on every power cycle. The internal
|
|
1287
|
+
RAM and the expansion blocks (RAM1-3, BLK1-3, BLK5) all follow it.
|
|
1288
|
+
Colour RAM powers on at zero. `Vic20::Bus::RAM_POWER_ON` holds it.
|
|
1289
|
+
- Pinned by `VIC20/raminitpattern`: `ae.crt` fails unless `$0288` reads
|
|
1290
|
+
`$ff` and `jellymonsters.crt` unless `$1046` does, read from a
|
|
1291
|
+
cartridge before the KERNAL clears RAM. The readme says AE and Jelly
|
|
1292
|
+
Monsters need `$ff` there. Its dumps of real machines' `$1000-$1fff`
|
|
1293
|
+
show bytes alternating `$00` and `$ff` on most machines, with either
|
|
1294
|
+
phase, and noise or other patterns on the rest. They show nothing
|
|
1295
|
+
for colour RAM or expansion RAM that a pattern could be read from.
|
|
1296
|
+
- Spec guard: *RAM at power-on* in
|
|
1297
|
+
[`vic20/bus_spec.rb`](../spec/badline/vic20/bus_spec.rb).
|
|
1298
|
+
|
|
1299
|
+
## VIC-I fetches and the V-bus
|
|
1300
|
+
|
|
1301
|
+
- On a line of the text window the 6561 fetches the first character code
|
|
1302
|
+
4 cycles after the column in `$9000`, 16 cycles after the raster count
|
|
1303
|
+
moves with the KERNAL's origin of 12, then the code's pattern byte in
|
|
1304
|
+
the next cycle, two cycles a character. Outside the window it fetches
|
|
1305
|
+
nothing.
|
|
1306
|
+
- A read where no chip answers in I/O 0 (`$9100`, `$9200`) returns the
|
|
1307
|
+
V-bus's last byte: the VIC's fetch in a cycle it fetches in, and the
|
|
1308
|
+
CPU's own last byte on the V-bus in the other cycles.
|
|
1309
|
+
- Pinned by `VIC20/split-tests/timing`: all 1,024 bytes of its readings
|
|
1310
|
+
of `$9003`, `$9004`, `$9100` and `$9200` over 256 cycles match
|
|
1311
|
+
`dumps/dump6561e.prg`, a real 6561E. The later 6561-101's dump reads
|
|
1312
|
+
`$20` in the idle cycles instead; badline follows the 6561E.
|
|
1313
|
+
- Spec guard:
|
|
1314
|
+
[`vic20/vic_split_tests_timing_spec.rb`](../spec/badline/vic20/vic_split_tests_timing_spec.rb)
|
|
1315
|
+
(`:slow`), and *the fetches* in
|
|
1316
|
+
[`vic20/vic_video_spec.rb`](../spec/badline/vic20/vic_video_spec.rb).
|
|
1317
|
+
- A write to `$900F` or `$900E` takes hold from the second of the four
|
|
1318
|
+
pixels of the cycle it lands in, the reverse bit two pixels later, and
|
|
1319
|
+
a character's pixels come out in the two cycles after its pattern
|
|
1320
|
+
fetch. These match xvic's screenshots of a test of cycle-timed writes
|
|
1321
|
+
pixel for pixel; no testprog or hardware capture checks them.
|
|
1322
|
+
- Spec guard: *a colour write* in
|
|
1323
|
+
[`vic20/vic_video_spec.rb`](../spec/badline/vic20/vic_video_spec.rb).
|
|
1324
|
+
|
|
1325
|
+
## VIC-I sound
|
|
1326
|
+
|
|
1327
|
+
No testprog checks the VIC-I's sound, so these rules are pinned by xvic
|
|
1328
|
+
(VICE 3.10) recordings, run as a black box: `-sounddev wav` at 44.1 kHz of
|
|
1329
|
+
programs that set the registers, the same programs run on badline, and
|
|
1330
|
+
the two compared by period, harmonics and spectrum. xvic's own source
|
|
1331
|
+
wasn't read.
|
|
1332
|
+
|
|
1333
|
+
- A voice's counter comes round every 128 - ((value + 1) & 127) ticks of
|
|
1334
|
+
16, 8, 4 and 2 cycles from bass to noise, and a tone voice's shift
|
|
1335
|
+
register plays 16 shifts a period, as Marko Mäkelä's `VIC-I.txt`
|
|
1336
|
+
(revision 1.2, Levente Hársfalvi's measurements) gives the frequencies.
|
|
1337
|
+
- Pinned by xvic: `$900A` = `$FE`, `$80` and `$FF` measure 4329.70,
|
|
1338
|
+
34.0922 and 33.8256 Hz, `$900B` = `$F0` 577.29 Hz, and `$900C` = `$F0`
|
|
1339
|
+
and `$A0` 1154.59 and 182.30 Hz, each within 0.001 Hz of the formula
|
|
1340
|
+
on the PAL clock.
|
|
1341
|
+
- Spec guard: *a tone voice's counter* in
|
|
1342
|
+
[`vic20/sound_spec.rb`](../spec/badline/vic20/sound_spec.rb).
|
|
1343
|
+
- A tone voice's shift register takes bit 7 back into bit 0 inverted while
|
|
1344
|
+
the voice is on and a zero while it's off, and keeps shifting either way.
|
|
1345
|
+
Bit 0 is the output, not gated by the enable bit. This is the die-shot
|
|
1346
|
+
reading of the 6561 on the Denial forum (Lance Ewing: the feedback is a
|
|
1347
|
+
NOR of bit 7 and the inverted enable bit, and the counter keeps shifting
|
|
1348
|
+
a voice that's off).
|
|
1349
|
+
- Pinned by xvic: a bass voice loaded with 10101010, 11000000, 10000000
|
|
1350
|
+
and 11101000 by turning it on and off a shift at a time, then left
|
|
1351
|
+
on, has the same harmonics in xvic's recording and badline's to
|
|
1352
|
+
0.1 dB through the 12th. 10101010 puts the 7th and 9th harmonics
|
|
1353
|
+
above the fundamental, which a register cleared while off couldn't.
|
|
1354
|
+
- Spec guard: *a tone voice* in
|
|
1355
|
+
[`vic20/sound_spec.rb`](../spec/badline/vic20/sound_spec.rb).
|
|
1356
|
+
- The noise voice's counter steps a 16-bit LFSR: bit 0 takes the XOR of
|
|
1357
|
+
bits 3, 12, 14 and 15 while the voice is on and a one while it's off.
|
|
1358
|
+
Each rise of the LFSR's bit 0 shifts the noise voice's own shift
|
|
1359
|
+
register, bit 7 back into bit 0, inverted while the voice is on, and
|
|
1360
|
+
its bit 0 is the output while the voice is on. These are the die-shot
|
|
1361
|
+
readings on the Denial forum (Lance Ewing and nippur72), which also
|
|
1362
|
+
say the voice is silent while off.
|
|
1363
|
+
- Pinned by xvic: noise at `$FE` and `$FD` repeats every 0.11825 s and
|
|
1364
|
+
0.2365 s (autocorrelation 0.98 at those lags, in both xvic's
|
|
1365
|
+
recording and badline's), 65535 steps of 2 and 4 cycles. The octave
|
|
1366
|
+
band levels of noise at `$FE`, `$FD`, `$F0`, `$C0` and `$80` match
|
|
1367
|
+
xvic's within 0.5 dB up to 8 kHz.
|
|
1368
|
+
- Spec guard: *the noise voice* in
|
|
1369
|
+
[`vic20/sound_spec.rb`](../spec/badline/vic20/sound_spec.rb).
|
|
1370
|
+
- The output is the voices that are high plus 2/9 of a voice, times the
|
|
1371
|
+
volume, so a volume write steps the output with every voice off, as
|
|
1372
|
+
4-bit samples played through `$900E` need.
|
|
1373
|
+
- Pinned by xvic: a volume step from 0 to 15 with every voice off peaks
|
|
1374
|
+
at 0.218 of a voice turned on at volume 15.
|
|
1375
|
+
- Spec guard: *the volume* in
|
|
1376
|
+
[`vic20/sound_spec.rb`](../spec/badline/vic20/sound_spec.rb).
|
|
1377
|
+
- Not pinned: the volume scales the output linearly. xvic's tone level
|
|
1378
|
+
per volume step isn't linear (volume 1 is 0.099 of volume 15 and 14
|
|
1379
|
+
is 1.015), and nothing here says whether the hardware is.
|
|
1380
|
+
- The output stage is a one-pole low-pass at 1,420 Hz and a one-pole
|
|
1381
|
+
high-pass at 158 Hz.
|
|
1382
|
+
- Pinned by xvic: a bass voice turned on at volume 15 fits those two RC
|
|
1383
|
+
stages at 1,417 and 158.0 Hz, with an RMS error of 6 against a peak of
|
|
1384
|
+
11,280. badline's own recording fits 1,420 and 157.6 Hz.
|
|
1385
|
+
- Spec guard: *a step* in
|
|
1386
|
+
[`vic20/sound/output_spec.rb`](../spec/badline/vic20/sound/output_spec.rb).
|
|
1387
|
+
|
|
1198
1388
|
## 1541 serial port
|
|
1199
1389
|
|
|
1200
1390
|
- The drive sees the C64's side of the serial bus a host cycle late. The
|