badline 0.17.0 → 0.19.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 (195) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +193 -0
  3. data/CLAUDE.md +19 -7
  4. data/CONTRIBUTING.md +11 -1
  5. data/README.md +178 -26
  6. data/doc/library.md +5 -1
  7. data/doc/media.md +3 -2
  8. data/doc/pinned-behaviour.md +169 -1
  9. data/doc/snapshot-format.md +302 -35
  10. data/doc/snapshots.md +97 -26
  11. data/doc/vice.md +344 -0
  12. data/exe/badline-ruby +5 -0
  13. data/lib/badline/audio/renderer.rb +4 -8
  14. data/lib/badline/audio/terminal.rb +34 -2
  15. data/lib/badline/c128/keyed_state.rb +2 -0
  16. data/lib/badline/c128.rb +5 -0
  17. data/lib/badline/c64/bus/fittings.rb +6 -0
  18. data/lib/badline/c64/keyed_state.rb +2 -0
  19. data/lib/badline/c64.rb +7 -0
  20. data/lib/badline/cbm2/keyed_state.rb +4 -0
  21. data/lib/badline/cbm2/p500.rb +9 -3
  22. data/lib/badline/cbm2.rb +10 -3
  23. data/lib/badline/chips/cia/timer.rb +2 -2
  24. data/lib/badline/chips/cpu/core.rb +29 -4
  25. data/lib/badline/chips/cpu/instruction_set.rb +1 -1
  26. data/lib/badline/chips/cpu/interrupts.rb +9 -0
  27. data/lib/badline/chips/cpu/keyed_state.rb +15 -9
  28. data/lib/badline/chips/cpu/microcode.rb +10 -0
  29. data/lib/badline/chips/m6809/arithmetic.rb +140 -0
  30. data/lib/badline/chips/m6809/bus_steps.rb +223 -0
  31. data/lib/badline/chips/m6809/core.rb +149 -0
  32. data/lib/badline/chips/m6809/indexed.rb +82 -0
  33. data/lib/badline/chips/m6809/interrupts.rb +159 -0
  34. data/lib/badline/chips/m6809/keyed_state.rb +147 -0
  35. data/lib/badline/chips/m6809/opcodes.rb +159 -0
  36. data/lib/badline/chips/m6809/operations.rb +258 -0
  37. data/lib/badline/chips/m6809/plans.rb +143 -0
  38. data/lib/badline/chips/m6809/registers.rb +82 -0
  39. data/lib/badline/chips/m6809/stack.rb +140 -0
  40. data/lib/badline/chips/m6809.rb +13 -0
  41. data/lib/badline/chips/riot/timer.rb +14 -3
  42. data/lib/badline/chips/rriot.rb +8 -3
  43. data/lib/badline/chips/sid/decimator.rb +1 -1
  44. data/lib/badline/chips/sid/filter.rb +4 -4
  45. data/lib/badline/chips/sid/keyed_parts.rb +51 -18
  46. data/lib/badline/chips/sid/waveform.rb +6 -6
  47. data/lib/badline/chips/sid.rb +6 -2
  48. data/lib/badline/chips/vic_i/keyed_parts.rb +12 -2
  49. data/lib/badline/chips/vic_i/light_pen.rb +89 -0
  50. data/lib/badline/chips/vic_i.rb +91 -23
  51. data/lib/badline/data_path.rb +3 -3
  52. data/lib/badline/drives/ieee_models.rb +54 -0
  53. data/lib/badline/drives/model1001.rb +37 -0
  54. data/lib/badline/drives/model1541/sector_reader.rb +20 -3
  55. data/lib/badline/drives/model1541.rb +1 -0
  56. data/lib/badline/drives/model1551.rb +1 -0
  57. data/lib/badline/drives/model1571.rb +1 -0
  58. data/lib/badline/drives/model1581.rb +1 -0
  59. data/lib/badline/drives/model2031.rb +7 -0
  60. data/lib/badline/drives/model4040/disk.rb +62 -0
  61. data/lib/badline/drives/model4040/ip_bus.rb +46 -0
  62. data/lib/badline/drives/model4040/keyed_state.rb +57 -0
  63. data/lib/badline/drives/model4040/mechanism.rb +195 -0
  64. data/lib/badline/drives/model4040/parts.rb +20 -0
  65. data/lib/badline/drives/model4040.rb +195 -0
  66. data/lib/badline/drives/model8050/board.rb +79 -0
  67. data/lib/badline/drives/model8050/dos_board.rb +134 -0
  68. data/lib/badline/drives/model8050/fdc_bus.rb +7 -0
  69. data/lib/badline/drives/model8050/idle.rb +148 -31
  70. data/lib/badline/drives/model8050/keyed_state.rb +5 -2
  71. data/lib/badline/drives/model8050.rb +32 -130
  72. data/lib/badline/drives/model9060/idle.rb +169 -0
  73. data/lib/badline/drives/model9060/keyed_state.rb +123 -0
  74. data/lib/badline/drives/model9060/parts.rb +98 -0
  75. data/lib/badline/drives/model9060/sasi_bus.rb +88 -0
  76. data/lib/badline/drives/model9060/sasi_commands.rb +168 -0
  77. data/lib/badline/drives/model9060/sasi_target.rb +161 -0
  78. data/lib/badline/drives/model9060.rb +197 -0
  79. data/lib/badline/frontend/app.rb +8 -0
  80. data/lib/badline/frontend/boot.rb +3 -2
  81. data/lib/badline/frontend/controls.rb +62 -6
  82. data/lib/badline/frontend/keys.rb +36 -0
  83. data/lib/badline/frontend/kim1_panel.rb +208 -0
  84. data/lib/badline/frontend/media_slots.rb +8 -1
  85. data/lib/badline/frontend/menu/drive_types.rb +56 -0
  86. data/lib/badline/frontend/menu/menu_dialogs.rb +61 -14
  87. data/lib/badline/frontend/menu/menu_media.rb +42 -12
  88. data/lib/badline/frontend/menu/menu_pages.rb +97 -2
  89. data/lib/badline/frontend/menu/menu_ports.rb +38 -1
  90. data/lib/badline/frontend/menu/pause_menu.rb +5 -1
  91. data/lib/badline/frontend/pet_keyboard.rb +23 -1
  92. data/lib/badline/frontend/screen.rb +1 -1
  93. data/lib/badline/frontend/screens.rb +40 -2
  94. data/lib/badline/frontend/teletype_pane.rb +152 -0
  95. data/lib/badline/frontend/timeline.rb +31 -2
  96. data/lib/badline/frontend.rb +3 -0
  97. data/lib/badline/input/joystick.rb +15 -2
  98. data/lib/badline/kim1/bus.rb +117 -0
  99. data/lib/badline/kim1/cpu.rb +25 -0
  100. data/lib/badline/kim1/host_terminal.rb +74 -0
  101. data/lib/badline/kim1/key_entry.rb +74 -0
  102. data/lib/badline/kim1/keyed_modules.rb +53 -0
  103. data/lib/badline/kim1/keyed_state.rb +133 -0
  104. data/lib/badline/kim1/panel.rb +176 -0
  105. data/lib/badline/kim1/rriots.rb +28 -0
  106. data/lib/badline/kim1/sound.rb +29 -0
  107. data/lib/badline/kim1/tape.rb +118 -0
  108. data/lib/badline/kim1/teletype.rb +193 -0
  109. data/lib/badline/kim1.rb +194 -0
  110. data/lib/badline/machine/ieee_drives.rb +94 -117
  111. data/lib/badline/machine/keyboard_buffer.rb +20 -3
  112. data/lib/badline/machine/line_sound.rb +122 -0
  113. data/lib/badline/machine.rb +49 -15
  114. data/lib/badline/media/extensions.rb +8 -4
  115. data/lib/badline/media/kim1_media.rb +150 -0
  116. data/lib/badline/media/pet_media.rb +3 -1
  117. data/lib/badline/media/true_drive.rb +52 -45
  118. data/lib/badline/media/vic20_media.rb +4 -2
  119. data/lib/badline/media.rb +16 -6
  120. data/lib/badline/memory.rb +2 -4
  121. data/lib/badline/options/family.rb +98 -8
  122. data/lib/badline/options/help.rb +44 -12
  123. data/lib/badline/options/table.rb +44 -12
  124. data/lib/badline/options/validation.rb +44 -8
  125. data/lib/badline/options.rb +27 -8
  126. data/lib/badline/pet/bus.rb +16 -2
  127. data/lib/badline/pet/keyboard_ports.rb +9 -2
  128. data/lib/badline/pet/keyed_state.rb +4 -0
  129. data/lib/badline/pet/model.rb +11 -2
  130. data/lib/badline/pet/rom_sets.rb +1 -0
  131. data/lib/badline/pet/sound.rb +5 -105
  132. data/lib/badline/pet/superpet/acia.rb +12 -0
  133. data/lib/badline/pet/superpet/board.rb +221 -0
  134. data/lib/badline/pet/superpet/dongle.rb +92 -0
  135. data/lib/badline/pet/superpet/keyed_modules.rb +63 -0
  136. data/lib/badline/pet/superpet/keyed_parts.rb +76 -0
  137. data/lib/badline/pet/superpet/m6809.rb +32 -0
  138. data/lib/badline/pet/superpet/waterloo_traps.rb +199 -0
  139. data/lib/badline/pet/superpet.rb +221 -0
  140. data/lib/badline/pet.rb +23 -3
  141. data/lib/badline/plus4/keyed_state.rb +2 -0
  142. data/lib/badline/plus4.rb +5 -0
  143. data/lib/badline/roms/1001/fdc-251257-02a.rom +0 -0
  144. data/lib/badline/roms/4040/dos-1.2.rom +0 -0
  145. data/lib/badline/roms/4040/dos-2.1-rev.rom +0 -0
  146. data/lib/badline/roms/4040/dos-2.1.rom +0 -0
  147. data/lib/badline/roms/4040/fdc-901466-02.rom +0 -0
  148. data/lib/badline/roms/4040/fdc-901466-04.rom +0 -0
  149. data/lib/badline/roms/9060/dos-3.0.rom +0 -0
  150. data/lib/badline/roms/9060/sasi-300515-revb.rom +0 -0
  151. data/lib/badline/roms/README +176 -0
  152. data/lib/badline/roms/kim1/6530-002.rom +0 -0
  153. data/lib/badline/roms/kim1/6530-003.rom +0 -0
  154. data/lib/badline/roms/pet/characters-superpet.rom +0 -0
  155. data/lib/badline/roms/pet/superpet-a000.rom +0 -0
  156. data/lib/badline/roms/pet/superpet-c000.rom +0 -0
  157. data/lib/badline/roms/pet/superpet-e000-50hz.rom +0 -0
  158. data/lib/badline/roms/pet/superpet-e000.rom +0 -0
  159. data/lib/badline/snapshot/container.rb +8 -4
  160. data/lib/badline/snapshot/field_doc/markdown.rb +1 -1
  161. data/lib/badline/snapshot/field_doc.rb +35 -10
  162. data/lib/badline/snapshot/image.rb +19 -7
  163. data/lib/badline/snapshot/kim1_setup.rb +28 -0
  164. data/lib/badline/snapshot/pet_setup.rb +27 -11
  165. data/lib/badline/snapshot/storage_setup.rb +4 -1
  166. data/lib/badline/snapshot/vic20_setup.rb +11 -7
  167. data/lib/badline/snapshot/vice/pet.rb +14 -7
  168. data/lib/badline/snapshot/vice/pet_cpu.rb +39 -5
  169. data/lib/badline/snapshot/vice/pet_crtc.rb +15 -2
  170. data/lib/badline/snapshot/vice/pet_dongle.rb +72 -0
  171. data/lib/badline/snapshot/vice/pet_drive8050.rb +188 -68
  172. data/lib/badline/snapshot/vice/pet_mem.rb +55 -5
  173. data/lib/badline/snapshot/vice/pet_restore.rb +40 -11
  174. data/lib/badline/snapshot/vice/vic20.rb +70 -0
  175. data/lib/badline/snapshot/vice/vic20_cpu.rb +61 -0
  176. data/lib/badline/snapshot/vice/vic20_mem.rb +85 -0
  177. data/lib/badline/snapshot/vice/vic20_restore.rb +124 -0
  178. data/lib/badline/snapshot/vice/vic20_vici.rb +200 -0
  179. data/lib/badline/snapshot/vice.rb +1 -0
  180. data/lib/badline/snapshot.rb +8 -4
  181. data/lib/badline/status.rb +30 -30
  182. data/lib/badline/storage/d67_image.rb +55 -0
  183. data/lib/badline/storage/d90_image.rb +180 -0
  184. data/lib/badline/storage/kim_tape.rb +254 -0
  185. data/lib/badline/storage/papertape.rb +90 -0
  186. data/lib/badline/storage.rb +4 -0
  187. data/lib/badline/support/kim1_checkpoint.rb +41 -0
  188. data/lib/badline/support/superpet_checkpoint.rb +35 -0
  189. data/lib/badline/version.rb +1 -1
  190. data/lib/badline/vic20/keyed_modules.rb +6 -3
  191. data/lib/badline/vic20/keyed_state.rb +6 -4
  192. data/lib/badline/vic20/port_wiring.rb +11 -0
  193. data/lib/badline/vic20.rb +30 -12
  194. data/lib/badline.rb +1 -0
  195. metadata +85 -1
