badline 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 41235fb28f9f33c9a88333beec1c09cd9825d45875f24d22b8cb5f66f9528467
4
- data.tar.gz: c214b37efce97c404dcd0838283e65e0f42aaa86a8376f18ef2323933b01b2f2
3
+ metadata.gz: feaedb95b99aa7efed205645c112426a2649ad7a08c975708d085bf69a7e9555
4
+ data.tar.gz: b284281a2e1256f0fe94abf5174990ac8dc8a98cd7035f1cd53aebd3ccbefbd6
5
5
  SHA512:
6
- metadata.gz: ab2c530282a35d8ac65c217d6901d46c6f844cde1d7c7ca143acb8ea8f05ac08d1da6b8ee290fb41bd016ce2079e308bfd5c5f338be18ed269be693612e07a50
7
- data.tar.gz: 6c27c6d41e73e495bb27e536fae7424b5524c12b9c1d12cdb3bccc2efb3a73be6137e5209c4356394594d71ceaa205309989f193344003a3ed65245df0ec74fa
6
+ metadata.gz: 870ff9cb5c9a9d65c8e9dd8dee6cc87a45871c1a07c79c4b9dc69a692600c3167f92b1debca0f860ab96b783a81bb608276542322b17e305acb82e95c9fc560b
7
+ data.tar.gz: 7c12bf1fd073b2b0e58e41195d67316f0c518a0f5b8c013ded19f025b48456fea738e5ad3df26a796c84151638e8c0449b5bf14b7d013fcb876c61db5d2d9469
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.8.0](https://github.com/elektronaut/badline/compare/v0.7.0...v0.8.0) (2026-10-03)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * F9 opens the pause menu instead of swapping the joysticks, which the Ports page does now, and Tab no longer steps through the mouse and paddle modes.
9
+ * --read-only is gone, and disks are write-protected by default. Pass --writable to let the machine write to a disk image.
10
+
11
+ ### Features
12
+
13
+ * find the disks of a set by their names ([b2a4ba4](https://github.com/elektronaut/badline/commit/b2a4ba47bb4c9d4175130104c4dd2d3d2d5e570a))
14
+ * pause the machine in a menu on F9 ([8b2568c](https://github.com/elektronaut/badline/commit/8b2568c8ebe894c3da56d404217189dc7b27db84))
15
+ * put disks in write-protected unless --writable ([aed9fa1](https://github.com/elektronaut/badline/commit/aed9fa173007c85a5b9c19840e011d34f5b6b615))
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * stop printing that the window runs below real time ([86a57a6](https://github.com/elektronaut/badline/commit/86a57a635189a8e46e285773ce62ecbf1dd5adde))
21
+
3
22
  ## [0.7.0](https://github.com/elektronaut/badline/compare/v0.6.1...v0.7.0) (2026-10-02)
4
23
 
5
24
 
data/CLAUDE.md CHANGED
@@ -164,7 +164,9 @@ the rows your change can't reach tell you nothing about it.
164
164
  - A pull request's CI is the verdict. It runs every suite on the Spinel
165
165
  build, compared row by row against
166
166
  `test/baselines/`, and every job is a required check. A row that moved
167
- fails it. Re-record only those rows, in the same change:
167
+ fails it. A pull request that changes only docs, or only a release's
168
+ version bump, skips the specs and suites; pushes to main always run
169
+ them. Re-record only those rows, in the same change:
168
170
  `rake "regression:record:<suite>[filter,...]"` (quote it, because zsh
169
171
  globs the brackets). It runs only the matching tests on CRuby and
170
172
  splices their rows into the baseline, and every other row keeps its
data/README.md CHANGED
@@ -73,7 +73,7 @@ differences noted in the table. `--help` lists the options for either.
73
73
  | Option | Effect |
74
74
  | --- | --- |
75
75
  | `--no-autostart` | Attach the media and stop at `READY.`, so you can type the `LOAD` yourself |
76
- | `--read-only` | Mount a disk image write-protected. The drive reports `26,WRITE PROTECT ON` for any write and the image file stays as it was |
76
+ | `--writable` | Let the machine write to disk images. Without it, a disk goes in write-protected: the drive reports `26,WRITE PROTECT ON` for any write and the image file stays as it was |
77
77
  | `--true-drive` | Put an emulated 1541 on device 8 instead of the KERNAL traps. See [Media](#media) |
78
78
  | `-s`, `--subtune N` | Pick a subtune of a `.sid` file, counting from 1 |
79
79
  | `--sid 6581`, `--sid 8580` | Fit the older or newer SID. `--sid auto`, the default, takes a `.sid` tune's own |
@@ -87,12 +87,6 @@ differences noted in the table. `--help` lists the options for either.
87
87
  | `--version` | Show the version and what built it (`badline` only) |
88
88
  | `-h`, `--help` | List the options |
89
89
 
90
- Both run the same window. `badline` plays the SID through the host's
91
- audio device, and `F10` mutes and unmutes it. In `badline-ruby` the
92
- machine runs below real time, so the sound stutters: it plays in bursts
93
- with silent gaps between them, at the right pitch, and never slows the
94
- emulation down.
95
-
96
90
  ### Scripted runs
97
91
 
98
92
  | Option | Effect |
@@ -113,234 +107,58 @@ badline --unpaced --frames 12000 --true-drive disk1.d64 \
113
107
  `--help` lists the events, and [native/README.md](native/README.md#running)
114
108
  describes them.
115
109
 
116
- ### ROMs
117
-
118
- The KERNAL, BASIC and character ROMs come with the gem. To run other
119
- images, such as a patched KERNAL, point `BADLINE_ROM_PATH` at a
120
- directory that holds `kernal.rom`, `basic.rom` and `character.rom`,
121
- plus `eapi/eapi-am29f040-14` if you attach EasyFlash cartridges. From
122
- Ruby, `Badline.rom_path = dir` does the same before a
123
- `Badline::Computer` is built, and `nil` restores the bundled set.
110
+ Other KERNAL, BASIC or character ROMs, and using badline as a Ruby
111
+ library, are covered in [doc/library.md](doc/library.md).
124
112
 
125
113
  ## Media
126
114
 
127
115
  | Format | Handling |
128
116
  |--------|----------|
129
117
  | `.prg`, `.p00` | Loaded into memory after boot. A program at the BASIC start (`$0801`) is `RUN`, anything else is left for you to `SYS` |
130
- | `.d64`, `.d71`, `.d81` | Mounted read-write as device 8, then `LOAD"*",8,1` and `RUN`. Writes go straight back to the image file. With `--read-only`, or an image the host can't write, it acts as a write-protected disk |
131
- | `.g64` | Put in a true 1541, which is plugged in as device 8 for it, then `LOAD"*",8,1` and `RUN`. The image holds the disk's raw GCR, half tracks and all, so copy protection and fast loaders that read it work. Tracks the drive writes go back to the image file. With `--read-only`, or an image the host can't write, it acts as a write-protected disk |
118
+ | `.d64`, `.d71`, `.d81` | Mounted as device 8, then `LOAD"*",8,1` and `RUN`. Write-protected unless `--writable` |
119
+ | `.g64` | Put in a true 1541, then `LOAD"*",8,1` and `RUN`. It holds the disk's raw GCR, so copy protection that reads it works. Write-protected unless `--writable` |
132
120
  | `.t64` | Mounted read-only as device 8 and loaded like a disk image. The files load by name, and no tape is involved |
133
121
  | `.tap` | Inserted in the datasette with PLAY pressed, then `LOAD` and `RUN`. It loads at the speed of a real tape |
134
122
  | `.crt` | The hardware types listed under [Cartridges](#whats-emulated). Other types are rejected |
135
123
  | `.sid` | PSID and RSID tunes, started through a small driver after boot |
136
124
  | `.vsf` | A snapshot of a running machine, badline's own or one VICE's x64sc saved. See [Snapshots](#snapshots) |
137
- | A directory | Mounted read-write as device 8. It serves the `.prg` and `.p00` files in it and the contents of any `.t64`, and `SAVE` writes a new `.prg` |
138
-
139
- Apart from a `.g64`, which only a true drive can read, there is no 1541
140
- unless `--true-drive` asks for one. Device 8 works by trapping the
141
- KERNAL's `LOAD` and `SAVE` routines and its serial bus primitives, so
142
- files open by name through `OPEN` and `CHRIN` as well. `LOAD"$",8` lists
143
- the directory of any medium mounted there, as a 1541 does. The command
144
- channel answers `I`, `B-P` and `U1` block reads, which covers loaders
145
- that read blocks directly. On a disk image it also takes `SAVE` (with
146
- `@0:` to replace a file), files opened for writing or appending, `S` to
147
- scratch, `U2` and `B-W` block writes, and `B-A` and `B-F`. Loaders that
148
- upload their own code to the drive with `M-W` and `M-E`, and copy
149
- protection that reads raw GCR, won't work there, but do on a true
150
- drive.
151
-
152
- `--true-drive` puts an emulated 1541 on device 8 instead, running its
153
- own DOS ROM on its own 6502 and talking to the machine over the serial
154
- bus. It reads `.d64` and `.g64` images, which it autostarts with the
155
- same `LOAD"*",8,1` and `RUN`, but not `.d71`, `.d81` or `.t64` images
156
- or directories. `--read-only` puts the disk in write-protected. Loading
157
- runs at the speed of a real 1541, and the drive's red LED lights in the
158
- bottom right corner of the border. Both executables take it.
159
-
160
- `Badline::Media.insert_disk(computer, path)` swaps the disk image or
161
- directory in device 8 while the machine runs, for software that asks for
162
- another disk. It takes `read_only: true`, and `Badline::Media.attach`
163
- takes `disk: { read_only: true }`, to mount a disk image write-protected,
164
- as the test harnesses under `bin/` do. A `.g64` goes in the true 1541,
165
- and takes out a disk mounted through the traps, so `LOAD` and `SAVE`
166
- reach the 1541 too. With the 1541 in device 8, a `.d64` goes in its
167
- drive as well.
125
+ | A directory | Mounted as device 8. It serves the `.prg` and `.p00` files in it and the contents of any `.t64`, and `SAVE` writes a new `.prg` |
126
+
127
+ Without `--true-drive`, device 8 is no drive at all but traps on the
128
+ KERNAL's disk routines. Loading is instant, but fast loaders and copy
129
+ protection that run code on the drive need `--true-drive`, which puts
130
+ an emulated 1541 there, running its own DOS at a real 1541's speed. Its
131
+ red LED lights in the bottom right corner of the border.
132
+ [doc/media.md](doc/media.md) has the details, and how to attach media
133
+ from Ruby.
168
134
 
169
135
  ## Snapshots
170
136
 
171
- In the window, `F11` saves the whole machine to a new
172
- `badline-<date>-<time>.vsf` in the working directory, and `F12` goes
173
- back to the snapshot last saved or opened, in a new machine built as the
174
- saved one was. Both executables do this, and both open a `.vsf` given as
175
- the media. A snapshot that fails to open leaves the machine running as
176
- it was. From Ruby, `computer.save_snapshot(path)` saves,
177
- `computer.restore_snapshot(path)` takes a machine back to a snapshot,
178
- and `Badline::Snapshot.load(path)` builds a new machine as the saved one
179
- was built and restores it. `computer.snapshot` and
180
- `computer.restore(state)` do the same in memory, without a file. A
181
- restore that fails leaves the machine as it was.
182
-
183
- A snapshot holds the machine as it was on the cycle it was saved: the
184
- chips down to the instruction step and the pixel pipeline, the RAM and
185
- any +60K or +256K expansion, the cartridge with its RAM and flash, a
186
- GEO-RAM, a true 1541 with its RAM, its VIAs and the disk under the head,
187
- a disk or directory mounted through the traps with its open channels,
188
- and the tape with its place on it. A restored machine runs on exactly
189
- as the saved one would have. A directory, a tape and a true drive's
190
- disk image open again from their paths when the snapshot is restored,
191
- the disk with its tracks as the drive last saw them. A disk image mounted through the traps comes back
192
- with its contents from the snapshot. What the host holds stays the host's: the keyboard, the
193
- joysticks, the mouse and paddles, sound, and blocks given to `on_init`
194
- that hadn't run yet, which a restore reports. A snapshot only restores
195
- in the badline version that wrote it, into a machine with the same
196
- chip models, RAM expansion and REU. `computer.snapshot` holds an REU's
197
- RAM, registers and transfer too, but a machine with an REU doesn't save
198
- to a file yet, as badline doesn't write VICE's REU module.
199
-
200
- Snapshots use VICE's `.vsf` format. badline writes VICE's modules for
201
- the CPU, RAM and CPU port, both CIAs, the SID and the VIC-II, plus the
202
- ones x64sc needs to open the file, with nothing attached to the
203
- cartridge, tape or user ports and no true drive. A `BADLINE` module,
204
- which VICE skips, holds the whole machine, and badline restores its own
205
- snapshots from it.
206
-
207
- x64sc 3.10 opens badline's snapshots, taken at the end of the
208
- instruction the CPU was in, as long as its VIC-II model matches
209
- (`-model c64` for the default machine). It keeps its own drives and
210
- leaves out the cartridge, the expansions and the tape. Snapshots x64sc
211
- saves open in badline through the same modules: the CPU at its
212
- instruction boundary, RAM, the CPU port, the CIAs' registers, timers and
213
- clocks, the SID's registers and reSID voice state, and the VIC-II's
214
- registers, beam position, counters and colour RAM. The VIC-II's pixel
215
- pipeline starts empty. badline reads the modules x64sc 3.7 to 3.10
216
- write, and VICE's development versions' `MAINC64CPU` and `VIC-IISC`. A module version
217
- it doesn't know is left out, or fails the restore for the CPU and RAM.
218
- It reports the modules it leaves out, such as the 1541 drives, the
219
- cartridge, the datasette and the keyboard, and carries on without them.
220
- An NTSC snapshot fails, as badline runs PAL only. Restored into a
221
- running machine, a VICE snapshot fails for a machine built another way,
222
- such as a C64C's snapshot in a C64, and otherwise takes the cartridge
223
- out and switches the machine off and on.
137
+ `F11` saves the whole machine to a new `badline-<date>-<time>.vsf` in
138
+ the working directory, and `F12` goes back to the snapshot last saved
139
+ or opened. Snapshots use VICE's `.vsf` format: badline opens those
140
+ x64sc saves, and x64sc opens badline's. See
141
+ [doc/snapshots.md](doc/snapshots.md) for what they hold and how far the
142
+ two agree.
224
143
 
225
144
  ## Playing and rendering SID tunes
226
145
 
227
- `badline-ruby --headless` plays a `.sid` tune on the host's audio
228
- device without opening the window, and `--audio-out` renders it to a
229
- 16-bit stereo PCM file instead. The file's extension picks the format, `.wav`
230
- or `.aiff`. The native `badline` has both modes too.
231
-
232
146
  ```sh
233
- badline sid ~/C64Music/MUSICIANS/H/Hubbard_Rob # play every tune below a directory
234
- badline sid tune.sid other.sid # play a queue of tunes
235
- badline-ruby --headless tune.sid # play, length from HVSC
236
- badline-ruby --headless -s 3 tune.sid # play the third subtune
237
- badline-ruby --headless --all-subtunes tune.sid # play on through every subtune
238
- badline-ruby --seconds 180 tune.sid --audio-out out.aiff
239
- badline-ruby -s 3 --rate 48000 tune.sid --audio-out out.wav
240
- badline-ruby --headless --sid 8580 tune.sid
241
- badline-ruby --filter-chunk 1 tune.sid --audio-out out.wav # exact filter, slower
147
+ badline tune.sid # play a tune in the SID player
148
+ badline sid ~/C64Music/MUSICIANS/H/Hubbard_Rob # play every tune below a directory
149
+ badline sid --headless tune.sid other.sid # play a queue in the terminal
150
+ badline --seconds 180 tune.sid --audio-out out.wav # render to a .wav or .aiff
242
151
  ```
243
152
 
244
- `badline sid FILE|DIR...` plays a queue of tunes in the SID player's
245
- window, in the order given, and a directory adds every `.sid` tune below
246
- it in path order. `badline sid --headless` plays the queue in the
247
- terminal instead. `badline sid` on its own opens the window with an
248
- empty queue. Dropping `.sid` files or folders on the window adds them
249
- to the end of the queue, and an empty queue starts playing them. It
250
- takes
251
- the options below except `--audio-out`, and `--subtune` picks the first
252
- tune's subtune. `--sid auto`, the default, fits each of a tune's SIDs
253
- the model its header names. A tune written for 2 or 3 SIDs plays on as
254
- many, at the addresses its header gives, in stereo: SID 1 on the left,
255
- SID 2 on the right and SID 3 in the centre. A tune on one SID plays the
256
- same on both channels. A file that isn't a tune is skipped.
257
- `badline tune.sid` plays the tune in the SID player too, unless an
258
- option of the emulator's window, such as `--ntsc` or `--reu`, asks for
259
- the machine: then a tune for one SID runs on the emulated C64, started
260
- through a small driver after boot.
261
-
262
- Both modes take the same options. The window's own, `--no-autostart`,
263
- `--read-only`, `--sound`, `--true-drive`, `--reu`, `--ntsc` and
264
- `--verbose`, don't apply to them. `--subtune` (or `-s`) picks the subtune, counting from 1 as HVSC
265
- does, and defaults to the tune's own start subtune. Playback asks the
266
- device for 44.1 kHz and takes whatever rate it offers, unless `--rate`
267
- says otherwise. Ctrl-C stops it.
268
-
269
- Played on a terminal, `--headless` and `sid` show each tune's name,
270
- author and release as it starts, then the tune's place in the queue,
271
- the subtune number and the time played against the subtune's length. `--headless`
272
- queues just the one tune. Each tune plays its own subtune: `--subtune`, or
273
- the tune's start subtune. When that subtune ends the player goes on to the next
274
- tune, and it stops after the last. `a`, or `--all-subtunes`, turns on
275
- playing all subtunes, so that a subtune that ends goes on to the tune's next
276
- subtune, and a tune stepped to starts on its first subtune.
277
-
278
- → and ← step to the tune's next and previous subtune, stopping at its
279
- first and last. `n` and `p` step to the next and previous tune. `s`
280
- turns shuffle on and off, which plays the queue's tunes in a random
281
- order, and `l` turns looping on and off, so that the end of the queue
282
- goes on to its start. `,` and `.` seek 10 seconds back and forward
283
- within the subtune, which plays it again from its start and runs silently
284
- up to the point asked for. Space pauses and `q` quits. The status line
285
- shows which modes are on, and they last until the player quits.
153
+ The SID player plays a queue of tunes, looking up each subtune's length
154
+ and STIL entry in an HVSC collection. Its window shows each voice's
155
+ note and output, the SID's registers, envelopes and filter, and the
156
+ tune's STIL entry, and is worked with the mouse. Tunes for 2 or 3 SIDs
157
+ play in stereo. [doc/sid-player.md](doc/sid-player.md) covers the
158
+ options, the keys and the window.
286
159
 
287
160
  ![The SID player's visualizer playing Rob Hubbard's Delta](doc/images/sid-player.png)
288
161
 
289
- The SID player's window is worked with the mouse. Its header shows the
290
- tune's name, author and release, the tune the subtune covers at the
291
- moment when HVSC's STIL credits one, following the times STIL gives, and
292
- buttons that switch between three views and between the tune's own SID
293
- model, the 6581 and the 8580, which changes the chips playing on the
294
- spot. Its footer shows the time played on a bar you can click to seek,
295
- and buttons that pause, step between tunes and between a tune's
296
- subtunes, and turn shuffle, looping and all subtunes on and off. The
297
- visualizer view shows each voice's note, and how far off it is in cents,
298
- over a scope of the voice's output, and the mixed output below them. A
299
- tune on more than one SID gets a row of voices for each SID, and the mix
300
- splits into its left and right. The SID view shows one SID at a time,
301
- and for a tune on more than one, a row of SID 1, 2 and 3 buttons at its
302
- top picks which. It shows each voice's waveforms and the shape
303
- they make, its control bits, pulse width, envelope settings, and the
304
- envelope's level and stage, and the filter's modes, cutoff, resonance,
305
- volume and its response on the chip playing. The INFO view shows the
306
- tune's STIL entry and the subtune's, with a scroll bar, the mouse wheel
307
- or the up and down keys for the long ones. The terminal's keys work in
308
- the window too, along with Tab to switch views and `c` to step through
309
- the SID models.
310
-
311
- `--no-tui`, or output that isn't a terminal, gives plain progress
312
- output instead and plays through the queue without the keys, while
313
- `--audio-out` renders just the one subtune.
314
-
315
- A `.sid` file doesn't store its length, so `badline-ruby` looks the
316
- tune up by MD5 in HVSC's `Songlengths.md5`. It finds the database
317
- through `--songlengths`, in a `DOCUMENTS` directory in any of the
318
- tune's parent directories (the layout of an HVSC collection), or under
319
- `$HVSC_BASE/DOCUMENTS`. Without a database or `--seconds` it runs for
320
- 60 seconds, but a subtune that falls silent for 5 seconds before then
321
- ends there, when played and when rendered alike. Silent means the
322
- output holds within 16 steps of one level, since a 6581 idles at a DC
323
- offset rather than at zero. A subtune with a known length plays to its
324
- length whatever it sounds like.
325
-
326
- A tune in an HVSC collection also gets its entry in HVSC's `STIL.txt`,
327
- found the same way: comments, covers, and subtune names and composers.
328
- The tune's own fields follow its header, and each subtune's print as it
329
- starts.
330
-
331
- PSID tunes run on a CPU and RAM with only the SID clocked, at about
332
- twice real time, so they play smoothly. RSID tunes set up their own
333
- interrupts, so they boot a full C64 first and run at about half real
334
- time. They render fine but stutter when played, and `badline-ruby` says
335
- so when it falls behind. The filter steps four cycles at a time;
336
- `--filter-chunk 1` steps it every cycle, which is exact and takes about
337
- twice as long. `badline-ruby --help` lists the options.
338
-
339
- The native `badline` takes the same options and runs the same code, so
340
- it renders the same file sample for sample, and it plays RSID tunes
341
- without stuttering. See
342
- [native/README.md](native/README.md#without-the-window).
343
-
344
162
  ## Input
345
163
 
346
164
  Keys map by their position on a US keyboard, whatever the host's layout,
@@ -362,109 +180,97 @@ types `"`. These keys have no same-named host key:
362
180
  | `+` / `*` | Keypad `+` / Keypad `*` |
363
181
  | `RESTORE` | `Page Up` |
364
182
 
365
- `Tab` steps through the input modes and `Shift-Tab` steps back. The
366
- window title shows the current mode:
183
+ `Tab` switches the keys between the C64 keyboard and the joysticks. The
184
+ window title shows where they go, and any device plugged into a control
185
+ port:
367
186
 
368
- | Mode | What the host drives |
369
- |------|----------------------|
187
+ | Title | What the host drives |
188
+ |-------|----------------------|
370
189
  | (none) | The keyboard |
371
- | `[JOY 2]` / `[JOY 1]` | Arrows and Space (or Right Ctrl) are the joystick named, `WASD` and Left Shift the other. `F9` swaps them |
190
+ | `[JOY 2]` / `[JOY 1]` | Arrows and Space (or Right Ctrl) are the joystick named, `WASD` and Left Shift the other. SWAP JOYSTICKS on the pause menu's Ports page swaps them |
372
191
  | `[MOUSE 1]` / `[MOUSE 2]` | A 1351 mouse in control port 1 or 2 |
373
192
  | `[PADDLE 1]` / `[PADDLE 2]` | A pair of paddles in control port 1 or 2 |
374
193
 
375
- The mouse and paddle modes capture the host mouse until you `Tab` out of
376
- them. Moving it moves the 1351 or turns the two paddle knobs, and the
377
- left and right buttons are the 1351's buttons, or the fire buttons of
378
- paddles A and B. Games differ in which port they read, which is why each
379
- device has a mode per port.
194
+ A 1351 mouse or a pair of paddles plugs into either port on the pause
195
+ menu's Ports page, and stays there whichever way `Tab` sends the keys.
196
+ While one is plugged in it holds the host mouse, and opening the pause
197
+ menu lets go. Moving it moves the 1351 or turns the two paddle knobs,
198
+ and the left and right buttons are the 1351's buttons, or the fire
199
+ buttons of paddles A and B. Games differ in which port they read.
380
200
 
381
201
  Game controllers work in every mode. The first one is joystick 2 and
382
202
  the second is joystick 1. The D-pad and left stick steer, the face and
383
203
  shoulder buttons fire, and controllers can be connected or removed while
384
204
  the emulator runs.
385
205
 
386
- Control port 1's fire line is also the VIC-II's light pen input, so
387
- joystick 1's fire button and the 1351's left button in port 1 latch the
388
- light pen registers.
389
-
390
206
  `F10` mutes and unmutes the sound, and the window title shows `[MUTED]`
391
207
  while it's off.
392
208
 
209
+ ## The pause menu
210
+
211
+ `F9` pauses the machine and opens a menu over the frozen picture, and
212
+ `F9` or `Esc` closes it again. On a Mac, hold `Fn` for `F9`, unless the
213
+ function keys are set to work as standard function keys. Up and Down move
214
+ through the rows, Right goes into a page and Left back out, and Return or
215
+ Space presses a row. A row with choices steps to the next. The mouse works
216
+ too.
217
+
218
+ | Page | What it holds |
219
+ |------|---------------|
220
+ | Drive 8 | The disk: insert, eject, the previous or next disk of its set, and whether it's writable |
221
+ | Datasette | The tape: insert, eject, PLAY and REWIND |
222
+ | Expansion port | The cartridge: insert, remove, and its freeze button if it has one |
223
+ | Ports | The device in each control port, and where the keys go |
224
+ | Sound | Mute, and the SID's model |
225
+ | Power | Reset, power cycle and quit |
226
+
227
+ INSERT opens a file browser. A disk's set comes from the names in its
228
+ folder: `Disk 1`, `Side B`, `d2`, TOSEC's `(Disk 1 of 2)`, or a trailing
229
+ `_1`, `_2` when the first of the set is there. WRITABLE starts as
230
+ `--writable` sets it and stays as set for the next disk. Quick open starts
231
+ a file in a new machine, as the command line does. It asks first, as
232
+ inserting or removing a cartridge does, since each power cycles the
233
+ machine.
234
+
235
+ A disk or tape dropped on the window goes into its drive. A cartridge,
236
+ program or `.sid` dropped on it opens the menu to ask first.
237
+
393
238
  ## What's emulated
394
239
 
395
240
  - **6510**: every opcode, documented and undocumented, with per-cycle
396
241
  bus behaviour checked against the
397
242
  [65x02 single step tests](https://github.com/SingleStepTests/65x02).
398
- `JAM` opcodes halt the CPU until reset.
399
- - **Memory**: banking through the 6510 port, including the cartridge
400
- `EXROM`/`GAME` lines and Ultimax mode. The +60K and +256K RAM
401
- expansions fit with `Badline::Computer.new(ram_expansion: :plus60k)` or
402
- `:plus256k`, banked through their register at `$D100`.
403
- - **VIC-II** (PAL 6569): the five standard graphics modes and the
404
- invalid ones, sprites with multicolour, expansion, priority and
405
- pixel-level collisions, raster interrupts, bad lines, sprite DMA, the
406
- border, VIC banks and the light pen.
407
- `Badline::Computer.new(vic_model: :mos8565)` fits the C64C's 8565
408
- instead, with its grey dots on colour register writes and its own
409
- timing for mode splits, sprite multicolour splits and the light pen.
410
- `Badline::Computer.new(region: Badline::Region::NTSC)` builds an NTSC
411
- machine instead: the 6567R8's 65 cycles by 263 lines at 1,022,727 Hz,
412
- with its later sprite fetches and its X counter, and TOD clocks on
413
- 60 Hz mains. `Badline::Region::NTSC_OLD` is the first NTSC C64s'
414
- 6567R56A, 64 cycles by 262 lines. The stock KERNAL tells them from PAL
415
- by the raster, so every region boots the same ROMs. `--ntsc` picks the
416
- 6567R8.
417
- - **CIA 1 and 2**: timers, time-of-day clocks with alarms, the serial
418
- shift register, interrupts, the keyboard matrix with its ghost keys,
419
- the control ports and the paddle multiplexer. The machine has the
420
- original 6526s; `Badline::Computer.new(cia_model: :mos6526a)` fits the
421
- C64C's 6526As instead, whose interrupt register timing differs.
422
- - **SID**: the 6581 and the 8580, with oscillators, ring modulation and
423
- sync, the envelope generator including the ADSR delay bug, the filter,
424
- and the RC network on the board that removes the DC offset from the
425
- output. The machine has a 6581 unless a `.sid` tune asks for an 8580
426
- in its header, and `--sid 6581` or `--sid 8580` overrides either.
427
- - **REU**: the 1700, 1764 and 1750 RAM Expansion Units, and the bigger
428
- units up to 16M built on the same REC chip, with DMA timed against the
429
- VIC's bad lines and sprites. `--reu SIZE` plugs one in, and
430
- `Badline::Computer.new(reu: 512)` does the same from Ruby. An
431
- REU beside a cartridge loses I/O 2 to the cartridge.
432
- - **Datasette**: `.tap` playback into CIA 1's FLAG line, with the motor
433
- and sense lines on the 6510 port.
243
+ - **Memory**: banking through the 6510 port, the cartridge lines and
244
+ Ultimax mode, and the +60K and +256K RAM expansions.
245
+ - **VIC-II**: the PAL 6569, the C64C's 8565, and NTSC's 6567R8 (`--ntsc`)
246
+ and 6567R56A: every graphics mode, sprites, collisions, bad lines,
247
+ sprite DMA, the border and the light pen.
248
+ - **CIA 1 and 2**: the 6526 and the C64C's 6526A, with timers,
249
+ time-of-day clocks, the serial shift register, the keyboard matrix
250
+ and the control ports.
251
+ - **SID**: the 6581 and the 8580, filter and all.
252
+ - **REU**: the 1700, 1764 and 1750 and bigger units up to 16M
253
+ (`--reu`), with DMA timed against the VIC's bad lines and sprites.
254
+ - **Datasette**: `.tap` playback.
255
+ - **1541**: an emulated drive running its own DOS (`--true-drive`).
434
256
  - **Cartridges**: standard 8K, 16K and Ultimax, Simons' BASIC, Ocean,
435
- Fun Play / Power Play, Super Games, Epyx FastLoad, Westermann Learning,
436
- Rex Utility, C64 Game System / System 3, Dinamic, Zaxxon / Super Zaxxon,
437
- Magic Desk, Comal-80, EasyFlash, Mach 5, Pagefox, RGCD and GMod2, and
438
- the freezers Action Replay (v4.2 to v6), Atomic Power / Nordic Power,
439
- Retro Replay / Nordic Replay, Final Cartridge III / III+ and the KCS
440
- Power Cartridge.
441
- EasyFlash and GMod2 flash takes writes through the chip's command set
442
- (program, sector and chip erase, autoselect), so games and EAPI can
443
- save to it. An EasyFlash image's EAPI is swapped for a bundled copy of
444
- the Am29F040 EAPI on attach, as VICE does. The writes stay in memory
445
- and are lost when the emulator quits: the `.crt` file is never
446
- overwritten. The Retro Replay's flash
447
- works the same way in flash mode, which the flash jumper enables:
448
- `Media.attach(computer, path, cartridge: { flash_jumper: true })`, with
449
- `bank_jumper: true` to run from the second 64K of a 128K image. The
450
- GMod2 EEPROM and the Retro Replay clock port aren't there.
451
- - **GEO-RAM**: 64K to 4M of RAM seen through the `$DE00` page, with the
452
- `$DFFE`/`$DFFF` page and block registers. It takes the expansion port,
453
- so it can't sit alongside a cartridge:
454
- `computer.attach_cartridge(Badline::Cartridge::GeoRAM.new(size: 512))`.
455
- Its contents are lost when the emulator quits.
257
+ Fun Play / Power Play, Super Games, Epyx FastLoad, Westermann
258
+ Learning, Rex Utility, C64 Game System / System 3, Dinamic, Zaxxon /
259
+ Super Zaxxon, Magic Desk, Comal-80, EasyFlash, Mach 5, Pagefox, RGCD,
260
+ GMod2 and GEO-RAM, and the freezers Action Replay (v4.2 to v6), Atomic
261
+ Power / Nordic Power, Retro Replay / Nordic Replay, Final Cartridge III
262
+ / III+ and the KCS Power Cartridge. Flash writes stay in memory.
263
+
264
+ Machines other than the default, and the cartridges' jumpers, are
265
+ built from Ruby: see [doc/library.md](doc/library.md).
456
266
 
457
267
  Known gaps:
458
268
 
459
- - `badline-ruby` runs below real time, so its live audio stutters.
460
- `badline` plays smoothly, and so do PSID tunes under
461
- `badline-ruby --headless`.
269
+ - `badline-ruby` runs below real time, so its sound, which `--sound`
270
+ turns on, stutters: it plays in bursts with silent gaps between them.
462
271
  - Without `--true-drive`, fast loaders and anything else that runs code
463
- on the drive won't work (see [Media](#media)). The command channel
464
- doesn't rename, copy, format or validate disks.
272
+ on the drive won't work.
465
273
  - No PAL-N (Drean) machine.
466
- - The emulator window has no freeze button yet, so a freezer cartridge
467
- runs its menu but can't freeze a program.
468
274
 
469
275
  ## Contributing
470
276
 
data/doc/library.md ADDED
@@ -0,0 +1,62 @@
1
+ # Using badline from Ruby
2
+
3
+ The gem is also a library, which runs a `Badline::Computer` from Ruby
4
+ without a window.
5
+
6
+ ```ruby
7
+ require "badline"
8
+
9
+ computer = Badline::Computer.new
10
+ Badline::Media.attach(computer, "game.d64") # attaches and autostarts
11
+ computer.on_init { computer.type_text("print 6*7\r") } # once the machine has booted
12
+ 3_500_000.times { computer.cycle! }
13
+ computer.address_bus.peek(0x0400) # screen RAM starts at $0400
14
+ ```
15
+
16
+ [media.md](media.md) covers attaching and swapping media, and
17
+ [snapshots.md](snapshots.md) saving and restoring the machine.
18
+
19
+ ## Building a machine
20
+
21
+ `Badline::Computer.new` builds the default machine: a PAL C64 with the
22
+ 6569 VIC-II, 6526 CIAs and a 6581 SID. Its keywords build others:
23
+
24
+ - `vic_model: :mos8565` fits the C64C's 8565, with its grey dots on
25
+ colour register writes and its own timing for mode splits, sprite
26
+ multicolour splits and the light pen.
27
+ - `region: Badline::Region::NTSC` builds an NTSC machine: the 6567R8's
28
+ 65 cycles by 263 lines at 1,022,727 Hz, with its later sprite fetches
29
+ and its X counter, and TOD clocks on 60 Hz mains.
30
+ `Badline::Region::NTSC_OLD` is the first NTSC C64s' 6567R56A, 64 cycles
31
+ by 262 lines. The stock KERNAL tells them from PAL by the raster, so
32
+ every region boots the same ROMs.
33
+ - `cia_model: :mos6526a` fits the C64C's 6526As, whose interrupt
34
+ register timing differs.
35
+ - `sid_model: :mos8580` fits the 8580.
36
+ - `ram_expansion: :plus60k` or `:plus256k` fits the +60K or +256K RAM
37
+ expansion, banked through its register at `$D100`.
38
+ - `reu: 512` plugs in a RAM Expansion Unit of that many K.
39
+
40
+ ## Cartridges
41
+
42
+ `Media.attach(computer, path, cartridge: { flash_jumper: true })` sets
43
+ the Retro Replay's flash jumper, which makes its flash take writes, and
44
+ `bank_jumper: true` runs it from the second 64K of a 128K image.
45
+ EasyFlash and GMod2 flash take writes through the chip's command set
46
+ (program, sector and chip erase, autoselect), so games and EAPI can save
47
+ to it. An EasyFlash image's EAPI is swapped for a bundled copy of the
48
+ Am29F040 EAPI on attach, as VICE does. Flash writes stay in memory and
49
+ are lost when the emulator quits: the `.crt` file is never overwritten.
50
+
51
+ A GEO-RAM takes the expansion port, so it can't sit alongside a
52
+ cartridge: `computer.attach_cartridge(Badline::Cartridge::GeoRAM.new(size: 512))`.
53
+ Its contents are lost when the emulator quits.
54
+
55
+ ## ROMs
56
+
57
+ The KERNAL, BASIC and character ROMs come with the gem. To run other
58
+ images, such as a patched KERNAL, point `BADLINE_ROM_PATH` at a
59
+ directory that holds `kernal.rom`, `basic.rom` and `character.rom`, plus
60
+ `eapi/eapi-am29f040-14` if you attach EasyFlash cartridges.
61
+ `Badline.rom_path = dir` does the same before a `Badline::Computer` is
62
+ built, and `nil` restores the bundled set.