badline 0.11.1 → 0.12.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 +26 -0
- data/CLAUDE.md +8 -7
- data/CONTRIBUTING.md +7 -6
- data/README.md +12 -5
- data/doc/media.md +28 -1
- data/doc/pinned-behaviour.md +31 -1
- data/exe/badline-ruby +1 -1
- data/lib/badline/address_bus/saved_state.rb +4 -10
- data/lib/badline/address_bus.rb +8 -27
- data/lib/badline/audio/bare_player.rb +1 -1
- data/lib/badline/c128/bus.rb +17 -52
- data/lib/badline/c128/bus_state.rb +5 -5
- data/lib/badline/c128/drives.rb +35 -22
- data/lib/badline/c128/fast_serial.rb +1 -0
- data/lib/badline/c128/io_pages.rb +35 -0
- data/lib/badline/c128/mmu.rb +9 -7
- data/lib/badline/c128/modes.rb +17 -4
- data/lib/badline/c128/saved_state.rb +22 -0
- data/lib/badline/c128/z80.rb +49 -0
- data/lib/badline/c128/z80_pages.rb +118 -0
- data/lib/badline/c128/z80_turns.rb +106 -0
- data/lib/badline/c128.rb +21 -83
- data/lib/badline/cartridge/action_replay.rb +2 -2
- data/lib/badline/cartridge/comal80.rb +1 -7
- data/lib/badline/cartridge/dinamic.rb +0 -8
- data/lib/badline/cartridge/final_cartridge3.rb +6 -6
- data/lib/badline/cartridge/fun_play.rb +0 -8
- data/lib/badline/cartridge/game_system.rb +0 -8
- data/lib/badline/cartridge/kcs_power.rb +10 -7
- data/lib/badline/cartridge/mach5.rb +2 -4
- data/lib/badline/cartridge/magic_desk.rb +0 -8
- data/lib/badline/cartridge/ocean.rb +0 -8
- data/lib/badline/cartridge/pagefox.rb +2 -2
- data/lib/badline/cartridge/retro_replay.rb +7 -6
- data/lib/badline/cartridge/rex_utility.rb +2 -6
- data/lib/badline/cartridge/rgcd.rb +2 -2
- data/lib/badline/cartridge/simons_basic.rb +0 -5
- data/lib/badline/cartridge/super_games.rb +4 -2
- data/lib/badline/cartridge/westermann.rb +2 -6
- data/lib/badline/cartridge.rb +37 -9
- data/lib/badline/cia/fast_forward.rb +21 -3
- data/lib/badline/cia.rb +8 -5
- data/lib/badline/computer/attachments.rb +14 -95
- data/lib/badline/computer/common.rb +34 -0
- data/lib/badline/computer/kernal_traps.rb +65 -5
- data/lib/badline/computer/true_drives.rb +69 -0
- data/lib/badline/computer.rb +9 -68
- data/lib/badline/core.rb +4 -2
- data/lib/badline/cpu_port.rb +112 -0
- data/lib/badline/drive/core.rb +8 -33
- data/lib/badline/drive/fast_serial.rb +73 -0
- data/lib/badline/drive/idle.rb +1 -11
- data/lib/badline/drive/orbit.rb +2 -5
- data/lib/badline/drive/sleep.rb +0 -2
- data/lib/badline/drive/vias.rb +84 -0
- data/lib/badline/drive.rb +2 -0
- data/lib/badline/drive1541/disk.rb +14 -17
- data/lib/badline/drive1541/disk_state.rb +7 -15
- data/lib/badline/drive1541.rb +1 -0
- data/lib/badline/drive1571/wd1770.rb +94 -8
- data/lib/badline/drive1571.rb +8 -58
- data/lib/badline/drive1581/bus.rb +137 -0
- data/lib/badline/drive1581/cpu.rb +11 -0
- data/lib/badline/drive1581/disk.rb +135 -0
- data/lib/badline/drive1581/disk_state.rb +87 -0
- data/lib/badline/drive1581/mechanism.rb +117 -0
- data/lib/badline/drive1581/serial_port.rb +52 -0
- data/lib/badline/drive1581/slot.rb +78 -0
- data/lib/badline/drive1581/track.rb +100 -0
- data/lib/badline/drive1581/track_bytes.rb +75 -0
- data/lib/badline/drive1581/wd1772/registers.rb +89 -0
- data/lib/badline/drive1581/wd1772/sector_writes.rb +73 -0
- data/lib/badline/drive1581/wd1772/sectors.rb +150 -0
- data/lib/badline/drive1581/wd1772/state.rb +66 -0
- data/lib/badline/drive1581/wd1772/stepping.rb +109 -0
- data/lib/badline/drive1581/wd1772/tracks.rb +125 -0
- data/lib/badline/drive1581/wd1772/turn.rb +73 -0
- data/lib/badline/drive1581/wd1772.rb +216 -0
- data/lib/badline/drive1581.rb +233 -0
- data/lib/badline/frontend/app.rb +1 -3
- data/lib/badline/frontend/audio_device.rb +67 -0
- data/lib/badline/frontend/audio_sink.rb +16 -50
- data/lib/badline/frontend/boot.rb +24 -67
- data/lib/badline/frontend/buttons.rb +7 -7
- data/lib/badline/frontend/keys.rb +33 -8
- data/lib/badline/frontend/media_slots.rb +42 -0
- data/lib/badline/frontend/{confirmation.rb → menu/confirmation.rb} +4 -4
- data/lib/badline/frontend/{file_browser.rb → menu/file_browser.rb} +18 -34
- data/lib/badline/frontend/{menu_dialogs.rb → menu/menu_dialogs.rb} +3 -7
- data/lib/badline/frontend/{menu_media.rb → menu/menu_media.rb} +26 -51
- data/lib/badline/frontend/{menu_pages.rb → menu/menu_pages.rb} +5 -8
- data/lib/badline/frontend/{name_field.rb → menu/name_field.rb} +11 -24
- data/lib/badline/frontend/{pause_menu.rb → menu/pause_menu.rb} +13 -28
- data/lib/badline/frontend/menu/theme.rb +18 -0
- data/lib/badline/frontend/{filter_view.rb → player/filter_view.rb} +4 -4
- data/lib/badline/frontend/{info_view.rb → player/info_view.rb} +3 -3
- data/lib/badline/frontend/{player_window.rb → player/player_controller.rb} +17 -25
- data/lib/badline/frontend/{player_footer.rb → player/player_footer.rb} +8 -8
- data/lib/badline/frontend/{player_header.rb → player/player_header.rb} +5 -5
- data/lib/badline/frontend/{player_screen.rb → player/player_screen.rb} +4 -5
- data/lib/badline/frontend/{scope.rb → player/scope.rb} +1 -1
- data/lib/badline/frontend/{sid_view.rb → player/sid_view.rb} +16 -20
- data/lib/badline/frontend/player/theme.rb +18 -0
- data/lib/badline/frontend/{visualizer_view.rb → player/visualizer_view.rb} +8 -8
- data/lib/badline/frontend/sound.rb +19 -38
- data/lib/badline/frontend/timeline.rb +3 -14
- data/lib/badline/frontend.rb +24 -20
- data/lib/badline/iec_bus.rb +14 -2
- data/lib/badline/kernal_trap/{file.rb → file_routine.rb} +1 -1
- data/lib/badline/kernal_trap/load.rb +1 -1
- data/lib/badline/kernal_trap/save.rb +1 -1
- data/lib/badline/kernal_trap.rb +1 -1
- data/lib/badline/machine/clocking.rb +50 -0
- data/lib/badline/machine.rb +63 -6
- data/lib/badline/media/boot_disk.rb +50 -0
- data/lib/badline/media/disk_list.rb +3 -3
- data/lib/badline/media/disk_set.rb +1 -1
- data/lib/badline/media/extensions.rb +33 -0
- data/lib/badline/media/not_disk.rb +8 -0
- data/lib/badline/media/program.rb +28 -0
- data/lib/badline/media/true_drive.rb +38 -17
- data/lib/badline/media/tune.rb +35 -0
- data/lib/badline/media/vic20_cartridge.rb +1 -7
- data/lib/badline/media/vic20_media.rb +38 -80
- data/lib/badline/media.rb +90 -81
- data/lib/badline/options/event.rb +4 -2
- data/lib/badline/options/family.rb +3 -9
- data/lib/badline/options/help.rb +2 -1
- data/lib/badline/roms/README +9 -0
- data/lib/badline/roms/dos1581.rom +0 -0
- data/lib/badline/sdl.rb +37 -20
- data/lib/badline/sid.rb +1 -1
- data/lib/badline/snapshot/machine_state.rb +9 -1
- data/lib/badline/snapshot/state.rb +6 -4
- data/lib/badline/snapshot.rb +11 -9
- data/lib/badline/storage/d64_image.rb +15 -7
- data/lib/badline/storage/disk_image/writing.rb +2 -2
- data/lib/badline/storage/disk_image.rb +1 -1
- data/lib/badline/storage/host_directory.rb +1 -1
- data/lib/badline/storage/p00.rb +8 -0
- data/lib/badline/storage/t64.rb +1 -1
- data/lib/badline/time_of_day.rb +3 -3
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic/bank.rb +1 -1
- data/lib/badline/vic/border_mask.rb +1 -1
- data/lib/badline/vic/collisions.rb +1 -1
- data/lib/badline/vic/color_patches.rb +1 -1
- data/lib/badline/vic/display_state.rb +1 -1
- data/lib/badline/vic/graphics_mode.rb +1 -1
- data/lib/badline/vic/graphics_shifter.rb +1 -1
- data/lib/badline/vic/register_log.rb +1 -1
- data/lib/badline/vic/registers.rb +1 -1
- data/lib/badline/vic/sequencer.rb +1 -1
- data/lib/badline/vic/sequencer_output.rb +1 -1
- data/lib/badline/vic/sequencer_state.rb +1 -1
- data/lib/badline/vic/sprite/internal_bus.rb +1 -1
- data/lib/badline/vic/sprite/saved_state.rb +1 -1
- data/lib/badline/vic/sprite/shifter.rb +1 -1
- data/lib/badline/vic/sprite/timing.rb +1 -1
- data/lib/badline/vic/sprite.rb +1 -1
- data/lib/badline/vic/sprites.rb +1 -1
- data/lib/badline/vic/sprites_state.rb +1 -1
- data/lib/badline/vic.rb +6 -5
- data/lib/badline/vic20/attachments.rb +15 -71
- data/lib/badline/vic20/saved_state.rb +2 -30
- data/lib/badline/vic20.rb +4 -37
- data/lib/badline/z80/core.rb +2 -0
- data/lib/badline/z80/saved_state.rb +69 -0
- metadata +61 -23
- data/lib/badline/cycleable.rb +0 -38
- /data/lib/badline/frontend/{menu_ports.rb → menu/menu_ports.rb} +0 -0
- /data/lib/badline/frontend/{player_commands.rb → player/player_commands.rb} +0 -0
- /data/lib/badline/frontend/{player_state.rb → player/player_state.rb} +0 -0
- /data/lib/badline/frontend/{sid_history.rb → player/sid_history.rb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8872c5d5117a691aa38d054acd5dd7e84f7abf737c977a2dc309c6dc3072381d
|
|
4
|
+
data.tar.gz: fa4f4e5b3729989c78443f73bd655c2083555d62a8d3ee45437d147bfe0e5fb8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d278ba0e0341242af3e1782a8c003bc4cbdb1594be434021b5bbccae126ddf12dd89ffa0520dd615075a77f89b1285595d2101868db0e6679b69130586ed210c
|
|
7
|
+
data.tar.gz: 5dabb1d53a29dc43b619f90abd67495ab3847d3ba8d8f89275d45f276aac4fbe3ca37a4963f048e300e88cd50228b35bd39da7efbd431f46527b893b1c4bd95c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.12.1](https://github.com/elektronaut/badline/compare/v0.12.0...v0.12.1) (2026-10-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* keep the 1581's idle deadline within a native build's integers ([a98848f](https://github.com/elektronaut/badline/commit/a98848f0889ca7ad4c12007976b63d54bbbf122b))
|
|
9
|
+
* refuse snapshot values a native build can't hold, on CRuby too ([5ec51e8](https://github.com/elektronaut/badline/commit/5ec51e81cfabfdb585367bb2f8183516ac64d2b0))
|
|
10
|
+
|
|
11
|
+
## [0.12.0](https://github.com/elektronaut/badline/compare/v0.11.1...v0.12.0) (2026-10-10)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* add the 1581's WD1772 and its .d81 disks at sector level ([b834218](https://github.com/elektronaut/badline/commit/b834218bb686ceef295f2aafada86910fe8b61a2))
|
|
17
|
+
* boot C128 boot disks such as CP/M at power-on ([69359b6](https://github.com/elektronaut/badline/commit/69359b60bfe91ec0d9634e3dec4e4039044814e7))
|
|
18
|
+
* emulate the 1581 drive on the C64, the VIC-20 and the C128 ([4696c5b](https://github.com/elektronaut/badline/commit/4696c5b205689b2a86f91503ce153a63ff0f6816))
|
|
19
|
+
* put the C128's Z80 on its bus and boot the C128 through it ([b3d0e60](https://github.com/elektronaut/badline/commit/b3d0e603a8dc606d090917a67a52c4f31854f307))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
* let the 1571's WD1770 run its commands, so CP/M's disk BIOS finds no MFM disk ([a380768](https://github.com/elektronaut/badline/commit/a380768ae02ce5da33e73dc23147b4edb72c72ff))
|
|
25
|
+
* parse --at insert of a disk list without the rest of badline ([5d6b93a](https://github.com/elektronaut/badline/commit/5d6b93a86cf4b57be3312bfb7da32980d38f2800))
|
|
26
|
+
* save the KCS Power cartridge's I/O RAM in snapshots ([54fab40](https://github.com/elektronaut/badline/commit/54fab408d0d7447d5b7b977905aa7aaabf8ad92a))
|
|
27
|
+
* uninstall the serial traps when the VIC-20 unmounts ([b2acc3f](https://github.com/elektronaut/badline/commit/b2acc3ff495f10ec5bff3b56aae0e89b2741bd34))
|
|
28
|
+
|
|
3
29
|
## [0.11.1](https://github.com/elektronaut/badline/compare/v0.11.0...v0.11.1) (2026-10-09)
|
|
4
30
|
|
|
5
31
|
|
data/CLAUDE.md
CHANGED
|
@@ -51,7 +51,7 @@ requires only the namespace file.
|
|
|
51
51
|
| SingleStepTests 65x02 | `rake test` (100 sampled cases per opcode) | CPU, per-cycle bus traces |
|
|
52
52
|
| SingleStepTests z80 | `rake test` (the first 100 cases per opcode, `Z80_SAMPLE=all` for all 1,604,000) | `Z80`: registers, flags, ports and the bus pins on every T-state |
|
|
53
53
|
| Wolfgang Lorenz suite | `bin/lorenz` | CPU, CIA, interrupts |
|
|
54
|
-
| VICE testbench | `bin/testbench <subtree>` | `VICII/`, `CIA/`, `interrupts/`, `CPU/`, cartridges with `--carts`, the true 1541 drive with `--drive`, the VIC-20 with `--vic20`,
|
|
54
|
+
| VICE testbench | `bin/testbench <subtree>` | `VICII/`, `CIA/`, `interrupts/`, `CPU/`, cartridges with `--carts`, the true 1541 drive with `--drive`, the VIC-20 with `--vic20`, the C128 in C64 mode with `--c128c64`, in C128 mode with `--c128`, and its Z80 with `--c128-z80` |
|
|
55
55
|
| VICE SID testprogs | `bin/sidtests` | SID |
|
|
56
56
|
| Drive scenarios | `bin/drive_scenarios` | The true 1541 running the DOS ROM: save, format, the error channel, idle, write protect and autostart |
|
|
57
57
|
| CIA offline grids | `bundle exec rspec --tag slow spec/badline/cia` | CIA timers and shift register, against a bare CIA in about 2 min |
|
|
@@ -136,10 +136,11 @@ worktree and owns a different set of files.
|
|
|
136
136
|
fails a whole-suite run (every spec file, no filters) below 90%, while
|
|
137
137
|
single-file and filtered runs skip the floor. `:slow` specs are excluded
|
|
138
138
|
by default: run them with `bundle exec rspec --tag slow`
|
|
139
|
-
-
|
|
140
|
-
in
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
- `bundle exec parallel_rspec` is the whole run, `:slow` specs included,
|
|
140
|
+
in a process per core, held to the same 90% over the merged coverage.
|
|
141
|
+
CI runs it as two jobs, the plain examples (with the floor) and the
|
|
142
|
+
`:slow` ones. Agents run only the spec files they touch, with
|
|
143
|
+
plain `bundle exec rspec`, and leave whole runs to CI
|
|
143
144
|
- Keep each plain example to a few hundred ms. A million cycles of a C64 or
|
|
144
145
|
a C128 cost 3 to 5 s of CPU, and about three times that under coverage,
|
|
145
146
|
so an example that boots a machine or runs more than about a million
|
|
@@ -215,13 +216,13 @@ the 6526A) for anything the interrupt register or the CIA model reaches; cartrid
|
|
|
215
216
|
`testbench-drive` (`bin/testbench --drive`) and `drive-scenarios` (`bin/drive_scenarios <filter>`), plus `testbench-vic20` for the VIA; the VIC-20 (`vic20/`) →
|
|
216
217
|
`testbench-vic20` (`bin/testbench --vic20`); the C128 (`c128.rb`, `c128/`), or
|
|
217
218
|
the VIC-IIe, CPU or PLA code it shares with the C64 → `testbench-c128c64`
|
|
218
|
-
(`bin/testbench --c128c64`); SID → `sid`, plus `sid-8580` for anything the 8580
|
|
219
|
+
(`bin/testbench --c128c64`); the C128's Z80, MMU or hand-over → `testbench-c128-z80` (`bin/testbench --c128-z80`) and `testbench-c128`; SID → `sid`, plus `sid-8580` for anything the 8580
|
|
219
220
|
model reaches (`bin/sidtests --sid 8580`). Leave the Lorenz chain to CI,
|
|
220
221
|
unless your code has a rule in `doc/pinned-behaviour.md` that names Lorenz
|
|
221
222
|
tests: the interrupt polling, CPU port and CIA timer rules. Run just the
|
|
222
223
|
tests that rule names, one at a time, with
|
|
223
224
|
`ruby --yjit bin/lorenz --resume <test> --stop-after <test>`. A stretch
|
|
224
|
-
resumes on a fresh machine, so its cuts in
|
|
225
|
+
resumes on a fresh machine, so its cuts in `test/support/suites.rb` have to stay before
|
|
225
226
|
`trap1`, where the tests start carrying state from one to the next. Both Lorenz
|
|
226
227
|
and testbench load through the LOAD trap and type through the keyboard
|
|
227
228
|
buffer, so storage, IEC and keyboard changes can move them too. A broken
|
data/CONTRIBUTING.md
CHANGED
|
@@ -55,17 +55,18 @@ brew install sdl2 # macOS
|
|
|
55
55
|
apt install libsdl2-2.0-0 # Debian/Ubuntu
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
Install the dependencies and run the
|
|
58
|
+
Install the dependencies and run the whole suite, a process per core, as
|
|
59
|
+
CI does:
|
|
59
60
|
|
|
60
61
|
```sh
|
|
61
62
|
bundle install
|
|
62
|
-
bundle exec
|
|
63
|
+
bundle exec parallel_rspec
|
|
63
64
|
```
|
|
64
65
|
|
|
65
|
-
A run of the whole suite fails if line coverage drops below 90%.
|
|
66
|
-
single files or filtered examples
|
|
67
|
-
boot the whole machine and
|
|
68
|
-
`bundle exec rspec --tag slow`.
|
|
66
|
+
A run of the whole suite fails if line coverage drops below 90%. Run
|
|
67
|
+
single files or filtered examples with `bundle exec rspec`, which skips
|
|
68
|
+
that check. Specs tagged `:slow` boot the whole machine, and a plain
|
|
69
|
+
`bundle exec rspec` skips them. Run them with `bundle exec rspec --tag slow`.
|
|
69
70
|
|
|
70
71
|
The CPU is verified separately against the
|
|
71
72
|
[65x02 single step tests](https://github.com/SingleStepTests/65x02), and
|
data/README.md
CHANGED
|
@@ -125,7 +125,7 @@ library, are covered in [doc/library.md](doc/library.md).
|
|
|
125
125
|
| Format | Handling |
|
|
126
126
|
|--------|----------|
|
|
127
127
|
| `.prg`, `.p00` | Loaded into memory after boot. A program at the BASIC start (`$0801`) is `RUN`, anything else is left for you to `SYS` |
|
|
128
|
-
| `.d64`, `.d71`, `.d81` | Mounted as device 8, then `LOAD"*",8,1` and `RUN`. Write-protected unless `--writable` |
|
|
128
|
+
| `.d64`, `.d71`, `.d81` | Mounted as device 8, then `LOAD"*",8,1` and `RUN`. On a C128 in C128 mode a boot disk goes in a true drive instead and boots at power-on. See [Media](doc/media.md#c128-boot-disks). Write-protected unless `--writable` |
|
|
129
129
|
| `.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` |
|
|
130
130
|
| `.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 |
|
|
131
131
|
| `.t64` | Mounted read-only as device 8 and loaded like a disk image. The files load by name, and no tape is involved |
|
|
@@ -139,7 +139,8 @@ Without `--true-drive`, device 8 is no drive at all but traps on the
|
|
|
139
139
|
KERNAL's disk routines. Loading is instant, but fast loaders and copy
|
|
140
140
|
protection that run code on the drive need `--true-drive`, which puts
|
|
141
141
|
an emulated 1541 there, running its own DOS at a real 1541's speed. Its
|
|
142
|
-
red LED lights in the bottom right corner of the border.
|
|
142
|
+
red LED lights in the bottom right corner of the border. With
|
|
143
|
+
`--true-drive`, a `.d81` goes in an emulated 1581 in place of the 1541.
|
|
143
144
|
[doc/media.md](doc/media.md) has the details, and how to attach media
|
|
144
145
|
from Ruby.
|
|
145
146
|
|
|
@@ -185,8 +186,11 @@ cartridge, through the KERNAL. `GO64` gets there from BASIC 7.0. A
|
|
|
185
186
|
program that loads at `$1C01`, where BASIC 7.0 starts, runs, and other
|
|
186
187
|
programs load at their own address. The disk in device 8 is served
|
|
187
188
|
through the KERNAL traps in either mode, or with `--true-drive` by the
|
|
188
|
-
C128D's 1571.
|
|
189
|
-
|
|
189
|
+
C128D's 1571. A boot disk boots in C128 mode, as on a real C128: CP/M's
|
|
190
|
+
system disks, a `.d81` such as VICE-testprogs' `c128-cpm/cpm3.d81` on a
|
|
191
|
+
1581 among them, and boot games. `badline c128 cpm3.d81` comes up at
|
|
192
|
+
CP/M's `A>` prompt. The Z80 starts the machine, as on a real C128, and hands
|
|
193
|
+
it to the 8502. `--model` picks the board: `c128` (the default, the flat C128
|
|
190
194
|
and the plastic C128D, PAL, with the 6581 SID and a VDC with 16K of
|
|
191
195
|
RAM), `c128dcr` (the metal C128DCR, with the 8580, 6526As and a VDC with
|
|
192
196
|
64K), and `c128ntsc` and `c128dcrntsc` for their NTSC versions. `--sid`
|
|
@@ -349,11 +353,14 @@ program or `.sid` dropped on it opens the menu to ask first.
|
|
|
349
353
|
- **C128**: C128 mode with BASIC 7.0 and C64 mode, on the 8502 with its
|
|
350
354
|
port, FAST mode, the VIC-IIe with its extra keyboard lines, the 8722
|
|
351
355
|
MMU, the 8563 or 8568 VDC with its 80 column display, and 128K of RAM
|
|
352
|
-
(`badline c128`)
|
|
356
|
+
(`badline c128`), and the Z80, which boots the machine.
|
|
353
357
|
- **1541**: an emulated drive running its own DOS (`--true-drive`).
|
|
354
358
|
- **1571**: the C128D's drive running DOS 3.0, in 1541 mode and in 1571
|
|
355
359
|
mode at 2 MHz with both sides of a `.d71` or `.g71`, and fast serial
|
|
356
360
|
(burst) to a C128 in C128 mode (`badline c128 --true-drive`).
|
|
361
|
+
- **1581**: the 3.5" drive running its own DOS on its WD1772 and 8520,
|
|
362
|
+
reading and writing `.d81` images, on the C64, the VIC-20 and the C128
|
|
363
|
+
(`--true-drive` with a `.d81`).
|
|
357
364
|
- **Cartridges**: standard 8K, 16K and Ultimax, Simons' BASIC, Ocean,
|
|
358
365
|
Fun Play / Power Play, Super Games, Epyx FastLoad, Westermann
|
|
359
366
|
Learning, Rex Utility, C64 Game System / System 3, Dinamic, Zaxxon /
|
data/doc/media.md
CHANGED
|
@@ -36,6 +36,31 @@ drive's red LED lights in the bottom right corner of the border.
|
|
|
36
36
|
A `.g64` holds the disk's raw GCR, half tracks and all, so copy
|
|
37
37
|
protection and fast loaders that read it work.
|
|
38
38
|
|
|
39
|
+
## The true 1581
|
|
40
|
+
|
|
41
|
+
With a true drive on device 8, a `.d81` goes in an emulated 1581 in
|
|
42
|
+
its place: the 3.5" drive's own DOS on its 6502, with its WD1772 reading
|
|
43
|
+
and writing the image's sectors and its 8520 on the serial bus. Another
|
|
44
|
+
disk image swaps the 1541 (or on the C128 the 1571) back in. On the
|
|
45
|
+
C128 in C128 mode the 1581 talks fast serial (burst), as the 1571 does.
|
|
46
|
+
|
|
47
|
+
## C128 boot disks
|
|
48
|
+
|
|
49
|
+
At power-on the C128 KERNAL reads track 1, sector 0 of the disk in
|
|
50
|
+
device 8, and when the block starts with `CBM` it loads and runs it.
|
|
51
|
+
CP/M's system disks and boot games boot that way. A 1581 first loads and
|
|
52
|
+
runs a `USR` file named `COPYRIGHT CBM 86` when the disk has one, which
|
|
53
|
+
is how CP/M's 1581 disks hand the KERNAL their boot block.
|
|
54
|
+
|
|
55
|
+
On a C128 in C128 mode, a `.d64`, `.d71` or `.d81` that boots, with that
|
|
56
|
+
block or that file, goes in a true drive as device 8, a 1581 for a
|
|
57
|
+
`.d81` and the C128D's 1571 otherwise, and nothing is typed, so the
|
|
58
|
+
KERNAL boots it. `badline c128 cpm3.d81` comes up at CP/M's `A>`
|
|
59
|
+
prompt. Other disks keep the traps and `LOAD"*",8,1`, `--true-drive`
|
|
60
|
+
puts any disk in a true drive, and on the C64, the VIC-20 and a C128 in
|
|
61
|
+
C64 mode nothing changes. A boot disk inserted while the machine runs
|
|
62
|
+
boots at the next reset.
|
|
63
|
+
|
|
39
64
|
## Write protection
|
|
40
65
|
|
|
41
66
|
Disks given on the command line, inserted from the pause menu or by an
|
|
@@ -56,7 +81,9 @@ another disk. Both write to disk images unless told otherwise:
|
|
|
56
81
|
`disk: { read_only: true }`, as the test harnesses under `bin/` do. A
|
|
57
82
|
`.g64` goes in the true 1541, and takes out a disk mounted through the
|
|
58
83
|
traps, so `LOAD` and `SAVE` reach the 1541 too. With the 1541 in device
|
|
59
|
-
8, a `.d64` goes in its drive as well
|
|
84
|
+
8, a `.d64` goes in its drive as well, and a `.d81` in a 1581 that takes
|
|
85
|
+
the 1541's place. On a C128 in C128 mode, `attach` puts a boot disk in a
|
|
86
|
+
true drive and types nothing (`Badline::Media::BootDisk`).
|
|
60
87
|
|
|
61
88
|
`Badline::Media::DiskSet.around(path)` lists the disks of the set a disk
|
|
62
89
|
image belongs to, which the pause menu's PREVIOUS DISK and NEXT DISK step
|
data/doc/pinned-behaviour.md
CHANGED
|
@@ -26,6 +26,7 @@ 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-IIe 2 MHz and TEST bit](#vic-iie-2-mhz-and-test-bit)
|
|
29
|
+
- [C128 Z80 bus](#c128-z80-bus)
|
|
29
30
|
- [VIC-II NTSC](#vic-ii-ntsc)
|
|
30
31
|
- [VIC-II 6572 (Drean)](#vic-ii-6572-drean)
|
|
31
32
|
- [CIA 6526 timer pipeline](#cia-6526-timer-pipeline)
|
|
@@ -1001,6 +1002,35 @@ $1C0E and checks the readings they print.
|
|
|
1001
1002
|
per-cycle blanking. Their 8566 shows no grey dots. The 2mhzVIC
|
|
1002
1003
|
references have none either.
|
|
1003
1004
|
|
|
1005
|
+
## C128 Z80 bus
|
|
1006
|
+
|
|
1007
|
+
- The Z80 gets 2 T-states in every cycle BA leaves it the bus, with no
|
|
1008
|
+
wait states for memory or I/O: each of the 1,868 `c128z80timing`
|
|
1009
|
+
programs measures `T-states / 2` 1 MHz cycles with the screen blanked.
|
|
1010
|
+
Pinned by `c128/z80/c128z80timing`. The timing rows can't pin where in
|
|
1011
|
+
an I/O machine cycle the chips see an IN or OUT, since the timer starts
|
|
1012
|
+
and stops through the same OUT: `Z80Turns::IO_DELAY` is 2 because
|
|
1013
|
+
`c128modez80-23`'s IN at `$D700`, which reads open bus, passes at 1 or 2
|
|
1014
|
+
and fails at 0, 3 and 4.
|
|
1015
|
+
- In C128 mode with CR bits 6-7 both 0, `$0000-$0FFF` reads the BIOS
|
|
1016
|
+
(`$D000-$DFFF` of the KERNAL ROM), and a write, IN or OUT there reaches
|
|
1017
|
+
the RAM at `$Dxxx` of bank 0. CR `$BF` (bank 2, which is bank 0 on a
|
|
1018
|
+
128K machine) leaves the BIOS out, as does bank 1: `$0xxx` is RAM, common
|
|
1019
|
+
RAM's or the bank's. `$D000-$DFFF` is RAM to the Z80's memory accesses.
|
|
1020
|
+
Pinned by `c128modez80-15` to `-22` and `-25`, `outi/tstouti2` and
|
|
1021
|
+
`mmu_zp_sp/tstz80bk` (x128 fails the last).
|
|
1022
|
+
- IN and OUT reach the chips at `$D000-$DFFF` whatever CR's I/O bit says,
|
|
1023
|
+
in both modes. The MMU at `$D500` takes an OUT either way in C128 mode,
|
|
1024
|
+
but answers an IN only with I/O on. Pinned by `c128modez80-10` (the IN)
|
|
1025
|
+
and `tstz80bk`, which programs page relocation through OUT with CR
|
|
1026
|
+
`$BF`.
|
|
1027
|
+
- While I/O is mapped in, the colour RAM the 8502 sees also answers at
|
|
1028
|
+
`$1000-$13FF`, in memory and through IN and OUT. Pinned by
|
|
1029
|
+
`c128modez80-02` to `-09` and `c64modez80-03` and `-05`.
|
|
1030
|
+
- In C64 mode the Z80's memory accesses decode as the 8502's do through
|
|
1031
|
+
the PLA, with no BIOS. Pinned by `c64modez80-00` to `-06`.
|
|
1032
|
+
- Spec guard: [`z80_bus_spec.rb`](../spec/badline/c128/z80_bus_spec.rb).
|
|
1033
|
+
|
|
1004
1034
|
## VIC-II NTSC
|
|
1005
1035
|
|
|
1006
1036
|
The 6567R8 (`Region::NTSC`) and the 6567R56A (`Region::NTSC_OLD`) run
|
|
@@ -1507,7 +1537,7 @@ wasn't read.
|
|
|
1507
1537
|
[`mechanism_spec.rb`](../spec/badline/drive1541/mechanism_spec.rb),
|
|
1508
1538
|
and the `format/name-and-id`, `format/bam-free` and
|
|
1509
1539
|
`format/trap-readable` rows of the `drive-scenarios` suite
|
|
1510
|
-
([`drive_scenarios.rb`](../test/drive_scenarios.rb)), which read the
|
|
1540
|
+
([`drive_scenarios.rb`](../test/support/drive_scenarios.rb)), which read the
|
|
1511
1541
|
formatted disk back from its image.
|
|
1512
1542
|
- The disk turns at 300 rpm whatever bit rate VIA 2's PB5-6 select: a
|
|
1513
1543
|
turn is 200,000 drive cycles over every track and over a half track
|
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::
|
|
42
|
+
Badline::Frontend::PlayerController.new(input:, output:)
|
|
43
43
|
end
|
|
44
44
|
else
|
|
45
45
|
Badline::Audio::Console.method(:new)
|
|
@@ -17,15 +17,12 @@ module Badline
|
|
|
17
17
|
|
|
18
18
|
# The 6510 port's direction and output registers, and the charge left
|
|
19
19
|
# on its floating bits.
|
|
20
|
-
def port_state = [@
|
|
20
|
+
def port_state = [@cpu_port.ddr, @cpu_port.data, @cpu_port.floating]
|
|
21
21
|
|
|
22
22
|
# Sets the port as port_state reads it, as a snapshot restores it,
|
|
23
23
|
# leaving the RAM under $00 and $01 alone.
|
|
24
24
|
def restore_port(ddr, out, floating)
|
|
25
|
-
@
|
|
26
|
-
@port_out = out
|
|
27
|
-
@port_floating = floating
|
|
28
|
-
update_port!
|
|
25
|
+
@cpu_port.restore(ddr, out, floating)
|
|
29
26
|
end
|
|
30
27
|
|
|
31
28
|
# The machine's memory and everything on the bus but the keyboard, the
|
|
@@ -33,7 +30,7 @@ module Badline
|
|
|
33
30
|
# already in the port, built from its setup (Computer#load_state).
|
|
34
31
|
def save_state(out)
|
|
35
32
|
out.marker("BUS")
|
|
36
|
-
out.int(@
|
|
33
|
+
out.int(@cpu_port.ddr).int(@cpu_port.data).int(@cpu_port.floating)
|
|
37
34
|
@ram.save_state(out)
|
|
38
35
|
@color_ram.save_state(out)
|
|
39
36
|
@ram_expansion.save_state(out)
|
|
@@ -55,10 +52,7 @@ module Badline
|
|
|
55
52
|
@ram_expansion.load_state(input)
|
|
56
53
|
@cartridge&.load_state(input)
|
|
57
54
|
@datasette.load_state(input)
|
|
58
|
-
@
|
|
59
|
-
@port_out = port_out
|
|
60
|
-
@port_floating = floating
|
|
61
|
-
@io_port.value = port_value
|
|
55
|
+
@cpu_port.load(ddr, port_out, floating)
|
|
62
56
|
update_overlays!
|
|
63
57
|
@vic.load_state(input)
|
|
64
58
|
@cia1.load_state(input)
|
data/lib/badline/address_bus.rb
CHANGED
|
@@ -52,9 +52,9 @@ module Badline
|
|
|
52
52
|
def poke(_addr, _value); end
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
# The 6510's port pins with pull-ups, and the floating ones (CPUPort).
|
|
55
56
|
PORT_PULLUPS = 0b0001_0111
|
|
56
57
|
PORT_FLOATING = 0b1100_1000
|
|
57
|
-
TAPE_SENSE = 0b0001_0000
|
|
58
58
|
|
|
59
59
|
# RAM powers on in runs of $00 $00 $FF $FF $FF $FF $00 $00, inverted in
|
|
60
60
|
# the second and fourth 16K: a C64C (ASSY 250469 R4) from
|
|
@@ -92,7 +92,7 @@ module Badline
|
|
|
92
92
|
|
|
93
93
|
@datasette = Datasette.new
|
|
94
94
|
@datasette.on_flag { @cia1.flag! }
|
|
95
|
-
@datasette.on_sense_change { @
|
|
95
|
+
@datasette.on_sense_change { @cpu_port.refresh }
|
|
96
96
|
|
|
97
97
|
@color_ram = ColorMemory.new(@vic)
|
|
98
98
|
@vic.vic_bank.connect(cia2: @cia2, color_ram: @color_ram)
|
|
@@ -100,10 +100,9 @@ module Badline
|
|
|
100
100
|
@open_bus = OpenBus.new(@vic)
|
|
101
101
|
@cpu_off_bus = false
|
|
102
102
|
|
|
103
|
-
@
|
|
104
|
-
@
|
|
105
|
-
@
|
|
106
|
-
@io_port = PortStatus.new(%i[basic kernal io tape_out tape_switch tape_motor], value: port_value)
|
|
103
|
+
@cpu_port = CPUPort.new(@datasette, pullups: PORT_PULLUPS, floating: PORT_FLOATING)
|
|
104
|
+
@cpu_port.on_change { update_overlays! }
|
|
105
|
+
@io_port = @cpu_port.status
|
|
107
106
|
|
|
108
107
|
@read_pages = Array.new(256)
|
|
109
108
|
@write_pages = Array.new(256)
|
|
@@ -134,9 +133,7 @@ module Badline
|
|
|
134
133
|
# their charge.
|
|
135
134
|
def reset!
|
|
136
135
|
@ram_expansion.reset!
|
|
137
|
-
@
|
|
138
|
-
@port_out = 0x00
|
|
139
|
-
update_port!
|
|
136
|
+
@cpu_port.reset!
|
|
140
137
|
end
|
|
141
138
|
|
|
142
139
|
def disable_overlays!
|
|
@@ -150,7 +147,7 @@ module Badline
|
|
|
150
147
|
end
|
|
151
148
|
|
|
152
149
|
def peek(addr)
|
|
153
|
-
return @
|
|
150
|
+
return @cpu_port.ddr if addr.zero?
|
|
154
151
|
return @io_port.value if addr == 0x01
|
|
155
152
|
|
|
156
153
|
@read_pages[addr >> 8].peek(addr)
|
|
@@ -162,8 +159,7 @@ module Badline
|
|
|
162
159
|
def poke(addr, value)
|
|
163
160
|
if addr < 0x02
|
|
164
161
|
@ram.poke(addr, @vic.phi1_data)
|
|
165
|
-
addr.zero? ? @
|
|
166
|
-
update_port!
|
|
162
|
+
addr.zero? ? @cpu_port.write_ddr(value) : @cpu_port.write_data(value)
|
|
167
163
|
elsif !@cpu_off_bus
|
|
168
164
|
@write_pages[addr >> 8].poke(addr, value)
|
|
169
165
|
end
|
|
@@ -185,21 +181,6 @@ module Badline
|
|
|
185
181
|
|
|
186
182
|
private
|
|
187
183
|
|
|
188
|
-
def update_port!
|
|
189
|
-
driven = @port_ddr & PORT_FLOATING
|
|
190
|
-
@port_floating = (@port_floating & ~driven) | (@port_out & driven)
|
|
191
|
-
@io_port.value = port_value
|
|
192
|
-
# $01 bit 5 drives the motor through an inverter: low runs it.
|
|
193
|
-
@datasette.motor = !@io_port.tape_motor?
|
|
194
|
-
update_overlays!
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
def port_value
|
|
198
|
-
input = PORT_PULLUPS | (@port_floating & PORT_FLOATING)
|
|
199
|
-
input &= ~TAPE_SENSE if @datasette.sense_low?
|
|
200
|
-
(@port_out & @port_ddr) | (input & ~@port_ddr & 0xff)
|
|
201
|
-
end
|
|
202
|
-
|
|
203
184
|
# Banking changes only on $01 writes and cartridge line/bank changes,
|
|
204
185
|
# so reads and writes dispatch through per-page handler tables instead
|
|
205
186
|
# of range checks.
|
data/lib/badline/c128/bus.rb
CHANGED
|
@@ -37,6 +37,8 @@ module Badline
|
|
|
37
37
|
include AddressBus::PLA
|
|
38
38
|
include AddressBus::ROMs
|
|
39
39
|
include MMUPages
|
|
40
|
+
include IOPages
|
|
41
|
+
include Z80Pages
|
|
40
42
|
include SavedState
|
|
41
43
|
|
|
42
44
|
# The 8502's port has seven pins. P0-P5 are the 6510's, and P6 senses
|
|
@@ -45,7 +47,6 @@ module Badline
|
|
|
45
47
|
PORT_PULLUPS = 0b0001_0111
|
|
46
48
|
PORT_FLOATING = 0b1000_1000
|
|
47
49
|
CAPS_LOCK = 0b0100_0000
|
|
48
|
-
TAPE_SENSE = 0b0001_0000
|
|
49
50
|
|
|
50
51
|
# The C64's power-on pattern (AddressBus::RAM_POWER_ON) in both 64K
|
|
51
52
|
# banks. The C128's own DRAMs' pattern is unmeasured.
|
|
@@ -124,9 +125,6 @@ module Badline
|
|
|
124
125
|
# KERNAL and the character ROM's C128 set.
|
|
125
126
|
attr_reader :basic_low_rom, :basic_high_rom, :editor_rom, :c128_kernal_rom, :c128_character_rom
|
|
126
127
|
|
|
127
|
-
# Whether CAPS LOCK is down, holding P6 low.
|
|
128
|
-
attr_reader :caps_lock
|
|
129
|
-
|
|
130
128
|
# The chips +model+, a Model::Profile, names, with the SID
|
|
131
129
|
# +sid_model+. +mode+ is the mode the MMU resets into.
|
|
132
130
|
def initialize(model, sid_model: model.sid_model, mode: :c64)
|
|
@@ -137,7 +135,6 @@ module Badline
|
|
|
137
135
|
@mmu = MMU.new(mode)
|
|
138
136
|
@cartridge = nil
|
|
139
137
|
@debug_page = nil
|
|
140
|
-
@caps_lock = false
|
|
141
138
|
|
|
142
139
|
load_roms
|
|
143
140
|
load_c128_roms
|
|
@@ -148,19 +145,18 @@ module Badline
|
|
|
148
145
|
|
|
149
146
|
@datasette = Datasette.new
|
|
150
147
|
@datasette.on_flag { @cia1.flag! }
|
|
151
|
-
@datasette.on_sense_change { @
|
|
148
|
+
@datasette.on_sense_change { @cpu_port.refresh }
|
|
152
149
|
|
|
153
150
|
@color_lines = ColorLines.new(@vic, @cia2, character_rom, @c128_character_rom)
|
|
154
151
|
@color_ram = @color_lines.color_ram(1)
|
|
152
|
+
build_z80_pages
|
|
155
153
|
@vic_writes = VICWrites.new(@vic, @control_ports)
|
|
156
154
|
@open_bus = AddressBus::OpenBus.new(@vic)
|
|
157
155
|
@configuration_reads = ConfigurationPage.new(@mmu, @open_bus)
|
|
158
156
|
@configuration_writes = ConfigurationPage.new(@mmu, @open_bus)
|
|
159
157
|
|
|
160
|
-
@
|
|
161
|
-
@
|
|
162
|
-
@port_floating = 0x00
|
|
163
|
-
@io_port = PortStatus.new(%i[basic kernal io tape_out tape_switch tape_motor], value: port_value)
|
|
158
|
+
@cpu_port = CPUPort.new(@datasette, pullups: PORT_PULLUPS, floating: PORT_FLOATING, caps_lock: CAPS_LOCK)
|
|
159
|
+
@io_port = @cpu_port.status
|
|
164
160
|
|
|
165
161
|
@read_pages = Array.new(256)
|
|
166
162
|
@write_pages = Array.new(256)
|
|
@@ -168,6 +164,7 @@ module Badline
|
|
|
168
164
|
@data = 0
|
|
169
165
|
@io_mapped = false
|
|
170
166
|
@mmu.on_change { update_overlays! }
|
|
167
|
+
@cpu_port.on_change { update_overlays! }
|
|
171
168
|
update_overlays!
|
|
172
169
|
end
|
|
173
170
|
|
|
@@ -188,19 +185,19 @@ module Badline
|
|
|
188
185
|
@ram.clear!(RAM_POWER_ON)
|
|
189
186
|
end
|
|
190
187
|
|
|
191
|
-
# The RES line clears the port's direction and
|
|
192
|
-
#
|
|
188
|
+
# The RES line resets the MMU and clears the port's direction and
|
|
189
|
+
# output registers. The port's floating bit keeps its charge.
|
|
193
190
|
def reset!
|
|
194
|
-
@port_ddr = 0x00
|
|
195
|
-
@port_out = 0x00
|
|
196
191
|
@mmu.reset!
|
|
197
|
-
|
|
192
|
+
@cpu_port.reset!
|
|
198
193
|
end
|
|
199
194
|
|
|
195
|
+
# Whether CAPS LOCK is down, holding P6 low.
|
|
196
|
+
def caps_lock = @cpu_port.caps_lock
|
|
197
|
+
|
|
200
198
|
# Holds CAPS LOCK down, or lets it up.
|
|
201
199
|
def caps_lock=(down)
|
|
202
|
-
@caps_lock = down
|
|
203
|
-
@io_port.value = port_value
|
|
200
|
+
@cpu_port.caps_lock = down
|
|
204
201
|
end
|
|
205
202
|
|
|
206
203
|
# Calls the block whenever MCR bit 6 takes the machine into C64 mode or
|
|
@@ -233,7 +230,7 @@ module Badline
|
|
|
233
230
|
@data = if addr > 0x01
|
|
234
231
|
@read_pages[addr >> 8].peek(addr)
|
|
235
232
|
else
|
|
236
|
-
addr.zero? ? @
|
|
233
|
+
addr.zero? ? @cpu_port.ddr : @io_port.value
|
|
237
234
|
end
|
|
238
235
|
end
|
|
239
236
|
|
|
@@ -251,8 +248,7 @@ module Badline
|
|
|
251
248
|
@data = value
|
|
252
249
|
if addr < 0x02
|
|
253
250
|
@write_pages[0].poke(addr, @vic.phi1_data)
|
|
254
|
-
addr.zero? ? @
|
|
255
|
-
update_port!
|
|
251
|
+
addr.zero? ? @cpu_port.write_ddr(value) : @cpu_port.write_data(value)
|
|
256
252
|
else
|
|
257
253
|
@write_pages[addr >> 8].poke(addr, value)
|
|
258
254
|
end
|
|
@@ -291,21 +287,6 @@ module Badline
|
|
|
291
287
|
@vdc = VDC.new(model: model.vdc_model, ram_kb: model.vdc_ram_kb, clock_hz: @region.clock_hz)
|
|
292
288
|
end
|
|
293
289
|
|
|
294
|
-
def update_port!
|
|
295
|
-
driven = @port_ddr & PORT_FLOATING
|
|
296
|
-
@port_floating = (@port_floating & ~driven) | (@port_out & driven)
|
|
297
|
-
@io_port.value = port_value
|
|
298
|
-
@datasette.motor = !@io_port.tape_motor?
|
|
299
|
-
update_overlays!
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
def port_value
|
|
303
|
-
input = PORT_PULLUPS | (@port_floating & PORT_FLOATING)
|
|
304
|
-
input |= CAPS_LOCK unless @caps_lock
|
|
305
|
-
input &= ~TAPE_SENSE if @datasette.sense_low?
|
|
306
|
-
(@port_out & @port_ddr) | (input & ~@port_ddr & 0xff)
|
|
307
|
-
end
|
|
308
|
-
|
|
309
290
|
def update_overlays!
|
|
310
291
|
@ultimax = @cartridge ? @cartridge.ultimax? : false
|
|
311
292
|
@phi1_ultimax = @cartridge ? @cartridge.phi1_ultimax? : false
|
|
@@ -318,6 +299,7 @@ module Badline
|
|
|
318
299
|
romh: @cartridge&.romh)
|
|
319
300
|
@color_ram = @color_lines.cpu_color_ram(c64_mode, port)
|
|
320
301
|
c64_mode ? map_pla_pages : map_c128_pages
|
|
302
|
+
update_z80!
|
|
321
303
|
mode_changed if c64_mode != @c64_mode
|
|
322
304
|
end
|
|
323
305
|
|
|
@@ -325,23 +307,6 @@ module Badline
|
|
|
325
307
|
@c64_mode = !@c64_mode
|
|
326
308
|
@on_mode_change&.call
|
|
327
309
|
end
|
|
328
|
-
|
|
329
|
-
def map_io_pages
|
|
330
|
-
@io_mapped = true
|
|
331
|
-
@read_pages.fill(@vic, 0xd0, 4)
|
|
332
|
-
@write_pages.fill(@vic_writes, 0xd0, 4)
|
|
333
|
-
@read_pages[0xd4] = @write_pages[0xd4] = @sid
|
|
334
|
-
@read_pages[0xd5] = @write_pages[0xd5] = @mmu.c64_mode? ? @open_bus : @mmu
|
|
335
|
-
@read_pages[0xd6] = @write_pages[0xd6] = @vdc
|
|
336
|
-
@read_pages[0xd7] = @write_pages[0xd7] = @debug_page || @open_bus
|
|
337
|
-
@read_pages.fill(@color_ram, 0xd8, 4)
|
|
338
|
-
@write_pages.fill(@color_ram, 0xd8, 4)
|
|
339
|
-
@read_pages[0xdc] = @write_pages[0xdc] = @cia1
|
|
340
|
-
@read_pages[0xdd] = @write_pages[0xdd] = @cia2
|
|
341
|
-
@read_pages.fill(@open_bus, 0xde, 2)
|
|
342
|
-
@write_pages.fill(@open_bus, 0xde, 2)
|
|
343
|
-
map_cartridge_io if @cartridge
|
|
344
|
-
end
|
|
345
310
|
end
|
|
346
311
|
end
|
|
347
312
|
end
|
|
@@ -11,7 +11,7 @@ module Badline
|
|
|
11
11
|
# host holds. A cartridge is already in the port, built from its setup.
|
|
12
12
|
def save_state(out)
|
|
13
13
|
out.marker("C128 BUS")
|
|
14
|
-
out.int(@
|
|
14
|
+
out.int(@cpu_port.ddr).int(@cpu_port.data).int(@cpu_port.floating).int(@address).int(@data)
|
|
15
15
|
@mmu.save_state(out)
|
|
16
16
|
@ram.save_state(out)
|
|
17
17
|
@color_lines.color_ram(0).save_state(out)
|
|
@@ -27,9 +27,9 @@ module Badline
|
|
|
27
27
|
|
|
28
28
|
def load_state(input)
|
|
29
29
|
input.marker("C128 BUS")
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
ddr = input.int
|
|
31
|
+
data = input.int
|
|
32
|
+
floating = input.int
|
|
33
33
|
@address = input.int
|
|
34
34
|
@data = input.int
|
|
35
35
|
@mmu.load_state(input)
|
|
@@ -38,7 +38,7 @@ module Badline
|
|
|
38
38
|
@color_lines.color_ram(1).load_state(input)
|
|
39
39
|
@cartridge&.load_state(input)
|
|
40
40
|
@datasette.load_state(input)
|
|
41
|
-
@
|
|
41
|
+
@cpu_port.load(ddr, data, floating)
|
|
42
42
|
update_overlays!
|
|
43
43
|
@vic.load_state(input)
|
|
44
44
|
@control_ports.extra_rows = 0xf8 | @vic.extra_keyboard_lines
|