badline 0.16.1 → 0.18.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.
Files changed (256) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +213 -0
  3. data/CLAUDE.md +11 -7
  4. data/CONTRIBUTING.md +7 -1
  5. data/README.md +265 -26
  6. data/doc/media.md +5 -2
  7. data/doc/pinned-behaviour.md +189 -0
  8. data/doc/snapshot-format.md +616 -74
  9. data/doc/snapshots.md +192 -24
  10. data/exe/badline-ruby +5 -0
  11. data/lib/badline/audio/terminal.rb +34 -2
  12. data/lib/badline/c128/keyed_state.rb +2 -0
  13. data/lib/badline/c128.rb +1 -0
  14. data/lib/badline/c64/keyed_state.rb +2 -0
  15. data/lib/badline/c64.rb +1 -0
  16. data/lib/badline/cbm2/acia.rb +10 -0
  17. data/lib/badline/cbm2/bus.rb +263 -0
  18. data/lib/badline/cbm2/cpu.rb +58 -0
  19. data/lib/badline/cbm2/crtc_video.rb +133 -0
  20. data/lib/badline/cbm2/ieee_drive.rb +18 -0
  21. data/lib/badline/cbm2/ieee_layout.rb +69 -0
  22. data/lib/badline/cbm2/ieee_ports.rb +104 -0
  23. data/lib/badline/cbm2/ieee_traps.rb +81 -0
  24. data/lib/badline/cbm2/keyboard_ports.rb +60 -0
  25. data/lib/badline/cbm2/keyed_modules.rb +67 -0
  26. data/lib/badline/cbm2/keyed_state.rb +95 -0
  27. data/lib/badline/cbm2/model.rb +44 -0
  28. data/lib/badline/cbm2/p500/control_ports.rb +80 -0
  29. data/lib/badline/cbm2/p500/ieee_layout.rb +41 -0
  30. data/lib/badline/cbm2/p500/keyed_state.rb +85 -0
  31. data/lib/badline/cbm2/p500/model.rb +39 -0
  32. data/lib/badline/cbm2/p500/pages.rb +57 -0
  33. data/lib/badline/cbm2/p500.rb +264 -0
  34. data/lib/badline/cbm2/sid_page.rb +19 -0
  35. data/lib/badline/cbm2.rb +270 -0
  36. data/lib/badline/{plus4 → chips}/acia/frames.rb +1 -1
  37. data/lib/badline/chips/acia/keyed_state.rb +47 -0
  38. data/lib/badline/chips/acia.rb +307 -0
  39. data/lib/badline/chips/cia/timer.rb +2 -2
  40. data/lib/badline/chips/cpu/instruction_set.rb +1 -1
  41. data/lib/badline/chips/crtc.rb +3 -2
  42. data/lib/badline/chips/m6809/arithmetic.rb +140 -0
  43. data/lib/badline/chips/m6809/bus_steps.rb +223 -0
  44. data/lib/badline/chips/m6809/core.rb +149 -0
  45. data/lib/badline/chips/m6809/indexed.rb +82 -0
  46. data/lib/badline/chips/m6809/interrupts.rb +159 -0
  47. data/lib/badline/chips/m6809/keyed_state.rb +147 -0
  48. data/lib/badline/chips/m6809/opcodes.rb +159 -0
  49. data/lib/badline/chips/m6809/operations.rb +258 -0
  50. data/lib/badline/chips/m6809/plans.rb +143 -0
  51. data/lib/badline/chips/m6809/registers.rb +82 -0
  52. data/lib/badline/chips/m6809/stack.rb +140 -0
  53. data/lib/badline/chips/m6809.rb +13 -0
  54. data/lib/badline/chips/riot/fast_forward.rb +72 -0
  55. data/lib/badline/chips/riot/keyed_parts.rb +69 -0
  56. data/lib/badline/chips/riot/timer.rb +91 -0
  57. data/lib/badline/chips/riot.rb +162 -0
  58. data/lib/badline/chips/rriot/keyed_state.rb +30 -0
  59. data/lib/badline/chips/rriot.rb +134 -0
  60. data/lib/badline/chips/sid/filter.rb +4 -4
  61. data/lib/badline/chips/sid/waveform.rb +6 -6
  62. data/lib/badline/chips/tpi/keyed_state.rb +38 -0
  63. data/lib/badline/chips/tpi.rb +233 -0
  64. data/lib/badline/chips/vic/bank.rb +60 -5
  65. data/lib/badline/chips/vic/sprite.rb +4 -3
  66. data/lib/badline/chips/vic_i/keyed_parts.rb +7 -2
  67. data/lib/badline/chips/vic_i.rb +84 -21
  68. data/lib/badline/data_path.rb +3 -3
  69. data/lib/badline/drives/datasette/keyed_state.rb +9 -1
  70. data/lib/badline/drives/datasette.rb +27 -3
  71. data/lib/badline/drives/ieee_models.rb +54 -0
  72. data/lib/badline/drives/model1001.rb +37 -0
  73. data/lib/badline/drives/model2031.rb +6 -0
  74. data/lib/badline/drives/model4040/disk.rb +62 -0
  75. data/lib/badline/drives/model4040/ip_bus.rb +46 -0
  76. data/lib/badline/drives/model4040/keyed_state.rb +57 -0
  77. data/lib/badline/drives/model4040/mechanism.rb +192 -0
  78. data/lib/badline/drives/model4040/parts.rb +20 -0
  79. data/lib/badline/drives/model4040.rb +179 -0
  80. data/lib/badline/drives/model8050/board.rb +77 -0
  81. data/lib/badline/drives/model8050/disk.rb +163 -0
  82. data/lib/badline/drives/model8050/dos_board.rb +91 -0
  83. data/lib/badline/drives/model8050/fdc_bus.rb +102 -0
  84. data/lib/badline/drives/model8050/idle.rb +181 -0
  85. data/lib/badline/drives/model8050/ieee_port.rb +147 -0
  86. data/lib/badline/drives/model8050/ip_bus.rb +93 -0
  87. data/lib/badline/drives/model8050/keyed_state.rb +163 -0
  88. data/lib/badline/drives/model8050/mechanism.rb +230 -0
  89. data/lib/badline/drives/model8050/parts.rb +37 -0
  90. data/lib/badline/drives/model8050.rb +131 -0
  91. data/lib/badline/drives/model9060/idle.rb +149 -0
  92. data/lib/badline/drives/model9060/keyed_state.rb +123 -0
  93. data/lib/badline/drives/model9060/parts.rb +98 -0
  94. data/lib/badline/drives/model9060/sasi_bus.rb +88 -0
  95. data/lib/badline/drives/model9060/sasi_commands.rb +168 -0
  96. data/lib/badline/drives/model9060/sasi_target.rb +161 -0
  97. data/lib/badline/drives/model9060.rb +195 -0
  98. data/lib/badline/frontend/app.rb +18 -3
  99. data/lib/badline/frontend/boot.rb +4 -3
  100. data/lib/badline/frontend/controls.rb +107 -15
  101. data/lib/badline/frontend/gamepads.rb +3 -3
  102. data/lib/badline/frontend/keys.rb +97 -2
  103. data/lib/badline/frontend/kim1_panel.rb +208 -0
  104. data/lib/badline/frontend/media_slots.rb +8 -1
  105. data/lib/badline/frontend/menu/drive_types.rb +56 -0
  106. data/lib/badline/frontend/menu/menu_dialogs.rb +61 -14
  107. data/lib/badline/frontend/menu/menu_media.rb +47 -14
  108. data/lib/badline/frontend/menu/menu_pages.rb +113 -4
  109. data/lib/badline/frontend/menu/menu_ports.rb +77 -4
  110. data/lib/badline/frontend/menu/pause_menu.rb +6 -2
  111. data/lib/badline/frontend/pet_keyboard.rb +45 -7
  112. data/lib/badline/frontend/screen.rb +1 -1
  113. data/lib/badline/frontend/screens.rb +40 -2
  114. data/lib/badline/frontend/teletype_pane.rb +152 -0
  115. data/lib/badline/frontend/timeline.rb +49 -11
  116. data/lib/badline/frontend.rb +3 -0
  117. data/lib/badline/kernal_trap/dos/disk_commands.rb +80 -0
  118. data/lib/badline/kernal_trap/dos/status.rb +3 -0
  119. data/lib/badline/kernal_trap/dos.rb +18 -5
  120. data/lib/badline/kernal_trap/ieee.rb +4 -2
  121. data/lib/badline/kernal_trap/ieee_layout.rb +95 -43
  122. data/lib/badline/kim1/bus.rb +117 -0
  123. data/lib/badline/kim1/cpu.rb +25 -0
  124. data/lib/badline/kim1/host_terminal.rb +74 -0
  125. data/lib/badline/kim1/key_entry.rb +74 -0
  126. data/lib/badline/kim1/keyed_modules.rb +53 -0
  127. data/lib/badline/kim1/keyed_state.rb +133 -0
  128. data/lib/badline/kim1/panel.rb +176 -0
  129. data/lib/badline/kim1/rriots.rb +28 -0
  130. data/lib/badline/kim1/sound.rb +29 -0
  131. data/lib/badline/kim1/tape.rb +116 -0
  132. data/lib/badline/kim1/teletype.rb +193 -0
  133. data/lib/badline/kim1.rb +190 -0
  134. data/lib/badline/machine/ieee_drives.rb +171 -0
  135. data/lib/badline/machine/keyboard_buffer.rb +20 -3
  136. data/lib/badline/machine/line_sound.rb +122 -0
  137. data/lib/badline/machine/settling.rb +4 -0
  138. data/lib/badline/machine.rb +62 -14
  139. data/lib/badline/media/cbm2_media.rb +29 -0
  140. data/lib/badline/media/extensions.rb +8 -4
  141. data/lib/badline/media/kim1_media.rb +150 -0
  142. data/lib/badline/media/pet_media.rb +3 -1
  143. data/lib/badline/media/program.rb +6 -3
  144. data/lib/badline/media/true_drive.rb +51 -25
  145. data/lib/badline/media.rb +23 -8
  146. data/lib/badline/options/family.rb +108 -6
  147. data/lib/badline/options/help.rb +58 -12
  148. data/lib/badline/options/table.rb +60 -14
  149. data/lib/badline/options/validation.rb +71 -11
  150. data/lib/badline/options.rb +46 -13
  151. data/lib/badline/pet/bus.rb +16 -2
  152. data/lib/badline/pet/cassettes.rb +22 -1
  153. data/lib/badline/pet/ieee_drive.rb +5 -64
  154. data/lib/badline/pet/ieee_ports.rb +7 -0
  155. data/lib/badline/pet/keyboard_ports.rb +9 -2
  156. data/lib/badline/pet/keyed_state.rb +4 -0
  157. data/lib/badline/pet/model.rb +11 -2
  158. data/lib/badline/pet/rom_sets.rb +1 -0
  159. data/lib/badline/pet/sound.rb +5 -105
  160. data/lib/badline/pet/superpet/acia.rb +12 -0
  161. data/lib/badline/pet/superpet/board.rb +221 -0
  162. data/lib/badline/pet/superpet/dongle.rb +81 -0
  163. data/lib/badline/pet/superpet/keyed_modules.rb +63 -0
  164. data/lib/badline/pet/superpet/keyed_parts.rb +76 -0
  165. data/lib/badline/pet/superpet/m6809.rb +32 -0
  166. data/lib/badline/pet/superpet/waterloo_traps.rb +199 -0
  167. data/lib/badline/pet/superpet.rb +216 -0
  168. data/lib/badline/pet.rb +33 -6
  169. data/lib/badline/plus4/acia.rb +4 -298
  170. data/lib/badline/plus4/keyed_parts.rb +0 -44
  171. data/lib/badline/plus4/keyed_state.rb +2 -0
  172. data/lib/badline/plus4.rb +2 -0
  173. data/lib/badline/roms/1001/fdc-251257-02a.rom +0 -0
  174. data/lib/badline/roms/4040/dos-1.2.rom +0 -0
  175. data/lib/badline/roms/4040/dos-2.1-rev.rom +0 -0
  176. data/lib/badline/roms/4040/dos-2.1.rom +0 -0
  177. data/lib/badline/roms/4040/fdc-901466-02.rom +0 -0
  178. data/lib/badline/roms/4040/fdc-901466-04.rom +0 -0
  179. data/lib/badline/roms/8050/dos-2.7.rom +0 -0
  180. data/lib/badline/roms/8050/fdc-901869-01.rom +0 -0
  181. data/lib/badline/roms/8050/fdc-901885-04.rom +0 -0
  182. data/lib/badline/roms/9060/dos-3.0.rom +0 -0
  183. data/lib/badline/roms/9060/sasi-300515-revb.rom +0 -0
  184. data/lib/badline/roms/README +277 -0
  185. data/lib/badline/roms/cbm2/basic128-02b.rom +0 -0
  186. data/lib/badline/roms/cbm2/basic128.rom +0 -0
  187. data/lib/badline/roms/cbm2/basic256.rom +0 -0
  188. data/lib/badline/roms/cbm2/characters-600.rom +0 -0
  189. data/lib/badline/roms/cbm2/characters-700.rom +0 -0
  190. data/lib/badline/roms/cbm2/kernal-03b.rom +0 -0
  191. data/lib/badline/roms/cbm2/kernal-04a.rom +0 -0
  192. data/lib/badline/roms/cbm2/p500-basic.rom +0 -0
  193. data/lib/badline/roms/cbm2/p500-kernal.rom +0 -0
  194. data/lib/badline/roms/kim1/6530-002.rom +0 -0
  195. data/lib/badline/roms/kim1/6530-003.rom +0 -0
  196. data/lib/badline/roms/pet/characters-superpet.rom +0 -0
  197. data/lib/badline/roms/pet/superpet-a000.rom +0 -0
  198. data/lib/badline/roms/pet/superpet-c000.rom +0 -0
  199. data/lib/badline/roms/pet/superpet-e000-50hz.rom +0 -0
  200. data/lib/badline/roms/pet/superpet-e000.rom +0 -0
  201. data/lib/badline/snapshot/cbm2_setup.rb +53 -0
  202. data/lib/badline/snapshot/container.rb +9 -2
  203. data/lib/badline/snapshot/field_doc/markdown.rb +4 -2
  204. data/lib/badline/snapshot/field_doc.rb +59 -3
  205. data/lib/badline/snapshot/image.rb +65 -9
  206. data/lib/badline/snapshot/kim1_setup.rb +28 -0
  207. data/lib/badline/snapshot/pet_setup.rb +27 -11
  208. data/lib/badline/snapshot/storage_setup.rb +4 -1
  209. data/lib/badline/snapshot/vic20_setup.rb +11 -7
  210. data/lib/badline/snapshot/vice/cbm2.rb +93 -0
  211. data/lib/badline/snapshot/vice/cbm2_acia.rb +75 -0
  212. data/lib/badline/snapshot/vice/cbm2_crtc.rb +127 -0
  213. data/lib/badline/snapshot/vice/cbm2_mains.rb +49 -0
  214. data/lib/badline/snapshot/vice/cbm2_mem.rb +75 -0
  215. data/lib/badline/snapshot/vice/cbm2_restore.rb +204 -0
  216. data/lib/badline/snapshot/vice/cbm2_tpi.rb +58 -0
  217. data/lib/badline/snapshot/vice/cias.rb +13 -9
  218. data/lib/badline/snapshot/vice/p500.rb +96 -0
  219. data/lib/badline/snapshot/vice/p500_restore.rb +130 -0
  220. data/lib/badline/snapshot/vice/p500_vicii.rb +166 -0
  221. data/lib/badline/snapshot/vice/pet.rb +20 -10
  222. data/lib/badline/snapshot/vice/pet_cpu.rb +42 -5
  223. data/lib/badline/snapshot/vice/pet_crtc.rb +25 -17
  224. data/lib/badline/snapshot/vice/pet_drive.rb +180 -0
  225. data/lib/badline/snapshot/vice/pet_drive8050.rb +336 -0
  226. data/lib/badline/snapshot/vice/pet_mem.rb +49 -5
  227. data/lib/badline/snapshot/vice/pet_restore.rb +100 -7
  228. data/lib/badline/snapshot/vice/pet_via.rb +6 -5
  229. data/lib/badline/snapshot/vice/sid_registers.rb +2 -1
  230. data/lib/badline/snapshot/vice/vicii_import.rb +10 -6
  231. data/lib/badline/snapshot/vice.rb +3 -0
  232. data/lib/badline/snapshot.rb +15 -3
  233. data/lib/badline/status.rb +30 -30
  234. data/lib/badline/storage/crt_file.rb +7 -1
  235. data/lib/badline/storage/d64_image.rb +7 -0
  236. data/lib/badline/storage/d67_image.rb +55 -0
  237. data/lib/badline/storage/d80_image.rb +17 -1
  238. data/lib/badline/storage/d81_image.rb +14 -0
  239. data/lib/badline/storage/d90_image.rb +180 -0
  240. data/lib/badline/storage/disk_image/bam.rb +18 -3
  241. data/lib/badline/storage/disk_image/formatting.rb +69 -0
  242. data/lib/badline/storage/disk_image/writing.rb +37 -2
  243. data/lib/badline/storage/disk_image.rb +2 -0
  244. data/lib/badline/storage/kim_tape.rb +254 -0
  245. data/lib/badline/storage/papertape.rb +90 -0
  246. data/lib/badline/storage.rb +5 -0
  247. data/lib/badline/support/cbm2_checkpoint.rb +48 -0
  248. data/lib/badline/support/kim1_checkpoint.rb +41 -0
  249. data/lib/badline/support/p500_checkpoint.rb +35 -0
  250. data/lib/badline/support/superpet_checkpoint.rb +35 -0
  251. data/lib/badline/version.rb +1 -1
  252. data/lib/badline/vic20/keyed_modules.rb +6 -3
  253. data/lib/badline/vic20/keyed_state.rb +6 -4
  254. data/lib/badline/vic20.rb +26 -12
  255. data/lib/badline.rb +2 -0
  256. metadata +148 -2