data/doc/snapshots.md CHANGED
@@ -17,7 +17,7 @@ autosave that fails warns once and stops autosaving.
17
17
 
18
18
  The pause menu's Snapshots page quicksaves, saves under a name in the
19
19
  `saves` folder and loads a named save. The name starts as the game's,
20
- from its cartridge, disk or tape, or BASIC, with the next free number,
20
+ from its cartridge, disk or tape, or BASIC, or KIM-1 on a KIM-1, with the next free number,
21
21
  and saving over a name already taken asks first. Below those, the
22
22
  newest quicksaves and autosaves, with the time each was saved, load
23
23
  with a press.
@@ -83,6 +83,9 @@ disk comes back write-protected. A directory mounted as device 8 opens
83
83
  again from its path. What the host holds stays the
84
84
  host's: the keyboard, the joysticks, the mouse and paddles, sound, and
85
85
  blocks given to `on_init` that hadn't run yet, which a restore reports.
86
+ A SID that was recording saves how far into its current sample it had
87
+ got, and a restored one that records again at the same rate carries on
88
+ from there, so its output runs on as the saved one's would have.
86
89
 
87
90
  Every model saves this way, PAL, NTSC, old NTSC and Drean alike, and so
88
91
  does a machine with an REU, with its RAM and its registers. A snapshot
