badline 0.14.0 → 0.15.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 +23 -0
- data/CLAUDE.md +15 -5
- data/README.md +68 -8
- data/doc/pinned-behaviour.md +145 -0
- data/doc/snapshot-format.md +188 -38
- data/doc/snapshots.md +18 -1
- data/lib/badline/audio/bare_player.rb +4 -8
- data/lib/badline/audio/machine_player.rb +2 -12
- data/lib/badline/c128/banks.rb +1 -3
- data/lib/badline/c128/bus.rb +19 -1
- data/lib/badline/c128/mmu_pages.rb +7 -0
- data/lib/badline/c64/bus/extra_sids.rb +80 -0
- data/lib/badline/c64/bus.rb +1 -0
- data/lib/badline/c64/cartridge/action_replay.rb +6 -2
- data/lib/badline/c64/cartridge/comal80.rb +1 -0
- data/lib/badline/c64/cartridge/dinamic.rb +3 -1
- data/lib/badline/c64/cartridge/final_cartridge3.rb +1 -0
- data/lib/badline/c64/cartridge/fun_play.rb +2 -1
- data/lib/badline/c64/cartridge/game_system.rb +2 -1
- data/lib/badline/c64/cartridge/keyed_state.rb +155 -34
- data/lib/badline/c64/cartridge/magic_desk.rb +2 -1
- data/lib/badline/c64/cartridge/ocean.rb +1 -0
- data/lib/badline/c64/cartridge/pagefox.rb +1 -0
- data/lib/badline/c64/cartridge/rgcd.rb +2 -1
- data/lib/badline/c64/cartridge/super_games.rb +3 -2
- data/lib/badline/c64/cartridge/zaxxon.rb +1 -0
- data/lib/badline/c64/cartridge.rb +3 -3
- data/lib/badline/c64/keyed_modules.rb +6 -2
- data/lib/badline/chips/ted/beam.rb +13 -14
- data/lib/badline/chips/ted/fetches.rb +199 -0
- data/lib/badline/chips/ted/keyed_state.rb +156 -0
- data/lib/badline/chips/ted/modes.rb +134 -0
- data/lib/badline/chips/ted/palette.rb +43 -0
- data/lib/badline/chips/ted/picture.rb +182 -0
- data/lib/badline/chips/ted/sound/output.rb +86 -0
- data/lib/badline/chips/ted/sound.rb +284 -0
- data/lib/badline/chips/ted.rb +53 -6
- data/lib/badline/chips/tia.rb +12 -0
- data/lib/badline/drives/datasette/keyed_state.rb +7 -2
- data/lib/badline/drives/datasette.rb +22 -5
- data/lib/badline/frontend/boot.rb +3 -1
- data/lib/badline/frontend/controls.rb +7 -3
- data/lib/badline/frontend/keys.rb +14 -2
- data/lib/badline/frontend/media_slots.rb +11 -1
- data/lib/badline/frontend/menu/menu_dialogs.rb +2 -1
- data/lib/badline/frontend/menu/menu_media.rb +13 -3
- data/lib/badline/frontend/menu/menu_pages.rb +8 -8
- data/lib/badline/frontend/menu/menu_ports.rb +13 -1
- data/lib/badline/frontend/screen.rb +33 -12
- data/lib/badline/frontend/screens.rb +2 -1
- data/lib/badline/frontend/sound.rb +4 -4
- data/lib/badline/frontend/timeline.rb +19 -6
- data/lib/badline/machine/settling.rb +1 -1
- data/lib/badline/machine.rb +26 -6
- data/lib/badline/media/plus4_media.rb +68 -0
- data/lib/badline/media/program.rb +20 -6
- data/lib/badline/media.rb +33 -12
- data/lib/badline/options/family.rb +1 -0
- data/lib/badline/options/help.rb +30 -6
- data/lib/badline/options/table.rb +15 -2
- data/lib/badline/options/validation.rb +26 -4
- data/lib/badline/options.rb +37 -9
- data/lib/badline/plus4/bus.rb +77 -14
- data/lib/badline/plus4/cassette_sense.rb +21 -0
- data/lib/badline/plus4/keyboard_port.rb +35 -10
- data/lib/badline/plus4/keyed_modules.rb +99 -0
- data/lib/badline/plus4/keyed_parts.rb +143 -0
- data/lib/badline/plus4/keyed_state.rb +41 -0
- data/lib/badline/plus4.rb +92 -16
- data/lib/badline/snapshot/container.rb +2 -0
- data/lib/badline/snapshot/field_doc/markdown.rb +7 -6
- data/lib/badline/snapshot/field_doc.rb +46 -7
- data/lib/badline/snapshot/image.rb +12 -3
- data/lib/badline/snapshot/plus4_setup.rb +39 -0
- data/lib/badline/snapshot.rb +9 -4
- data/lib/badline/storage/g64_image.rb +1 -1
- data/lib/badline/storage/tap.rb +21 -12
- data/lib/badline/support/checkpoint.rb +3 -2
- data/lib/badline/support/plus4_checkpoint.rb +42 -0
- data/lib/badline/version.rb +1 -1
- metadata +15 -1
data/doc/snapshot-format.md
CHANGED
|
@@ -13,19 +13,20 @@ machine built afresh has: the default below. `word`, `byte` and
|
|
|
13
13
|
`int & 0x..` are ints cut to the latch's width. A text that lists
|
|
14
14
|
its values takes one of them. An optional int is absent when the
|
|
15
15
|
latch holds nothing. A true drive's modules are named from its
|
|
16
|
-
device number, `BL-D8` to `BL-D11
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
device number, `BL-D8` to `BL-D11`, and the SIDs past the first
|
|
17
|
+
are `BL-SID2` onwards, in the order they were fitted. Keys with
|
|
18
|
+
`<N>` stand for each numbered unit. A default of "written only" is
|
|
19
|
+
a key the load doesn't read, or reads only when the snapshot has
|
|
20
|
+
it. Where the machines differ, the default is given for each, and a
|
|
21
|
+
key only some of them have names them.
|
|
21
22
|
|
|
22
23
|
## BL-MACHINE
|
|
23
24
|
|
|
24
|
-
Written by the C64, VIC-20, C128.
|
|
25
|
+
Written by the C64, VIC-20, C128, Plus/4.
|
|
25
26
|
|
|
26
27
|
| Key | Type | Default |
|
|
27
28
|
| --- | --- | --- |
|
|
28
|
-
| `family` | text: c64 vic20 c128 | "c64" |
|
|
29
|
+
| `family` | text: c64 vic20 c128 plus4 | "c64" |
|
|
29
30
|
| `region` | text: pal ntsc ntscold drean | C64: "pal" |
|
|
30
31
|
| `vic_model` | text: mos6569 mos8565 mos8566 mos8564 | C64: "mos6569" |
|
|
31
32
|
| `cia_model` | text: mos6526 mos6526a | C64: "mos6526" |
|
|
@@ -36,7 +37,7 @@ Written by the C64, VIC-20, C128.
|
|
|
36
37
|
| `datasette` | bool | C64: true |
|
|
37
38
|
| `board` | text: c64 pet64 gs max | C64: "c64" |
|
|
38
39
|
| `cycles` | int | 0 |
|
|
39
|
-
| `nmi_asserted` | bool | false |
|
|
40
|
+
| `nmi_asserted` | bool | C64: false; VIC-20: false; C128: false |
|
|
40
41
|
| `cartridge_nmi` | bool | C64: false; C128: false |
|
|
41
42
|
| `restore_pulse` | bool | C64: false; C128: false |
|
|
42
43
|
| `freezing` | bool | C64: false |
|
|
@@ -48,7 +49,7 @@ Written by the C64, VIC-20, C128.
|
|
|
48
49
|
| `ram` | text: unexpanded 3k 8k 16k 24k 32k all | VIC-20: "unexpanded" |
|
|
49
50
|
| `bus.data` | byte | VIC-20: 253; C128: 255 |
|
|
50
51
|
| `bus.video_data` | byte | VIC-20: 0 |
|
|
51
|
-
| `model` | text: c128 c128ntsc c128dcr c128dcrntsc | C128: "c128" |
|
|
52
|
+
| `model` | text: c128 c128ntsc c128dcr c128dcrntsc | C128: "c128"; Plus/4: "plus4" |
|
|
52
53
|
| `mode` | text: c64 c128 | C128: "c64" |
|
|
53
54
|
| `bus.address` | word | C128: 65533 |
|
|
54
55
|
| `clock_bits` | int | C128: 0 |
|
|
@@ -60,14 +61,20 @@ Written by the C64, VIC-20, C128.
|
|
|
60
61
|
| `host.typist.code` | int, optional | C128: absent |
|
|
61
62
|
| `host.typist.wait` | int | C128: 0 |
|
|
62
63
|
| `host.typist.typing` | bool | C128: false |
|
|
64
|
+
| `ram_kb` | int | Plus/4: 64 or 16 |
|
|
65
|
+
| `tcbm` | bool | Plus/4: false |
|
|
63
66
|
|
|
64
67
|
## BL-RAM
|
|
65
68
|
|
|
66
|
-
Written by the C64, VIC-20, C128.
|
|
69
|
+
Written by the C64, VIC-20, C128, Plus/4.
|
|
67
70
|
|
|
68
71
|
| Key | Type | Default |
|
|
69
72
|
| --- | --- | --- |
|
|
70
|
-
| `ram` | bytes | C64: 65536 values; VIC-20: 49152 values; C128: 131072 values |
|
|
73
|
+
| `ram` | bytes | C64: 65536 values; VIC-20: 49152 values; C128: 131072 values; Plus/4: 65536 × 0 or 16384 × 0 |
|
|
74
|
+
| `bus.low_bank` | int & 0x3 | Plus/4: 0 |
|
|
75
|
+
| `bus.high_bank` | int & 0x3 | Plus/4: 0 |
|
|
76
|
+
| `bus.rom_selected` | bool | Plus/4: true |
|
|
77
|
+
| `bus.data` | byte | Plus/4: 255 |
|
|
71
78
|
|
|
72
79
|
## BL-COLORRAM
|
|
73
80
|
|
|
@@ -80,14 +87,14 @@ Written by the C64, VIC-20, C128.
|
|
|
80
87
|
|
|
81
88
|
## BL-CPU
|
|
82
89
|
|
|
83
|
-
Written by the C64, C128, VIC-20.
|
|
90
|
+
Written by the C64, C128, Plus/4, VIC-20.
|
|
84
91
|
|
|
85
92
|
| Key | Type | Default |
|
|
86
93
|
| --- | --- | --- |
|
|
87
|
-
| `port.ddr` | byte | C64: 0; C128: 0 |
|
|
88
|
-
| `port.data` | byte | C64: 0; C128: 0 |
|
|
94
|
+
| `port.ddr` | byte | C64: 0; C128: 0; Plus/4: 0 |
|
|
95
|
+
| `port.data` | byte | C64: 0; C128: 0; Plus/4: 0 |
|
|
89
96
|
| `port.floating` | byte | C64: 0; C128: 0 |
|
|
90
|
-
| `pc` | word | C64: 64738; VIC-20: 64802; C128: 65341 |
|
|
97
|
+
| `pc` | word | C64: 64738; VIC-20: 64802; C128: 65341; Plus/4: 65526 |
|
|
91
98
|
| `sp` | byte | 255 |
|
|
92
99
|
| `a` | byte | 0 |
|
|
93
100
|
| `x` | byte | 0 |
|
|
@@ -410,16 +417,18 @@ Written by the C64, C128.
|
|
|
410
417
|
|
|
411
418
|
## BL-TAPE
|
|
412
419
|
|
|
413
|
-
Written by the C64, VIC-20, C128.
|
|
420
|
+
Written by the C64, VIC-20, C128, Plus/4.
|
|
414
421
|
|
|
415
422
|
| Key | Type | Default |
|
|
416
423
|
| --- | --- | --- |
|
|
417
424
|
| `playing` | bool | false |
|
|
418
425
|
| `motor` | bool | false |
|
|
419
426
|
| `countdown` | int | 0 |
|
|
427
|
+
| `rise_at` | int | 0 |
|
|
428
|
+
| `low_recorded` | bool | false |
|
|
420
429
|
| `tape.bytes` | bytes | [] |
|
|
421
|
-
| `tape.path` | text | C64: "" |
|
|
422
|
-
| `tape.position` | int | C64: 0 |
|
|
430
|
+
| `tape.path` | text | C64: ""; Plus/4: "" |
|
|
431
|
+
| `tape.position` | int | C64: 0; Plus/4: 0 |
|
|
423
432
|
|
|
424
433
|
## BL-RAMEXP
|
|
425
434
|
|
|
@@ -476,14 +485,14 @@ Written by the C64.
|
|
|
476
485
|
|
|
477
486
|
## BL-CART
|
|
478
487
|
|
|
479
|
-
Written by the C64, VIC-20.
|
|
488
|
+
Written by the C64, VIC-20, Plus/4.
|
|
480
489
|
|
|
481
490
|
| Key | Type | Default |
|
|
482
491
|
| --- | --- | --- |
|
|
483
492
|
| `geo_ram_kb` | int | C64: 0 |
|
|
484
493
|
| `crt` | bytes | C64: [] |
|
|
485
|
-
| `exrom` | int & 0x1 | C64: 1 |
|
|
486
|
-
| `game` | int & 0x1 | C64: 0 |
|
|
494
|
+
| `exrom` | int & 0x1 | C64: 1 or 0 |
|
|
495
|
+
| `game` | int & 0x1 | C64: 0 or 1 |
|
|
487
496
|
| `nmi` | bool | C64: false |
|
|
488
497
|
| `button` | bool | C64: false |
|
|
489
498
|
| `bank` | int | C64: 0 |
|
|
@@ -511,9 +520,17 @@ Written by the C64, VIC-20.
|
|
|
511
520
|
| `flash_high.erasing_sectors` | ints | C64: [] |
|
|
512
521
|
| `flash_high.windows` | ints | C64: [] |
|
|
513
522
|
| `flash_high.status_windows` | ints | C64: [] |
|
|
523
|
+
| `high_bank` | int | C64: 0 |
|
|
524
|
+
| `active` | bool | C64: true |
|
|
525
|
+
| `ram` | bytes | C64: 8192 × 0 |
|
|
526
|
+
| `ram<N>.data` | bytes | C64: 8192 × 0 |
|
|
514
527
|
| `roms` | int | VIC-20: 0 |
|
|
515
528
|
| `rom0.bytes` | bytes | VIC-20: [] |
|
|
516
529
|
| `rom0.start` | word | VIC-20: 0 |
|
|
530
|
+
| `c1lo` | bytes | Plus/4: [] |
|
|
531
|
+
| `c2lo` | bytes | Plus/4: [] |
|
|
532
|
+
| `c1hi` | bytes | Plus/4: [] |
|
|
533
|
+
| `c2hi` | bytes | Plus/4: [] |
|
|
517
534
|
|
|
518
535
|
## BL-TRAPDOS
|
|
519
536
|
|
|
@@ -547,29 +564,29 @@ Written by the C64.
|
|
|
547
564
|
|
|
548
565
|
## BL-D8
|
|
549
566
|
|
|
550
|
-
Written by the C64, C128.
|
|
567
|
+
Written by the C64, C128, Plus/4.
|
|
551
568
|
|
|
552
569
|
| Key | Type | Default |
|
|
553
570
|
| --- | --- | --- |
|
|
554
|
-
| `model` | text: 1541 1571 1581 | C64: "1541" or "1581"; C128: "1541" or "1571" |
|
|
571
|
+
| `model` | text: 1541 1571 1581 | C64: "1541" or "1581"; C128: "1541" or "1571"; Plus/4: "1541" |
|
|
555
572
|
| `phase` | int | 0 |
|
|
556
573
|
| `cycles` | int | 0 |
|
|
557
574
|
| `so_pending` | bool | false |
|
|
558
|
-
| `serial.host` | int | 255 |
|
|
575
|
+
| `serial.host` | int | C64: 255; C128: 255; Plus/4: 0 |
|
|
559
576
|
| `atn` | bool | C64: true |
|
|
560
577
|
|
|
561
578
|
## BL-D8-RAM
|
|
562
579
|
|
|
563
|
-
Written by the C64, C128.
|
|
580
|
+
Written by the C64, C128, Plus/4.
|
|
564
581
|
|
|
565
582
|
| Key | Type | Default |
|
|
566
583
|
| --- | --- | --- |
|
|
567
|
-
| `data` | byte | C64: 234 or 175; C128: 234 |
|
|
568
|
-
| `ram` | bytes | C64: 2048 × 0 or 8192 × 0; C128: 2048 × 0 |
|
|
584
|
+
| `data` | byte | C64: 234 or 175; C128: 234; Plus/4: 234 |
|
|
585
|
+
| `ram` | bytes | C64: 2048 × 0 or 8192 × 0; C128: 2048 × 0; Plus/4: 2048 × 0 |
|
|
569
586
|
|
|
570
587
|
## BL-D8-VIA1
|
|
571
588
|
|
|
572
|
-
Written by the C64, C128.
|
|
589
|
+
Written by the C64, C128, Plus/4.
|
|
573
590
|
|
|
574
591
|
| Key | Type | Default |
|
|
575
592
|
| --- | --- | --- |
|
|
@@ -603,7 +620,7 @@ Written by the C64, C128.
|
|
|
603
620
|
| `ifr.flags` | int & 0x7f | 0 |
|
|
604
621
|
| `ifr.enable` | int & 0x7f | 0 |
|
|
605
622
|
| `ca.control` | int & 0xf | 0 |
|
|
606
|
-
| `ca.c1_high` | bool | true |
|
|
623
|
+
| `ca.c1_high` | bool | C64: true; C128: true; Plus/4: false |
|
|
607
624
|
| `ca.c2_high` | bool | true |
|
|
608
625
|
| `ca.handshake_low` | bool | false |
|
|
609
626
|
| `ca.pulse` | int | 0 |
|
|
@@ -617,7 +634,7 @@ Written by the C64, C128.
|
|
|
617
634
|
|
|
618
635
|
## BL-D8-VIA2
|
|
619
636
|
|
|
620
|
-
Written by the C64, C128.
|
|
637
|
+
Written by the C64, C128, Plus/4.
|
|
621
638
|
|
|
622
639
|
| Key | Type | Default |
|
|
623
640
|
| --- | --- | --- |
|
|
@@ -665,11 +682,11 @@ Written by the C64, C128.
|
|
|
665
682
|
|
|
666
683
|
## BL-D8-CPU
|
|
667
684
|
|
|
668
|
-
Written by the C64, C128.
|
|
685
|
+
Written by the C64, C128, Plus/4.
|
|
669
686
|
|
|
670
687
|
| Key | Type | Default |
|
|
671
688
|
| --- | --- | --- |
|
|
672
|
-
| `pc` | word | C64: 60064 or 44836; C128: 60064 |
|
|
689
|
+
| `pc` | word | C64: 60064 or 44836; C128: 60064; Plus/4: 60064 |
|
|
673
690
|
| `sp` | byte | 255 |
|
|
674
691
|
| `a` | byte | 0 |
|
|
675
692
|
| `x` | byte | 0 |
|
|
@@ -691,7 +708,7 @@ Written by the C64, C128.
|
|
|
691
708
|
|
|
692
709
|
## BL-D8-DISK
|
|
693
710
|
|
|
694
|
-
Written by the C64, C128.
|
|
711
|
+
Written by the C64, C128, Plus/4.
|
|
695
712
|
|
|
696
713
|
| Key | Type | Default |
|
|
697
714
|
| --- | --- | --- |
|
|
@@ -706,13 +723,13 @@ Written by the C64, C128.
|
|
|
706
723
|
|
|
707
724
|
## BL-D8-MECH
|
|
708
725
|
|
|
709
|
-
Written by the C64, C128.
|
|
726
|
+
Written by the C64, C128, Plus/4.
|
|
710
727
|
|
|
711
728
|
| Key | Type | Default |
|
|
712
729
|
| --- | --- | --- |
|
|
713
|
-
| `half_track` | int | C64: 35; C128: 37 |
|
|
714
|
-
| `slip` | int & 0x3 | C64: 0; C128: 2 |
|
|
715
|
-
| `side` | int | C64: 0 or 1; C128: 85 |
|
|
730
|
+
| `half_track` | int | C64: 35; C128: 37; Plus/4: 35 |
|
|
731
|
+
| `slip` | int & 0x3 | C64: 0; C128: 2; Plus/4: 0 |
|
|
732
|
+
| `side` | int | C64: 0 or 1; C128: 85; Plus/4: 0 |
|
|
716
733
|
| `zone` | int & 0x3 | 3 |
|
|
717
734
|
| `time` | int | 0 |
|
|
718
735
|
| `read_clock_in` | int | 2097152 |
|
|
@@ -721,7 +738,7 @@ Written by the C64, C128.
|
|
|
721
738
|
| `ones` | int | 0 |
|
|
722
739
|
| `bits` | int | 0 |
|
|
723
740
|
| `write_shift` | int | 0 |
|
|
724
|
-
| `motor` | bool | C64: true or false; C128: true |
|
|
741
|
+
| `motor` | bool | C64: true or false; C128: true; Plus/4: true |
|
|
725
742
|
| `led` | bool | true |
|
|
726
743
|
| `sync` | bool | false |
|
|
727
744
|
| `byte_ready` | bool | false |
|
|
@@ -843,6 +860,49 @@ Written by the C64, C128.
|
|
|
843
860
|
| `registers` | ints | C128: [0, 0, 0, 0] |
|
|
844
861
|
| `result` | int | C128: 0 |
|
|
845
862
|
|
|
863
|
+
## BL-SID2
|
|
864
|
+
|
|
865
|
+
Written by the C64.
|
|
866
|
+
|
|
867
|
+
| Key | Type | Default |
|
|
868
|
+
| --- | --- | --- |
|
|
869
|
+
| `address` | word | 54304 |
|
|
870
|
+
| `model` | text: mos6581 mos8580 | "mos6581" |
|
|
871
|
+
| `registers` | bytes | 32 × 0 |
|
|
872
|
+
| `bus_value` | byte | 0 |
|
|
873
|
+
| `bus_ttl` | int | 0 |
|
|
874
|
+
| `voice<N>.wave.accumulator` | int & 0xffffff | 5592405 |
|
|
875
|
+
| `voice<N>.wave.shift_register` | int & 0x7fffff | 8388606 |
|
|
876
|
+
| `voice<N>.wave.shift_register_reset` | int | 0 |
|
|
877
|
+
| `voice<N>.wave.shift_pipeline` | int | 0 |
|
|
878
|
+
| `voice<N>.wave.delayed_triangle` | int & 0xfff | 0 |
|
|
879
|
+
| `voice<N>.wave.delayed_sawtooth` | int & 0xfff | 0 |
|
|
880
|
+
| `voice<N>.wave.msb_rising` | bool | false |
|
|
881
|
+
| `voice<N>.wave.floating` | int & 0xfff | 0 |
|
|
882
|
+
| `voice<N>.wave.floating_ttl` | int | 0 |
|
|
883
|
+
| `voice<N>.wave.pulse` | int & 0xfff | 4095 |
|
|
884
|
+
| `voice<N>.env.state` | text: attack decay_sustain release | "release" |
|
|
885
|
+
| `voice<N>.env.next_state` | text: attack decay_sustain release | "release" |
|
|
886
|
+
| `voice<N>.env.counter` | byte | 0 |
|
|
887
|
+
| `voice<N>.env.env<N>` | byte | 0 |
|
|
888
|
+
| `voice<N>.env.rate_counter` | int & 0x7fff | 0 |
|
|
889
|
+
| `voice<N>.env.rate_period` | int | 8 |
|
|
890
|
+
| `voice<N>.env.reset_rate_counter` | bool | false |
|
|
891
|
+
| `voice<N>.env.exponential_counter` | int | 0 |
|
|
892
|
+
| `voice<N>.env.exponential_period` | int | 1 |
|
|
893
|
+
| `voice<N>.env.state_pipeline` | int | 0 |
|
|
894
|
+
| `voice<N>.env.envelope_pipeline` | int | 0 |
|
|
895
|
+
| `voice<N>.env.exponential_pipeline` | int | 0 |
|
|
896
|
+
| `voice<N>.env.hold_zero` | bool | true |
|
|
897
|
+
| `filter.highpass` | int | 0 |
|
|
898
|
+
| `filter.bandpass` | int | 0 |
|
|
899
|
+
| `filter.lowpass` | int | 0 |
|
|
900
|
+
| `filter.unfiltered` | int | 0 |
|
|
901
|
+
| `filter.input` | int | 0 |
|
|
902
|
+
| `ext.lowpass` | int | 0 |
|
|
903
|
+
| `ext.highpass` | int | 0 |
|
|
904
|
+
| `ext.output` | int | 0 |
|
|
905
|
+
|
|
846
906
|
## BL-VICI
|
|
847
907
|
|
|
848
908
|
Written by the VIC-20.
|
|
@@ -1045,3 +1105,93 @@ Written by the C128.
|
|
|
1045
1105
|
| `int` | bool | false |
|
|
1046
1106
|
| `nmi` | bool | false |
|
|
1047
1107
|
| `nmi_pending` | bool | false |
|
|
1108
|
+
|
|
1109
|
+
## BL-TED
|
|
1110
|
+
|
|
1111
|
+
Written by the Plus/4.
|
|
1112
|
+
|
|
1113
|
+
| Key | Type | Default |
|
|
1114
|
+
| --- | --- | --- |
|
|
1115
|
+
| `registers` | bytes | 32 × 0 |
|
|
1116
|
+
| `interrupt_flags` | byte | 0 |
|
|
1117
|
+
| `key_latch` | byte | 255 |
|
|
1118
|
+
| `blink` | int & 0xf | 0 |
|
|
1119
|
+
| `blink_on` | bool | false |
|
|
1120
|
+
| `timer<N>.count` | word | 0 |
|
|
1121
|
+
| `timer<N>.running` | bool | false |
|
|
1122
|
+
| `timer1.reload` | word | 0 |
|
|
1123
|
+
| `column` | int | 0 |
|
|
1124
|
+
| `line` | int & 0x1ff | 0 |
|
|
1125
|
+
| `ba` | bool | false |
|
|
1126
|
+
| `cpu_slots` | int | 1 |
|
|
1127
|
+
| `fetch.patterns` | bytes | 40 × 0 |
|
|
1128
|
+
| `fetch.pointers` | bytes | 40 × 0 |
|
|
1129
|
+
| `fetch.attributes` | bytes | 40 × 0 |
|
|
1130
|
+
| `fetch.next_attributes` | bytes | 40 × 0 |
|
|
1131
|
+
| `fetch.char_position` | int & 0x3ff | 0 |
|
|
1132
|
+
| `fetch.line_position` | int & 0x3ff | 0 |
|
|
1133
|
+
| `fetch.row_line` | int & 0x7 | 0 |
|
|
1134
|
+
| `fetch.row_active` | bool | false |
|
|
1135
|
+
| `fetch.dma` | text: none attributes pointers | "none" |
|
|
1136
|
+
| `fetch.patterns_on` | bool | false |
|
|
1137
|
+
| `scanline` | int | 0 |
|
|
1138
|
+
| `window_open` | bool | false |
|
|
1139
|
+
| `line.layout` | int | 0 |
|
|
1140
|
+
| `line.painted` | int | 0 |
|
|
1141
|
+
| `display` | bytes | 119808 × 0 |
|
|
1142
|
+
|
|
1143
|
+
## BL-TEDSOUND
|
|
1144
|
+
|
|
1145
|
+
Written by the Plus/4.
|
|
1146
|
+
|
|
1147
|
+
| Key | Type | Default |
|
|
1148
|
+
| --- | --- | --- |
|
|
1149
|
+
| `voice<N>.phase` | int & 0x1 | 1 |
|
|
1150
|
+
| `voice<N>.toggle_in` | int, optional | absent |
|
|
1151
|
+
| `noise` | byte | 255 |
|
|
1152
|
+
| `ran_ago` | int | 0 |
|
|
1153
|
+
|
|
1154
|
+
## BL-KEYPORT
|
|
1155
|
+
|
|
1156
|
+
Written by the Plus/4.
|
|
1157
|
+
|
|
1158
|
+
| Key | Type | Default |
|
|
1159
|
+
| --- | --- | --- |
|
|
1160
|
+
| `output` | byte | 255 |
|
|
1161
|
+
|
|
1162
|
+
## BL-USERPORT
|
|
1163
|
+
|
|
1164
|
+
Written by the Plus/4.
|
|
1165
|
+
|
|
1166
|
+
| Key | Type | Default |
|
|
1167
|
+
| --- | --- | --- |
|
|
1168
|
+
| `output` | byte | 255 |
|
|
1169
|
+
|
|
1170
|
+
## BL-ACIA
|
|
1171
|
+
|
|
1172
|
+
Written by the Plus/4.
|
|
1173
|
+
|
|
1174
|
+
| Key | Type | Default |
|
|
1175
|
+
| --- | --- | --- |
|
|
1176
|
+
| `command` | byte | 0 |
|
|
1177
|
+
| `control` | byte | 0 |
|
|
1178
|
+
|
|
1179
|
+
## BL-TIA1
|
|
1180
|
+
|
|
1181
|
+
Written by the Plus/4.
|
|
1182
|
+
|
|
1183
|
+
| Key | Type | Default |
|
|
1184
|
+
| --- | --- | --- |
|
|
1185
|
+
| `ports` | ints | [0, 0, 0] |
|
|
1186
|
+
| `directions` | ints | [0, 0, 0] |
|
|
1187
|
+
| `inputs` | ints | [0, 0, 0] |
|
|
1188
|
+
|
|
1189
|
+
## BL-TIA2
|
|
1190
|
+
|
|
1191
|
+
Written by the Plus/4.
|
|
1192
|
+
|
|
1193
|
+
| Key | Type | Default |
|
|
1194
|
+
| --- | --- | --- |
|
|
1195
|
+
| `ports` | ints | [0, 0, 0] |
|
|
1196
|
+
| `directions` | ints | [0, 0, 0] |
|
|
1197
|
+
| `inputs` | ints | [0, 0, 0] |
|
data/doc/snapshots.md
CHANGED
|
@@ -87,7 +87,9 @@ blocks given to `on_init` that hadn't run yet, which a restore reports.
|
|
|
87
87
|
Every model saves this way, PAL, NTSC, old NTSC and Drean alike, and so
|
|
88
88
|
does a machine with an REU, with its RAM and its registers. A snapshot
|
|
89
89
|
restores into a machine with the same chip models, region, RAM
|
|
90
|
-
expansion, REU, KERNAL, datasette and board.
|
|
90
|
+
expansion, REU, KERNAL, datasette and board. The second and third SIDs
|
|
91
|
+
the SID player fits for a stereo tune are saved too, each with its
|
|
92
|
+
address and model, and a restore fits them.
|
|
91
93
|
|
|
92
94
|
Text typed with `type_text` that the machine hasn't taken yet, such as
|
|
93
95
|
autostart's `RUN`, carries over, and so do the keys a C128 is typing on
|
|
@@ -123,6 +125,21 @@ do, and holds only badline's modules, so x128 doesn't open it, and
|
|
|
123
125
|
badline doesn't open x128's. Restoring a C128 snapshot while another machine runs swaps the
|
|
124
126
|
machine in the window, as for the VIC-20.
|
|
125
127
|
|
|
128
|
+
## The Plus/4
|
|
129
|
+
|
|
130
|
+
The Plus/4, the C16 and the C116 save and restore the same way. A
|
|
131
|
+
snapshot of one holds its RAM with the ROM bank latch and whether ROM or
|
|
132
|
+
RAM is selected, the cartridges' ROMs in each slot, the CPU with its
|
|
133
|
+
port, the TED with its timers, its counters and its picture, the TED's
|
|
134
|
+
sound, the keyboard's 6529, the Plus/4's user port 6529 and ACIA, a TCBM
|
|
135
|
+
interface's TIAs, the tape with its place on it, the disk or directory
|
|
136
|
+
device 8 serves through the traps and a true 1541 or 1581. It restores
|
|
137
|
+
into a machine of the same model with the same RAM, and the BASIC,
|
|
138
|
+
KERNAL and function ROMs come with the model. Its file names its machine
|
|
139
|
+
`PLUS4`, as xplus4's do, and holds only badline's modules, so xplus4
|
|
140
|
+
doesn't open it, and badline doesn't open xplus4's. `--vice` and
|
|
141
|
+
`computer.export_snapshot(path)` refuse a Plus/4.
|
|
142
|
+
|
|
126
143
|
## VICE
|
|
127
144
|
|
|
128
145
|
Snapshots use VICE's `.vsf` format, and badline's own modules are named
|
|
@@ -93,10 +93,7 @@ module Badline
|
|
|
93
93
|
sections << Snapshot::Keyed.section("BL-CIA1") { |out| bus.cia1.save_fields(out) }
|
|
94
94
|
sections << Snapshot::Keyed.section("BL-CIA2") { |out| bus.cia2.save_fields(out) }
|
|
95
95
|
sections << Snapshot::Keyed.section("BL-SID") { |out| bus.sid.save_fields(out) }
|
|
96
|
-
|
|
97
|
-
sections << Snapshot::Keyed.section("BL-SID#{index + 2}") { |out| sid.save_fields(out) }
|
|
98
|
-
end
|
|
99
|
-
sections
|
|
96
|
+
bus.save_extra_sid_modules(sections)
|
|
100
97
|
end
|
|
101
98
|
|
|
102
99
|
# Takes a rig that hasn't started to where #save_modules found one, in
|
|
@@ -152,10 +149,9 @@ module Badline
|
|
|
152
149
|
bus.vic.load_fields(modules.required("BL-VIC"))
|
|
153
150
|
bus.cia1.load_fields(modules.required("BL-CIA1"))
|
|
154
151
|
bus.cia2.load_fields(modules.required("BL-CIA2"))
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
end
|
|
152
|
+
bus.sid.load_fields(modules.required("BL-SID"))
|
|
153
|
+
bus.load_extra_sid_modules(modules)
|
|
154
|
+
@stereo.sids.each(&:restored!)
|
|
159
155
|
bus.vic.restored!
|
|
160
156
|
bus.cia1.restored!
|
|
161
157
|
bus.cia2.restored!
|
|
@@ -40,23 +40,13 @@ module Badline
|
|
|
40
40
|
def clock_hz = @computer.region.clock_hz
|
|
41
41
|
|
|
42
42
|
# The whole machine as its keyed snapshot modules, as it stands between
|
|
43
|
-
# frames,
|
|
44
|
-
def save_modules
|
|
45
|
-
sections = @computer.save_modules
|
|
46
|
-
@extras.each_with_index do |sid, index|
|
|
47
|
-
sections << Snapshot::Keyed.section("BL-SID#{index + 2}") { |out| sid.save_fields(out) }
|
|
48
|
-
end
|
|
49
|
-
sections
|
|
50
|
-
end
|
|
43
|
+
# frames, with the extra SIDs as BL-SID2 and BL-SID3, once it plays.
|
|
44
|
+
def save_modules = @computer.save_modules
|
|
51
45
|
|
|
52
46
|
# Takes a machine that hasn't started to where #save_modules found one,
|
|
53
47
|
# in place of #start.
|
|
54
48
|
def load_modules(modules)
|
|
55
49
|
@computer.load_modules(modules)
|
|
56
|
-
@extras.each_with_index do |sid, index|
|
|
57
|
-
sid.load_fields(modules.required("BL-SID#{index + 2}"))
|
|
58
|
-
sid.restored!
|
|
59
|
-
end
|
|
60
50
|
@stereo.synthesize!
|
|
61
51
|
@started = true
|
|
62
52
|
end
|
data/lib/badline/c128/banks.rb
CHANGED
|
@@ -21,9 +21,7 @@ module Badline
|
|
|
21
21
|
# The CR value the KERNAL's table holds for the bank.
|
|
22
22
|
def configuration(bank) = @kernal_rom.peek(CONFIGURATIONS + (bank & 0x0f))
|
|
23
23
|
|
|
24
|
-
def
|
|
25
|
-
bytes.each_with_index { |byte, i| @ram.poke(physical(bank, (addr + i) & 0xffff), byte) }
|
|
26
|
-
end
|
|
24
|
+
def poke(bank, addr, value) = @ram.poke(physical(bank, addr), value)
|
|
27
25
|
|
|
28
26
|
private
|
|
29
27
|
|
data/lib/badline/c128/bus.rb
CHANGED
|
@@ -228,7 +228,25 @@ module Badline
|
|
|
228
228
|
system_rom_peek(addr)
|
|
229
229
|
end
|
|
230
230
|
|
|
231
|
-
|
|
231
|
+
# Stores +bytes+ from +addr+ on in the C128 KERNAL's bank number
|
|
232
|
+
# +bank+, as its INDSTA does, with CR set to the bank's CR value for
|
|
233
|
+
# each byte and put back after it: into the chips where that value
|
|
234
|
+
# maps I/O, the MMU's at $D500 among them, into nothing at $FF00-$FF04,
|
|
235
|
+
# where the configuration registers take the byte, and otherwise into
|
|
236
|
+
# the RAM the bank reaches (Banks).
|
|
237
|
+
def write_bank(bank, addr, bytes)
|
|
238
|
+
cr = @mmu.cr
|
|
239
|
+
io = @banks.configuration(bank).nobits?(0x01)
|
|
240
|
+
bytes.each_with_index do |byte, i|
|
|
241
|
+
address = (addr + i) & 0xffff
|
|
242
|
+
if io && (address & 0xf000) == 0xd000
|
|
243
|
+
bank_io_poke(address, byte)
|
|
244
|
+
elsif !address.between?(0xff00, 0xff04)
|
|
245
|
+
@banks.poke(bank, address, byte)
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
@mmu.poke_configuration(0xff00, cr) unless @mmu.cr == cr
|
|
249
|
+
end
|
|
232
250
|
|
|
233
251
|
def install_debug_register(&)
|
|
234
252
|
@debug_page = DebugPage.new(@open_bus, &)
|
|
@@ -66,6 +66,13 @@ module Badline
|
|
|
66
66
|
@bank_io_reads[addr >> 8].peek(addr)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
+
# Writes the chip at +addr+, in $D000-$DFFF, as C128 mode's I/O maps it.
|
|
70
|
+
def bank_io_poke(addr, value)
|
|
71
|
+
lay_out_io(@bank_io_reads, @bank_io_writes)
|
|
72
|
+
@bank_io_writes[0xd5] = @mmu
|
|
73
|
+
@bank_io_writes[addr >> 8].poke(addr, value)
|
|
74
|
+
end
|
|
75
|
+
|
|
69
76
|
# The bank CR picks, with common RAM in bank 0, then the pages page 0
|
|
70
77
|
# and page 1 move to.
|
|
71
78
|
def map_ram_pages
|
|
@@ -7,7 +7,16 @@ module Badline
|
|
|
7
7
|
# them, each over its 32 bytes of the I/O area (SIDSlots). The SID
|
|
8
8
|
# player's machine has nothing else in I/O 1 and 2, so the rest of a
|
|
9
9
|
# page there reads the open bus.
|
|
10
|
+
#
|
|
11
|
+
# A snapshot holds each in its own keyed module, BL-SID2 onwards in the
|
|
12
|
+
# order they were fitted, with the address it sits at and its model
|
|
13
|
+
# ahead of the SID's own fields.
|
|
10
14
|
module ExtraSIDs
|
|
15
|
+
SID_MODEL_NAMES = %w[mos6581 mos8580].freeze
|
|
16
|
+
|
|
17
|
+
# The SIDs fitted past the first, in the order they were fitted.
|
|
18
|
+
attr_reader :extra_sids
|
|
19
|
+
|
|
11
20
|
# Fits a SID at the address it was built at, where it takes its 32
|
|
12
21
|
# bytes over from whatever maps there.
|
|
13
22
|
def add_sid(sid)
|
|
@@ -18,14 +27,85 @@ module Badline
|
|
|
18
27
|
@sid_slots << slots
|
|
19
28
|
end
|
|
20
29
|
slots.place(sid)
|
|
30
|
+
@extra_sids << sid
|
|
31
|
+
update_overlays!
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Takes the extra SIDs out, giving their addresses back to what maps
|
|
35
|
+
# there.
|
|
36
|
+
def remove_extra_sids
|
|
37
|
+
@sid_slots.clear
|
|
38
|
+
@extra_sids.clear
|
|
21
39
|
update_overlays!
|
|
22
40
|
end
|
|
23
41
|
|
|
42
|
+
def save_extra_sid_modules(sections)
|
|
43
|
+
@extra_sids.each_with_index do |sid, index|
|
|
44
|
+
sections << Snapshot::Keyed.section("BL-SID#{index + 2}") do |out|
|
|
45
|
+
out.int("address", sid.start).text("model", sid.model.to_s)
|
|
46
|
+
sid.save_fields(out)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
sections
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Fits the extra SIDs the snapshot's modules hold and loads them. A
|
|
53
|
+
# SID already fitted at the same address stays, on the model the
|
|
54
|
+
# snapshot names, and one the snapshot hasn't comes out. A module
|
|
55
|
+
# whose address no SID fits at is left out, and reported.
|
|
56
|
+
def load_extra_sid_modules(modules)
|
|
57
|
+
addresses = []
|
|
58
|
+
inputs = extra_sid_inputs(modules, addresses)
|
|
59
|
+
models = inputs.map { |input| sid_model_named(input.choice("model", SID_MODEL_NAMES, "mos6581")) }
|
|
60
|
+
refit_sids(addresses, models)
|
|
61
|
+
@extra_sids.each_with_index do |sid, index|
|
|
62
|
+
model = models[index]
|
|
63
|
+
sid.model = model unless sid.model == model
|
|
64
|
+
sid.load_fields(inputs[index])
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
24
68
|
private
|
|
25
69
|
|
|
26
70
|
def map_extra_sids
|
|
27
71
|
@sid_slots.each { |slots| @read_pages[slots.page] = @write_pages[slots.page] = slots }
|
|
28
72
|
end
|
|
73
|
+
|
|
74
|
+
def extra_sid_inputs(modules, taken)
|
|
75
|
+
inputs = []
|
|
76
|
+
number = 2
|
|
77
|
+
input = modules.optional("BL-SID2")
|
|
78
|
+
while input
|
|
79
|
+
address = input.word("address", 0xd420)
|
|
80
|
+
if sid_fits?(address) && !taken.include?(address)
|
|
81
|
+
inputs << input
|
|
82
|
+
taken << address
|
|
83
|
+
else
|
|
84
|
+
input.adjust(format("no SID fits at $%04x, so it's left out", address))
|
|
85
|
+
end
|
|
86
|
+
number += 1
|
|
87
|
+
input = modules.optional("BL-SID#{number}")
|
|
88
|
+
end
|
|
89
|
+
inputs
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# A SID's 32 bytes past the first SID's own, in $D420-$D7FF, or in
|
|
93
|
+
# I/O 1 or 2.
|
|
94
|
+
def sid_fits?(address)
|
|
95
|
+
address.nobits?(0x1f) && ((0xd420..0xd7e0).cover?(address) || (0xde00..0xdfe0).cover?(address))
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def sid_model_named(name) = name == "mos8580" ? :mos8580 : :mos6581
|
|
99
|
+
|
|
100
|
+
def refit_sids(addresses, models)
|
|
101
|
+
fitted = @extra_sids.dup
|
|
102
|
+
return if fitted.map(&:start) == addresses
|
|
103
|
+
|
|
104
|
+
remove_extra_sids
|
|
105
|
+
addresses.each_with_index do |address, index|
|
|
106
|
+
add_sid(fitted.find { |sid| sid.start == address } || Chips::SID.new(model: models[index], at: address))
|
|
107
|
+
end
|
|
108
|
+
end
|
|
29
109
|
end
|
|
30
110
|
end
|
|
31
111
|
end
|
data/lib/badline/c64/bus.rb
CHANGED
|
@@ -22,6 +22,10 @@ module Badline
|
|
|
22
22
|
include Freezer
|
|
23
23
|
|
|
24
24
|
CONTROL_MODES = %i[rom8k rom16k off ultimax].freeze
|
|
25
|
+
|
|
26
|
+
# Ultimax mode with the RAM at ROML and I/O 2 and the first bank at
|
|
27
|
+
# ROMH, as a freeze leaves the register.
|
|
28
|
+
FREEZE_CONTROL = 0x23
|
|
25
29
|
IO2_PAGE = 0x1f00
|
|
26
30
|
|
|
27
31
|
def connect(ram:, open_bus:)
|
|
@@ -59,8 +63,7 @@ module Badline
|
|
|
59
63
|
|
|
60
64
|
def freeze!
|
|
61
65
|
@active = true
|
|
62
|
-
|
|
63
|
-
select(:ultimax, @isolated, io2_ram: true)
|
|
66
|
+
control(FREEZE_CONTROL)
|
|
64
67
|
end
|
|
65
68
|
|
|
66
69
|
private
|
|
@@ -72,6 +75,7 @@ module Badline
|
|
|
72
75
|
end
|
|
73
76
|
|
|
74
77
|
def control(value)
|
|
78
|
+
@control = value
|
|
75
79
|
self.nmi = false if value.anybits?(0x40)
|
|
76
80
|
@rom = bank(@rom_banks, (value >> 3) & 0x03)
|
|
77
81
|
configure(value)
|