@@ -49,10 +49,11 @@ module Badline
49
49
  # wrapped as the banner is.
50
50
  def media_kinds
51
51
  text = "Media can be #{listed(Media::Extensions::PROGRAMS)} program, #{listed(%i[disk])} disk image, " \
52
- "#{listed(%i[ieee_disk])} disk image for a PET, #{listed(%i[gcr])} disk image for a true drive, " \
53
- "#{listed(%i[disk_list])} list of disk images, " \
52
+ "#{listed(%i[ieee_disk])} disk image or #{listed(%i[hard_disk])} hard disk for a PET, " \
53
+ "#{listed(%i[gcr])} disk image for a true drive, #{listed(%i[disk_list])} list of disk images, " \
54
54
  "#{listed(%i[archive])} tape archive, #{listed(%i[tape])} tape, #{listed(%i[cartridge])} " \
55
- "cartridge, #{listed(%i[tune])} tune, #{listed(%w[.vsf])} snapshot, or a directory to mount as device 8."
55
+ "cartridge, #{listed(%i[tune])} tune, #{listed(%i[papertape])} papertape for a KIM-1, " \
56
+ "#{listed(%w[.vsf])} snapshot, or a directory to mount as device 8."
56
57
  wrap(text)
57
58
  end
58
59
 