@@ -105,11 +108,42 @@ RAM, a cartridge's ROM, the VIC with its picture and sound, both VIAs,
105
108
  the CPU, the tape with its place on it, the disk or directory device 8
106
109
  serves through the traps and a true 1541 or 1581, and restores into a
107
110
  VIC-20 with the same RAM expansion. Its file names its machine `VIC20`,
108
- as xvic's do, and holds only badline's modules, so xvic doesn't open it,
109
- and badline doesn't open xvic's. Restoring a
111
+ as xvic's do, and holds only badline's modules, so xvic doesn't open it
112
+ unless it is saved with `--vice` (see [xvic](#xvic)). Restoring a
110
113
  VIC-20 snapshot while a C64 runs, or a C64 one while a VIC-20 runs,
111
114
  swaps the machine in the window.
112
115
 
116
+ ### xvic
117
+
118
+ A VIC-20 snapshot saved with `--vice`, or `computer.export_snapshot(path)`,
119
+ also holds xvic's modules for the CPU, the RAM, the VIC-I with the colour
120
+ RAM and both VIAs, and the ones xvic 3.10 needs to open the file, with no
121
+ cartridge, nothing open on the file system drive, the joystick released
122
+ and nothing on the user port. The file says it is in VICE's snapshot
123
+ format 3.1, the only one xvic reads.
124
+
125
+ xvic 3.10 opens those snapshots as long as its model matches:
126
+ `-model vic20` or `vic20ntsc`. It takes the RAM expansion from the
127
+ snapshot, whatever its `-memory` says, keeps its own drives and leaves
128
+ out badline's cartridge, tapes and disks. A program it runs on from badline's
129
+ snapshot runs as it does in badline, cycle for cycle, with the raster,
130
+ the VIAs' timers and RAM alike, but for a snapshot taken in an
131
+ interlaced frame, whose field xvic ends early (see
132
+ [VICE](vice.md#xvic)).
133
+
134
+ Snapshots xvic saves open in badline through the same modules: the CPU
135
+ at its instruction boundary, the RAM and the data lines' last bytes, the
136
+ VIC-I's registers, beam, frame, interlaced field, text window and
137
+ fetches, its light pen and the colour RAM, and both VIAs' registers,
138
+ timers and shift registers. The picture starts again with the next
139
+ frame, and the sound as at power-on. VIC20MEM's blocks and the VIC-I's
140
+ picture size build the machine: its RAM expansion and model. It reports
141
+ the modules it leaves out, such as the drives, the cartridge, the
142
+ datasette and the keyboard, and carries on without them. Restored into a
143
+ running VIC-20, an xvic snapshot fails for a VIC-20 built another way,
144
+ and otherwise switches the machine off and on, keeping its cartridge,
145
+ tapes and the disk device 8 serves.
146
+
113
147
  ## The C128
114
148
 
115
149
  `badline c128` saves and restores the same way too. A C128 snapshot
@@ -149,9 +183,14 @@ port lines the 8296's RAM follows, both PIAs, the VIA, the CPU, the
149
183
  CRTC on the boards that have one, the picture with where the video is
150
184
  in its frame, the tapes in both datasettes with their places on them,
151
185
  and the disk or directory device 8 serves through the IEEE-488 traps.
152
- It restores into a machine of the same model with the same RAM, the
153
- same editor frame rate, the same ROMs, which come with the model, and
154
- an 8296's same jumpers. Its file names its machine `PET`, as xpet's do,
186
+ A SuperPET's also holds its board's latches and 64K of bank RAM, the
187
+ 6702, the ACIA, the 6809 and the traps on the Waterloo ROM's IEEE-488
188
+ routines, in 6502 mode and in 6809 mode alike, and saves once the CPU
189
+ that has the bus is between instructions. It restores into a machine of
190
+ the same model with the same RAM, the same editor frame rate, the same
191
+ ROMs, which come with the model, an 8296's same jumpers and a SuperPET's
192
+ CPU and RAM switches at the same positions. Its file names its machine
193
+ `PET`, as xpet's do,
155
194
  and holds only badline's modules, so xpet doesn't open it unless it is
156
195
  saved with `--vice` (see [xpet](#xpet)).
157
196
 
@@ -160,28 +199,35 @@ saved with `--vice` (see [xpet](#xpet)).
160
199
  A PET snapshot saved with `--vice`, or `computer.export_snapshot(path)`,
161
200
  also holds xpet's modules for the CPU, the RAM with the screen RAM, or
162
201
  an 8296's 32K from `$8000`, an 8096's or 8296's board and its control
163
- register, the CRTC, both PIAs and the VIA, a true 2031's CPU, RAM, VIAs
164
- and head, or a true 8050's or 8250's interface processor with its RAM
165
- and 6532s and the heads' tracks, and the ones xpet 3.10 needs to open
202
+ register, a SuperPET's board, its bank and its `$EFFE` bit, the CRTC
203
+ with the character set VIA CA2 picks, both PIAs and the VIA, a
204
+ SuperPET's 6809 and ACIA, a true 2031's CPU, RAM, VIAs and head, or the
205
+ interface processor of a true 8050, 8250, SFD-1001, 4040, 3040, 2040,
206
+ D9060 or D9090, with its RAM and 6532s and the heads' tracks, and the
207
+ ones xpet 3.10 needs to open
166
208
  the file, with nothing open on the file system drive and nothing on the
167
209
  user port. The CRTC module carries the discrete boards' video too, in
168
210
  xpet's terms. The file says it is in VICE's snapshot format 1.0, the
169
211
  only one xpet reads.
170
212
 
171
213
  xpet 3.10 opens those snapshots as long as its model and editor match:
172
- `-model 2001`, `3032`, `3032B`, `4032`, `8032`, `8096` or `8296`, and
173
- for a badline editor other than xpet's own, `-editor` naming badline's
174
- ROM. xpet's 8296 runs the 8032's editor, 901474-04 dated 0283, so an
214
+ `-model 2001`, `3032`, `3032B`, `4032`, `8032`, `8096`, `8296` or
215
+ `SuperPET`, and for a badline editor other than xpet's own, `-editor`
216
+ naming badline's ROM. xpet runs a SuperPET's 6809 when the snapshot
217
+ says it has the bus, whatever its own CPU switch, takes its 6702, and
218
+ has no system latch or write protect to take from it. xpet's 8296 runs the 8032's editor, 901474-04 dated 0283, so an
175
219
  8296 saved for it has to run that editor (`--editor 4-80-b-50hz-0283`),
176
220
  and xpet takes the 8296's jumpers from its own settings. It keeps its
177
221
  own datasettes and leaves out badline's tapes and disks. A true drive
178
- needs `-drive8type 2031`, `8050` or `8250` with `-drive8truedrive` and
179
- the disk attached as `-8`. Its snapshot is settled with the 2031's CPU
222
+ needs `-drive8type 2031`, `8050`, `8250`, `1001`, `4040`, `3040`,
223
+ `2040`, or `9000` for either hard disk, with `-drive8truedrive` and the
224
+ disk attached as `-8`. Its snapshot is settled with the 2031's CPU
180
225
  between instructions too, and one saved while the 2031 talks on the bus
181
226
  can stall there in xpet, as xpet's own snapshots saved while it searches
182
- for a file do. xpet runs an 8050's floppy controller at a high level, so
183
- a snapshot for it is settled until badline's controller sits in its idle
184
- loop with both processors between instructions, and xpet's controller
227
+ for a file do. xpet runs an 8050's floppy controller, and a hard disk's
228
+ SASI host, at a high level, so a snapshot for it is settled until
229
+ badline's controller, or host, sits in its idle loop with both
230
+ processors between instructions, and xpet's controller
185
231
  starts from idle there, taking up any job the interface processor has
186
232
  left it. A unit that doesn't reach its idle loop within about 262,000
187
233
  cycles, such as one still starting up, is left out of xpet's modules,
@@ -195,24 +241,33 @@ at its instruction boundary, the RAM, the screen RAM, an 8096's or
195
241
  8296's board, the CRTC's registers and beam, both PIAs' registers and
196
242
  flags, the VIA's registers, timers and shift register, a true 2031's
197
243
  CPU, RAM, VIAs and head, which go on the bus with the disk badline's
198
- 2031 had in it, and a true 8050's or 8250's interface processor, its RAM
199
- and both 6532s, which go on the bus with the disks badline's unit of the
200
- same model had in it. Its floppy controller comes back as a unit
244
+ 2031 had in it, and the interface processor of a true 8050, 8250,
245
+ SFD-1001, 4040, 3040, 2040, D9060 or D9090, its RAM and both 6532s,
246
+ which go on the bus with the disks badline's unit of the same model had
247
+ in it. xpet's type 9000 stands for both hard disks, and the hard disk
248
+ badline's had in it, of either, makes it a D9090 for an image of six
249
+ heads and otherwise a D9060. Its floppy controller comes back as a unit
201
250
  switched on has it, in its idle loop with the heads on track 1: its next
202
251
  job steps them out to the track, and a job xpet's controller had under
203
- way starts again from there. A program
252
+ way starts again from there. A hard disk's SASI host comes back in its
253
+ job loop the same way. A program
204
254
  badline runs on from xpet's snapshot finds the vertical sync on the
205
255
  cycle xpet does, so the two run on alike, cycle for cycle. The picture
206
256
  starts again with the next frame. xpet doesn't save its ROMs, which
207
257
  keyboard it has or an 8296's jumpers, so the board, the RAM and the
208
258
  CRTC's frame build the machine: a 2001, a 3032 for any other discrete
209
259
  board, a 4032, an 8032, an 8096 or an 8296 with none of its jumpers
210
- fitted, at 50 or 60 Hz, and an 8032, 8096 or 8296 whose CRTC lines are
211
- 64 cycles long runs xpet's own 50 Hz editor, 901474-04 dated 0283. A
212
- SuperPET's snapshot fails. It reports the modules it leaves out, such
260
+ fitted, or a SuperPET, at 50 or 60 Hz, and an 8032, 8096 or 8296 whose
261
+ CRTC lines are 64 cycles long runs xpet's own 50 Hz editor, 901474-04
262
+ dated 0283. A SuperPET comes with its bank RAM, its bank, its `$EFFE`
263
+ bit and its ACIA, its CPU switch at the CPU that had the bus, and while
264
+ that is the 6809, the 6809's registers, and its 6702. Its RAM switch is
265
+ at R/W, the only position xpet has, and its system latch is clear, since
266
+ xpet saves neither, and in 6809 mode its
267
+ frame rate is the one the Waterloo ROM's CRTC table sets. It reports the modules it leaves out, such
213
268
  as the drives past device 8, the datasettes and the keyboard, and
214
269
  carries on without them, and a snapshot without a true drive takes
215
- badline's, a 2031, an 8050 or an 8250, off the bus and says so.
270
+ badline's off the bus and says so.
216
271
  Restored into a running PET, an xpet snapshot fails for a PET built
217
272
  another way, such as a 3032B, and otherwise switches the machine off
218
273
  and on, keeping its tapes and the disk device 8 serves.
@@ -329,6 +384,19 @@ xcbm2's snapshots. Restored into a running P500, an
329
384
  xcbm5x0 snapshot fails for a P500 built another way, and otherwise
330
385
  switches the machine off and on, keeping the disk device 8 serves.
331
386
 
387
+ ## The KIM-1
388
+
389
+ A KIM-1 saves and restores as the others do. A snapshot of one holds
390
+ its RAM, the expansion's too, the CPU, both 6530s with their 64 bytes,
391
+ ports and timers, the timer's interrupt flag among them, the panel with
392
+ the TTY/KB jumper, the key held down and how long each LED segment has
393
+ been lit, the teletype with the character on its way in or out, what
394
+ it has queued and all it has printed, the SST switch, U3's wiring to
395
+ IRQ and the speaker, and the keys `type_keys` has still to press. It
396
+ restores into a KIM-1 with the same RAM. Its file names its machine
397
+ `KIM1`, since VICE has no KIM-1, so no VICE emulator opens it, and
398
+ `--vice` fails for it.
399
+
332
400
  ## VICE
333
401
 
334
402
  Snapshots use VICE's `.vsf` format, and badline's own modules are named
@@ -345,7 +413,10 @@ snapshot from its own modules, and leaves VICE's alone.
345
413
  x64sc 3.10 opens those snapshots, which are saved between
346
414
  instructions with no REU transfer under way, as long as its VIC-II
347
415
  model matches: `-model c64`, `c64c`, `ntsc`, `newntsc`,
348
- `oldntsc` or `drean`, as `--model` names the machine. It takes the REU
416
+ `oldntsc`, `drean`, `pet64` or `c64gs`, as `--model` names the machine.
417
+ The MAX Machine's needs `-model ultimax -VICIImodel 5`, since x64sc's
418
+ `ultimax` has the 6567R8 and badline's the 6567R56A. The snapshot names
419
+ the discrete glue logic, which x64sc's `c64c` and `c64gs` switch to. It takes the REU
349
420
  from the snapshot, keeps its own drives and leaves out the cartridge,
350
421
  the other expansions and the tape. A program x64sc runs on from badline's
351
422
  snapshot reads the raster as badline does, cycle for cycle.
data/doc/vice.md ADDED
@@ -0,0 +1,344 @@
1
+ # VICE
2
+
3
+ badline checks itself against VICE 3.10's emulators, run as black boxes:
4
+ their command lines, their remote monitor, their screenshots, sound
5
+ recordings and snapshots. VICE's source isn't read for this, and badline
6
+ holds none of its code, ROMs or data. The VICE-testprogs repository is a
7
+ separate project: its testlists, hooks and reference screenshots are what
8
+ `bin/testbench` runs (see [CLAUDE.md](../CLAUDE.md#oracles)). This page
9
+ covers what each emulator checks, how they're driven, what they get
10
+ wrong or leave out, the `.vsf` modules badline reads and writes, and
11
+ where badline knowingly does otherwise.
12
+
13
+ - [Which emulator checks what](#which-emulator-checks-what)
14
+ - [Driving them](#driving-them)
15
+ - [Quirks and bugs](#quirks-and-bugs)
16
+ - [Snapshot modules](#snapshot-modules)
17
+ - [Where badline differs](#where-badline-differs)
18
+
19
+ ## Which emulator checks what
20
+
21
+ | Emulator | Machines | What it checks |
22
+ | --- | --- | --- |
23
+ | `x64sc` | C64, every `--model` | The testbench's published results, runs from an exact start, and `.vsf` both ways |
24
+ | `x128` | C128 | The VDC (`-exitscreenshot`), the MMU and both modes' boot screens. Not the C64-mode VIC-II or 2 MHz (below) |
25
+ | `xvic` | VIC-20, PAL and NTSC | The 6560's raster count and interlace, the VIC-I's sound by recording, the power-on RAM, cycle-timed writes by screenshot, `.vsf` both ways |
26
+ | `xplus4` | Plus/4, C16, C116 | The TED's fetches and picture by screenshot and trace probe, its sound by recording, the 1551's load time, the ACIA's registers and timing |
27
+ | `xpet` | Every PET and CBM model, the SuperPET | Boot banners and BYTES FREE, frame lengths, the CRTC's frame, the IEEE-488 drives' listings and error channels, `.vsf` both ways |
28
+ | `xcbm2` | The B series | Boot, the CRTC's frame, the burn-in disk on a true 8050, `.vsf` both ways |
29
+ | `xcbm5x0` | The P500 | Boot, the VIC-II's cycle stealing, `.vsf` both ways |
30
+ | `c1541` | Disk images | Blank `.d67` and `.d90` images, which `D67Image` and `D90Image` format alike byte for byte (their specs' fixtures), and listing and validating the images badline's true drives write |
31
+ | `petcat` | BASIC text | `petcat -w2 -o out.prg in.txt` turns a BASIC listing into a `.prg` |
32
+
33
+ VICE has no KIM-1. No row of VICE's testlists runs the PET's IEEE-488
34
+ floppies and hard disks, the SuperPET's 6809 or a 1581, so those rest
35
+ on badline's own drive scenarios and specs, the schematics and the ROMs.
36
+
37
+ `x128` runs older VIC-II emulation than `x64sc`: in its results for the
38
+ C64-mode testlist (r45942) about 180 rows that `x64sc` passes fail, among
39
+ them 52 `spritesplit`, 25 `irqdma` and 18 `reutiming2` rows, and it fails
40
+ all 33 `d030tester` and all 4 `2mhzVIC` screenshot rows in C128 mode. So
41
+ `testbench-c128c64` is held to badline's own C64C verdicts, and the 2 MHz
42
+ rows to the testprogs' references, which come from real machines.
43
+
44
+ ## Driving them
45
+
46
+ - Run each by its full path, such as `/opt/homebrew/bin/x64sc`. A bare
47
+ `x64sc` failed with "argv[0] is NULL". Headless, `x64sc` needs
48
+ `-console`, or it aborts for want of GSettings schemas.
49
+ - **Exit codes.** `-debugcart` gives the program a debug register, and a
50
+ write to it ends the run with that exit code, `$00` for a pass and
51
+ `$FF` for a fail. It is `$D7FF` on the C64 and the C128, `$910F` on
52
+ the VIC-20, `$FDCF` on the 264 series, `$8BFF` on the PET and `$DAFF`
53
+ in segment 15 on the CBM-II. `-limitcycles N` ends a run that hasn't
54
+ written it, as a timeout. `bin/testbench` installs the same register
55
+ (`install_debug_register`) and the same cycle budgets.
56
+ - **Screenshots.** `-exitscreenshot` writes a PNG as the run ends
57
+ (`-exitscreenshotvicii` for the C128's 40 columns, with
58
+ `-exitscreenshot` its VDC). Sizes: 384x288 PAL and 384x242 NTSC on
59
+ `xplus4`; 384x217 for the PET's discrete board, 384x273 for 40 CRTC
60
+ columns and 704x273 for 80 on `xpet`; 704x267 for a 600 and 704x367 for
61
+ a 700 on `xcbm2`; 384x272 PAL and 384x247 NTSC on `xcbm5x0`. The
62
+ testbench hooks compare from (32,35) on the C64, the 264 and the
63
+ CBM-II ((32,23) on an NTSC `xcbm2`), (32,33) on the PET, and (96,48)
64
+ PAL and (40,22) NTSC on the VIC-20.
65
+ - **Typing.** `-keybuf` types into the keyboard buffer once the machine
66
+ is up. On `xpet` keep each line under 80 characters. The monitor's
67
+ `keybuf` with `\"` escapes typed nothing there.
68
+ - **The remote monitor.** `-remotemonitor -remotemonitoraddress
69
+ ip4://127.0.0.1:PORT` takes monitor commands over a socket: registers
70
+ (`r`, and `r PC = $xxxx` to set one), memory (`m`, `bsave`), `io`,
71
+ breakpoints, the stopwatch, `dump` and `undump` for snapshots, and
72
+ `resourceget "Name"`, with the name quoted. A breakpoint hit is
73
+ reported only after the next command, so poll with `r`, then `x`.
74
+ Numbers are hex unless marked, counts too (`ignore 1 36` skips 54
75
+ hits). Its `CYC` is badline's column at the instruction boundary plus
76
+ one. `-moncommands` with the GTK monitor waits for input at reset and
77
+ hangs; `-nativemonitor` with the commands on stdin runs them.
78
+ - **An exact start.** `x64sc`'s autostart adds a random delay, so one run
79
+ of a test that depends on where it starts is no reference: the
80
+ published results show `irq-ack-vicii` passing 15 runs in 16 for that
81
+ reason. To compare from the same place, park the CPU in a loop at
82
+ `$C000` in both emulators, break on its first fetch on a chosen raster
83
+ line, and resume at the program's entry through a stub of N cycles.
84
+ badline and `x64sc` started this way agreed cycle for cycle over 91
85
+ start positions.
86
+ - **Power-on RAM.** `xvic -default -memory all -initbreak reset
87
+ -moncommands cmds.txt`, with `bsave "path" 0 0000 1fff` and `quit` in
88
+ the file, dumps RAM before the KERNAL touches it.
89
+ - **Sound.** `-sounddev wav -soundarg f.wav +autostart-warp` records
90
+ from power-on in real time. `-sounddev dummy -soundrecdev wav` writes
91
+ an empty file, because autostart turns warp on. The Homebrew `xpet`
92
+ has no WAV driver.
93
+ - **Models.** Use `-model vic20ntsc` for an NTSC VIC-20: `xvic -ntsc`
94
+ keeps the PAL KERNAL. `x64sc` 3.10's default VIC-II is the 8565, so a
95
+ 6569 snapshot needs `-model c64`. The 264's RAM expansions are
96
+ `-memoryexphack 1|2|3` (Csory 256K, Hannes 256K, Hannes 1M);
97
+ `-ramsize` takes only 16, 32 and 64. The B series' autostart needs a
98
+ device on 8 (`-busdevice8 +drive8truedrive`).
99
+ - **Paths.** `xpet`'s `-editor` and `-autostart` need absolute paths. A
100
+ relative one gives a blank or stuck screen.
101
+ - **True drives.** `-drive8type T -drive8truedrive` with the disk as `-8`.
102
+ `-attach8ro` is a flag of its own: `-attach8ro -8 <img>` mounts an
103
+ image write-protected.
104
+
105
+ ## Quirks and bugs
106
+
107
+ What follows was observed from outside. Each is a reason a row, a
108
+ recording or a snapshot from that emulator isn't a reference for the
109
+ part named.
110
+
111
+ ### x64sc
112
+
113
+ - `undump` of a snapshot with any module short of what it expects resets
114
+ the machine without saying so, beyond "pre 2.4.30 snapshot" in the log.
115
+ MAINCPU 1.4 is 103 bytes, and 3.10 reads that layout whatever the minor
116
+ version.
117
+ - `-limitcycles` below a snapshot's own clock exits before a frame.
118
+ - Its true 1581 caches a track and writes it back later, so a run that
119
+ formats and exits through the debug register leaves the `.d81`
120
+ unwritten. Send `I0` and wait before the exit.
121
+ - In the remote monitor, a condition on `RL` works, but `RL == … && CY
122
+ >= …` never fired.
123
+
124
+ ### xvic
125
+
126
+ - Its remote monitor stopped answering a new connection after an earlier
127
+ client disconnected. Drive a session over one socket, from one script
128
+ that starts `xvic` and stops it by its PID.
129
+ - `xvic -ntsc` keeps the PAL KERNAL (above).
130
+ - Its monitor's `LIN`, and so a breakpoint's `RL`, stays modulo 261
131
+ under interlace, while `$9003`/`$9004` and its own snapshots follow
132
+ the 263- and 262-line fields: a frame after a long field shows `LIN`
133
+ 2 more than the line, and so on.
134
+ - `undump` of a snapshot taken in an interlaced frame ends that frame
135
+ after 261 lines, its own snapshots too: the field after it starts 2
136
+ lines early after a long field and 1 after a short one. The fields
137
+ alternate as before from there.
138
+ - It refuses a snapshot whose file isn't in format 3.1, and resets on the
139
+ first instruction without `FSDRIVE`, `TAPEPORT`, `JOYPORT0`,
140
+ `JOYSTICK0` and `USERPORT`. Without any drive module it keeps its own
141
+ drives, but with `DRIVE8` and no `DRIVECPU0` and the 1541's VIAs it
142
+ resets too.
143
+
144
+ ### xplus4
145
+
146
+ - Its default drive 8 is a 1551, on the `plus4`, `c16` and `c16ntsc`
147
+ models. `Plus4/tcbm/test.prg` passes only with it.
148
+ - It clocks a SID card only with a real sound device: with `-sounddev
149
+ dummy`, OSC3 reads 0.
150
+ - r45284 shows a bitmap fetched from empty ROM space wrongly against the
151
+ photo of a real machine in `Plus4/openmem`.
152
+ - It steps the TED's line about 3 single clock cycles after the
153
+ datasheet's decode, and fails `trap10`, `trap12` and `trap14` of the
154
+ Lorenz suite's plus4 build (below).
155
+ - Its C16 model loads no tape, not even one it saved itself, and never
156
+ asks for PLAY: LOAD goes straight to SEARCHING. Its Plus/4 model loads
157
+ the tapes badline saves for the 264 (#704).
158
+ - It writes a version 2 `.tap` with one byte per whole wave (`$36`, `$6B`,
159
+ `$D5`, version 1's values), where the format and badline give one per
160
+ half wave (`$1A`, `$35`, `$6A`). Both time the same signal.
161
+
162
+ ### xpet
163
+
164
+ - **Its 6809 runs with the wrong instruction timing.** Single-stepped
165
+ stopwatch deltas: BSR 5, PULS D 5, SUBD # 1, LDX # 0, ABX 2, JSR [,X]
166
+ 8, LEAS 3, CLRA 1, 25 cycles for a sequence the datasheet times at
167
+ about 41. `-limitcycles` never fires under `-cpu6809`, so take 6809
168
+ screenshots through the monitor. Its 6809 runs one cycle per PET cycle,
169
+ 16,650 cycles between the Waterloo ROM's frame interrupts.
170
+ - **The SuperPET has no software CPU select and no write protect.** With
171
+ `-cpuprog` it boots the 6502, and no write to `$EFF4`-`$EFFF` starts
172
+ the 6809. Writes to the bank RAM stick after any one bit written to
173
+ `$EFF4`-`$EFFB`, with the switch at 6502 or at PROG. The
174
+ CPU switch (`CPUswitch`) is read only at reset. `$EFFD` acts as
175
+ `$EFFC`. Its 6702 at `$EFE0` answers 16 reads with no write with `$D6`,
176
+ and writes and reads in turn of 0 to 15 with `d6 c6 c6 56 56 44 44 d6
177
+ d6 84 84 15 15 01 01 91`, as badline's does. It saves the 6702 in
178
+ PETMEM's settings (below), and every other PET's settings hold one as
179
+ RES leaves it.
180
+ - **Its 2040 isn't usable.** On a 4032 or a 3032 `OPEN15,8,15` hangs and
181
+ `LOAD"$0",8` never finishes; on a 2001 the directory comes back empty.
182
+ - **It runs only the interface processor of an IEEE-488 drive** with two
183
+ processors: the 8050, 8250, SFD-1001, 4040, 3040, 2040 and its type
184
+ 9000. The floppy controller and the hard disk's SASI side run at a high
185
+ level, in a module `FDC0`, and the 9000 loads no SASI ROM. Nothing in
186
+ `xpet` times the second processor, the mechanism or SASI. The monitor
187
+ reaches no device for the controller.
188
+ - On `-model 2001` its screen mirror takes the `$8BFF` write before the
189
+ debug cartridge sees it, so `pet-pass.prg` times out with PET-PASS on
190
+ the screen; `+screen2001` gives exit 0. On `-model 8296` the same row
191
+ times out.
192
+ - It patches the 2001's BASIC 1 ROM at start ("patching 2001 ROM to make
193
+ IEEE488 work!"), so a 2001's LOAD from a drive in `xpet` is no
194
+ reference for the stock ROM.
195
+ - It repeats a CRTC row's character lines past the eighth, where the
196
+ 8032029 and 8032087 schematics blank them. Its results mark `crtc3`,
197
+ `crtc10` and `crtc13` as errors, and `crtc13`'s reference shows `xpet`'s
198
+ own power-on RAM. Its 8296 runs the 8032's editor, 901474-04 dated
199
+ 0283.
200
+ - Its discrete board's monitor `LIN` and `CYC` run on a 20,032-cycle
201
+ raster, out of step with its 16,640-cycle retrace. `-pal` and `-ntsc`
202
+ change nothing measurable on a PET.
203
+ - `-autostart` refuses ("Autostart is not available on this setup") once
204
+ `-editor` names a ROM it doesn't know by checksum, and `-initbreak
205
+ ready` never breaks then. Load through the monitor instead
206
+ (`l "path.prg" 0`, `g 0410`), or break on a store.
207
+ - `undump` wants snapshot format 1.0, and with `FSDRIVE`, `TAPEPORT` or
208
+ `USERPORT` missing it loads, then resets on the first instruction
209
+ stepped. A snapshot it saved while its true 2031 searched for a file
210
+ never finishes the LOAD, its own included; mid-transfer ones resume.
211
+ Its CRTC loses a few lines on opening any snapshot.
212
+ - `-autostart` with `-limitcycles` sometimes times out on a 3032; a rerun
213
+ passes.
214
+
215
+ ### xcbm2
216
+
217
+ - **It ticks the mains once a frame of its CRTC**, as vertical sync
218
+ ends, whatever its mains is set to: 40,064 cycles apart on a 600 at
219
+ 50 Hz, where 50 Hz is 40,000, and its 700 has no 60 Hz. Every 610 run,
220
+ `-ntsc` and `-power60` included, used the 50 Hz CRTC table. Its 710
221
+ defaults to `-ntsc -power60`.
222
+ - **It has no DRAM refresh**, so the burn-in disk's 6526 timer cell
223
+ reads BAD on its 610, after one cycle of the test and after three.
224
+ - **The 610 + 2031 TALK race reproduces in it.** With a true 2031,
225
+ `LOAD"$",8` typed at some phases after power-on gives `?FILE NOT
226
+ FOUND`: the KERNAL's TALK puts DAV about 44 cycles after ATN, and the
227
+ 2031's DOS raises NRFD while ATNA is still set. `xcbm2` fails at
228
+ `-keybuf-delay` 0 and 10 to 50 and lists at 5 and 100, as badline fails
229
+ at some phases and not others. The first `LOAD"$"` after power-on gives
230
+ FILE NOT FOUND in it too.
231
+ - **It reads the wrong top bits of TPI1's port C in mode 1.** At READY
232
+ on a 610, with CR `$E3` (CA low, CB high) and no interrupt, its monitor
233
+ reads `$C0` at `$DE02`, though its own `io de00` says CA is low and no
234
+ interrupt is active. The 6525 datasheet reads the pins there, CB, CA
235
+ and IRQ, so badline reads `$A0`: CB high, CA low and IRQ released.
236
+ - It saves no mains and no TPI priority stack. Its cursor blinks 32
237
+ fields on and 32 off, where the 6845 blinks 16 and 16. Opening any
238
+ snapshot costs it a couple of hundred cycles of its CRTC.
239
+
240
+ ### xcbm5x0
241
+
242
+ - It runs VICE's line-based VIC-II, not `x64sc`'s, so it reads the
243
+ raster a cycle off now and then.
244
+ - It ticks the mains every 19,656 cycles, a PAL frame, on NTSC too:
245
+ about 52 Hz, where the NTSC 510's mains is 60.
246
+ - A sprite's phi2 bytes in text mode read the KERNAL from `$E040` on,
247
+ where the FPLA puts the video bus.
248
+
249
+ ### c1541
250
+
251
+ - It refuses `d60` as an image type, but formats a zero-filled `.d90` of
252
+ a D9060's size.
253
+
254
+ ## Snapshot modules
255
+
256
+ No VICE document lays out the `.vsf` modules, so badline's readers and
257
+ writers in `lib/badline/snapshot/vice/` were mapped from dumps: known
258
+ pokes into memory, register writes and breakpoints at known delays,
259
+ compared with the monitor at the same moment. Each file's doc comment
260
+ gives its module's layout and what maps across.
261
+ [snapshots.md](snapshots.md#vice) covers what each emulator opens and
262
+ what it leaves out.
263
+
264
+ | Emulator | Machine name, format | Modules (files) |
265
+ | --- | --- | --- |
266
+ | `x64sc` | `C64SC`, 2.0 | MAINCPU 1.4 (`main_cpu.rb`), C64MEM (`c64_mem.rb`), CIA1 and CIA2 (`cias.rb`, `cias_import.rb`), SID and SIDEXTENDED (`sid_registers.rb`, `sid_extended.rb`), VIC-II (`vicii.rb`, `vicii_import.rb`), REU1764 (`reu1764.rb`), and the empty ports it refuses a file without (`peripherals.rb`) |
267
+ | `xpet` | `PET`, 1.0 | MAINCPU 1.3 (`pet_cpu.rb`), PETMEM 1.3 (`pet_mem.rb`), CRTC 1.2 (`pet_crtc.rb`), PIA1 and PIA2 (`pet_pias.rb`), VIA 2.2 (`pet_via.rb`), CPU6809 1.1 (`pet_cpu.rb`) and Acia1 (`cbm2_acia.rb`) for the SuperPET, a 2031 (`pet_drive.rb`) and the two-processor drives (`pet_drive8050.rb`) |
268
+ | `xcbm2` | `CBM-II`, 1.0 | The PET's CPU, CBM2MEM 1.0 (`cbm2_mem.rb`), CRTC 1.2 (`cbm2_crtc.rb`), TPI1 and TPI2 (`cbm2_tpi.rb`), Acia1 1.1 (`cbm2_acia.rb`), the C64's CIA and SID, the mains (`cbm2_mains.rb`) |
269
+ | `xcbm5x0` | `CBM-II-5x0`, 0.0 | As `xcbm2`, with its own VIC-II 1.3 (`p500_vicii.rb`) and C500DATA, the cycles to the mains' next tick (`p500.rb`) |
270
+ | `xvic` | `VIC20`, 3.1 | MAINCPU 1.4 (`vic20_cpu.rb`), VIC20MEM 1.1 (`vic20_mem.rb`), VIC-I 0.4 with the colour RAM (`vic20_vici.rb`), VIA1 and VIA2 (`pet_via.rb`), and the empty ports it resets without (`vic20.rb`) |
271
+ | `x128`, `xplus4` | `C128` 1.0, `PLUS4` | None read or written |
272
+
273
+ Facts the layouts rest on that the files' comments state in full:
274
+
275
+ - CBM2MEM's header is the RAM board's size in 128K units, the RAM mapped
276
+ into segment 15 beyond the B series' own (`$40` on a P500), the model
277
+ line (0 a 700, 1 a 600 at 60 Hz, 2 a 600 at 50 Hz) and both segment
278
+ registers.
279
+ - A TPI module is the eight registers, then the latched interrupts and CA
280
+ and CB. In mode 1 `xcbm2` keeps the latches in PRC's low five bits and
281
+ the mask in DDRC's.
282
+ - PETMEM's 24 bytes of settings at the end hold the SuperPET's 6702 from
283
+ the fifth byte: the byte it reads, the last write that shifted it, 1
284
+ while the last write left D0 clear, then a little-endian word per data
285
+ line, bit k the XOR of stages k and k + 1 of its shift register. Mapped
286
+ from dumps after 56 writes to `$EFE0`, which all decode to the
287
+ registers badline's 6702 has after the same writes.
288
+ - CPU6809 1.1 is an 8-byte clock, X, Y, U, S and PC, DP, CC, A and B,
289
+ then 5 zero bytes.
290
+ - xvic's MAINCPU 1.4 is 83 bytes, x64sc's without the BA flags and the
291
+ two clocks after the interrupt counts. VIC20MEM 1.1 is a byte of the
292
+ blocks that hold RAM (bit 0 the 3K, bits 1-3 BLK1-BLK3, bit 5 BLK5),
293
+ both data lines' last bytes, a byte badline leaves at 0, then
294
+ `$0000`-`$03FF`, `$1000`-`$1FFF`, the 3K and the blocks in turn.
295
+ - VIC-I 0.4 holds the interlace flag and field, the frame's first clock,
296
+ the beam, the text window's state, its counters and the line's fetch
297
+ state, the light pen, the colour RAM, the registers and xvic's picture
298
+ (1,648 by 632 bytes on PAL, 1,536 by 532 on NTSC). xvic's monitor's
299
+ cycle at an instruction boundary is badline's column.
300
+ - The two-processor drives all save the 8050's set: DRIVE8 2.0,
301
+ DRIVECPU0 1.3 for the interface processor, RIOT1D0 and RIOT2D0, FDC0
302
+ (8 bytes) and FSDRIVE. DRIVE8's type word tells the models apart, and
303
+ the SFD-1001's and the 9000's DRIVE8 holds one drive. A RIOT module's
304
+ timer flag, bit 7, is set only while the timer's interrupt is enabled.
305
+
306
+ ## Where badline differs
307
+
308
+ Where VICE and a schematic, a datasheet or a test from real hardware
309
+ disagree, badline follows the hardware source. These are the places a
310
+ program can tell:
311
+
312
+ - **The CBM-II's DRAM refresh**, a cycle in about 21, which `xcbm2`
313
+ lacks. It passes the burn-in's timer cell, and a program badline runs
314
+ on from an `xcbm2` snapshot runs about 5% slower than in `xcbm2`.
315
+ `refresh: false` builds a B series without it, for comparing with
316
+ `xcbm2`. [CBM-II DRAM refresh](pinned-behaviour.md#cbm-ii-dram-refresh).
317
+ - **The TED's line step and the 7501's port**: the datasheet's decode,
318
+ about 3 cycles ahead of `xplus4`, and the trap tests `xplus4` fails.
319
+ [TED beam and the 7501 port](pinned-behaviour.md#ted-beam-and-the-7501-port).
320
+ Where the TED's fetches, picture and sound follow `xplus4` over the
321
+ datasheet, such as a voice's 1023 - x period, the same doc says so
322
+ under the TED's entries.
323
+ - **The 6809's timing** follows the MC6809E datasheet and the neetandev
324
+ vectors, never `xpet`.
325
+ [6809 dead cycles](pinned-behaviour.md#6809-dead-cycles).
326
+ - **The SuperPET's CPU select and write protect** through the system
327
+ latch at `$EFF8`, after the 324037 schematic, Levak and Fachat
328
+ (`PET::SuperPET::Board`). A program that uses them runs otherwise on
329
+ `xpet`. With SW2 at PROG, badline starts the 6809 at power-on, as the
330
+ latch's clear bit 0 picks it; `xpet` boots the 6502.
331
+ - **A CRTC PET's rows taller than eight lines** blank the lines past the
332
+ eighth, after the schematics, where `xpet` repeats them
333
+ (`PET::CRTCVideo`). Don't take `xpet` as a reference for tall rows.
334
+ - **A 6525's port C in mode 1** reads the CB, CA and IRQ pins in its top
335
+ three bits, after the datasheet (`Chips::TPI`): `$A0` at a B series'
336
+ READY, where `xcbm2` reads `$C0`.
337
+ - **The P500's sprite bytes in phi2** come from the video bus the FPLA
338
+ describes (`Chips::VIC::Bank#peek_sprite`), not the KERNAL bytes
339
+ `xcbm5x0` returns.
340
+ - **The PET's power-on RAM** is zeros. `crtc13`'s reference shows
341
+ `xpet`'s own pattern, and no dump of a real PET's is known.
342
+ - **The VIC-I's sound**: its volume scales the output linearly, where
343
+ `xvic`'s doesn't, and its loudness and output stage are fitted, not
344
+ pinned. [VIC-I sound](pinned-behaviour.md#vic-i-sound).
data/exe/badline-ruby CHANGED
@@ -34,6 +34,11 @@ def load_sdl
34
34
  require "badline/frontend"
35
35
  end
36
36
 
37
+ if options.kim1_terminal?
38
+ require "badline/audio/console"
39
+ exit Badline::KIM1::HostTerminal.start(options, Badline::Audio::Console.new(input: $stdin, output: $stdout))
40
+ end
41
+
37
42
  if options.headless?
38
43
  require "badline/audio/console"
39
44
  console = if options.player_window?
@@ -143,7 +143,6 @@ module Badline
143
143
  audio = modules.required("BL-AUDIO")
144
144
  restore_player(modules, audio)
145
145
  record
146
- player.stereo.sids.each_with_index { |sid, index| sid.load_recording_fields(audio, "sid#{index + 1}.rec.") }
147
146
  @level = audio.int("level", 0)
148
147
  @still = audio.int("still", 0)
149
148
  audio.int("played", 0)
@@ -176,9 +175,9 @@ module Badline
176
175
  end
177
176
 
178
177
  # The player's modules, after a BL-AUDIO module with the cycles into
179
- # the subtune, each SID's model and how far its recording has got,
180
- # and the silence count. The SIDs have caught up as the frame drained
181
- # them, so they leave no samples behind.
178
+ # the subtune, each SID's model and the silence count. Each SID's own
179
+ # module holds how far its recording has got. The SIDs have caught up
180
+ # as the frame drained them, so they leave no samples behind.
182
181
  def save_checkpoint(played, clock_hz)
183
182
  checkpoints = @checkpoints
184
183
  return if checkpoints.nil? || !checkpoints.due?(played, clock_hz)
@@ -187,10 +186,7 @@ module Badline
187
186
  sections = player.save_modules
188
187
  audio = Snapshot::Keyed.section("BL-AUDIO") do |out|
189
188
  out.int("played", played)
190
- sids.each_with_index do |sid, index|
191
- out.text("sid#{index + 1}.model", sid.model.to_s)
192
- sid.save_recording_fields(out, "sid#{index + 1}.rec.")
193
- end
189
+ sids.each_with_index { |sid, index| out.text("sid#{index + 1}.model", sid.model.to_s) }
194
190
  out.int("level", @level).int("still", @still)
195
191
  end
196
192
  checkpoints.keep(played, [audio, *sections])
@@ -4,8 +4,9 @@ module Badline
4
4
  module Audio
5
5
  # The terminal face of `--headless`: the tune's header, a status line
6
6
  # redrawn in place, and single keypresses read without waiting for
7
- # Return. Ctrl-C still interrupts. A subclass puts the terminal in raw
8
- # mode with #raw! and #restore and waits for keys with #readable?:
7
+ # Return, or for the KIM-1, the text typed and printed (#typing).
8
+ # Ctrl-C still interrupts. A subclass puts the terminal in raw mode
9
+ # with #raw! and #restore and waits for keys with #readable?:
9
10
  # Console with io/console for badline-ruby, and Native::Console with
10
11
  # stty and poll(2) for the native badline.
11
12
  class Terminal
@@ -50,6 +51,37 @@ module Badline
50
51
  end
51
52
  end
52
53
 
54
+ # Raw input for the length of the block, the cursor showing, for a
55
+ # session that types and prints text, as the KIM-1's teletype does.
56
+ def typing
57
+ mode = raw! if @input.tty?
58
+ yield
59
+ ensure
60
+ restore(mode) if mode
61
+ @output.print "\r\n"
62
+ end
63
+
64
+ # Waits up to `seconds` for keys and returns what they typed, as raw
65
+ # mode reads it, or an empty string.
66
+ def read_text(seconds)
67
+ if @closed
68
+ sleep(seconds)
69
+ return ""
70
+ end
71
+ return "" unless readable?(seconds)
72
+
73
+ text = @input.read_nonblock(64, exception: false)
74
+ return "" if text == :wait_readable
75
+
76
+ @closed = true if text.nil?
77
+ text.nil? ? "" : text
78
+ end
79
+
80
+ def print_text(text)
81
+ @output.print(text)
82
+ @output.flush
83
+ end
84
+
53
85
  def header(lines)
54
86
  lines.each { |line| @output.print "#{line}\r\n" }
55
87
  @output.print "←/→ subtune n/p tune ,/. seek space pause s shuffle l loop a all subtunes q quit\r\n"