badline 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -0
- data/CLAUDE.md +5 -3
- data/README.md +60 -5
- data/doc/library.md +15 -1
- data/doc/pinned-behaviour.md +75 -0
- data/doc/snapshots.md +19 -3
- data/lib/badline/address_bus/fittings.rb +38 -0
- data/lib/badline/address_bus/pla.rb +38 -21
- data/lib/badline/address_bus/roms.rb +12 -5
- data/lib/badline/address_bus.rb +20 -2
- data/lib/badline/c128/banks.rb +35 -0
- data/lib/badline/c128/bus.rb +347 -0
- data/lib/badline/c128/bus_state.rb +53 -0
- data/lib/badline/c128/color_lines.rb +39 -0
- data/lib/badline/c128/cpu.rb +10 -0
- data/lib/badline/c128/keys.rb +35 -0
- data/lib/badline/c128/mmu.rb +182 -0
- data/lib/badline/c128/mmu_pages.rb +105 -0
- data/lib/badline/c128/model.rb +39 -0
- data/lib/badline/c128/modes.rb +48 -0
- data/lib/badline/c128/saved_state.rb +120 -0
- data/lib/badline/c128/vdc/memory.rb +54 -0
- data/lib/badline/c128/vdc/painter.rb +143 -0
- data/lib/badline/c128/vdc/raster.rb +97 -0
- data/lib/badline/c128/vdc/window.rb +215 -0
- data/lib/badline/c128/vdc.rb +268 -0
- data/lib/badline/c128.rb +320 -0
- data/lib/badline/chrout_trap.rb +3 -0
- data/lib/badline/computer/attachments.rb +4 -13
- data/lib/badline/computer/kernal_traps.rb +29 -0
- data/lib/badline/computer.rb +13 -8
- data/lib/badline/frontend/app.rb +34 -21
- data/lib/badline/frontend/boot.rb +31 -1
- data/lib/badline/frontend/controls.rb +11 -0
- data/lib/badline/frontend/keys.rb +28 -1
- data/lib/badline/frontend/machine_window.rb +16 -13
- data/lib/badline/frontend/menu_pages.rb +6 -1
- data/lib/badline/frontend/menu_ports.rb +1 -1
- data/lib/badline/frontend/pause_menu.rb +1 -0
- data/lib/badline/frontend/screen.rb +33 -8
- data/lib/badline/frontend/screens.rb +90 -0
- data/lib/badline/frontend/timeline.rb +15 -4
- data/lib/badline/frontend.rb +1 -0
- data/lib/badline/kernal_trap/file.rb +1 -1
- data/lib/badline/kernal_trap/layout.rb +58 -8
- data/lib/badline/kernal_trap/load.rb +1 -1
- data/lib/badline/kernal_trap/save.rb +1 -1
- data/lib/badline/kernal_trap/serial.rb +5 -0
- data/lib/badline/keyboard.rb +12 -1
- data/lib/badline/machine.rb +16 -7
- data/lib/badline/media.rb +8 -6
- data/lib/badline/model.rb +29 -12
- data/lib/badline/options/event.rb +5 -1
- data/lib/badline/options/family.rb +52 -0
- data/lib/badline/options/help.rb +5 -1
- data/lib/badline/options/table.rb +8 -2
- data/lib/badline/options/validation.rb +14 -1
- data/lib/badline/options.rb +20 -19
- data/lib/badline/roms/README +51 -0
- data/lib/badline/roms/c128/basic.rom +0 -0
- data/lib/badline/roms/c128/character.rom +0 -0
- data/lib/badline/roms/c128/kernal.rom +0 -0
- data/lib/badline/roms/c64gs.rom +0 -0
- data/lib/badline/roms/kernal-pet64.rom +0 -0
- data/lib/badline/snapshot/container.rb +2 -0
- data/lib/badline/snapshot/image.rb +14 -0
- data/lib/badline/snapshot/setup.rb +15 -10
- data/lib/badline/snapshot/state.rb +5 -4
- data/lib/badline/snapshot/vice.rb +2 -1
- data/lib/badline/snapshot.rb +9 -2
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic/bank.rb +2 -1
- data/lib/badline/vic/display_state.rb +12 -0
- data/lib/badline/vic/registers.rb +3 -0
- data/lib/badline/vic.rb +124 -9
- data/lib/badline.rb +1 -0
- metadata +27 -1
data/lib/badline/vic.rb
CHANGED
|
@@ -24,9 +24,29 @@ module Badline
|
|
|
24
24
|
0x8a8a8a, 0xb3ec91, 0x867ade, 0xb3b3b3
|
|
25
25
|
].freeze
|
|
26
26
|
|
|
27
|
+
# The sixteen colours' luminances, out of 32, as Philip Timmermann
|
|
28
|
+
# (Pepto) measured them on the 6569.
|
|
29
|
+
LUMINANCES = [0, 32, 10, 20, 12, 16, 8, 24, 12, 8, 16, 10, 15, 24, 15, 20].freeze
|
|
30
|
+
|
|
31
|
+
# The sixteen colours on a green monochrome monitor, which shows only
|
|
32
|
+
# their luminance, as the PET 64's does.
|
|
33
|
+
GREEN_PALETTE = LUMINANCES.map do |luminance|
|
|
34
|
+
green = luminance * 255 / 32
|
|
35
|
+
((green / 4) << 16) | (green << 8) | (green / 4)
|
|
36
|
+
end.freeze
|
|
37
|
+
|
|
27
38
|
attr_reader :display, :width, :height, :vic_bank, :column,
|
|
28
39
|
:rasterline, :dirty_lines, :model, :region
|
|
29
40
|
|
|
41
|
+
# The RGB colours #display's palette indices stand for: PALETTE, or
|
|
42
|
+
# GREEN_PALETTE on a monochrome monitor.
|
|
43
|
+
attr_accessor :palette
|
|
44
|
+
|
|
45
|
+
# The line of #display the beam draws, which is the raster line unless
|
|
46
|
+
# the VIC-IIe's TEST bit has moved the raster counter on since the
|
|
47
|
+
# last vertical sync (#test_step!).
|
|
48
|
+
attr_reader :output_line
|
|
49
|
+
|
|
30
50
|
# The parts a VICE snapshot reads and sets.
|
|
31
51
|
attr_reader :registers, :display_state, :sequencer, :sprites, :character_buffer, :color_buffer,
|
|
32
52
|
:fetch_d011
|
|
@@ -71,6 +91,11 @@ module Badline
|
|
|
71
91
|
HOOK_DISPLAY = 16
|
|
72
92
|
HOOK_LAST = 32
|
|
73
93
|
|
|
94
|
+
# The vertical sync starts this many lines into the vertical blank,
|
|
95
|
+
# and lasts VSYNC_LINES.
|
|
96
|
+
VSYNC_DELAY = 3
|
|
97
|
+
VSYNC_LINES = 3
|
|
98
|
+
|
|
74
99
|
# On the 6569 the DMA compares fall in columns 53 and 54 and the
|
|
75
100
|
# display compare in column 57. A region whose sprite fetches run later
|
|
76
101
|
# moves them with the fetches (Region::Profile#sprite_cycle).
|
|
@@ -94,6 +119,7 @@ module Badline
|
|
|
94
119
|
@iie = %i[mos8566 mos8564].include?(model)
|
|
95
120
|
@core = model == :mos6569 ? :mos6569 : :mos8565
|
|
96
121
|
@region = region
|
|
122
|
+
@palette = PALETTE
|
|
97
123
|
@lightpen_extra = @core == :mos8565 ? 1 : 2
|
|
98
124
|
@grey_dots = @core == :mos8565
|
|
99
125
|
@delayed_fetch = @core == :mos8565
|
|
@@ -109,6 +135,7 @@ module Badline
|
|
|
109
135
|
@height = region.lines_per_frame
|
|
110
136
|
@last_column = @columns_per_line - 1
|
|
111
137
|
@last_line = @height - 1
|
|
138
|
+
@vsync_line = region.vblank[0] + VSYNC_DELAY
|
|
112
139
|
layout_columns
|
|
113
140
|
@blank_columns = Array.new(@columns_per_line) { |column| Region.blanked?(column, region.hblank) }.freeze
|
|
114
141
|
@blank_lines = Array.new(@height) { |line| Region.blanked?(line, region.vblank) }.freeze
|
|
@@ -137,6 +164,7 @@ module Badline
|
|
|
137
164
|
|
|
138
165
|
@column = 0
|
|
139
166
|
@rasterline = 0
|
|
167
|
+
@output_line = 0
|
|
140
168
|
|
|
141
169
|
@character_buffer = Array.new(40, 0)
|
|
142
170
|
@color_buffer = Array.new(40, 0)
|
|
@@ -153,11 +181,13 @@ module Badline
|
|
|
153
181
|
@lp_triggered = false
|
|
154
182
|
@lp_low = false
|
|
155
183
|
@raster_match = false
|
|
184
|
+
@test_wrap = false
|
|
156
185
|
end
|
|
157
186
|
|
|
158
187
|
# Everything the VIC holds between cycles: the beam, the fetch and
|
|
159
188
|
# g-access pipeline, the light pen and raster latches, the finished
|
|
160
|
-
# lines, the
|
|
189
|
+
# lines, on the VIC-IIe the display line and the TEST bit's wrap, the
|
|
190
|
+
# registers and the display, sequencer and sprite logic.
|
|
161
191
|
# Whether it renders is the host's, and every line comes back dirty so
|
|
162
192
|
# a front end repaints.
|
|
163
193
|
def save_state(out)
|
|
@@ -168,6 +198,7 @@ module Badline
|
|
|
168
198
|
out.int(@vic_bank.lines)
|
|
169
199
|
out.blob(@character_buffer).blob(@color_buffer).booleans(@sprite_ba)
|
|
170
200
|
@lines.each { |line| out.blob(line) }
|
|
201
|
+
out.int(@output_line).boolean(@test_wrap) if @iie
|
|
171
202
|
@registers.save_state(out)
|
|
172
203
|
@display_state.save_state(out)
|
|
173
204
|
@sequencer.save_state(out)
|
|
@@ -179,6 +210,7 @@ module Badline
|
|
|
179
210
|
load_beam(input)
|
|
180
211
|
load_buffers(input)
|
|
181
212
|
load_lines(input)
|
|
213
|
+
load_test_state(input) if @iie
|
|
182
214
|
@registers.load_state(input)
|
|
183
215
|
@display_state.load_state(input)
|
|
184
216
|
@sequencer.load_state(input)
|
|
@@ -202,6 +234,7 @@ module Badline
|
|
|
202
234
|
if @column == @columns_per_line
|
|
203
235
|
finish_line!
|
|
204
236
|
@column = 0
|
|
237
|
+
step_output_line
|
|
205
238
|
@rasterline = @rasterline == @last_line ? 0 : @rasterline + 1
|
|
206
239
|
check_raster_irq!(@rasterline.zero? ? @last_line : @rasterline)
|
|
207
240
|
end
|
|
@@ -239,6 +272,57 @@ module Badline
|
|
|
239
272
|
def fast? = @registers.fast?
|
|
240
273
|
def test? = @registers.test?
|
|
241
274
|
|
|
275
|
+
# $D030's FAST and TEST bits as bits 0 and 1, which the C128 reads once
|
|
276
|
+
# a cycle.
|
|
277
|
+
def clock_bits = @registers.clock_bits
|
|
278
|
+
|
|
279
|
+
# Whether the cycle just run was one of the five refresh cycles, Bauer's
|
|
280
|
+
# 11-15, whose phi1 half the VIC keeps in the VIC-IIe's FAST mode.
|
|
281
|
+
# @column has already advanced, so it is the Bauer cycle less one.
|
|
282
|
+
def refresh_cycle? = @column.between?(10, 14)
|
|
283
|
+
|
|
284
|
+
# In the VIC-IIe's FAST mode the 8502 drives the bus in both halves of
|
|
285
|
+
# the cycle, and the VIC's accesses in the cycle just run latched what
|
|
286
|
+
# it put there. The g-access, or the idle access, took the byte of
|
|
287
|
+
# phi1. A c-access took the byte of phi2 as one made before AEC does
|
|
288
|
+
# (#fetch_character_data!): $ff for the video matrix, unless the CPU
|
|
289
|
+
# was reading or writing the VIC's own registers, and the byte's low
|
|
290
|
+
# nibble for colour. AEC can't follow BA down while the CPU runs at
|
|
291
|
+
# 2 MHz, so on a bad line it falls three cycles after FAST mode ends.
|
|
292
|
+
def take_cpu_bus(phi1, phi2, register_access)
|
|
293
|
+
slot = @g_tick
|
|
294
|
+
@g_data[slot] = phi1 unless @g_kind[slot] == G_BLANK
|
|
295
|
+
display_state = @display_state
|
|
296
|
+
display_state.keep_bus(@column)
|
|
297
|
+
return unless display_state.fetching?(@column.zero? ? @last_column : @column - 1)
|
|
298
|
+
|
|
299
|
+
vmli = display_state.vmli
|
|
300
|
+
@character_buffer[vmli] = register_access ? phi2 : 0xff
|
|
301
|
+
@color_buffer[vmli] = phi2 & 0x0f
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# The VIC-IIe's TEST bit clocks the raster counter in every cycle, and
|
|
305
|
+
# the C128 calls this ahead of each cycle the bit is set in. The line's
|
|
306
|
+
# last cycle, whose own step it falls in with, adds nothing more. The
|
|
307
|
+
# counter takes two steps from the frame's last line to line 0, as line
|
|
308
|
+
# 0 reads the last line for its first cycle.
|
|
309
|
+
def test_step!
|
|
310
|
+
return if @column == @last_column
|
|
311
|
+
|
|
312
|
+
if @rasterline == @last_line
|
|
313
|
+
@test_wrap = !@test_wrap
|
|
314
|
+
return if @test_wrap
|
|
315
|
+
|
|
316
|
+
@rasterline = 0
|
|
317
|
+
@display_state.new_frame
|
|
318
|
+
else
|
|
319
|
+
@test_wrap = false
|
|
320
|
+
@rasterline += 1
|
|
321
|
+
end
|
|
322
|
+
@display_state.raster_step(@rasterline)
|
|
323
|
+
check_raster_irq!
|
|
324
|
+
end
|
|
325
|
+
|
|
242
326
|
def peek(addr)
|
|
243
327
|
i = offset_of(addr) % (2**6)
|
|
244
328
|
case i
|
|
@@ -347,7 +431,7 @@ module Badline
|
|
|
347
431
|
|
|
348
432
|
# Puts the beam at the start of `line`.
|
|
349
433
|
def restore_line(line)
|
|
350
|
-
@rasterline = line
|
|
434
|
+
@rasterline = @output_line = line
|
|
351
435
|
@column = 0
|
|
352
436
|
end
|
|
353
437
|
|
|
@@ -380,13 +464,11 @@ module Badline
|
|
|
380
464
|
@dirty_lines.fill(false)
|
|
381
465
|
end
|
|
382
466
|
|
|
383
|
-
def palette = PALETTE
|
|
384
|
-
|
|
385
467
|
private
|
|
386
468
|
|
|
387
469
|
def load_beam(input)
|
|
388
470
|
@column = input.int
|
|
389
|
-
@rasterline = input.int
|
|
471
|
+
@rasterline = @output_line = input.int
|
|
390
472
|
@cycles = input.int
|
|
391
473
|
@pending_write = input.boolean?
|
|
392
474
|
@g_tick = input.int
|
|
@@ -407,6 +489,13 @@ module Badline
|
|
|
407
489
|
input.booleans_into(@sprite_ba)
|
|
408
490
|
end
|
|
409
491
|
|
|
492
|
+
# The VIC-IIe's display line and TEST wrap, which only its TEST bit
|
|
493
|
+
# moves off the raster line.
|
|
494
|
+
def load_test_state(input)
|
|
495
|
+
@output_line = input.int
|
|
496
|
+
@test_wrap = input.boolean?
|
|
497
|
+
end
|
|
498
|
+
|
|
410
499
|
# The display is the finished lines one after another.
|
|
411
500
|
def load_lines(input)
|
|
412
501
|
@lines.each_with_index do |line, number|
|
|
@@ -649,7 +738,7 @@ module Badline
|
|
|
649
738
|
# or not there is a line to draw — then composite the active sprites
|
|
650
739
|
# over the finished background and copy the line into the frame display.
|
|
651
740
|
def finish_line!
|
|
652
|
-
return
|
|
741
|
+
return finish_blank_line if vblank? || !@render
|
|
653
742
|
|
|
654
743
|
composite = @sprites.active?
|
|
655
744
|
@sequencer.apply_color_patches
|
|
@@ -658,12 +747,38 @@ module Badline
|
|
|
658
747
|
@sequencer.apply_border if composite
|
|
659
748
|
|
|
660
749
|
colors = @sequencer.colors
|
|
661
|
-
|
|
750
|
+
output_line = @output_line
|
|
751
|
+
line = @lines[output_line]
|
|
662
752
|
return if line == colors
|
|
663
753
|
|
|
664
754
|
line[0, @width] = colors
|
|
665
|
-
@display[
|
|
666
|
-
@dirty_lines[
|
|
755
|
+
@display[output_line * @width, @width] = colors
|
|
756
|
+
@dirty_lines[output_line] = true
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
# A blanked line paints nothing, and is never shown unless the TEST
|
|
760
|
+
# bit has moved the beam off the raster line, where it shows black.
|
|
761
|
+
def finish_blank_line
|
|
762
|
+
@sprites.finish_line(nil, @sequencer.fg)
|
|
763
|
+
return if @output_line == @rasterline || !@render
|
|
764
|
+
|
|
765
|
+
line = @output_line
|
|
766
|
+
@lines[line].fill(0)
|
|
767
|
+
@display.fill(0, line * @width, @width)
|
|
768
|
+
@dirty_lines[line] = true
|
|
769
|
+
end
|
|
770
|
+
|
|
771
|
+
# The display line the beam draws next follows the one before it, and
|
|
772
|
+
# a line that ends in the vertical sync puts it back on the raster
|
|
773
|
+
# line. Only the VIC-IIe's TEST bit moves the raster counter on between
|
|
774
|
+
# the two, so the lines it skips shift the picture up until the next
|
|
775
|
+
# sync.
|
|
776
|
+
def step_output_line
|
|
777
|
+
@output_line = if @rasterline.between?(@vsync_line, @vsync_line + VSYNC_LINES - 1)
|
|
778
|
+
@rasterline + 1
|
|
779
|
+
else
|
|
780
|
+
@output_line == @last_line ? 0 : @output_line + 1
|
|
781
|
+
end
|
|
667
782
|
end
|
|
668
783
|
|
|
669
784
|
def video_matrix(index)
|
data/lib/badline.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: badline
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Inge Jørgensen
|
|
@@ -50,6 +50,7 @@ files:
|
|
|
50
50
|
- lib/badline.rb
|
|
51
51
|
- lib/badline/address_bus.rb
|
|
52
52
|
- lib/badline/address_bus/extra_sids.rb
|
|
53
|
+
- lib/badline/address_bus/fittings.rb
|
|
53
54
|
- lib/badline/address_bus/pla.rb
|
|
54
55
|
- lib/badline/address_bus/roms.rb
|
|
55
56
|
- lib/badline/address_bus/saved_state.rb
|
|
@@ -70,6 +71,23 @@ files:
|
|
|
70
71
|
- lib/badline/audio/stereo.rb
|
|
71
72
|
- lib/badline/audio/terminal.rb
|
|
72
73
|
- lib/badline/audio/wav.rb
|
|
74
|
+
- lib/badline/c128.rb
|
|
75
|
+
- lib/badline/c128/banks.rb
|
|
76
|
+
- lib/badline/c128/bus.rb
|
|
77
|
+
- lib/badline/c128/bus_state.rb
|
|
78
|
+
- lib/badline/c128/color_lines.rb
|
|
79
|
+
- lib/badline/c128/cpu.rb
|
|
80
|
+
- lib/badline/c128/keys.rb
|
|
81
|
+
- lib/badline/c128/mmu.rb
|
|
82
|
+
- lib/badline/c128/mmu_pages.rb
|
|
83
|
+
- lib/badline/c128/model.rb
|
|
84
|
+
- lib/badline/c128/modes.rb
|
|
85
|
+
- lib/badline/c128/saved_state.rb
|
|
86
|
+
- lib/badline/c128/vdc.rb
|
|
87
|
+
- lib/badline/c128/vdc/memory.rb
|
|
88
|
+
- lib/badline/c128/vdc/painter.rb
|
|
89
|
+
- lib/badline/c128/vdc/raster.rb
|
|
90
|
+
- lib/badline/c128/vdc/window.rb
|
|
73
91
|
- lib/badline/cartridge.rb
|
|
74
92
|
- lib/badline/cartridge/action_replay.rb
|
|
75
93
|
- lib/badline/cartridge/atomic_power.rb
|
|
@@ -108,6 +126,7 @@ files:
|
|
|
108
126
|
- lib/badline/color_memory.rb
|
|
109
127
|
- lib/badline/computer.rb
|
|
110
128
|
- lib/badline/computer/attachments.rb
|
|
129
|
+
- lib/badline/computer/kernal_traps.rb
|
|
111
130
|
- lib/badline/computer/saved_state.rb
|
|
112
131
|
- lib/badline/control_ports.rb
|
|
113
132
|
- lib/badline/core.rb
|
|
@@ -173,6 +192,7 @@ files:
|
|
|
173
192
|
- lib/badline/frontend/player_window.rb
|
|
174
193
|
- lib/badline/frontend/scope.rb
|
|
175
194
|
- lib/badline/frontend/screen.rb
|
|
195
|
+
- lib/badline/frontend/screens.rb
|
|
176
196
|
- lib/badline/frontend/screenshot.rb
|
|
177
197
|
- lib/badline/frontend/sid_history.rb
|
|
178
198
|
- lib/badline/frontend/sid_view.rb
|
|
@@ -228,6 +248,7 @@ files:
|
|
|
228
248
|
- lib/badline/model.rb
|
|
229
249
|
- lib/badline/options.rb
|
|
230
250
|
- lib/badline/options/event.rb
|
|
251
|
+
- lib/badline/options/family.rb
|
|
231
252
|
- lib/badline/options/help.rb
|
|
232
253
|
- lib/badline/options/option.rb
|
|
233
254
|
- lib/badline/options/table.rb
|
|
@@ -247,11 +268,16 @@ files:
|
|
|
247
268
|
- lib/badline/rom.rb
|
|
248
269
|
- lib/badline/roms/README
|
|
249
270
|
- lib/badline/roms/basic.rom
|
|
271
|
+
- lib/badline/roms/c128/basic.rom
|
|
272
|
+
- lib/badline/roms/c128/character.rom
|
|
273
|
+
- lib/badline/roms/c128/kernal.rom
|
|
274
|
+
- lib/badline/roms/c64gs.rom
|
|
250
275
|
- lib/badline/roms/character.rom
|
|
251
276
|
- lib/badline/roms/dos1541.rom
|
|
252
277
|
- lib/badline/roms/eapi/LICENSE.md
|
|
253
278
|
- lib/badline/roms/eapi/README
|
|
254
279
|
- lib/badline/roms/eapi/eapi-am29f040-14
|
|
280
|
+
- lib/badline/roms/kernal-pet64.rom
|
|
255
281
|
- lib/badline/roms/kernal-sx64.rom
|
|
256
282
|
- lib/badline/roms/kernal.rom
|
|
257
283
|
- lib/badline/roms/vic20/basic.rom
|