@@ -86,16 +87,20 @@ module Badline
86
87
  #{@program} c128 [options] [media]
87
88
  #{@program} plus4 [options] [media]
88
89
  #{@program} pet [options] [media]
90
+ #{@program} cbm2 [options] [media]
91
+ #{@program} kim1 [options] [program]
89
92
  #{@program} --headless [options] tune.sid
90
93
  #{@program} [options] tune.sid --audio-out FILE
91
94
  #{@program} sid [options] FILE|DIR...
92
95
 
93
96
  Commands:
94
97
  c64 Run a C64, the one --model names (the default)
95
- vic20 Run a PAL VIC-20, with the RAM --ram names
98
+ vic20 Run a VIC-20, PAL or --ntsc, with the RAM --ram names
96
99
  c128 Run a C128 in C128 mode, the one --model names
97
100
  plus4 Run a Plus/4 or a C16, the one --model names
98
101
  pet Run a PET or a CBM, the one --model names
102
+ cbm2 Run a CBM-II, a B series or a P500, the one --model names
103
+ kim1 Run a MOS KIM-1, on its keypad and LED display
99
104
  sid Play .sid tunes and directories of them
100
105
 
101
106
  #{media_kinds}
@@ -120,20 +125,59 @@ module Badline
120
125
  ESC, Page Down RUN/STOP and F4 HELP.
121
126
 
122
127
  The PET and the CBM take programs, disks, .d80 and .d82 among them,
123
- and tapes, and a .d80, a .d82 or a PET tape starts one without
124
- `pet`. Their keys type what the host's keys type, Alt with a key
128
+ and tapes, and a .d80, .d82, .d67 or .d90 or a PET tape starts one
129
+ without `pet`. Their keys type what the host's keys type, Alt with a key
125
130
  presses the PET's SHIFT and the key its unshifted character is on,
126
131
  and the pause menu's KEYBOARD page says where the rest are. --basic
127
132
  and --editor fit the upgrades Commodore sold, as in --model 2001
128
133
  --basic 2. BASIC 1 can't LOAD from a disk drive, though a disk still
129
134
  starts its first program, and BASIC 2 can. Their --true-drive makes
130
135
  device 8 an emulated 2031 on the IEEE-488 bus, which reads .d64 and
131
- .g64 images. The 8032 and the 8096 have two 50 Hz editors:
132
- 4-80-b-50hz, the default, and 4-80-b-50hz-0283, another chip's,
136
+ .g64 images, and a .d80 or a .d82 then goes in an emulated 8050 or
137
+ 8250. --drive-type 8050 or 8250 plugs either in instead, and
138
+ --drive-type 1001 an SFD-1001, which takes a .d82 in its one drive.
139
+ --drive-type 4040 or 3040 puts a .d64 in a 4040 or a 3040 instead
140
+ of the 2031, and a .d67, DOS 1's disk, goes in a 2040. A .d90 hard
141
+ disk always goes in a D9060 or a D9090, by its size. The pause
142
+ menu's DRIVE 8 page picks the drive type on the bus.
143
+ The 8032 and the 8096 have two 50 Hz editors: 4-80-b-50hz, the
144
+ default, and 4-80-b-50hz-0283, another chip's,
133
145
  with 64-cycle lines and 313 lines a frame. The 8296 runs its own,
134
146
  4-80-b-50hz-8296, and takes the 8032's too. --characters din fits
135
147
  it with the DIN character ROM, and --jumpers ram9,rama puts RAM at
136
- $9000 and $A000, as xpet's -petram9 and -petramA do.
148
+ $9000 and $A000, as xpet's -petram9 and -petramA do. --model
149
+ superpet runs the SuperPET, and --cpu 6809 its Waterloo 6809 side.
150
+ --bank-ram read write-protects its 64K bank RAM.
151
+
152
+ The CBM-II takes programs, disks, .d80 and .d82 among them, and
153
+ cartridges, and a cartridge made for it starts one without `cbm2`.
154
+ --kernal 03b fits the 1983 KERNAL in place of 04a, and --60hz runs
155
+ it on 60 Hz mains. Its --true-drive makes device 8 an emulated 2031
156
+ on its IEEE-488 bus, which reads .d64 and .g64 images, and a .d80
157
+ or a .d82 then goes in an emulated 8050 or 8250, and --drive-type
158
+ plugs in either from the start, as on the PET. Its keys type what
159
+ the host's keys type, F12 is RUN/STOP, Alt with F9 or F10 presses
160
+ its F9 or F10, and the pause menu's KEYBOARD page says where the
161
+ rest are. --model 510 or 510ntsc runs the P500, on the VIC-II with
162
+ KERNAL 02, whose keys are the B series' and whose two joysticks Tab
163
+ switches to.
164
+
165
+ The KIM-1 starts in its monitor, on the keypad and the six LED
166
+ digits, which the window draws with the keys under them. 0-9 and A-F
167
+ are the hex keys, comma AD, period DA, space or + +, G or Return GO,
168
+ P PC, S or Esc ST, R RS and T the SST switch, and a click presses a
169
+ key too. The pause menu's PANEL page sets SST, the TTY/KB jumper and
170
+ what U3's PB7 and PA0 are wired to. --tty puts the monitor on a
171
+ teletype at --baud, shown in the window, or with --headless on the
172
+ terminal, where Ctrl-C quits.
173
+ It loads .ptp and .pap papertapes, which start a KIM-1 without
174
+ `kim1`, and .bin files at --load-address. The program goes into RAM,
175
+ the NMI and IRQ vectors at $17FA and $17FE point at the monitor, and
176
+ the monitor starts it where it loads, or at --start-address.
177
+ --tty-load reads a papertape through the monitor's L command
178
+ instead. --ram 5k fills $0400-$13FF, and --ram expanded $2000-$DFFF
179
+ too. A .wav recording of a KIM tape goes in the cassette deck, which
180
+ the pause menu's DATASETTE page plays for LOADT at $1873.
137
181
 
138
182
  --headless plays a .sid tune on the host's audio device without the
139
183
  window, and --audio-out renders it to 16-bit PCM instead. The
@@ -156,11 +200,13 @@ module Badline
156
200
  in --at 3500:key=space or --at 250,500:screenshot=shot%05d.bmp.
157
201
  key=NAME presses a key (space, return, a, f1, run_stop, restore, and
158
202
  on the C128 esc, help, keypad1 and the rest, on the Plus/4
159
- esc, help and f1 to f3, and on the PET rvs, escape and kp1) or a
160
- joystick's
203
+ esc, help and f1 to f3, on the PET rvs, escape and kp1, and on
204
+ the CBM-II escape, norm_graph and kp00, and on the KIM-1 its keys,
205
+ as 0 to f, ad, da, plus, go, pc, st and rs) or a joystick's
161
206
  direction or fire (joy1-up, joy2-fire) for #{Event::HOLD} frames, and
162
207
  pushes the C128's caps_lock or forty_eighty, which lock. type=TEXT
163
- types it, with \\n for RETURN. insert=FILE swaps in a disk, a list's
208
+ types it, with \\n for RETURN, or on the KIM-1 presses the keys it
209
+ names, as in type=AD 0200 DA A9. insert=FILE swaps in a disk, a list's
164
210
  first disk, a tape or a cartridge, and eject=disk, tape or
165
211
  cartridge takes one out. screenshot=FILE saves the frame as a .bmp,
166
212
  with the frame's number in place of %d. menu opens the pause menu,
@@ -7,8 +7,7 @@ module Badline
7
7
  # The names Badline::Model builds, in the order the help lists them.
8
8
  MODELS = %w[c64 c64c ntsc newntsc oldntsc drean sx64 pet64 c64gs ultimax].freeze
9
9
 
10
- # The VIC-20's models, as xvic names its video standards. Only PAL is
11
- # emulated.
10
+ # The VIC-20's models, as xvic names its video standards.
12
11
  VIC20_MODELS = %w[pal ntsc].freeze
13
12
 
14
13
  # The C128's models, as C128::Model names them.
@@ -20,7 +19,27 @@ module Badline
20
19
 
21
20
  # The PETs and CBMs, as PET::Model names them, the 8032 first, the
22
21
  # default.
23
- PET_MODELS = %w[8032 8096 8296 4032 3032 3032b 2001].freeze
22
+ PET_MODELS = %w[8032 8096 8296 4032 3032 3032b 2001 superpet].freeze
23
+
24
+ # The CBM-II's B series, as CBM2::Model names them, the 610 first, the
25
+ # default, and the P500, as CBM2::P500::Model names them.
26
+ CBM2_MODELS = %w[610 620 710 720 510 510ntsc].freeze
27
+
28
+ # The KIM-1, which has the one model.
29
+ KIM1_MODELS = %w[kim1].freeze
30
+
31
+ # The KIM-1 teletype's rates, as KIM1::Teletype takes them.
32
+ KIM1_BAUDS = %w[110 300 1200 2400 4800 9600].freeze
33
+
34
+ # The KIM-1's RAM as --ram names it, and the names
35
+ # KIM1::Bus::RAM_CONFIGURATIONS gives it.
36
+ KIM1_RAM = { "1k" => :"1k", "5k" => :"5k", "expanded" => :expanded }.freeze
37
+
38
+ # The B series' KERNALs --kernal names, 901244-04a first, the default.
39
+ CBM2_KERNALS = %w[04a 03b].freeze
40
+
41
+ # The P500's one KERNAL, 901234-02.
42
+ P500_KERNALS = %w[02].freeze
24
43
 
25
44
  # The true drives --drive-type names for the Plus/4.
26
45
  PLUS4_DRIVE_TYPES = %w[1541 1551].freeze
@@ -39,6 +58,22 @@ module Badline
39
58
  Option.new("--disable-jit", "Run without enabling YJIT", section: "Options", build: :ruby),
40
59
  Option.new("-h, --help", "Show this help", section: "Options"),
41
60
  Option.new("--version", "Show the version and what built it", section: "Options", build: :native),
61
+ Option.new("--tty", "Fit the KIM-1's TTY/KB jumper, so its monitor talks to a teletype: a pane in the " \
62
+ "window, or the terminal with --headless",
63
+ section: "Options"),
64
+ Option.new("--baud N", "The KIM-1 teletype's baud: #{KIM1_BAUDS.join(', ')} (default: 9600)",
65
+ section: "Options"),
66
+ Option.new("--tty-load", "Load the KIM-1's .ptp or .pap through its monitor's L command on the teletype, " \
67
+ "in real time, instead of straight into RAM; implies --tty",
68
+ section: "Options"),
69
+ Option.new("--load-address ADDR", "Where the KIM-1 loads a .bin, in hex (default: 0200)",
70
+ section: "Options"),
71
+ Option.new("--start-address ADDR", "Where the KIM-1 starts its program, in hex (default: where it loads)",
72
+ section: "Options"),
73
+ Option.new("--ram SIZE", "VIC-20 RAM expansion: #{RAM_NAMES.join(', ')} (default: unexpanded); " \
74
+ "Plus/4 RAM: 16k, 32k or 64k; PET RAM: 4k, 8k, 16k or 32k (default: the model's own); " \
75
+ "KIM-1 RAM: 1k, 5k or expanded (default: 1k)",
76
+ section: "Options"),
42
77
  Option.new("--no-autostart", "Boot to READY. instead of running the program",
43
78
  section: "Window options", needs: :window),
44
79
  Option.new("--writable", "Let the machine write to disk images, changing their files",
@@ -47,23 +82,28 @@ module Badline
47
82
  section: "Window options", needs: :window),
48
83
  Option.new("--no-sound", "Don't play the SID", section: "Window options", needs: :window, build: :native),
49
84
  Option.new("--true-drive", "Put a true 1541 on device 8 instead of the KERNAL traps, a 1571 on the C128, " \
50
- "a 1551 on the Plus/4, a 2031 on the PET",
85
+ "a 1551 on the Plus/4, a 2031 on the PET or the CBM-II, or for a .d80 or .d82 " \
86
+ "an 8050 or 8250",
51
87
  section: "Window options", needs: :window),
52
- Option.new("--drive-type MODEL", "The Plus/4's true drive: 1541 or 1551 (default: 1551); implies --true-drive",
88
+ Option.new("--drive-type MODEL", "The Plus/4's true drive: 1541 or 1551 (default: 1551); the PET's and the " \
89
+ "CBM-II's: #{Drives::IEEEModels::NAMES.join(', ')} (default: 2031); " \
90
+ "implies --true-drive",
53
91
  section: "Window options", needs: :window),
54
92
  Option.new("--reu SIZE", "Plug in an REU of SIZE K: 128, 256, 512 (a 1750) or up to 16384",
55
93
  section: "Window options", needs: :window),
56
- Option.new("--model NAME", "C64 to run: #{MODELS.join(', ')} (default: #{MODELS.first}); VIC-20: pal; " \
57
- "C128: #{C128_MODELS.join(', ')}; Plus/4: #{PLUS4_MODELS.join(', ')}; " \
58
- "PET: #{PET_MODELS.join(', ')}",
94
+ Option.new("--model NAME", "C64 to run: #{MODELS.join(', ')} (default: #{MODELS.first}); " \
95
+ "VIC-20: #{VIC20_MODELS.join(', ')}; C128: #{C128_MODELS.join(', ')}; " \
96
+ "Plus/4: #{PLUS4_MODELS.join(', ')}; " \
97
+ "PET: #{PET_MODELS.join(', ')}; CBM-II: #{CBM2_MODELS.join(', ')}",
98
+ section: "Window options", needs: :window),
99
+ Option.new("--ntsc", "Run an NTSC C64 or VIC-20, as --model ntsc does",
59
100
  section: "Window options", needs: :window),
60
- Option.new("--ntsc", "Run an NTSC C64, as --model ntsc does", section: "Window options", needs: :window),
61
101
  Option.new("--c64", "Start the C128 in C64 mode, holding C= at power-on",
62
102
  section: "Window options", needs: :window),
63
- Option.new("--ram SIZE", "VIC-20 RAM expansion: #{RAM_NAMES.join(', ')} (default: unexpanded); " \
64
- "Plus/4 RAM: 16k, 32k or 64k; PET RAM: 4k, 8k, 16k or 32k (default: the model's own)",
103
+ Option.new("--60hz", "Run a CRTC PET's 60 Hz editor instead of its 50 Hz one, or a CBM-II on 60 Hz mains",
65
104
  section: "Window options", needs: :window),
66
- Option.new("--60hz", "Run a CRTC PET's 60 Hz editor instead of its 50 Hz one",
105
+ Option.new("--kernal VERSION", "Fit a CBM-II with KERNAL #{CBM2_KERNALS.join(' or ')} " \
106
+ "(default: #{CBM2_KERNALS.first}); the P500 takes #{P500_KERNALS.first}",
67
107
  section: "Window options", needs: :window),
68
108
  Option.new("--basic VERSION", "Fit a PET with BASIC 1, 2 or 4, as its board takes (default: its own)",
69
109
  section: "Window options", needs: :window),
@@ -76,6 +116,12 @@ module Badline
76
116
  "$9000 and $A000, userport for the user port's PA0-PA2 to switch in " \
77
117
  "the RAM under the ROMs",
78
118
  section: "Window options", needs: :window),
119
+ Option.new("--cpu CPU", "Set the SuperPET's CPU switch: 6502, 6809 or prog, for the system latch to pick " \
120
+ "(default: 6502)",
121
+ section: "Window options", needs: :window),
122
+ Option.new("--bank-ram MODE", "Set the SuperPET's bank RAM switch: rw, read for write-protected, or prog, " \
123
+ "for the system latch to pick (default: rw)",
124
+ section: "Window options", needs: :window),
79
125
  Option.new("--c1lo FILE", "Put a .bin ROM image in the Plus/4's cartridge 1, low slot ($8000)",
80
126
  section: "Window options", needs: :window),
81
127
  Option.new("--c1hi FILE", "Put a .bin ROM image in cartridge 1's high slot ($C000)",
@@ -94,7 +140,7 @@ module Badline
94
140
  section: "Window options", needs: :window),
95
141
  Option.new("--verbose", "Print the display, sound and gamepad setup and the frame timing",
96
142
  section: "Window options", needs: :window),
97
- Option.new("--headless", "Play a .sid tune in the terminal instead of the window",
143
+ Option.new("--headless", "Play a .sid tune, or run the KIM-1's teletype, in the terminal instead of the window",
98
144
  section: "Options without the window"),
99
145
  Option.new("--audio-out FILE", "Render a .sid tune to a .wav or .aiff file",
100
146
  section: "Options without the window"),
@@ -118,7 +164,7 @@ module Badline
118
164
  section: "Testing options", needs: :window),
119
165
  Option.new("--save-snapshot FILE", "Save the machine as a .vsf snapshot after the last frame",
120
166
  section: "Testing options", needs: :window),
121
- Option.new("--vice", "Add VICE's modules to --save-snapshot's C64 or PET snapshot, for x64sc or xpet",
167
+ Option.new("--vice", "Add VICE's modules to --save-snapshot's C64, PET or CBM-II snapshot",
122
168
  section: "Testing options", needs: :window),
123
169
  Option.new("--at FRAME:EVENT", "Run EVENT once FRAME frames have run (see above)",
124
170
  section: "Testing options", needs: :window),
@@ -52,11 +52,25 @@ module Badline
52
52
  end
53
53
 
54
54
  def drive_type_for(value)
55
- raise Error, "invalid argument: --drive-type #{value}" unless PLUS4_DRIVE_TYPES.include?(value)
55
+ unless (PLUS4_DRIVE_TYPES + Drives::IEEEModels::NAMES).include?(value)
56
+ raise Error, "invalid argument: --drive-type #{value}"
57
+ end
56
58
 
57
59
  value
58
60
  end
59
61
 
62
+ def kernal_for(value)
63
+ raise Error, "invalid argument: --kernal #{value}" unless (CBM2_KERNALS + P500_KERNALS).include?(value)
64
+
65
+ value
66
+ end
67
+
68
+ def baud_for(value)
69
+ raise Error, "invalid argument: --baud #{value}" unless KIM1_BAUDS.include?(value)
70
+
71
+ value.to_i
72
+ end
73
+
60
74
  def reu_size(value)
61
75
  raise Error, "invalid argument: --reu #{value}" unless REU_SIZES.include?(value)
62
76
 
@@ -77,7 +91,7 @@ module Badline
77
91
 
78
92
  def validate
79
93
  validate_family
80
- raise Error, "--drive-type needs plus4" unless @drive_type.nil? || @family == :plus4
94
+ validate_drive_type
81
95
 
82
96
  validate_mode
83
97
  validate_models
@@ -85,10 +99,20 @@ module Badline
85
99
  validate_paths
86
100
  end
87
101
 
102
+ def validate_drive_type
103
+ return if @drive_type.nil?
104
+
105
+ types = @family == :plus4 ? PLUS4_DRIVE_TYPES : Drives::IEEEModels::NAMES
106
+ return if %i[plus4 pet cbm2].include?(@family) && types.include?(@drive_type)
107
+
108
+ raise Error, "--drive-type needs #{PLUS4_DRIVE_TYPES.include?(@drive_type) ? 'plus4' : 'pet or cbm2'}"
109
+ end
110
+
88
111
  def validate_mode
89
112
  if headless?
90
113
  raise Error, "#{@window_only.first} needs the window" unless @window_only.empty?
91
114
  raise Error, "#{@any_window_only.first} needs the window" unless player_window? || @any_window_only.empty?
115
+ return if @family == :kim1
92
116
  raise Error, "no tune given" if tune_paths.empty? && !player_window?
93
117
 
94
118
  tune_paths.each { |path| validate_tune(path) }
@@ -99,9 +123,11 @@ module Badline
99
123
 
100
124
  def validate_family
101
125
  ram_option
126
+ @family == :kim1 ? validate_kim1 : refuse_kim1_options
102
127
  validate_vic20 if @family == :vic20
103
128
  @family == :plus4 ? validate_plus4 : refuse_plus4_options
104
129
  @family == :pet ? validate_pet : refuse_pet_options
130
+ @family == :cbm2 ? validate_cbm2 : refuse_cbm2_options
105
131
  if @family == :c128
106
132
  validate_c128
107
133
  elsif @c64_mode
@@ -118,7 +144,8 @@ module Badline
118
144
  when :vic20 then @ram = ram_configuration(@ram_name)
119
145
  when :plus4 then @ram_kb = plus4_ram(@ram_name)
120
146
  when :pet then @ram_kb = pet_ram(@ram_name)
121
- else raise Error, "--ram needs vic20, plus4 or pet"
147
+ when :kim1 then @ram = kim1_ram(@ram_name)
148
+ else raise Error, "--ram needs vic20, plus4, pet or kim1"
122
149
  end
123
150
  end
124
151
 
@@ -130,11 +157,8 @@ module Badline
130
157
  raise Error, "the C128 needs the window" if headless?
131
158
  end
132
159
 
133
- # The VIC-20 is a PAL one, in the window, without the C64's SID and
134
- # REU.
160
+ # The VIC-20 runs in the window, without the C64's SID and REU.
135
161
  def validate_vic20
136
- raise Error, "the NTSC VIC-20 isn't emulated yet" if @models.include?("ntsc")
137
-
138
162
  raise Error, "--sid needs the C64" unless @sid_model.nil?
139
163
  raise Error, "--reu needs the C64" unless @reu.nil?
140
164
  raise Error, "the VIC-20 needs the window" if headless?
@@ -170,14 +194,16 @@ module Badline
170
194
  raise Error, "--sid-card-address needs --sid-card" unless @sid_card_address.nil? || @sid_card
171
195
  end
172
196
 
173
- # Only the PET has a frame rate to pick and BASIC and editor ROMs to
174
- # fit.
197
+ # Only the PET has BASIC and editor ROMs to fit, and only it and the
198
+ # CBM-II a frame rate to pick.
175
199
  def refuse_pet_options
176
- raise Error, "--60hz needs pet" unless @refresh_hz.nil?
200
+ raise Error, "--60hz needs pet or cbm2" unless @refresh_hz.nil? || @family == :cbm2
177
201
  raise Error, "--basic needs pet" unless @basic.nil?
178
202
  raise Error, "--editor needs pet" unless @editor.nil?
179
203
  raise Error, "--characters needs pet" unless @characters.nil?
180
204
  raise Error, "--jumpers needs pet" unless @jumpers.empty?
205
+ raise Error, "--cpu needs pet --model superpet" unless @cpu.nil?
206
+ raise Error, "--bank-ram needs pet --model superpet" unless @bank_ram.nil?
181
207
  end
182
208
 
183
209
  # The PET runs in the window, without the C64's SID and REU, at the
@@ -195,7 +221,8 @@ module Badline
195
221
  end
196
222
 
197
223
  # --characters names a character ROM the board takes, --jumpers the
198
- # 8296 board's jumpers, and the 8296 has all of its RAM soldered on.
224
+ # 8296 board's jumpers, and the 8296 has all of its RAM soldered on,
225
+ # as the SuperPET has besides its bank RAM.
199
226
  def validate_pet_board
200
227
  unless @characters.nil? || PET::ROMSets.characters(model).include?(@characters)
201
228
  raise Error, "the #{model} takes no character ROM #{@characters}"
@@ -204,6 +231,22 @@ module Badline
204
231
  unknown = @jumpers.find { |jumper| !PET::ROMSets.jumpers(model).include?(jumper) }
205
232
  raise Error, "the #{model} has no jumper #{unknown}" unless unknown.nil?
206
233
  raise Error, "the 8296 has 32k of RAM" if model == "8296" && ![nil, 32].include?(@ram_kb)
234
+ raise Error, "--ram doesn't fit the superpet" if model == "superpet" && !@ram_kb.nil?
235
+
236
+ validate_cpu_switch
237
+ end
238
+
239
+ # --cpu and --bank-ram set the SuperPET's switches, which no other
240
+ # PET has.
241
+ def validate_cpu_switch
242
+ validate_switch("--cpu", @cpu, PET::SuperPET::Board::CPU_SWITCH)
243
+ validate_switch("--bank-ram", @bank_ram, PET::SuperPET::Board::RAM_SWITCH)
244
+ end
245
+
246
+ def validate_switch(flag, value, positions)
247
+ return if value.nil?
248
+ raise Error, "#{flag} needs pet --model superpet" unless model == "superpet"
249
+ raise Error, "invalid argument: #{flag} #{value}" unless positions.include?(value)
207
250
  end
208
251
 
209
252
  # --basic and --editor name ROMs the model's board takes
@@ -232,6 +275,23 @@ module Badline
232
275
  @refresh_hz = editor_hz
233
276
  end
234
277
 
278
+ # Only the CBM-II has a KERNAL to pick.
279
+ def refuse_cbm2_options
280
+ raise Error, "--kernal needs cbm2" unless @kernal.nil?
281
+ end
282
+
283
+ # The CBM-II runs in the window, without the C64's SID and REU, and
284
+ # its model takes the KERNAL named.
285
+ def validate_cbm2
286
+ raise Error, "--ntsc needs the C64; a CBM-II on 60 Hz mains is --60hz" if @models.include?("ntsc")
287
+ raise Error, "--sid needs the C64" unless @sid_model.nil?
288
+ raise Error, "--reu needs the C64" unless @reu.nil?
289
+ raise Error, "the CBM-II needs the window" if headless?
290
+
291
+ kernals = p500? ? P500_KERNALS : CBM2_KERNALS
292
+ raise Error, "the #{model} takes KERNAL #{kernals.join(' or ')}" unless kernals.include?(kernal)
293
+ end
294
+
235
295
  # `sid` takes directories as well as tunes.
236
296
  def validate_tune(path)
237
297
  return if !File.exist?(path) || File.extname(path).casecmp?(".sid")
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "badline/pet/rom_sets"
4
+ require "badline/drives/ieee_models"
4
5
  require "badline/options/option"
5
6
  require "badline/options/event"
6
7
  require "badline/options/table"
@@ -13,10 +14,11 @@ module Badline
13
14
  # Either opens the window for any media, or with --headless or
14
15
  # --audio-out plays or renders a .sid tune without one. `sid`, given
15
16
  # first, plays .sid tunes and directories of them in the terminal.
16
- # `c64`, `vic20`, `c128`, `plus4` or `pet`, given first, names the
17
- # machine family, and without one the family is the C64, the C128 for a
18
- # program that loads where C128 BASIC starts, or the PET for an 8050's
19
- # or 8250's disk or a PET tape.
17
+ # `c64`, `vic20`, `c128`, `plus4`, `pet` or `cbm2`, given first, names
18
+ # the machine family, and without one the family is the C64, the C128
19
+ # for a program that loads where C128 BASIC starts, the PET for an
20
+ # 8050's or 8250's disk or a PET tape, or the CBM-II for a cartridge
21
+ # signed as its own. `kim1` runs a MOS KIM-1.
20
22
  # The native build adds --no-sound and --version, and badline-ruby adds
21
23
  # --disable-jit.
22
24
  #
@@ -40,7 +42,7 @@ module Badline
40
42
  SID_MODELS = { "6581" => :mos6581, "8580" => :mos8580 }.freeze
41
43
 
42
44
  # What `sid` leaves out besides the window's options.
43
- NOT_FOR_SID = %w[--audio-out].freeze
45
+ NOT_FOR_SID = %w[--audio-out --tty --baud --tty-load --load-address --start-address --ram].freeze
44
46
 
45
47
  REU_SIZES = %w[128 256 512 1024 2048 4096 8192 16384].freeze
46
48
 
@@ -77,7 +79,7 @@ module Badline
77
79
  :audio_out, :seconds, :songlengths, :filter_chunk, :timeline
78
80
 
79
81
  # The machine family to build (Badline::Machine), :c64, :vic20, :c128,
80
- # :plus4 or :pet.
82
+ # :plus4, :pet or :cbm2.
81
83
  attr_reader :family
82
84
 
83
85
  # The ROMs --basic, --editor and --characters fit a PET with, keys of
@@ -88,8 +90,17 @@ module Badline
88
90
  # The 8296's board jumpers --jumpers names (PET::Bus::Expansion::JUMPERS).
89
91
  attr_reader :jumpers
90
92
 
93
+ # The SuperPET's CPU switch, as --cpu sets it: "6502", "6809" or
94
+ # "prog".
95
+ def cpu = @cpu || "6502"
96
+
97
+ # The SuperPET's bank RAM switch, as --bank-ram sets it: "rw", "read"
98
+ # or "prog".
99
+ def bank_ram = @bank_ram || "rw"
100
+
91
101
  # The VIC-20's RAM expansion --ram names, a key of
92
- # Vic20::Bus::RAM_CONFIGURATIONS, or nil without --ram.
102
+ # Vic20::Bus::RAM_CONFIGURATIONS, or the KIM-1's, one of
103
+ # KIM1::Bus::RAM_CONFIGURATIONS, or nil without --ram.
93
104
  attr_reader :ram
94
105
 
95
106
  # The Plus/4's or the PET's RAM in K --ram names, one of PLUS4_RAM's or
@@ -137,6 +148,8 @@ module Badline
137
148
  @ram_kb = nil
138
149
  @ram_name = nil
139
150
  initialize_pet
151
+ initialize_kim1
152
+ @kernal = nil
140
153
  @cartridges = {}
141
154
  @autostart = true
142
155
  @writable = false
@@ -228,8 +241,9 @@ module Badline
228
241
 
229
242
  def true_drive? = @true_drive || !@drive_type.nil?
230
243
 
231
- # The Plus/4's true drive --drive-type names, "1551" without it.
232
- def drive_type = @drive_type || "1551"
244
+ # The true drive --drive-type names: without it, "1551" on the Plus/4
245
+ # and the 2031 on the PET and the CBM-II.
246
+ def drive_type = @drive_type || (@family == :plus4 ? "1551" : Drives::IEEEModels::DEFAULT)
233
247
 
234
248
  # Whether --save-snapshot adds VICE's modules, so x64sc opens it.
235
249
  def vice? = @vice
@@ -246,9 +260,20 @@ module Badline
246
260
  def c64_mode? = @c64_mode
247
261
 
248
262
  # The frame rate of a CRTC PET's editor: 60 with --60hz or a 60 Hz
249
- # --editor, else 50.
263
+ # --editor, else 50. A B series CBM-II's mains, which its editor
264
+ # follows.
250
265
  def refresh_hz = @refresh_hz || 50
251
266
 
267
+ # The CBM-II's mains, 60 with --60hz, or nil for the model's own.
268
+ def mains_hz = @refresh_hz
269
+
270
+ # The CBM-II's KERNAL --kernal names, one of CBM2_KERNALS or, on the
271
+ # P500, P500_KERNALS, the first of them without it.
272
+ def kernal = @kernal || (p500? ? P500_KERNALS : CBM2_KERNALS).first
273
+
274
+ # Whether the CBM-II to run is a P500, a 510 of either region.
275
+ def p500? = @family == :cbm2 && model.start_with?("510")
276
+
252
277
  def help? = @help
253
278
 
254
279
  def version? = @version
@@ -264,7 +289,7 @@ module Badline
264
289
  # A .sid on its own plays in the SID player, as `sid` would, unless an
265
290
  # option of the emulator's window asks for the machine.
266
291
  def play_lone_tune
267
- return if @sid_command || %i[vic20 plus4 pet].include?(@family) || headless? || !@window_only.empty?
292
+ return if @sid_command || %i[vic20 plus4 pet cbm2 kim1].include?(@family) || headless? || !@window_only.empty?
268
293
  return if @media_path.nil?
269
294
 
270
295
  @sid_command = File.extname(@media_path).casecmp?(".sid")
@@ -324,8 +349,9 @@ module Badline
324
349
  when "--model" then @models << value
325
350
  when "--reu" then @reu = reu_size(value)
326
351
  when "--ram" then @ram_name = value
327
- when "--basic", "--editor", "--characters", "--jumpers" then pet_option(name, value)
352
+ when "--basic", "--editor", "--characters", "--jumpers", "--cpu", "--bank-ram" then pet_option(name, value)
328
353
  when "--drive-type" then @drive_type = drive_type_for(value)
354
+ when "--kernal" then @kernal = kernal_for(value)
329
355
  when "--c1lo", "--c1hi", "--c2lo", "--c2hi" then @cartridges[CARTRIDGE_SLOTS.fetch(name)] = value
330
356
  when "--frames" then @frames = number(flag, value)
331
357
  when "--screenshot" then @screenshot = value
@@ -335,12 +361,16 @@ module Badline
335
361
  when "--seconds" then @seconds = decimal(flag, value)
336
362
  when "--songlengths" then @songlengths = value
337
363
  when "--rate" then @rate = number(flag, value)
364
+ when "--baud", "--load-address", "--start-address" then kim1_option(name, flag, value)
338
365
  else @filter_chunk = number(flag, value)
339
366
  end
340
367
  end
341
368
 
342
- # The PET's frame rate, ROMs and board jumpers, its own until named.
369
+ # The PET's frame rate, ROMs, board jumpers and the SuperPET's CPU and
370
+ # bank RAM switches, its own until named.
343
371
  def initialize_pet
372
+ @cpu = nil
373
+ @bank_ram = nil
344
374
  @refresh_hz = nil
345
375
  @basic = nil
346
376
  @editor = nil
@@ -353,6 +383,8 @@ module Badline
353
383
  when "--basic" then @basic = value
354
384
  when "--editor" then @editor = value
355
385
  when "--characters" then @characters = value
386
+ when "--cpu" then @cpu = value
387
+ when "--bank-ram" then @bank_ram = value
356
388
  else @jumpers = value.split(",")
357
389
  end
358
390
  end
@@ -377,6 +409,7 @@ module Badline
377
409
  when "--headless" then @headless = true
378
410
  when "--quiet" then @quiet = true
379
411
  when "--all-subtunes" then @all_subtunes = true
412
+ when "--tty", "--tty-load" then kim1_switch(name)
380
413
  else @tui = false
381
414
  end
382
415
  end
@@ -8,11 +8,12 @@ module Badline
8
8
  #
9
9
  # $0000-$7FFF - RAM, 4K, 8K, 16K or 32K of it from $0000, then nothing
10
10
  # $8000-$8FFF - screen RAM, repeated (Model), then nothing
11
- # $9000-$AFFF - two empty ROM sockets
11
+ # $9000-$AFFF - two empty ROM sockets, or the SuperPET's bank RAM at
12
+ # $9000
12
13
  # $B000-$DFFF - BASIC 4, or BASIC 1 or 2 from $C000
13
14
  # $E000-$E7FF - the screen editor ROM
14
15
  # $E800-$E8FF - I/O (IO)
15
- # $E900-$EFFF - nothing
16
+ # $E900-$EFFF - nothing, but the SuperPET's I/O page at $EF00
16
17
  # $F000-$FFFF - the KERNAL ROM
17
18
  #
18
19
  # The data lines hold the last byte they carried, so a read from an
@@ -136,6 +137,7 @@ module Badline
136
137
  @user_port = !@expansion.nil? && @expansion.user_port?
137
138
  @debug_register = nil
138
139
  @io_write_handler = nil
140
+ @board = nil
139
141
  map_pages
140
142
  end
141
143
 
@@ -174,6 +176,11 @@ module Badline
174
176
  @write_pages[addr >> 8].poke(addr, value)
175
177
  end
176
178
 
179
+ # #peek and #poke as the SuperPET's 6809 calls them.
180
+ def read(addr) = peek(addr)
181
+
182
+ def write(addr, value) = poke(addr, value)
183
+
177
184
  # Whether the CPU reads the KERNAL ROM at $F000-$FFFF, which an 8096's
178
185
  # board covers while its control register turns it on, and an 8296's
179
186
  # RAM too.
@@ -185,6 +192,12 @@ module Badline
185
192
  map_pages
186
193
  end
187
194
 
195
+ # Lays the SuperPET's board (SuperPET::Board) over its pages.
196
+ def fit_board(board)
197
+ @board = board
198
+ map_pages
199
+ end
200
+
188
201
  # Lays the pages out again, for the board's control register.
189
202
  def map_pages
190
203
  map(@open_bus, 0x00, 0x100)
@@ -195,6 +208,7 @@ module Badline
195
208
  map(@io, 0xe8, 0x01)
196
209
  @read_pages.fill(@kernal_rom, 0xf0, 0x10)
197
210
  @expansion&.map(@read_pages, @write_pages)
211
+ @board&.map(@read_pages, @write_pages)
198
212
  map_debug_register if @debug_register
199
213
  end
200
214